diff --git a/.gitignore b/.gitignore index d5dca0c..9606eee 100644 --- a/.gitignore +++ b/.gitignore @@ -412,3 +412,5 @@ FodyWeavers.xsd # Built Visual Studio Code Extensions *.vsix +# Minified css files +**.min.css diff --git a/Annotations/CategoryAttribute.cs b/Annotations/CategoryAttribute.cs new file mode 100644 index 0000000..063d1d3 --- /dev/null +++ b/Annotations/CategoryAttribute.cs @@ -0,0 +1,538 @@ +namespace Connected.Annotations; + +/// +/// Specifies the name of the category in which to group the property of a MudBlazor component when displayed in the API documentation. +/// +/// +/// Use this attribute together with the .
+/// This attribute is similar to .
+/// The name of the category can be specified by using a constant defined in the class. +///
+[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] +public class CategoryAttribute : Attribute +{ + public CategoryAttribute(string name) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("The category name cannot be null nor empty."); + if (!categoryOrder.ContainsKey(name)) + throw new ArgumentException($"The given category name '{name}' isn't in the categoryOrder field."); + Name = name; + } + + /// The name of the category. + public string Name { get; } + + /// The order of the category - the greater the number the lower the category will be displayed in the API documentation. + public int Order => categoryOrder[Name]; + + // Possible categories of component properties and the order in which they are displayed in the API documentation. + private static readonly Dictionary categoryOrder = new() + { + ["Data"] = 0, // general category + ["Validation"] = 1, // general category + + // specific categories associated with data + ["Validated data"] = 2, + ["Validation result"] = 3, + + ["Behavior"] = 100, // general category + + ["Header"] = 101, + ["Rows"] = 102, + ["Footer"] = 103, + + // specific behaviors of a component + ["Filtering"] = 200, + ["Grouping"] = 201, + ["Expanding"] = 202, + ["Sorting"] = 203, + ["Pagination"] = 204, + ["Selecting"] = 205, + ["Editing"] = 206, + ["Click action"] = 207, + ["Items"] = 208, + ["Disable"] = 209, + ["DraggingClass"] = 210, + ["DropRules"] = 211, + + ["Appearance"] = 300, // general category + + // specific parts of a component together with their behavior and appearance + ["Popup behavior"] = 400, + ["Popup appearance"] = 401, + ["List behavior"] = 402, + ["List appearance"] = 403, + ["Picker behavior"] = 404, + ["Picker appearance"] = 405, + ["Dot"] = 406, + + // "Miscellaneous" category. In classes inheriting from MudComponentBase it can be used only exceptionally - + // - only when the property can define behavior or appearance depending on value of the property. + ["Misc"] = int.MaxValue - 1, + + ["Common"] = int.MaxValue // general category + }; +} + +/// +/// Possible categories of MudBlazor components properties. +/// +/// +/// General categories +/// +/// - Data - Used e.g. in form fields, pickers, , , , +/// , and . Containers have this group when their items can be defined +/// not only in markup language, but also programmatically in the Items property and by specifying ItemTemplate.
+/// - Validation - Used in form fields and pickers.
+/// - Behavior - Changing these properties changes behavior of the component and behavior of the application. So in some way they are or may be more +/// important than the "Appearance" category. Example properties are: a) the Disabled property, b) icons (or avatars) without default value +/// (because setting their value can pass additional information).
+/// - Appearance - Changing these properties doesn't change behavior of the component and behavior of the application, but only changes the appearance +/// of the component irrelevant to the understanding of the application by a user. So in some way they are less important than the "Behavior" +/// category, because they are only used to adjust the look of the application. Example properties are: a) Elevation, Outlined, +/// Square, Rounded, DisableGutters, Dense, DisableRipple; b) size, color, and typography of the item +/// and its subelements; c) CSS classes and styles of subelements; d) icons with the default value already set (because most often changing its value +/// doesn't change passed information).
+/// - Common - Properties defined in . +///
+/// +/// Note: The following properties belong to the "Behavior" group, not to the "Appearance" group:
+/// - - because it describes meaning of the button, since MudIconButton doesn't have text,
+/// - - because it describes meaning of the field,
+/// - - because it can describe information important to a user, e.g. a numeric field unit such as kilograms.
+/// Sometimes choosing a category can be difficult - in such case choose a category that makes the most sense. +///
+/// +/// Categories for specific behaviors or specific parts of components +/// If some elements or behaviors can be distinguished in a component, then their properties are included in separate groups. +/// +/// Note: If a property qualifies for both the "Appearance" or "Behavior" group, and for some special group, then this special group takes precedence. +/// For example, could belong to the "Appearance" group, but belongs to the "Editing" group. +/// +/// Additional information +/// The list of categories is inspired by the categories displayed for Windows Forms and Web Forms components in the Visual Studio "Properties" window. +///
+public static class CategoryTypes +{ + /* Implementation note: + * Almost all components use the "Behavior" and "Appearance" categories. We could simplify the code + * by inheriting these constants, but C# doesn't allow to inherit static members of a class. + */ + + /// Used in . + public static class ComponentBase + { + public const string Common = "Common"; + } + + /// Used in: , all components inheriting from it, and . + public static class Button + { + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + /// Used in and all components inheriting from it. + public static class FormComponent + { + public const string Data = "Data"; + public const string Validation = "Validation"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + public const string ListBehavior = "List behavior"; + public const string ListAppearance = "List appearance"; + public const string PickerBehavior = "Picker behavior"; + public const string PickerAppearance = "Picker appearance"; + } + + /// Used in all charts, that is in and all components inheriting from it. + public static class Chart + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + /// Used in other base classes. + public static class General + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + public static class Alert + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class AppBar + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Avatar + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class AvatarGroup + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Badge + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Breadcrumbs + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class BreakpointProvider + { + public const string Behavior = "Behavior"; + } + + public static class ButtonGroup + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Card + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Carousel + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Chip + { + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + public static class ChipSet + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Container + { + public const string Behavior = "Behavior"; + } + + public static class Dialog + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + public const string Misc = "Misc"; + } + + public static class Divider + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Drawer + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class DropZone + { + public const string Appearance = "Appearance"; + public const string Behavior = "Behavior"; + public const string Disabled = "Disable"; + public const string Sorting = "Sorting"; + public const string DraggingClass = "DraggingClass"; + public const string DropRules = "DropRules"; + public const string Items = "Items"; + } + + public static class Element + { + public const string Misc = "Misc"; + } + + public static class ExpansionPanel + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Field + { + public const string Data = "Data"; + public const string Validation = "Validation"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class FileUpload + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class FocusTrap + { + public const string Behavior = "Behavior"; + } + + public static class Form + { + public const string ValidatedData = "Validated data"; + public const string ValidationResult = "Validation result"; + public const string Behavior = "Behavior"; + } + + public static class Grid + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Highlighter + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Image + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Item + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Hidden + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Icon + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Link + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class List + { + public const string Behavior = "Behavior"; + public const string Expanding = "Expanding"; + public const string Selecting = "Selecting"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + public static class MainContent + { + public const string Behavior = "Behavior"; + } + + public static class Menu + { + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + public const string PopupBehavior = "Popup behavior"; + public const string PopupAppearance = "Popup appearance"; + } + + public static class MessageBox + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class NavMenu + { + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + public static class Overlay + { + public const string Behavior = "Behavior"; + public const string ClickAction = "Click action"; + } + + public static class Pagination + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Paper + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Popover + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class ProgressLinear + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class ProgressCircular + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Radio + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Rating + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class RTLProvider + { + public const string Behavior = "Behavior"; + } + + public static class ScrollToTop + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Skeleton + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Stack + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Slider + { + public const string Data = "Data"; + public const string Validation = "Validation"; + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class SwipeArea + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Table + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string Header = "Header"; + public const string Rows = "Rows"; + public const string Footer = "Footer"; + public const string Filtering = "Filtering"; + public const string Grouping = "Grouping"; + public const string Sorting = "Sorting"; + public const string Pagination = "Pagination"; + public const string Selecting = "Selecting"; + public const string Editing = "Editing"; + public const string Appearance = "Appearance"; + } + + public static class SimpleTable + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Tabs + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Timeline + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + public const string Dot = "Dot"; + } + + public static class ToolBar + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class Tooltip + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } + + public static class TreeView + { + public const string Data = "Data"; + public const string Behavior = "Behavior"; + public const string Expanding = "Expanding"; + public const string Selecting = "Selecting"; + public const string ClickAction = "Click action"; + public const string Appearance = "Appearance"; + } + + public static class Text + { + public const string Behavior = "Behavior"; + public const string Appearance = "Appearance"; + } +} diff --git a/Annotations/LabelAttribute.cs b/Annotations/LabelAttribute.cs new file mode 100644 index 0000000..8e906da --- /dev/null +++ b/Annotations/LabelAttribute.cs @@ -0,0 +1,12 @@ +namespace Connected.Annotations; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] +public class LabelAttribute : Attribute +{ + public LabelAttribute(string name) + { + Name = name; + } + + public string Name { get; } +} diff --git a/Colors.cs b/Colors.cs new file mode 100644 index 0000000..771f00b --- /dev/null +++ b/Colors.cs @@ -0,0 +1,343 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected; + +[ExcludeFromCodeCoverage] +public static class Colors +{ + public static partial class Red + { + public static string Default { get; } = "#F44336"; + public static string Lighten5 { get; } = "#FFEBEE"; + public static string Lighten4 { get; } = "#FFCDD2"; + public static string Lighten3 { get; } = "#EF9A9A"; + public static string Lighten2 { get; } = "#E57373"; + public static string Lighten1 { get; } = "#EF5350"; + public static string Darken1 { get; } = "#E53935"; + public static string Darken2 { get; } = "#D32F2F"; + public static string Darken3 { get; } = "#C62828"; + public static string Darken4 { get; } = "#B71C1C"; + public static string Accent1 { get; } = "#FF8A80"; + public static string Accent2 { get; } = "#FF5252"; + public static string Accent3 { get; } = "#FF1744"; + public static string Accent4 { get; } = "#D50000"; + } + + public static class Pink + { + public static string Default { get; } = "#E91E63"; + public static string Lighten5 { get; } = "#FCE4EC"; + public static string Lighten4 { get; } = "#F8BBD0"; + public static string Lighten3 { get; } = "#F48FB1"; + public static string Lighten2 { get; } = "#F06292"; + public static string Lighten1 { get; } = "#EC407A"; + public static string Darken1 { get; } = "#D81B60"; + public static string Darken2 { get; } = "#C2185B"; + public static string Darken3 { get; } = "#AD1457"; + public static string Darken4 { get; } = "#880E4F"; + public static string Accent1 { get; } = "#FF80AB"; + public static string Accent2 { get; } = "#FF4081"; + public static string Accent3 { get; } = "#F50057"; + public static string Accent4 { get; } = "#C51162"; + } + + public static class Purple + { + public static string Default { get; } = "#9C27B0"; + public static string Lighten5 { get; } = "#F3E5F5"; + public static string Lighten4 { get; } = "#E1BEE7"; + public static string Lighten3 { get; } = "#CE93D8"; + public static string Lighten2 { get; } = "#BA68C8"; + public static string Lighten1 { get; } = "#AB47BC"; + public static string Darken1 { get; } = "#8E24AA"; + public static string Darken2 { get; } = "#7B1FA2"; + public static string Darken3 { get; } = "#6A1B9A"; + public static string Darken4 { get; } = "#4A148C"; + public static string Accent1 { get; } = "#EA80FC"; + public static string Accent2 { get; } = "#E040FB"; + public static string Accent3 { get; } = "#D500F9"; + public static string Accent4 { get; } = "#AA00FF"; + } + + public static class DeepPurple + { + public static string Default { get; } = "#673AB7"; + public static string Lighten5 { get; } = "#EDE7F6"; + public static string Lighten4 { get; } = "#D1C4E9"; + public static string Lighten3 { get; } = "#B39DDB"; + public static string Lighten2 { get; } = "#9575CD"; + public static string Lighten1 { get; } = "#7E57C2"; + public static string Darken1 { get; } = "#5E35B1"; + public static string Darken2 { get; } = "#512DA8"; + public static string Darken3 { get; } = "#4527A0"; + public static string Darken4 { get; } = "#311B92"; + public static string Accent1 { get; } = "#B388FF"; + public static string Accent2 { get; } = "#7C4DFF"; + public static string Accent3 { get; } = "#651FFF"; + public static string Accent4 { get; } = "#6200EA"; + } + + public static class Indigo + { + public static string Default { get; } = "#3F51B5"; + public static string Lighten5 { get; } = "#E8EAF6"; + public static string Lighten4 { get; } = "#C5CAE9"; + public static string Lighten3 { get; } = "#9FA8DA"; + public static string Lighten2 { get; } = "#7986CB"; + public static string Lighten1 { get; } = "#5C6BC0"; + public static string Darken1 { get; } = "#3949AB"; + public static string Darken2 { get; } = "#303F9F"; + public static string Darken3 { get; } = "#283593"; + public static string Darken4 { get; } = "#1A237E"; + public static string Accent1 { get; } = "#8C9EFF"; + public static string Accent2 { get; } = "#536DFE"; + public static string Accent3 { get; } = "#3D5AFE"; + public static string Accent4 { get; } = "#304FFE"; + } + + public static class Blue + { + public static string Default { get; } = "#2196F3"; + public static string Lighten5 { get; } = "#E3F2FD"; + public static string Lighten4 { get; } = "#BBDEFB"; + public static string Lighten3 { get; } = "#90CAF9"; + public static string Lighten2 { get; } = "#64B5F6"; + public static string Lighten1 { get; } = "#42A5F5"; + public static string Darken1 { get; } = "#1E88E5"; + public static string Darken2 { get; } = "#1976D2"; + public static string Darken3 { get; } = "#1565C0"; + public static string Darken4 { get; } = "#0D47A1"; + public static string Accent1 { get; } = "#82B1FF"; + public static string Accent2 { get; } = "#448AFF"; + public static string Accent3 { get; } = "#2979FF"; + public static string Accent4 { get; } = "#2962FF"; + } + + public static class LightBlue + { + public static string Default { get; } = "#03A9F4"; + public static string Lighten5 { get; } = "#E1F5FE"; + public static string Lighten4 { get; } = "#B3E5FC"; + public static string Lighten3 { get; } = "#81D4FA"; + public static string Lighten2 { get; } = "#4FC3F7"; + public static string Lighten1 { get; } = "#29B6F6"; + public static string Darken1 { get; } = "#039BE5"; + public static string Darken2 { get; } = "#0288D1"; + public static string Darken3 { get; } = "#0277BD"; + public static string Darken4 { get; } = "#01579B"; + public static string Accent1 { get; } = "#80D8FF"; + public static string Accent2 { get; } = "#40C4FF"; + public static string Accent3 { get; } = "#00B0FF"; + public static string Accent4 { get; } = "#0091EA"; + } + + public static class Cyan + { + public static string Default { get; } = "#00BCD4"; + public static string Lighten5 { get; } = "#E0F7FA"; + public static string Lighten4 { get; } = "#B2EBF2"; + public static string Lighten3 { get; } = "#80DEEA"; + public static string Lighten2 { get; } = "#4DD0E1"; + public static string Lighten1 { get; } = "#26C6DA"; + public static string Darken1 { get; } = "#00ACC1"; + public static string Darken2 { get; } = "#0097A7"; + public static string Darken3 { get; } = "#00838F"; + public static string Darken4 { get; } = "#006064"; + public static string Accent1 { get; } = "#84FFFF"; + public static string Accent2 { get; } = "#18FFFF"; + public static string Accent3 { get; } = "#00E5FF"; + public static string Accent4 { get; } = "#00B8D4"; + } + + public static class Teal + { + public static string Default { get; } = "#009688"; + public static string Lighten5 { get; } = "#E0F2F1"; + public static string Lighten4 { get; } = "#B2DFDB"; + public static string Lighten3 { get; } = "#80CBC4"; + public static string Lighten2 { get; } = "#4DB6AC"; + public static string Lighten1 { get; } = "#26A69A"; + public static string Darken1 { get; } = "#00897B"; + public static string Darken2 { get; } = "#00796B"; + public static string Darken3 { get; } = "#00695C"; + public static string Darken4 { get; } = "#004D40"; + public static string Accent1 { get; } = "#A7FFEB"; + public static string Accent2 { get; } = "#64FFDA"; + public static string Accent3 { get; } = "#1DE9B6"; + public static string Accent4 { get; } = "#00BFA5"; + } + + public static class Green + { + public static string Default { get; } = "#4CAF50"; + public static string Lighten5 { get; } = "#E8F5E9"; + public static string Lighten4 { get; } = "#C8E6C9"; + public static string Lighten3 { get; } = "#A5D6A7"; + public static string Lighten2 { get; } = "#81C784"; + public static string Lighten1 { get; } = "#66BB6A"; + public static string Darken1 { get; } = "#43A047"; + public static string Darken2 { get; } = "#388E3C"; + public static string Darken3 { get; } = "#2E7D32"; + public static string Darken4 { get; } = "#1B5E20"; + public static string Accent1 { get; } = "#B9F6CA"; + public static string Accent2 { get; } = "#69F0AE"; + public static string Accent3 { get; } = "#00E676"; + public static string Accent4 { get; } = "#00C853"; + } + + public static class LightGreen + { + public static string Default { get; } = "#8BC34A"; + public static string Lighten5 { get; } = "#F1F8E9"; + public static string Lighten4 { get; } = "#DCEDC8"; + public static string Lighten3 { get; } = "#C5E1A5"; + public static string Lighten2 { get; } = "#AED581"; + public static string Lighten1 { get; } = "#9CCC65"; + public static string Darken1 { get; } = "#7CB342"; + public static string Darken2 { get; } = "#689F38"; + public static string Darken3 { get; } = "#558B2F"; + public static string Darken4 { get; } = "#33691E"; + public static string Accent1 { get; } = "#CCFF90"; + public static string Accent2 { get; } = "#B2FF59"; + public static string Accent3 { get; } = "#76FF03"; + public static string Accent4 { get; } = "#64DD17"; + } + + public static class Lime + { + public static string Default { get; } = "#CDDC39"; + public static string Lighten5 { get; } = "#F9FBE7"; + public static string Lighten4 { get; } = "#F0F4C3"; + public static string Lighten3 { get; } = "#E6EE9C"; + public static string Lighten2 { get; } = "#DCE775"; + public static string Lighten1 { get; } = "#D4E157"; + public static string Darken1 { get; } = "#C0CA33"; + public static string Darken2 { get; } = "#AFB42B"; + public static string Darken3 { get; } = "#9E9D24"; + public static string Darken4 { get; } = "#827717"; + public static string Accent1 { get; } = "#F4FF81"; + public static string Accent2 { get; } = "#EEFF41"; + public static string Accent3 { get; } = "#C6FF00"; + public static string Accent4 { get; } = "#AEEA00"; + } + + public static class Yellow + { + public static string Default { get; } = "#FFEB3B"; + public static string Lighten5 { get; } = "#FFFDE7"; + public static string Lighten4 { get; } = "#FFF9C4"; + public static string Lighten3 { get; } = "#FFF59D"; + public static string Lighten2 { get; } = "#FFF176"; + public static string Lighten1 { get; } = "#FFEE58"; + public static string Darken1 { get; } = "#FDD835"; + public static string Darken2 { get; } = "#FBC02D"; + public static string Darken3 { get; } = "#F9A825"; + public static string Darken4 { get; } = "#F57F17"; + public static string Accent1 { get; } = "#FFFF8D"; + public static string Accent2 { get; } = "#FFFF00"; + public static string Accent3 { get; } = "#FFEA00"; + public static string Accent4 { get; } = "#FFD600"; + } + + public static class Amber + { + public static string Default { get; } = "#FFC107"; + public static string Lighten5 { get; } = "#FFF8E1"; + public static string Lighten4 { get; } = "#FFECB3"; + public static string Lighten3 { get; } = "#FFE082"; + public static string Lighten2 { get; } = "#FFD54F"; + public static string Lighten1 { get; } = "#FFCA28"; + public static string Darken1 { get; } = "#FFB300"; + public static string Darken2 { get; } = "#FFA000"; + public static string Darken3 { get; } = "#FF8F00"; + public static string Darken4 { get; } = "#FF6F00"; + public static string Accent1 { get; } = "#FFE57F"; + public static string Accent2 { get; } = "#FFD740"; + public static string Accent3 { get; } = "#FFC400"; + public static string Accent4 { get; } = "#FFAB00"; + } + + public static class Orange + { + public static string Default { get; } = "#FF9800"; + public static string Lighten5 { get; } = "#FFF3E0"; + public static string Lighten4 { get; } = "#FFE0B2"; + public static string Lighten3 { get; } = "#FFCC80"; + public static string Lighten2 { get; } = "#FFB74D"; + public static string Lighten1 { get; } = "#FFA726"; + public static string Darken1 { get; } = "#FB8C00"; + public static string Darken2 { get; } = "#F57C00"; + public static string Darken3 { get; } = "#EF6C00"; + public static string Darken4 { get; } = "#E65100"; + public static string Accent1 { get; } = "#FFD180"; + public static string Accent2 { get; } = "#FFAB40"; + public static string Accent3 { get; } = "#FF9100"; + public static string Accent4 { get; } = "#FF6D00"; + } + + public static class DeepOrange + { + public static string Default { get; } = "#FF5722"; + public static string Lighten5 { get; } = "#FBE9E7"; + public static string Lighten4 { get; } = "#FFCCBC"; + public static string Lighten3 { get; } = "#FFAB91"; + public static string Lighten2 { get; } = "#FF8A65"; + public static string Lighten1 { get; } = "#FF7043"; + public static string Darken1 { get; } = "#F4511E"; + public static string Darken2 { get; } = "#E64A19"; + public static string Darken3 { get; } = "#D84315"; + public static string Darken4 { get; } = "#BF360C"; + public static string Accent1 { get; } = "#FF9E80"; + public static string Accent2 { get; } = "#FF6E40"; + public static string Accent3 { get; } = "#FF3D00"; + public static string Accent4 { get; } = "#DD2C00"; + } + + public static class Brown + { + public static string Default { get; } = "#795548"; + public static string Lighten5 { get; } = "#EFEBE9"; + public static string Lighten4 { get; } = "#D7CCC8"; + public static string Lighten3 { get; } = "#BCAAA4"; + public static string Lighten2 { get; } = "#A1887F"; + public static string Lighten1 { get; } = "#8D6E63"; + public static string Darken1 { get; } = "#6D4C41"; + public static string Darken2 { get; } = "#5D4037"; + public static string Darken3 { get; } = "#4E342E"; + public static string Darken4 { get; } = "#3E2723"; + } + + public static class BlueGrey + { + public static string Default { get; } = "#607D8B"; + public static string Lighten5 { get; } = "#ECEFF1"; + public static string Lighten4 { get; } = "#CFD8DC"; + public static string Lighten3 { get; } = "#B0BEC5"; + public static string Lighten2 { get; } = "#90A4AE"; + public static string Lighten1 { get; } = "#78909C"; + public static string Darken1 { get; } = "#546E7A"; + public static string Darken2 { get; } = "#455A64"; + public static string Darken3 { get; } = "#37474F"; + public static string Darken4 { get; } = "#263238"; + } + public static class Grey + { + public static string Default { get; } = "#9E9E9E"; + public static string Lighten5 { get; } = "#FAFAFA"; + public static string Lighten4 { get; } = "#F5F5F5"; + public static string Lighten3 { get; } = "#EEEEEE"; + public static string Lighten2 { get; } = "#E0E0E0"; + public static string Lighten1 { get; } = "#BDBDBD"; + public static string Darken1 { get; } = "#757575"; + public static string Darken2 { get; } = "#616161"; + public static string Darken3 { get; } = "#424242"; + public static string Darken4 { get; } = "#212121"; + } + + public static class Shades + { + public static string Black { get; } = "#000000"; + public static string White { get; } = "#FFFFFF"; + public static string Transparent { get; } = "transparent"; + } +} diff --git a/Components/Alert/Alert.razor b/Components/Alert/Alert.razor new file mode 100644 index 0000000..a656343 --- /dev/null +++ b/Components/Alert/Alert.razor @@ -0,0 +1,26 @@ +@namespace Connected.Components + +@inherits UIComponent + + \ No newline at end of file diff --git a/Components/Alert/Alert.razor.cs b/Components/Alert/Alert.razor.cs new file mode 100644 index 0000000..2146b93 --- /dev/null +++ b/Components/Alert/Alert.razor.cs @@ -0,0 +1,143 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Alert : UIComponent +{ + [CascadingParameter(Name = "RightToLeft")] + public bool RightToLeft { get; set; } + /// + /// Sets the position of the text to the start (Left in LTR and right in RTL). + /// + [Parameter] + public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left; + /// + /// The callback, when the close button has been clicked. + /// + [Parameter] public EventCallback CloseGlyphClicked { get; set; } + /// + /// Define the icon used for the close button. + /// + [Parameter] + public string CloseGlyph { get; set; } = Icons.Material.Filled.Close; + /// + /// Sets if the alert shows a close icon. + /// + [Parameter] + public bool CloseGlyphVisible { get; set; } + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + public int Elevation { set; get; } = 0; + /// + /// If true, rounded corners are disabled. + /// + [Parameter] + public bool Square { get; set; } + /// + /// If true, compact padding will be used. + /// + [Parameter] + public bool Dense { get; set; } + /// + /// If true, no alert icon will be used. + /// + [Parameter] + public bool GlyphVisible { get; set; } + /// + /// The severity of the alert. This defines the color and icon used. + /// + [Parameter] + public Severity Severity { get; set; } = Severity.Normal; + /// + /// The variant to use. + /// + [Parameter] + public Variant Variant { get; set; } = Variant.Text; + /// + /// Child content of the component. + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } + /// + /// Custom icon, leave unset to use the standard icon which depends on the Severity + /// + [Parameter] + public string Glyph { get; set; } = default!; + /// + /// Raised when the alert is clicked + /// + [Parameter] + public EventCallback OnClick { get; set; } + + protected string ClassList + { + get + { + return new CssBuilder("alert") + .AddClass($"alert-{Variant.ToDescriptionString()}-{Severity.ToDescriptionString()}") + .AddClass($"dense", Dense) + .AddClass($"square", Square) + .AddClass($"elevation-{Elevation}") + .AddClass(Class) + .Build(); + } + } + + protected string ClassPosition + { + get + { + return new CssBuilder("alert-position") + .AddClass($"justify-sm-{ConvertHorizontalAlignment(Alignment).ToDescriptionString()}") + .Build(); + } + } + + private HorizontalAlignment ConvertHorizontalAlignment(HorizontalAlignment contentAlignment) + { + return contentAlignment switch + { + HorizontalAlignment.Right => RightToLeft ? HorizontalAlignment.Start : HorizontalAlignment.End, + HorizontalAlignment.Left => RightToLeft ? HorizontalAlignment.End : HorizontalAlignment.Start, + _ => contentAlignment + }; + } + + + internal async Task OnCloseGlyphClick() + { + if (CloseGlyphClicked.HasDelegate) + { + await CloseGlyphClicked.InvokeAsync(this); + return; + } + + await Task.CompletedTask; + } + + //If we can check this exception can include the coverage again + [ExcludeFromCodeCoverage] + protected override void OnParametersSet() + { + if (!string.IsNullOrEmpty(Glyph)) + return; + + Glyph = Severity switch + { + Severity.Normal => Icons.Material.Outlined.EventNote, + Severity.Info => Icons.Material.Outlined.Info, + Severity.Success => Icons.Custom.Uncategorized.AlertSuccess, + Severity.Warning => Icons.Material.Outlined.ReportProblem, + Severity.Error => Icons.Material.Filled.ErrorOutline, + _ => throw new ArgumentOutOfRangeException(nameof(Severity)), + }; + } +} + + diff --git a/Components/AppBar/AppBar.razor b/Components/AppBar/AppBar.razor new file mode 100644 index 0000000..fb13ed1 --- /dev/null +++ b/Components/AppBar/AppBar.razor @@ -0,0 +1,10 @@ +@namespace Connected.Components +@inherits UIComponent + +
+ + @ChildContent + +
+ + diff --git a/Components/AppBar/AppBar.razor.cs b/Components/AppBar/AppBar.razor.cs new file mode 100644 index 0000000..41ac692 --- /dev/null +++ b/Components/AppBar/AppBar.razor.cs @@ -0,0 +1,75 @@ +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class AppBar : UIComponent +{ + /// + /// If true, Appbar will be placed at the bottom of the screen. + /// + [Parameter] + public bool Bottom { get; set; } + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + public int Elevation { set; get; } = 4; + + /// + /// If true, compact padding will be used. + /// + [Parameter] + public bool Dense { get; set; } + + /// + /// If true, the left and right padding is removed from from the appbar. + /// + [Parameter] + public bool DisableGutters { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// If true, appbar will be Fixed. + /// + [Parameter] + public bool Fixed { get; set; } = true; + + /// + /// User class names, separated by spaces for the nested toolbar. + /// + [Parameter] + public string? ToolBarClass { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } + + protected string ClassList() + { + return new CssBuilder("appbar") + .AddClass($"appbar-dense", Dense) + .AddClass($"appbar-fixed-top", Fixed && !Bottom) + .AddClass($"appbar-fixed-bottom", Fixed && Bottom) + .AddClass($"elevation-{Elevation}") + .AddClass($"theme-{Color.ToDescriptionString()}", Color != ThemeColor.Default) + .AddClass(Class) + .Build(); + } + + protected string ToolBarClassList() + { + return new CssBuilder("toolbar-appbar") + .AddClass(ToolBarClass) + .Build(); + } +} diff --git a/Components/Autocomplete/Autocomplete.razor b/Components/Autocomplete/Autocomplete.razor new file mode 100644 index 0000000..67eeda7 --- /dev/null +++ b/Components/Autocomplete/Autocomplete.razor @@ -0,0 +1,96 @@ +@namespace Connected.Components +@inherits InputBase +@typeparam T + + +
+ + + + + @if (ShowProgressIndicator && IsLoading) + { + @if (ProgressIndicatorTemplate is not null) + { + @ProgressIndicatorTemplate + } + else + { +
+ +
+ } + } + + + @if(ProgressIndicatorInPopoverTemplate != null && IsLoading) + { + @ProgressIndicatorInPopoverTemplate + } + else if (_items != null && _items.Length != 0) + { + + @for (var index = 0; index < _items.Length; index++) + { + var item = _items[index]; + bool is_selected = index == _selectedListItemIndex; + bool is_disabled = !_enabledItemIndices.Contains(index); + + @if (ItemTemplate == null) + { + @GetItemString(item) + } + else if (is_disabled && ItemDisabledTemplate is not null) + { + @ItemDisabledTemplate(item) + } + else if (is_selected) + { + @if (ItemSelectedTemplate is null) + @ItemTemplate(item) + else + @ItemSelectedTemplate(item) + + } + else + { + @ItemTemplate(item) + } + + } + @if (MoreItemsTemplate is not null && _itemsReturned > MaxItems) + { +
+ @MoreItemsTemplate +
+ } +
+ } + else if (NoItemsTemplate is not null) + { +
+ @NoItemsTemplate +
+ } +
+
+
+
+
+ + \ No newline at end of file diff --git a/Components/Autocomplete/Autocomplete.razor.cs b/Components/Autocomplete/Autocomplete.razor.cs new file mode 100644 index 0000000..b08bda5 --- /dev/null +++ b/Components/Autocomplete/Autocomplete.razor.cs @@ -0,0 +1,696 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Autocomplete : InputBase, IDisposable +{ + private Func? _toStringFunc; + private Task _currentSearchTask; + private CancellationTokenSource _cancellationTokenSrc; + private bool _isOpen; + private Timer _timer; + private T[] _items; + private int _selectedListItemIndex = 0; + private IList _enabledItemIndices = new List(); + private int _itemsReturned; //the number of items returned by the search function + int _elementKey = 0; + /// + /// This boolean will keep track if the clear function is called too keep the set text function to be called. + /// + private bool _isCleared; + private Input _elementReference; + /// + /// We need a random id for the year items in the year list so we can scroll to the item safely in every DatePicker. + /// + private readonly string _componentId = Guid.NewGuid().ToString(); + + public Autocomplete() + { + Adornment = Adornment.End; + IconSize = Size.Medium; + } + + [Inject] + IScrollManager ScrollManager { get; set; } + /// + /// User class names for the popover, separated by space + /// + [Parameter] + public string PopoverClass { get; set; } + /// + /// Set the anchor origin point to determen where the popover will open from. + /// + [Parameter] + public Origin AnchorOrigin { get; set; } = Origin.BottomCenter; + /// + /// Sets the transform origin point for the popover. + /// + [Parameter] + public Origin TransformOrigin { get; set; } = Origin.TopCenter; + /// + /// If true, compact vertical padding will be applied to all Autocomplete items. + /// + [Parameter] + public bool Dense { get; set; } + /// + /// The Open Autocomplete Icon + /// + [Parameter] + public string OpenIcon { get; set; } = Icons.Material.Filled.ArrowDropDown; + /// + /// The Close Autocomplete Icon + /// + [Parameter] + public string CloseIcon { get; set; } = Icons.Material.Filled.ArrowDropUp; + /// + /// The maximum height of the Autocomplete when it is open. + /// + [Parameter] + public int MaxHeight { get; set; } = 300; + /// + /// Defines how values are displayed in the drop-down list + /// + [Parameter] + public Func? ToStringFunc + { + get => _toStringFunc; + set + { + if (_toStringFunc == value) + return; + + _toStringFunc = value; + + Converter = new Converter + { + SetFunc = _toStringFunc ?? (x => x?.ToString()), + }; + } + } + /// + /// Whether to show the progress indicator. + /// + [Parameter] + public bool ShowProgressIndicator { get; set; } = false; + /// + /// The color of the progress indicator. + /// + [Parameter] + public ThemeColor ProgressIndicatorColor { get; set; } = ThemeColor.Default; + private bool IsLoading => _currentSearchTask is not null && !_currentSearchTask.IsCompleted; + /// + /// Func that returns a list of items matching the typed text. Provides a cancellation token that + /// is marked as cancelled when the user changes the search text or selects a value from the list. + /// This can be used to cancel expensive asynchronous work occuring within the SearchFunc itself. + /// + [Parameter] + public Func>> SearchFuncWithCancel { get; set; } + /// + /// The SearchFunc returns a list of items matching the typed text + /// + [Parameter] + public Func>> SearchFunc { get; set; } + /// + /// Maximum items to display, defaults to 10. + /// A null value will display all items. + /// + [Parameter] + public int? MaxItems { get; set; } = 10; + /// + /// Minimum characters to initiate a search + /// + [Parameter] + public int MinCharacters { get; set; } = 0; + /// + /// Reset value if user deletes the text + /// + [Parameter] + public bool ResetValueOnEmptyText { get; set; } = false; + /// + /// If true, clicking the text field will select (highlight) its contents. + /// + [Parameter] + public bool SelectOnClick { get; set; } = true; + /// + /// Debounce interval in milliseconds. + /// + [Parameter] + public int DebounceInterval { get; set; } = 100; + /// + /// Optional presentation template for unselected items + /// + [Parameter] + public RenderFragment ItemTemplate { get; set; } + /// + /// Optional presentation template for the selected item + /// + [Parameter] + public RenderFragment ItemSelectedTemplate { get; set; } + /// + /// Optional presentation template for disabled item + /// + [Parameter] + public RenderFragment ItemDisabledTemplate { get; set; } + /// + /// Optional presentation template for when more items were returned from the Search function than the MaxItems limit + /// + [Parameter] + public RenderFragment MoreItemsTemplate { get; set; } + /// + /// Optional presentation template for when no items were returned from the Search function + /// + [Parameter] + public RenderFragment NoItemsTemplate { get; set; } + /// + /// Optional template for progress indicator + /// + [Parameter] + public RenderFragment ProgressIndicatorTemplate { get; set; } + /// + /// Optional template for showing progress indicator inside the popover + /// + [Parameter] + public RenderFragment ProgressIndicatorInPopoverTemplate { get; set; } + /// + /// On drop-down close override Text with selected Value. This makes it clear to the user + /// which list value is currently selected and disallows incomplete values in Text. + /// + [Parameter] + public bool CoerceText { get; set; } = true; + /// + /// If user input is not found by the search func and CoerceValue is set to true the user input + /// will be applied to the Value which allows to validate it and display an error message. + /// + [Parameter] + public bool CoerceValue { get; set; } + /// + /// Function to be invoked when checking whether an item should be disabled or not + /// + [Parameter] + public Func ItemDisabledFunc { get; set; } + /// + /// Returns the open state of the drop-down. + /// + public bool IsOpen + { + get => _isOpen; + // Note: the setter is protected because it was needed by a user who derived his own autocomplete from this class. + // Note: setting IsOpen will not open or close it. Use ToggleMenu() for that. + protected set + { + if (value == _isOpen) + return; + + _isOpen = value; + + IsOpenChanged.InvokeAsync(_isOpen).AndForget(); + } + } + /// + /// An event triggered when the state of IsOpen has changed + /// + [Parameter] + public EventCallback IsOpenChanged { get; set; } + /// + /// If true, the currently selected item from the drop-down (if it is open) is selected. + /// + [Parameter] + public bool SelectValueOnTab { get; set; } = false; + /// + /// Show clear button. + /// + [Parameter] + public bool Clearable { get; set; } = false; + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] + public EventCallback OnClearButtonClick { get; set; } + + private string CurrentIcon => !string.IsNullOrWhiteSpace(AdornmentIcon) ? AdornmentIcon : _isOpen ? CloseIcon : OpenIcon; + + protected string ClassList() + { + return new CssBuilder("select") + .AddClass(Class) + .Build(); + } + + protected string AutocompleteClassList() + { + return new CssBuilder("select") + .AddClass("autocomplete") + .AddClass("width-full", FullWidth) + .AddClass("autocomplete--with-progress", ShowProgressIndicator && IsLoading) + .Build(); + } + + protected string CircularProgressClassList() + { + return new CssBuilder("progress-indicator-circular") + .AddClass("progress-indicator-circular--with-adornment", Adornment == Adornment.End) + .Build(); + } + + public async Task SelectOption(T value) + { + await SetValueAsync(value); + + if (_items is not null) + _selectedListItemIndex = Array.IndexOf(_items, value); + + var optionText = GetItemString(value); + + if (!_isCleared) + await SetTextAsync(optionText, false); + + _timer?.Dispose(); + + IsOpen = false; + + BeginValidate(); + + if (!_isCleared) + _elementReference?.SetText(optionText); + + _elementReference?.FocusAsync().AndForget(); + + StateHasChanged(); + } + /// + /// Toggle the menu (if not disabled or not readonly, and is opened). + /// + public async Task ToggleMenu() + { + if ((Disabled || ReadOnly) && !IsOpen) + return; + + await ChangeMenu(!IsOpen); + } + + private async Task ChangeMenu(bool open) + { + if (open) + { + if (SelectOnClick) + await _elementReference.SelectAsync(); + + await OnSearchAsync(); + } + else + { + _timer?.Dispose(); + + RestoreScrollPosition(); + + await CoerceTextToValue(); + + IsOpen = false; + + StateHasChanged(); + } + } + + protected override void OnInitialized() + { + var text = GetItemString(Value); + + if (!string.IsNullOrWhiteSpace(text)) + Text = text; + } + + protected override void OnAfterRender(bool firstRender) + { + _isCleared = false; + + base.OnAfterRender(firstRender); + } + + protected override Task UpdateTextPropertyAsync(bool updateValue) + { + _timer?.Dispose(); + // This keeps the text from being set when clear() was called + if (_isCleared) + return Task.CompletedTask; + + return base.UpdateTextPropertyAsync(updateValue); + } + + protected override async Task UpdateValuePropertyAsync(bool updateText) + { + _timer?.Dispose(); + + if (ResetValueOnEmptyText && string.IsNullOrWhiteSpace(Text)) + await SetValueAsync(default, updateText); + + if (DebounceInterval <= 0) + await OnSearchAsync(); + else + _timer = new Timer(OnTimerComplete, null, DebounceInterval, Timeout.Infinite); + } + + private void OnTimerComplete(object stateInfo) + { + InvokeAsync(OnSearchAsync); + } + private void CancelToken() + { + try + { + _cancellationTokenSrc?.Cancel(); + } + catch + { + } + + _cancellationTokenSrc = new CancellationTokenSource(); + } + /// + /// This async method needs to return a task and be awaited in order for + /// unit tests that trigger this method to work correctly. + /// + private async Task OnSearchAsync() + { + if (MinCharacters > 0 && (string.IsNullOrWhiteSpace(Text) || Text.Length < MinCharacters)) + { + IsOpen = false; + StateHasChanged(); + return; + } + + IEnumerable searchedItems = Array.Empty(); + CancelToken(); + + try + { + if (ProgressIndicatorInPopoverTemplate is not null) + IsOpen = true; + + var searchTask = SearchFuncWithCancel is not null ? SearchFuncWithCancel(Text, _cancellationTokenSrc.Token) : SearchFunc(Text); + + _currentSearchTask = searchTask; + + StateHasChanged(); + + searchedItems = await searchTask ?? Array.Empty(); + } + catch (TaskCanceledException) + { + } + catch (OperationCanceledException) + { + } + catch (Exception e) + { + Console.WriteLine($"The search function failed to return results: {e.Message}"); + } + + _itemsReturned = searchedItems.Count(); + + if (MaxItems.HasValue) + searchedItems = searchedItems.Take(MaxItems.Value); + + _items = searchedItems.ToArray(); + _enabledItemIndices = _items.Select((item, idx) => (item, idx)).Where(tuple => ItemDisabledFunc?.Invoke(tuple.item) != true).Select(tuple => tuple.idx).ToList(); + _selectedListItemIndex = _enabledItemIndices.Any() ? _enabledItemIndices.First() : -1; + + IsOpen = true; + + if (_items?.Length == 0) + { + await CoerceValueToText(); + + StateHasChanged(); + + return; + } + + StateHasChanged(); + } + + /// + /// Clears the autocomplete's text + /// + public async Task Clear() + { + _isCleared = true; + IsOpen = false; + + await SetTextAsync(string.Empty, updateValue: false); + await CoerceValueToText(); + + if (_elementReference is not null) + await _elementReference.SetText(string.Empty); + + _timer?.Dispose(); + + StateHasChanged(); + } + + protected override async void ResetValue() + { + await Clear(); + base.ResetValue(); + } + + private string GetItemString(T item) + { + if (item is null) + return string.Empty; + try + { + return Converter.Set(item); + } + catch (NullReferenceException) { } + + return "null"; + } + + internal virtual async Task OnInputKeyDown(KeyboardEventArgs args) + { + switch (args.Key) + { + case "Tab": + // NOTE: We need to catch Tab in Keydown because a tab will move focus to the next element and thus + // in OnInputKeyUp we'd never get the tab key + if (!IsOpen) + return; + if (SelectValueOnTab) + await OnEnterKey(); + else + IsOpen = false; + break; + } + } + + internal virtual async Task OnInputKeyUp(KeyboardEventArgs args) + { + switch (args.Key) + { + case "Enter": + case "NumpadEnter": + if (!IsOpen) + await ToggleMenu(); + else + await OnEnterKey(); + + break; + case "ArrowDown": + if (!IsOpen) + await ToggleMenu(); + else + { + var increment = _enabledItemIndices.ElementAtOrDefault(_enabledItemIndices.IndexOf(_selectedListItemIndex) + 1) - _selectedListItemIndex; + + await SelectNextItem(increment < 0 ? 1 : increment); + } + + break; + case "ArrowUp": + if (args.AltKey) + await ChangeMenu(false); + else if (!IsOpen) + await ToggleMenu(); + else + { + var decrement = _selectedListItemIndex - _enabledItemIndices.ElementAtOrDefault(_enabledItemIndices.IndexOf(_selectedListItemIndex) - 1); + await SelectNextItem(-(decrement < 0 ? 1 : decrement)); + } + + break; + case "Escape": + await ChangeMenu(false); + + break; + case "Tab": + await Task.Delay(1); + + if (!IsOpen) + return; + + if (SelectValueOnTab) + await OnEnterKey(); + else + await ToggleMenu(); + + break; + case "Backspace": + if (args.CtrlKey && args.ShiftKey) + Reset(); + break; + } + + base.InvokeKeyUp(args); + } + + private ValueTask SelectNextItem(int increment) + { + if (increment == 0 || _items is null || !_items.Any() || !_enabledItemIndices.Any()) + return ValueTask.CompletedTask; + // if we are at the end, or the beginning we just do an rollover + _selectedListItemIndex = Math.Clamp(value: (10 * _items.Length + _selectedListItemIndex + increment) % _items.Length, min: 0, max: _items.Length - 1); + + return ScrollToListItem(_selectedListItemIndex); + } + /// + /// Scroll to a specific item index in the Autocomplete list of items. + /// + /// the index to scroll to + public ValueTask ScrollToListItem(int index) + { + var id = GetListItemId(index); + //id of the scrolled element + return ScrollManager.ScrollToListItemAsync(id); + } + /* + * This restores the scroll position after closing the menu and element being 0 + */ + private void RestoreScrollPosition() + { + if (_selectedListItemIndex != 0) + return; + + ScrollManager.ScrollToListItemAsync(GetListItemId(0)); + } + + private string GetListItemId(in int index) + { + return $"{_componentId}_item{index}"; + } + + internal Task OnEnterKey() + { + if (!IsOpen) + return Task.CompletedTask; + + if (_items is null || !_items.Any()) + return Task.CompletedTask; + + if (_selectedListItemIndex >= 0 && _selectedListItemIndex < _items.Length) + return SelectOption(_items[_selectedListItemIndex]); + + return Task.CompletedTask; + } + + private Task OnInputBlurred(FocusEventArgs args) + { + OnBlur.InvokeAsync(args); + + return Task.CompletedTask; + // we should not validate on blur in autocomplete, because the user needs to click out of the input to select a value, + // resulting in a premature validation. thus, don't call base + //base.OnBlurred(args); + } + + private Task CoerceTextToValue() + { + if (!CoerceText) + return Task.CompletedTask; + + _timer?.Dispose(); + + var text = Value is null ? null : GetItemString(Value); + /* + * Don't update the value to prevent the popover from opening again after coercion + */ + if (text != Text) + return SetTextAsync(text, updateValue: false); + + return Task.CompletedTask; + } + + private Task CoerceValueToText() + { + if (!CoerceValue) + return Task.CompletedTask; + + _timer?.Dispose(); + + var value = Converter.Get(Text); + + return SetValueAsync(value, updateText: false); + } + + protected override void Dispose(bool disposing) + { + _timer?.Dispose(); + + if (_cancellationTokenSrc is not null) + { + try + { + _cancellationTokenSrc.Dispose(); + } + catch { } + } + + base.Dispose(disposing); + } + /// + /// Focus the input in the Autocomplete component. + /// + public override ValueTask FocusAsync() + { + return _elementReference.FocusAsync(); + } + /// + /// Blur from the input in the Autocomplete component. + /// + public override ValueTask BlurAsync() + { + return _elementReference.BlurAsync(); + } + + /// + /// Select all text within the Autocomplete input. + /// + public override ValueTask SelectAsync() + { + return _elementReference.SelectAsync(); + } + + /// + /// Select all text within the Autocomplete input and aligns its start and end points to the text content of the current input. + /// + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return _elementReference.SelectRangeAsync(pos1, pos2); + } + + private async Task OnTextChanged(string text) + { + await TextChanged.InvokeAsync(); + + if (text is null) + return; + + await SetTextAsync(text, true); + } + + private async Task ListItemOnClick(T item) + { + await SelectOption(item); + } +} diff --git a/Components/Avatar/Avatar.razor b/Components/Avatar/Avatar.razor new file mode 100644 index 0000000..601b64d --- /dev/null +++ b/Components/Avatar/Avatar.razor @@ -0,0 +1,23 @@ +@namespace Connected.Components +@inherits UIComponent + +@if(AvatarGroup == null || AvatarGroup.MaxGroupReached(this)) +{ +
+ @if (!String.IsNullOrEmpty(Image)) + { + if (!String.IsNullOrEmpty(Alt)) + { + @Alt + } + else + { + + } + } + else + { + @ChildContent + } +
+} \ No newline at end of file diff --git a/Components/Avatar/Avatar.razor.cs b/Components/Avatar/Avatar.razor.cs new file mode 100644 index 0000000..90564dc --- /dev/null +++ b/Components/Avatar/Avatar.razor.cs @@ -0,0 +1,108 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class Avatar : UIComponent, IDisposable +{ + [CascadingParameter] protected AvatarGroup AvatarGroup { get; set; } + protected string Classname => + new CssBuilder("mud-avatar") + .AddClass($"mud-avatar-{Size.ToDescriptionString()}") + .AddClass($"mud-avatar-rounded", Rounded) + .AddClass($"mud-avatar-square", Square) + .AddClass($"mud-avatar-{Variant.ToDescriptionString()}") + .AddClass($"mud-avatar-{Variant.ToDescriptionString()}-{Color.ToDescriptionString()}") + .AddClass($"mud-elevation-{Elevation.ToString()}") + .AddClass(AvatarGroup?.GetAvatarSpacing() ?? new CssBuilder(), AvatarGroup != null) + .AddClass(Class) + .Build(); + + protected string Stylesname => + new StyleBuilder() + .AddStyle(AvatarGroup?.GetAvatarZindex(this) ?? new StyleBuilder(), AvatarGroup != null) + .AddStyle(Style) + .Build(); + + /// + /// The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public int Elevation { set; get; } = 0; + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public bool Square { get; set; } + + /// + /// If true, border-radius is set to the themes default value. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public bool Rounded { get; set; } + + /// + /// Link to image, if set a image will be displayed instead of text. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Behavior)] + public string Image { get; set; } + + /// + /// If set (and Image is also set), will add an alt property to the img element + /// + [Parameter] + [Category(CategoryTypes.Avatar.Behavior)] + public string Alt { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The Size of the MudAvatar. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Appearance)] + public Variant Variant { get; set; } = Variant.Filled; + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Avatar.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected override void OnInitialized() + { + base.OnInitialized(); + + AvatarGroup?.AddAvatar(this); + } + + public void Dispose() + { + AvatarGroup?.RemoveAvatar(this); + } + + internal void ForceRedraw() + { + StateHasChanged(); + } +} diff --git a/Components/Avatar/AvatarGroup.razor b/Components/Avatar/AvatarGroup.razor new file mode 100644 index 0000000..b373864 --- /dev/null +++ b/Components/Avatar/AvatarGroup.razor @@ -0,0 +1,14 @@ +@namespace Connected.Components +@inherits UIComponent + +
+ + @ChildContent + + @if(_avatars.Count > Max) + { + + @($"+{_avatars.Count - Max}") + + } +
\ No newline at end of file diff --git a/Components/Avatar/AvatarGroup.razor.cs b/Components/Avatar/AvatarGroup.razor.cs new file mode 100644 index 0000000..b608c95 --- /dev/null +++ b/Components/Avatar/AvatarGroup.razor.cs @@ -0,0 +1,176 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class AvatarGroup : UIComponent +{ + private bool _childrenNeedUpdates = false; + + protected string Classname => + new CssBuilder("mud-avatar-group") + .AddClass($"mud-avatar-group-outlined", Outlined) + .AddClass($"mud-avatar-group-outlined-{OutlineColor.ToDescriptionString()}", Outlined) + .AddClass(Class) + .Build(); + + protected string MaxAvatarClassname => + new CssBuilder("mud-avatar-group-max-avatar") + .AddClass($"ms-n{Spacing}") + .AddClass(MaxAvatarClass) + .Build(); + + private int _spacing = 3; + + /// + /// Spacing between avatars where 0 is none and 16 max. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Behavior)] + public int Spacing + { + get => _spacing; + set + { + if (value != _spacing) + { + _spacing = value; + _childrenNeedUpdates = true; + } + } + } + + /// + /// Outlines the grouped avatars to distinguish them, useful when avatars are the same color or uses images. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public bool Outlined { get; set; } = true; + + /// + /// Sets the color of the outline if its used. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public ThemeColor OutlineColor { get; set; } = ThemeColor.Surface; + + /// + /// Elevation of the MaxAvatar the higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public int MaxElevation { set; get; } = 0; + + /// + /// If true, MaxAvatar border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public bool MaxSquare { get; set; } + + /// + /// If true, MaxAvatar will be rounded. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public bool MaxRounded { get; set; } + + /// + /// Color for the MaxAvatar. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public ThemeColor MaxColor { get; set; } = ThemeColor.Default; + + /// + /// Size of the MaxAvatar. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public Size MaxSize { get; set; } = Size.Medium; + + /// + /// Variant of the MaxAvatar. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public Variant MaxVariant { get; set; } = Variant.Filled; + + private int _max = 3; + + /// + /// Max avatars to show before showing +x avatar, default value 0 has no max. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Behavior)] + public int Max + { + get => _max; + set + { + if (value != _max) + { + _max = value; + _childrenNeedUpdates = true; + } + } + } + + /// + /// Custom class/classes for MaxAvatar + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Appearance)] + public string MaxAvatarClass { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.AvatarGroup.Behavior)] + public RenderFragment ChildContent { get; set; } + + internal List _avatars = new(); + + internal void AddAvatar(Avatar avatar) + { + _avatars.Add(avatar); + StateHasChanged(); + } + + internal void RemoveAvatar(Avatar avatar) + { + _avatars.Remove(avatar); + } + + internal CssBuilder GetAvatarSpacing() => new CssBuilder() + .AddClass($"ms-n{Spacing}"); + + internal StyleBuilder GetAvatarZindex(Avatar avatar) => new StyleBuilder() + .AddStyle("z-index", $"{_avatars.Count - _avatars.IndexOf(avatar)}"); + + internal bool MaxGroupReached(Avatar avatar) + { + if (_avatars.IndexOf(avatar) < Max) + return true; + else + return false; + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + + if (_childrenNeedUpdates == true) + { + foreach (var avatar in _avatars) + { + avatar.ForceRedraw(); + } + + _childrenNeedUpdates = false; + } + } +} diff --git a/Components/Badge/Badge.razor b/Components/Badge/Badge.razor new file mode 100644 index 0000000..ec26682 --- /dev/null +++ b/Components/Badge/Badge.razor @@ -0,0 +1,24 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + @if (Visible) + { + + + @if (!Dot) + { + @if (!String.IsNullOrEmpty(Icon)) + { + + } + else + { + @_content + } + } + + + } + diff --git a/Components/Badge/Badge.razor.cs b/Components/Badge/Badge.razor.cs new file mode 100644 index 0000000..9e2822c --- /dev/null +++ b/Components/Badge/Badge.razor.cs @@ -0,0 +1,176 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Badge : UIComponent +{ + protected string Classname => + new CssBuilder("mud-badge-root") + .AddClass(Class) + .Build(); + protected string WrapperClass => + new CssBuilder("mud-badge-wrapper") + .AddClass($"mud-badge-{Origin.ToDescriptionString().Replace("-", " ")}") + .Build(); + + protected string BadgeClassName => + new CssBuilder("mud-badge") + .AddClass("mud-badge-dot", Dot) + .AddClass("mud-badge-bordered", Bordered) + .AddClass("mud-badge-icon", !string.IsNullOrEmpty(Icon) && !Dot) + .AddClass($"mud-badge-{Origin.ToDescriptionString().Replace("-", " ")}") + .AddClass($"mud-elevation-{Elevation.ToString()}") + .AddClass("mud-theme-" + Color.ToDescriptionString(), Color != ThemeColor.Default) + .AddClass("mud-badge-default", Color == ThemeColor.Default) + .AddClass("mud-badge-overlap", Overlap) + .AddClass(BadgeClass) + .Build(); + + /// + /// The placement of the badge. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public Origin Origin { get; set; } = Origin.TopRight; + + /// + /// The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public int Elevation { set; get; } = 0; + + /// + /// The visibility of the badge. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public bool Visible { get; set; } = true; + + /// + /// The color of the badge. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// Aligns the badge to bottom. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use Origin instead.", true)] + [Parameter] public bool Bottom { get; set; } + + /// + /// Aligns the badge to left. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use Origin instead.", true)] + [Parameter] public bool Left { get => Start; set { Start = value; } } + + /// + /// Aligns the badge to the start (Left in LTR and right in RTL). + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use Origin instead.", true)] + [Parameter] public bool Start { get; set; } + + /// + /// Reduces the size of the badge and hide any of its content. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public bool Dot { get; set; } + + /// + /// Overlaps the childcontent on top of the content. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public bool Overlap { get; set; } + + /// + /// Applies a border around the badge. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public bool Bordered { get; set; } + + /// + /// Sets the Icon to use in the badge. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public string Icon { get; set; } + + /// + /// Max value to show when content is integer type. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public int Max { get; set; } = 99; + + /// + /// Content you want inside the badge. Supported types are string and integer. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public object Content { get; set; } + + /// + /// Badge class names, separated by space. + /// + [Parameter] + [Category(CategoryTypes.Badge.Appearance)] + public string BadgeClass { get; set; } + + /// + /// Child content of component, the content that the badge will apply to. + /// + [Parameter] + [Category(CategoryTypes.Badge.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Button click event if set. + /// + [Parameter] public EventCallback OnClick { get; set; } + + private string _content; + + internal Task HandleBadgeClick(MouseEventArgs e) + { + if (OnClick.HasDelegate) + return OnClick.InvokeAsync(e); + + return Task.CompletedTask; + } + + protected override void OnParametersSet() + { + if (Content is string stringContent) + { + _content = stringContent; + } + else if (Content is int numberContent) + { + if (numberContent > Max) + { + _content = Max + "+"; + } + else + { + _content = numberContent.ToString(); + } + } + else + { + _content = null; + } + } +} diff --git a/Components/BindableItemsControlBase.cs b/Components/BindableItemsControlBase.cs new file mode 100644 index 0000000..e087f92 --- /dev/null +++ b/Components/BindableItemsControlBase.cs @@ -0,0 +1,31 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public abstract class BindableItemsControlBase : ItemsControlBase + where TChildComponent : UIComponent +{ + + /// + /// Items Collection - For databinding usage + /// + [Parameter] + [Category(CategoryTypes.General.Data)] + public IEnumerable ItemsSource { get; set; } + + /// + /// Template for each Item in ItemsSource collection + /// + [Parameter] + [Category(CategoryTypes.General.Appearance)] + public RenderFragment ItemTemplate { get; set; } + + /// + /// Gets the Selected Item from ItemsSource, or Selected TChildComponent, when it's null + /// + public object SelectedItem + { + get => ItemsSource == null ? Items[SelectedIndex] : ItemsSource.ElementAtOrDefault(SelectedIndex); + } +} diff --git a/Components/BooleanInput.cs b/Components/BooleanInput.cs new file mode 100644 index 0000000..d7d59f5 --- /dev/null +++ b/Components/BooleanInput.cs @@ -0,0 +1,89 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public class BooleanInput : FormComponent +{ + public BooleanInput() : base(new BoolConverter()) { } + + /// + /// If true, the input will be disabled. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, the input will be read-only. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool ReadOnly { get; set; } + + /// + /// The state of the component + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public T Checked + { + get => _value; + set => _value = value; + } + + /// + /// If true will prevent the click from bubbling up the event tree. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool StopClickPropagation { get; set; } = true; + + /// + /// Fired when Checked changes. + /// + [Parameter] public EventCallback CheckedChanged { get; set; } + + protected bool? BoolValue => Converter.Set(Checked); + + protected virtual Task OnChange(ChangeEventArgs args) + { + Touched = true; + return SetBoolValueAsync((bool?)args.Value); + } + + protected Task SetBoolValueAsync(bool? value) + { + return SetCheckedAsync(Converter.Get(value)); + } + + protected async Task SetCheckedAsync(T value) + { + if (Disabled) + return; + if (!EqualityComparer.Default.Equals(Checked, value)) + { + Checked = value; + await CheckedChanged.InvokeAsync(value); + BeginValidate(); + FieldChanged(Checked); + } + } + + protected override bool SetConverter(Converter value) + { + var changed = base.SetConverter(value); + if (changed) + SetBoolValueAsync(Converter.Set(Checked)).AndForget(); + + return changed; + } + + /// + /// A value is required, so if not checked we return ERROR. + /// + protected override bool HasValue(T value) + { + return (BoolValue == true); + } +} diff --git a/Components/Breadcrumbs/BreadcrumbItem.cs b/Components/Breadcrumbs/BreadcrumbItem.cs new file mode 100644 index 0000000..f8fdf2b --- /dev/null +++ b/Components/Breadcrumbs/BreadcrumbItem.cs @@ -0,0 +1,17 @@ +namespace Connected.Components; + +public class BreadcrumbItem +{ + public string Text { get; } + public string Href { get; } + public bool Disabled { get; } + public string Icon { get; } + + public BreadcrumbItem(string text, string href, bool disabled = false, string icon = null) + { + Text = text; + Disabled = disabled; + Href = href; + Icon = icon; + } +} diff --git a/Components/Breadcrumbs/BreadcrumbLink.razor b/Components/Breadcrumbs/BreadcrumbLink.razor new file mode 100644 index 0000000..6784f68 --- /dev/null +++ b/Components/Breadcrumbs/BreadcrumbLink.razor @@ -0,0 +1,19 @@ +@namespace Connected.Components +@inherits UIComponent + +
  • + @if (Parent?.ItemTemplate is null) + { + + @if (Item?.Icon != null) + { + + } + @Item?.Text + + } + else + { + @Parent?.ItemTemplate(Item); + } +
  • \ No newline at end of file diff --git a/Components/Breadcrumbs/BreadcrumbLink.razor.cs b/Components/Breadcrumbs/BreadcrumbLink.razor.cs new file mode 100644 index 0000000..1b5e762 --- /dev/null +++ b/Components/Breadcrumbs/BreadcrumbLink.razor.cs @@ -0,0 +1,16 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; +public partial class BreadcrumbLink : UIComponent +{ + [Parameter] + public BreadcrumbItem Item { get; set; } + + [CascadingParameter] + public Breadcrumbs Parent { get; set; } + + private string Classname => new CssBuilder("mud-breadcrumb-item") + .AddClass("mud-disabled", Item?.Disabled) + .Build(); +} diff --git a/Components/Breadcrumbs/BreadcrumbSeparator.razor b/Components/Breadcrumbs/BreadcrumbSeparator.razor new file mode 100644 index 0000000..6b3cbdb --- /dev/null +++ b/Components/Breadcrumbs/BreadcrumbSeparator.razor @@ -0,0 +1,13 @@ +@namespace Connected.Components +@inherits UIComponent + + \ No newline at end of file diff --git a/Components/Breadcrumbs/BreadcrumbSeparator.razor.cs b/Components/Breadcrumbs/BreadcrumbSeparator.razor.cs new file mode 100644 index 0000000..a9cca7b --- /dev/null +++ b/Components/Breadcrumbs/BreadcrumbSeparator.razor.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; +public partial class BreadcrumbSeparator : UIComponent +{ + [CascadingParameter] + public Breadcrumbs Parent { get; set; } +} diff --git a/Components/Breadcrumbs/Breadcrumbs.razor b/Components/Breadcrumbs/Breadcrumbs.razor new file mode 100644 index 0000000..b521dc6 --- /dev/null +++ b/Components/Breadcrumbs/Breadcrumbs.razor @@ -0,0 +1,35 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (Items is null || !Items.Any()) +{ + return; +} + + +
      + @if (MaxItems is not null && Collapsed && Items.Count > MaxItems) + { + + +
    • + +
    • + + + } + else + { + @for (var i = 0; i < Items.Count; i++) + { + var item = Items[i]; + + + if (i != Items.Count - 1) + { + + } + } + } +
    +
    \ No newline at end of file diff --git a/Components/Breadcrumbs/Breadcrumbs.razor.cs b/Components/Breadcrumbs/Breadcrumbs.razor.cs new file mode 100644 index 0000000..1c7ee94 --- /dev/null +++ b/Components/Breadcrumbs/Breadcrumbs.razor.cs @@ -0,0 +1,72 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Breadcrumbs : UIComponent +{ + /// + /// A list of breadcrumb items/links. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Behavior)] + public List Items { get; set; } + + /// + /// Specifies the separator between the items. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Appearance)] + public string Separator { get; set; } = "/"; + + /// + /// Specifies a RenderFragment to use as the separator. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Appearance)] + public RenderFragment SeparatorTemplate { get; set; } + + /// + /// Specifies a RenderFragment to use as the items' contents. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Behavior)] + public RenderFragment ItemTemplate { get; set; } + + /// + /// Controls when (and if) the breadcrumbs will automatically collapse. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Behavior)] + public byte? MaxItems { get; set; } + + /// + /// Custom expander icon. + /// + [Parameter] + [Category(CategoryTypes.Breadcrumbs.Appearance)] + public string ExpanderIcon { get; set; } = Icons.Material.Filled.SettingsEthernet; + + public bool Collapsed { get; private set; } = true; + private string Classname => new CssBuilder("mud-breadcrumbs") + .AddClass("mud-typography-body1") + .AddClass(Class) + .Build(); + + internal static string GetItemClassname(BreadcrumbItem item) + { + return new CssBuilder("mud-breadcrumb-item") + .AddClass("mud-disabled", item.Disabled) + .Build(); + } + + internal void Expand() + { + if (!Collapsed) + return; + + Collapsed = false; + StateHasChanged(); + } +} diff --git a/Components/BreakpointProvider/BreakpointProvider.razor b/Components/BreakpointProvider/BreakpointProvider.razor new file mode 100644 index 0000000..d4a547d --- /dev/null +++ b/Components/BreakpointProvider/BreakpointProvider.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + \ No newline at end of file diff --git a/Components/BreakpointProvider/BreakpointProvider.razor.cs b/Components/BreakpointProvider/BreakpointProvider.razor.cs new file mode 100644 index 0000000..3dcca7d --- /dev/null +++ b/Components/BreakpointProvider/BreakpointProvider.razor.cs @@ -0,0 +1,46 @@ +using Connected.Annotations; +using Connected.Services; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class BreakpointProvider : UIComponent, IAsyncDisposable +{ + private Guid _breakPointListenerSubscriptionId; + + public Breakpoint Breakpoint { get; private set; } = Breakpoint.Always; + + [Parameter] public EventCallback OnBreakpointChanged { get; set; } + + [Inject] public IBreakpointService Service { get; set; } + + [Parameter] + [Category(CategoryTypes.BreakpointProvider.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender == true) + { + var attachResult = await Service.Subscribe(SetBreakpointCallback); + _breakPointListenerSubscriptionId = attachResult.SubscriptionId; + Breakpoint = attachResult.Breakpoint; + await OnBreakpointChanged.InvokeAsync(Breakpoint); + StateHasChanged(); + } + } + + private void SetBreakpointCallback(Breakpoint breakpoint) + { + InvokeAsync(() => + { + Breakpoint = breakpoint; + OnBreakpointChanged.InvokeAsync(breakpoint); + StateHasChanged(); + }).AndForget(); + } + + public async ValueTask DisposeAsync() => await Service.Unsubscribe(_breakPointListenerSubscriptionId); +} diff --git a/Components/Button/Button.razor b/Components/Button/Button.razor new file mode 100644 index 0000000..e081e23 --- /dev/null +++ b/Components/Button/Button.razor @@ -0,0 +1,31 @@ +@namespace Connected.Components +@using Connected.Extensions; +@inherits ButtonBase + + + + @if (!string.IsNullOrWhiteSpace(StartIcon)) + { + + + + } + @ChildContent + @if (!string.IsNullOrWhiteSpace(@EndIcon)) + { + + + + } + + diff --git a/Components/Button/Button.razor.cs b/Components/Button/Button.razor.cs new file mode 100644 index 0000000..3fcc879 --- /dev/null +++ b/Components/Button/Button.razor.cs @@ -0,0 +1,96 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Button : ButtonBase +{ + protected string Classname => + new CssBuilder("mud-button-root mud-button") + .AddClass($"mud-button-{Variant.ToDescriptionString()}") + .AddClass($"mud-button-{Variant.ToDescriptionString()}-{Color.ToDescriptionString()}") + .AddClass($"mud-button-{Variant.ToDescriptionString()}-size-{Size.ToDescriptionString()}") + .AddClass($"mud-width-full", FullWidth) + .AddClass($"mud-ripple", !DisableRipple) + .AddClass($"mud-button-disable-elevation", DisableElevation) + .AddClass(Class) + .Build(); + + protected string StartIconClass => + new CssBuilder("mud-button-icon-start") + .AddClass($"mud-button-icon-size-{Size.ToDescriptionString()}") + .AddClass(IconClass) + .Build(); + + protected string EndIconClass => + new CssBuilder("mud-button-icon-end") + .AddClass($"mud-button-icon-size-{Size.ToDescriptionString()}") + .AddClass(IconClass) + .Build(); + + /// + /// Icon placed before the text if set. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string StartIcon { get; set; } + + /// + /// Icon placed after the text if set. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string EndIcon { get; set; } + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// Icon class names, separated by space + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public string IconClass { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The Size of the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// If true, the button will take up 100% of available width. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public bool FullWidth { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public RenderFragment ChildContent { get; set; } + +} diff --git a/Components/Button/ButtonBase.cs b/Components/Button/ButtonBase.cs new file mode 100644 index 0000000..e567e5e --- /dev/null +++ b/Components/Button/ButtonBase.cs @@ -0,0 +1,143 @@ +using System.Windows.Input; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using static System.String; + +namespace Connected.Components; + +public abstract class ButtonBase : UIComponent +{ + /// + /// Potential activation target for this button. This enables RenderFragments with user-defined + /// buttons which will automatically activate the intended functionality. + /// + [CascadingParameter] protected IActivatable Activateable { get; set; } + + /// + /// The HTML element that will be rendered in the root by the component + /// By default, is a button + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public string HtmlTag { get; set; } = "button"; + + /// + /// The button Type (Button, Submit, Refresh) + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public ButtonType ButtonType { get; set; } + + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public string Href { get; set; } + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where (Obsolete replaced by Href) + /// + + [Obsolete("Use Href Instead.", false)] + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public string Link + { + get => Href; + set => Href = value; + } + + /// + /// The target attribute specifies where to open the link, if Link is specified. Possible values: _blank | _self | _parent | _top | framename + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public string Target { get; set; } + + /// + /// If true, the button will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, no drop-shadow will be used. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public bool DisableElevation { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// Command executed when the user clicks on an element. + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public ICommand Command { get; set; } + + /// + /// Command parameter. + /// + [Parameter] + [Category(CategoryTypes.Button.ClickAction)] + public object CommandParameter { get; set; } + + /// + /// Button click event. + /// + [Parameter] + public EventCallback OnClick { get; set; } + + protected async Task OnClickHandler(MouseEventArgs ev) + { + if (Disabled) + return; + await OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + Activateable?.Activate(this, ev); + } + + protected override void OnInitialized() + { + SetDefaultValues(); + } + + protected override void OnParametersSet() + { + //if params change, must set default values again + SetDefaultValues(); + } + + //Set the default value for HtmlTag, Link and Target + private void SetDefaultValues() + { + if (Disabled) + { + HtmlTag = "button"; + Href = null; + Target = null; + return; + } + + // Render an anchor element if Link property is set and is not disabled + if (!IsNullOrWhiteSpace(Href)) + { + HtmlTag = "a"; + } + } + + protected ElementReference _elementReference; + + public ValueTask FocusAsync() => _elementReference.FocusAsync(); +} diff --git a/Components/Button/Fab.razor b/Components/Button/Fab.razor new file mode 100644 index 0000000..1d64588 --- /dev/null +++ b/Components/Button/Fab.razor @@ -0,0 +1,30 @@ +@namespace Connected.Components + +@inherits ButtonBase + +@using Connected.Extensions; + + + + @if (!string.IsNullOrWhiteSpace(StartIcon)) + { + + } + @Label + @if (!string.IsNullOrWhiteSpace(EndIcon)) + { + + } + + diff --git a/Components/Button/Fab.razor.cs b/Components/Button/Fab.razor.cs new file mode 100644 index 0000000..2e3cbe0 --- /dev/null +++ b/Components/Button/Fab.razor.cs @@ -0,0 +1,80 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Fab : ButtonBase +{ + protected string Classname => + new CssBuilder("mud-button-root mud-fab") + .AddClass($"mud-fab-extended", !string.IsNullOrEmpty(Label)) + .AddClass($"mud-fab-{Color.ToDescriptionString()}") + .AddClass($"mud-fab-size-{Size.ToDescriptionString()}") + .AddClass($"mud-ripple", !DisableRipple && !Disabled) + .AddClass($"mud-fab-disable-elevation", DisableElevation) + .AddClass(Class) + .Build(); + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The Size of the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size Size { get; set; } = Size.Large; + + /// + /// If applied Icon will be added at the start of the component. + /// + [Obsolete("This property is obsolete. Use StartIcon instead.")][Parameter] public string Icon { get => StartIcon; set => StartIcon = value; } + + /// + /// If applied Icon will be added at the start of the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string StartIcon { get; set; } + + /// + /// If applied Icon will be added at the end of the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string EndIcon { get; set; } + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// The size of the icon. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + /// + /// If applied the text will be added to the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Label { get; set; } + + /// + /// Title of the icon used for accessibility. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Title { get; set; } +} diff --git a/Components/Button/IconButton.razor b/Components/Button/IconButton.razor new file mode 100644 index 0000000..9373c32 --- /dev/null +++ b/Components/Button/IconButton.razor @@ -0,0 +1,29 @@ +@namespace Connected.Components + +@inherits ButtonBase + +@using Connected.Extensions; + + + @if (!String.IsNullOrEmpty(Icon)) + { + + + + } + else + { + @ChildContent + } + diff --git a/Components/Button/IconButton.razor.cs b/Components/Button/IconButton.razor.cs new file mode 100644 index 0000000..b8e8a79 --- /dev/null +++ b/Components/Button/IconButton.razor.cs @@ -0,0 +1,76 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class IconButton : ButtonBase +{ + protected string Classname => + new CssBuilder("mud-button-root mud-icon-button") + .AddClass("mud-button", when: AsButton) + .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", !AsButton && Color != ThemeColor.Default) + .AddClass($"mud-button-{Variant.ToDescriptionString()}", AsButton) + .AddClass($"mud-button-{Variant.ToDescriptionString()}-{Color.ToDescriptionString()}", AsButton) + .AddClass($"mud-button-{Variant.ToDescriptionString()}-size-{Size.ToDescriptionString()}", AsButton) + .AddClass($"mud-ripple", !DisableRipple) + .AddClass($"mud-ripple-icon", !DisableRipple && !AsButton) + .AddClass($"mud-icon-button-size-{Size.ToDescriptionString()}", when: () => Size != Size.Medium) + .AddClass($"mud-icon-button-edge-{Edge.ToDescriptionString()}", when: () => Edge != Edge.False) + .AddClass($"mud-button-disable-elevation", DisableElevation) + .AddClass(Class) + .Build(); + + protected bool AsButton => Variant != Variant.Text; + + /// + /// The Icon that will be used in the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Icon { get; set; } + + /// + /// Title of the icon used for accessibility. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Title { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The Size of the component. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// If set uses a negative margin. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Edge Edge { get; set; } + + /// + /// Child content of component, only shows if Icon is null or Empty. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + +} diff --git a/Components/Button/ToggleIconButton.razor b/Components/Button/ToggleIconButton.razor new file mode 100644 index 0000000..c3d8765 --- /dev/null +++ b/Components/Button/ToggleIconButton.razor @@ -0,0 +1,21 @@ +@namespace Connected.Components + +@inherits UIComponent + +@{ + var ariaPressedValue = @Toggled ? "true" : "false"; +} + + diff --git a/Components/Button/ToggleIconButton.razor.cs b/Components/Button/ToggleIconButton.razor.cs new file mode 100644 index 0000000..02041c3 --- /dev/null +++ b/Components/Button/ToggleIconButton.razor.cs @@ -0,0 +1,119 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ToggleIconButton : UIComponent +{ + /// + /// The toggled value. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public bool Toggled { get; set; } + + /// + /// Fires whenever toggled is changed. + /// + [Parameter] public EventCallback ToggledChanged { get; set; } + + /// + /// The Icon that will be used in the untoggled state. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Icon { get; set; } + + /// + /// The Icon that will be used in the toggled state. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string ToggledIcon { get; set; } + + /// + /// Title of the icon used for accessibility. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string Title { get; set; } + + /// + /// Title used in toggled state, if different. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public string ToggledTitle { get; set; } + + /// + /// The color of the icon in the untoggled state. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The color of the icon in the toggled state. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public ThemeColor ToggledColor { get; set; } = ThemeColor.Default; + + /// + /// The Size of the component in the untoggled state. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The Size of the component in the toggled state. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Size ToggledSize { get; set; } = Size.Medium; + + /// + /// If set uses a negative margin. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Edge Edge { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// If true, the button will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Button.Behavior)] + public bool Disabled { get; set; } + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + public Task Toggle() + { + return SetToggledAsync(!Toggled); + } + + protected internal async Task SetToggledAsync(bool toggled) + { + if (Disabled) + return; + if (Toggled != toggled) + { + Toggled = toggled; + await ToggledChanged.InvokeAsync(Toggled); + } + } +} diff --git a/Components/ButtonGroup/ButtonGroup.razor b/Components/ButtonGroup/ButtonGroup.razor new file mode 100644 index 0000000..25a7d2d --- /dev/null +++ b/Components/ButtonGroup/ButtonGroup.razor @@ -0,0 +1,12 @@ +@namespace Connected.Components + +@inherits UIComponent + + + @ChildContent + + +@{ + if(!UserAttributes.ContainsKey("role")) + UserAttributes.Add("role", "group"); +} \ No newline at end of file diff --git a/Components/ButtonGroup/ButtonGroup.razor.cs b/Components/ButtonGroup/ButtonGroup.razor.cs new file mode 100644 index 0000000..6c1c350 --- /dev/null +++ b/Components/ButtonGroup/ButtonGroup.razor.cs @@ -0,0 +1,75 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ButtonGroup : UIComponent +{ + protected string Classname => + new CssBuilder("mud-button-group-root") + .AddClass($"mud-button-group-override-styles", OverrideStyles) + .AddClass($"mud-button-group-{Variant.ToDescriptionString()}") + .AddClass($"mud-button-group-{Variant.ToDescriptionString()}-{Color.ToDescriptionString()}") + .AddClass($"mud-button-group-{Variant.ToDescriptionString()}-size-{Size.ToDescriptionString()}") + .AddClass($"mud-button-group-vertical", VerticalAlign) + .AddClass($"mud-button-group-horizontal", !VerticalAlign) + .AddClass($"mud-button-group-disable-elevation", DisableElevation) + .AddClass($"mud-button-group-rtl", RightToLeft) + .AddClass(Class) + .Build(); + + + [CascadingParameter(Name = "RightToLeft")] + public bool RightToLeft { get; set; } + + /// + /// If true, the button group will override the styles of the individual buttons. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public bool OverrideStyles { get; set; } = true; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If true, the button group will be displayed vertically. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public bool VerticalAlign { get; set; } = false; + + /// + /// If true, no drop-shadow will be used. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public bool DisableElevation { get; set; } = false; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The size of the component. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.ButtonGroup.Appearance)] + public Variant Variant { get; set; } = Variant.Text; +} diff --git a/Components/Card/Card.razor b/Components/Card/Card.razor new file mode 100644 index 0000000..97c03f9 --- /dev/null +++ b/Components/Card/Card.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components + +@inherits UIComponent + + + @ChildContent + diff --git a/Components/Card/Card.razor.cs b/Components/Card/Card.razor.cs new file mode 100644 index 0000000..10d6e80 --- /dev/null +++ b/Components/Card/Card.razor.cs @@ -0,0 +1,41 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Card : UIComponent +{ + protected string Classname => + new CssBuilder("mud-card") + .AddClass(Class) + .Build(); + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + [Category(CategoryTypes.Card.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.Card.Appearance)] + public bool Square { get; set; } + + /// + /// If true, card will be outlined. + /// + [Parameter] + [Category(CategoryTypes.Card.Appearance)] + public bool Outlined { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Card/CardActions.razor b/Components/Card/CardActions.razor new file mode 100644 index 0000000..e03ba91 --- /dev/null +++ b/Components/Card/CardActions.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components + +@inherits UIComponent + +
    + @ChildContent +
    diff --git a/Components/Card/CardActions.razor.cs b/Components/Card/CardActions.razor.cs new file mode 100644 index 0000000..a5e38d9 --- /dev/null +++ b/Components/Card/CardActions.razor.cs @@ -0,0 +1,20 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class CardActions : UIComponent +{ + protected string Classname => + new CssBuilder("mud-card-actions") + .AddClass(Class) + .Build(); + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Card/CardContent.razor b/Components/Card/CardContent.razor new file mode 100644 index 0000000..e03ba91 --- /dev/null +++ b/Components/Card/CardContent.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components + +@inherits UIComponent + +
    + @ChildContent +
    diff --git a/Components/Card/CardContent.razor.cs b/Components/Card/CardContent.razor.cs new file mode 100644 index 0000000..2b17f57 --- /dev/null +++ b/Components/Card/CardContent.razor.cs @@ -0,0 +1,20 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class CardContent : UIComponent +{ + protected string Classname => + new CssBuilder("mud-card-content") + .AddClass(Class) + .Build(); + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Card/CardHeader.razor b/Components/Card/CardHeader.razor new file mode 100644 index 0000000..5cb24b9 --- /dev/null +++ b/Components/Card/CardHeader.razor @@ -0,0 +1,22 @@ +@namespace Connected.Components + +@inherits UIComponent + +
    + @if (CardHeaderAvatar is not null) + { +
    @CardHeaderAvatar
    + } + @if (CardHeaderContent is not null) + { +
    @CardHeaderContent
    + } + @if (CardHeaderActions is not null) + { +
    @CardHeaderActions
    + } + @if (ChildContent is not null) + { + @ChildContent + } +
    diff --git a/Components/Card/CardHeader.razor.cs b/Components/Card/CardHeader.razor.cs new file mode 100644 index 0000000..1150960 --- /dev/null +++ b/Components/Card/CardHeader.razor.cs @@ -0,0 +1,41 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class CardHeader : UIComponent +{ + protected string Classname => + new CssBuilder("mud-card-header") + .AddClass(Class) + .Build(); + + /// + /// If used renders child content of the CardHeaderAvatar. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment CardHeaderAvatar { get; set; } + + /// + /// If used renders child content of the CardHeaderContent. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment CardHeaderContent { get; set; } + + /// + /// If used renders child content of the CardHeaderActions. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment CardHeaderActions { get; set; } + + /// + /// Optional child content + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Card/CardMedia.razor b/Components/Card/CardMedia.razor new file mode 100644 index 0000000..2a52216 --- /dev/null +++ b/Components/Card/CardMedia.razor @@ -0,0 +1,5 @@ +@namespace Connected.Components + +@inherits UIComponent + +
    diff --git a/Components/Card/CardMedia.razor.cs b/Components/Card/CardMedia.razor.cs new file mode 100644 index 0000000..766adaa --- /dev/null +++ b/Components/Card/CardMedia.razor.cs @@ -0,0 +1,39 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class CardMedia : UIComponent +{ + protected string StyleString => + StyleBuilder.Default($"background-image:url(\"{Image}\");height: {Height}px;") + .AddStyle(this.Style) + .Build(); + + protected string Classname => + new CssBuilder("mud-card-media") + .AddClass(Class) + .Build(); + + /// + /// Title of the image used for accessibility. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public string Title { get; set; } + + /// + /// Specifies the path to the image. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public string Image { get; set; } + + /// + /// Specifies the height of the image in px. + /// + [Parameter] + [Category(CategoryTypes.Card.Behavior)] + public int Height { get; set; } = 300; +} diff --git a/Components/Carousel/Carousel.razor b/Components/Carousel/Carousel.razor new file mode 100644 index 0000000..ced067e --- /dev/null +++ b/Components/Carousel/Carousel.razor @@ -0,0 +1,84 @@ +@namespace Connected.Components +@inherits BindableItemsControlBase +@using Connected.Extensions +@implements IAsyncDisposable +@typeparam TData + +
    + + + + @*Selected Content*@ + @if (ItemsSource == null) + { + @ChildContent + } + else + { + foreach (TData item in ItemsSource) + { + + @ItemTemplate(item) + + } + } + + + @*Controls*@ +
    + @*Left Arrow*@ + @if (ShowArrows) + { + @if (PreviousButtonTemplate == null) + { + + } + else + { +
    + @PreviousButtonTemplate +
    + } + } + + @*Bullets*@ +
    + @if (ShowBullets) + { +
    + @for (int i = 0; i < Items.Count; i++) + { + int current = i; + if (BulletTemplate == null) + { + + } + else + { +
    + @BulletTemplate(current == SelectedIndex) +
    + } + } +
    + } +
    + + @*Right Arrow*@ + @if (ShowArrows) + { + @if (NextButtonTemplate == null) + { + + } + else + { +
    + @NextButtonTemplate +
    + } + } +
    + +
    +
    diff --git a/Components/Carousel/Carousel.razor.cs b/Components/Carousel/Carousel.razor.cs new file mode 100644 index 0000000..15dd0ed --- /dev/null +++ b/Components/Carousel/Carousel.razor.cs @@ -0,0 +1,349 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Carousel : BindableItemsControlBase, IAsyncDisposable +{ + protected string Classname => + new CssBuilder("mud-carousel") + .AddClass($"mud-carousel-{(BulletsColor ?? _currentColor).ToDescriptionString()}") + .AddClass(Class) + .Build(); + + protected string NavigationButtonsClassName => + new CssBuilder() + .AddClass($"align-self-{ConvertPosition(ArrowsPosition).ToDescriptionString()}", !(NavigationButtonsClass ?? "").Contains("align-self-")) + .AddClass("mud-carousel-elements-rtl", RightToLeft) + .AddClass(NavigationButtonsClass) + .Build(); + + protected string BulletsButtonsClassName => + new CssBuilder() + .AddClass(BulletsClass) + .Build(); + + private Timer _timer; + private bool _autoCycle = true; + private ThemeColor _currentColor = ThemeColor.Inherit; + private TimeSpan _cycleTimeout = TimeSpan.FromSeconds(5); + private void TimerElapsed(object stateInfo) => InvokeAsync(async () => await TimerTickAsync()); + + private static Position ConvertPosition(Position position) + { + return position switch + { + Position.Top => Position.Start, + Position.Start => Position.Start, + Position.Bottom => Position.End, + Position.End => Position.End, + _ => position + }; + } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + + /// + /// Gets or Sets if 'Next' and 'Previous' arrows must be visible + /// + [Parameter] + [Category(CategoryTypes.Carousel.Behavior)] + public bool ShowArrows { get; set; } = true; + + /// + /// Sets the position of the arrows. By default, the position is the Center position + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public Position ArrowsPosition { get; set; } = Position.Center; + + /// + /// Gets or Sets if bar with Bullets must be visible + /// + [Category(CategoryTypes.Carousel.Behavior)] + [Parameter] public bool ShowBullets { get; set; } = true; + + /// + /// Sets the position of the bullets. By default, the position is the Bottom position + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Parameter] public Position BulletsPosition { get; set; } = Position.Bottom; + + /// + /// Gets or Sets the Bullets color. + /// If not set, the color is determined based on the property of the active child. + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Parameter] public ThemeColor? BulletsColor { get; set; } + + + /// + /// Gets or Sets if bottom bar with Delimiters must be visible. + /// Deprecated, use ShowBullets instead. + /// + [Category(CategoryTypes.Carousel.Behavior)] + [Obsolete($"Use {nameof(ShowBullets)} instead", false)] + [ExcludeFromCodeCoverage] + [Parameter] public bool ShowDelimiters { get => ShowBullets; set => ShowBullets = value; } + + /// + /// Gets or Sets the Delimiters color. + /// If not set, the color is determined based on the property of the active child. + /// Deprecated, use BulletsColor instead. + /// + [Obsolete($"Use {nameof(BulletsColor)} instead", false)] + [Category(CategoryTypes.Carousel.Appearance)] + [ExcludeFromCodeCoverage] + [Parameter] public ThemeColor? DelimitersColor { get => BulletsColor; set => BulletsColor = value; } + + /// + /// Gets or Sets automatic cycle on item collection. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Behavior)] + public bool AutoCycle + { + get => _autoCycle; + set + { + _autoCycle = value; + + if (_autoCycle) + InvokeAsync(async () => await ResetTimerAsync()); + + else + InvokeAsync(async () => await StopTimerAsync()); + } + } + + + /// + /// Gets or Sets the Auto Cycle time + /// + [Parameter] + [Category(CategoryTypes.Carousel.Behavior)] + public TimeSpan AutoCycleTime + { + get => _cycleTimeout; + set + { + _cycleTimeout = value; + + if (_autoCycle == true) + InvokeAsync(async () => await ResetTimerAsync()); + + else + InvokeAsync(async () => await StopTimerAsync()); + } + } + + + /// + /// Gets or Sets custom class(es) for 'Next' and 'Previous' arrows + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string NavigationButtonsClass { get; set; } + + /// + /// Gets or Sets custom class(es) for Bullets buttons + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Parameter] public string BulletsClass { get; set; } + + /// + /// Gets or Sets custom class(es) for Delimiters buttons. + /// Deprecated, use BulletsClass instead. + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Obsolete($"Use {nameof(BulletsClass)} instead", false)] + [ExcludeFromCodeCoverage] + [Parameter] public string DelimitersClass { get => BulletsClass; set => BulletsClass = value; } + + /// + /// Custom previous navigation icon. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string PreviousIcon { get; set; } = Icons.Material.Filled.NavigateBefore; + + /// + /// Custom selected bullet icon. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string CheckedIcon { get; set; } = Icons.Material.Filled.RadioButtonChecked; + + /// + /// Custom unselected bullet icon. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string UncheckedIcon { get; set; } = Icons.Material.Filled.RadioButtonUnchecked; + + /// + /// Custom next navigation icon. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string NextIcon { get; set; } = Icons.Material.Filled.NavigateNext; + + /// + /// Gets or Sets the Template for the Left Arrow + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public RenderFragment NextButtonTemplate { get; set; } + + + /// + /// Gets or Sets the Template for the Right Arrow + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public RenderFragment PreviousButtonTemplate { get; set; } + + + /// + /// Gets or Sets the Template for Bullets + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Parameter] public RenderFragment BulletTemplate { get; set; } + + /// + /// Gets or Sets if swipe gestures are allowed for touch devices. + /// + [Category(CategoryTypes.Carousel.Behavior)] + [Parameter] + public bool EnableSwipeGesture { get; set; } = true; + + /// + /// Gets or Sets the Template for Delimiters. + /// Deprecated, use BulletsTemplate instead. + /// + [Category(CategoryTypes.Carousel.Appearance)] + [Obsolete($"Use {nameof(BulletTemplate)} instead", false)] + [ExcludeFromCodeCoverage] + [Parameter] public RenderFragment DelimiterTemplate { get => BulletTemplate; set => BulletTemplate = value; } + + + /// + /// Called when selected Index changed on base class + /// + protected override void SelectionChanged() + { + InvokeAsync(async () => await ResetTimerAsync()); + + _currentColor = SelectedContainer?.Color ?? ThemeColor.Inherit; + } + + //When an item is added, it automatically checks the color + public override void AddItem(CarouselItem item) + { + Items.Add(item); + if (Items.Count - 1 == SelectedIndex) + { + _currentColor = item.Color; + StateHasChanged(); + } + } + + + /// + /// Provides Selection changes by horizontal swipe gesture + /// + private void OnSwipe(SwipeDirection direction) + { + if (!EnableSwipeGesture) + { + return; + } + + switch (direction) + { + case SwipeDirection.LeftToRight: + if (RightToLeft) Next(); + else Previous(); + break; + + case SwipeDirection.RightToLeft: + if (RightToLeft) Previous(); + else Next(); + break; + } + } + + /// + /// Immediately starts the AutoCycle timer + /// + private ValueTask StartTimerAsync() + { + if (AutoCycle) + _timer?.Change(AutoCycleTime, TimeSpan.Zero); + + return ValueTask.CompletedTask; + } + + /// + /// Immediately stops the AutoCycle timer + /// + private ValueTask StopTimerAsync() + { + _timer?.Change(Timeout.Infinite, Timeout.Infinite); + return ValueTask.CompletedTask; + } + + /// + /// Stops and restart the AutoCycle timer + /// + private async ValueTask ResetTimerAsync() + { + await StopTimerAsync(); + await StartTimerAsync(); + } + + + /// + /// Changes the SelectedIndex to a next one (or restart on 0) + /// + private async ValueTask TimerTickAsync() + { + await InvokeAsync(Next); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender) + { + _timer = new Timer(TimerElapsed, null, AutoCycle ? AutoCycleTime : Timeout.InfiniteTimeSpan, AutoCycleTime); + } + } + + public async ValueTask DisposeAsync() + { + await DisposeAsync(true); + GC.SuppressFinalize(this); + } + + + protected virtual async ValueTask DisposeAsync(bool disposing) + { + if (disposing) + { + await StopTimerAsync(); + + var timer = _timer; + if (timer != null) + { + _timer = null; + await timer.DisposeAsync(); + } + } + } +} diff --git a/Components/Carousel/CarouselItem.razor b/Components/Carousel/CarouselItem.razor new file mode 100644 index 0000000..0f2c5a9 --- /dev/null +++ b/Components/Carousel/CarouselItem.razor @@ -0,0 +1,10 @@ +@namespace Connected.Components + +@inherits UIComponent + +@if (IsVisible) +{ +
    + @ChildContent +
    +} \ No newline at end of file diff --git a/Components/Carousel/CarouselItem.razor.cs b/Components/Carousel/CarouselItem.razor.cs new file mode 100644 index 0000000..fb15481 --- /dev/null +++ b/Components/Carousel/CarouselItem.razor.cs @@ -0,0 +1,91 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class CarouselItem : UIComponent, IDisposable +{ + protected string Classname => + new CssBuilder("mud-carousel-item") + .AddClass($"mud-carousel-item-{Color.ToDescriptionString()}") + .AddClass("mud-carousel-item-exit", !_disposed && Parent.LastContainer == this) + + .AddClass("mud-carousel-transition-fade-in", !_disposed && Transition == Transition.Fade && Parent.SelectedContainer == this) + .AddClass("mud-carousel-transition-fade-out", !_disposed && Transition == Transition.Fade && Parent.LastContainer == this) + + .AddClass("mud-carousel-transition-slide-next-enter", !_disposed && Transition == Transition.Slide && RightToLeft == false && Parent.SelectedContainer == this && Parent._moveNext) + .AddClass("mud-carousel-transition-slide-next-exit", !_disposed && Transition == Transition.Slide && RightToLeft == false && Parent.LastContainer == this && Parent._moveNext) + + .AddClass("mud-carousel-transition-slide-prev-enter", !_disposed && Transition == Transition.Slide && RightToLeft == false && Parent.SelectedContainer == this && !Parent._moveNext) + .AddClass("mud-carousel-transition-slide-prev-exit", !_disposed && Transition == Transition.Slide && RightToLeft == false && Parent.LastContainer == this && !Parent._moveNext) + + .AddClass("mud-carousel-transition-slide-next-rtl-enter", !_disposed && Transition == Transition.Slide && RightToLeft == true && Parent.SelectedContainer == this && Parent._moveNext) + .AddClass("mud-carousel-transition-slide-next-rtl-exit", !_disposed && Transition == Transition.Slide && RightToLeft == true && Parent.LastContainer == this && Parent._moveNext) + + .AddClass("mud-carousel-transition-slide-prev-rtl-enter", !_disposed && Transition == Transition.Slide && RightToLeft == true && Parent.SelectedContainer == this && !Parent._moveNext) + .AddClass("mud-carousel-transition-slide-prev-rtl-exit", !_disposed && Transition == Transition.Slide && RightToLeft == true && Parent.LastContainer == this && !Parent._moveNext) + + .AddClass("mud-carousel-transition-none", !_disposed && Transition == Transition.None && Parent.SelectedContainer != this) + + .AddClass(CustomTransitionEnter, !_disposed && Transition == Transition.Custom && Parent.SelectedContainer == this && Parent.SelectedContainer == this) + .AddClass(CustomTransitionExit, !_disposed && Transition == Transition.Custom && Parent.LastContainer == this && Parent.LastContainer == this) + + .AddClass(Class) + .Build(); + + [Parameter] + [Category(CategoryTypes.Carousel.Behavior)] + public RenderFragment ChildContent { get; set; } + + [CascadingParameter] protected internal ItemsControlBase Parent { get; set; } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The transition effect of the component. + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public Transition Transition { get; set; } = Transition.Slide; + + /// + /// The name of custom transition on entrance time + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string CustomTransitionEnter { get; set; } + + /// + /// The name of custom transition on exiting time + /// + [Parameter] + [Category(CategoryTypes.Carousel.Appearance)] + public string CustomTransitionExit { get; set; } + + + public bool IsVisible => Parent != null && (Parent.LastContainer == this || Parent.SelectedIndex == Parent.Items.IndexOf(this)); + + + protected override Task OnInitializedAsync() + { + Parent?.AddItem(this); + return Task.CompletedTask; + } + + private bool _disposed = false; + public void Dispose() + { + _disposed = true; + Parent?.Items.Remove(this); + } + +} diff --git a/Components/Chart/Chart.razor b/Components/Chart/Chart.razor new file mode 100644 index 0000000..93c81ad --- /dev/null +++ b/Components/Chart/Chart.razor @@ -0,0 +1,25 @@ +@namespace Connected.Components + +@inherits UIComponent + + +
    + @if (ChartType == ChartType.Donut) + { + + } + @if (ChartType == ChartType.Pie) + { + + } + @if (ChartType == ChartType.Line) + { + + } + @if (ChartType == ChartType.Bar) + { + + } +
    +
    + diff --git a/Components/Chart/Chart.razor.cs b/Components/Chart/Chart.razor.cs new file mode 100644 index 0000000..07706c8 --- /dev/null +++ b/Components/Chart/Chart.razor.cs @@ -0,0 +1,136 @@ +using System.Globalization; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Chart : UIComponent +{ + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public double[] InputData { get; set; } = Array.Empty(); + + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public string[] InputLabels { get; set; } = Array.Empty(); + + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public string[] XAxisLabels { get; set; } = Array.Empty(); + + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public List ChartSeries { get; set; } = new(); + + [Parameter] + [Category(CategoryTypes.Chart.Appearance)] + public ChartOptions ChartOptions { get; set; } = new(); + + /// + /// RenderFragment for costumization inside the chart's svg. + /// + [Parameter] + [Category(CategoryTypes.Chart.Appearance)] + public RenderFragment CustomGraphics { get; set; } + + protected string Classname => + new CssBuilder("mud-chart") + .AddClass($"mud-chart-legend-{ConvertLegendPosition(LegendPosition).ToDescriptionString()}") + .AddClass(Class) + .Build(); + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// The Type of the chart. + /// + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public ChartType ChartType { get; set; } + + /// + /// The Width of the chart, end with % or px. + /// + [Parameter] + [Category(CategoryTypes.Chart.Appearance)] + public string Width { get; set; } = "80%"; + + /// + /// The Height of the chart, end with % or px. + /// + [Parameter] + [Category(CategoryTypes.Chart.Appearance)] + public string Height { get; set; } = "80%"; + + /// + /// The placement direction of the legend if used. + /// + [Parameter] + [Category(CategoryTypes.Chart.Appearance)] + public Position LegendPosition { get; set; } = Position.Bottom; + + private Position ConvertLegendPosition(Position position) + { + return position switch + { + Position.Start => RightToLeft ? Position.Right : Position.Left, + Position.End => RightToLeft ? Position.Left : Position.Right, + _ => position + }; + } + + private int _selectedIndex; + + /// + /// Selected index of a portion of the chart. + /// + [Parameter] + [Category(CategoryTypes.Chart.Behavior)] + public int SelectedIndex + { + get => _selectedIndex; + set + { + if (value != _selectedIndex) + { + _selectedIndex = value; + SelectedIndexChanged.InvokeAsync(value); + } + } + } + + /// + /// Selected index of a portion of the chart. + /// + [Parameter] public EventCallback SelectedIndexChanged { get; set; } + + /// + /// Scales the input data to the range between 0 and 1 + /// + protected double[] GetNormalizedData() + { + if (InputData == null) + return Array.Empty(); + var total = InputData.Sum(); + return InputData.Select(x => Math.Abs(x) / total).ToArray(); + } + + protected string ToS(double d, string format = null) + { + if (string.IsNullOrEmpty(format)) + return d.ToString(CultureInfo.InvariantCulture); + + return d.ToString(format); + } + +} + +public enum ChartType +{ + Donut, + Line, + Pie, + Bar +} diff --git a/Components/Chart/Charts/Bar.razor b/Components/Chart/Charts/Bar.razor new file mode 100644 index 0000000..aba13fa --- /dev/null +++ b/Components/Chart/Charts/Bar.razor @@ -0,0 +1,45 @@ +@namespace Connected.Components +@using System.Globalization; +@inherits Chart + + + + + @foreach (var horizontalLine in _horizontalLines) + { + + } + + @if (ChartParent?.ChartOptions.XAxisLines==true) + { + + @foreach (var verticalLine in _verticalLines) + { + + } + + } + + + @foreach (var horizontalLineValue in _horizontalValues) + { + @((MarkupString)$"{horizontalLineValue.Value.ToString(CultureInfo.InvariantCulture)}") + } + + + @foreach (var verticalLineValue in _verticalValues) + { + @((MarkupString)$"{verticalLineValue.Value.ToString(CultureInfo.InvariantCulture)}") + } + + + @foreach (var bar in _bars) + { + + } + + + + @ChartParent?.CustomGraphics + + diff --git a/Components/Chart/Charts/Bar.razor.cs b/Components/Chart/Charts/Bar.razor.cs new file mode 100644 index 0000000..7a49a3f --- /dev/null +++ b/Components/Chart/Charts/Bar.razor.cs @@ -0,0 +1,150 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class Bar : Chart +{ + [CascadingParameter] public Chart ChartParent { get; set; } + + private List _horizontalLines = new(); + private List _horizontalValues = new(); + + private List _verticalLines = new(); + private List _verticalValues = new(); + + private List _legends = new(); + private List _series = new(); + + private List _bars = new(); + + protected override void OnParametersSet() + { + base.OnParametersSet(); + _horizontalLines.Clear(); + _verticalLines.Clear(); + _horizontalValues.Clear(); + _verticalValues.Clear(); + _legends.Clear(); + _bars.Clear(); + + if (ChartParent != null) + _series = ChartParent.ChartSeries; + + var maxY = 0.0; + var numValues = 0; + var numXLabels = XAxisLabels.Length; + foreach (var item in _series) + { + if (numValues < item.Data.Length) + { + numValues = item.Data.Length; + } + foreach (int i in item.Data) + { + if (maxY < i) + { + maxY = i; + } + } + } + + var boundHeight = 350.0; + var boundWidth = 650.0; + + double gridYUnits = ChartParent?.ChartOptions.YAxisTicks ?? 20; + double gridXUnits = 30; + + var numVerticalLines = numValues - 1; + + var numHorizontalLines = ((int)(maxY / gridYUnits)) + 1; + + var verticalStartSpace = 25.0; + var horizontalStartSpace = 30.0; + var verticalEndSpace = 25.0; + var horizontalEndSpace = 30.0; + + var verticalSpace = (boundHeight - verticalStartSpace - verticalEndSpace) / (numHorizontalLines); + var horizontalSpace = (boundWidth - horizontalStartSpace - horizontalEndSpace) / (numVerticalLines); + + //Horizontal Grid Lines + var y = verticalStartSpace; + double startGridY = 0; + for (var counter = 0; counter <= numHorizontalLines; counter++) + { + var line = new SvgPath() + { + Index = counter, + Data = $"M {ToS(horizontalStartSpace)} {ToS((boundHeight - y))} L {ToS((boundWidth - horizontalEndSpace))} {ToS((boundHeight - y))}" + }; + _horizontalLines.Add(line); + + var lineValue = new SvgText() { X = (horizontalStartSpace - 10), Y = (boundHeight - y + 5), Value = ToS(startGridY, ChartParent?.ChartOptions.YAxisFormat) }; + _horizontalValues.Add(lineValue); + + startGridY += gridYUnits; + y += verticalSpace; + } + + //Vertical Grid Lines + var x = horizontalStartSpace; + double startGridX = 0; + for (var counter = 0; counter <= numVerticalLines; counter++) + { + + var line = new SvgPath() + { + Index = counter, + Data = $"M {ToS(x)} {ToS((boundHeight - verticalStartSpace))} L {ToS(x)} {ToS(verticalEndSpace)}" + }; + _verticalLines.Add(line); + + var xLabels = ""; + if (counter < numXLabels) + { + xLabels = XAxisLabels[counter]; + } + + var lineValue = new SvgText() { X = x, Y = boundHeight - 2, Value = xLabels }; + _verticalValues.Add(lineValue); + + startGridX += gridXUnits; + x += horizontalSpace; + } + + + //Bars + var colorcounter = 0; + double barsPerSeries = 0; + foreach (var item in _series) + { + double gridValueX = horizontalStartSpace + barsPerSeries; + double gridValueY = boundHeight - verticalStartSpace; + + foreach (var dataLine in item.Data) + { + var dataValue = dataLine * verticalSpace / gridYUnits; + var gridValue = gridValueY - dataValue; + var bar = $"M {ToS(gridValueX)} {ToS(gridValueY)} L {ToS(gridValueX)} {ToS(gridValue)}"; + + gridValueX += horizontalSpace; + + var line = new SvgPath() + { + Index = colorcounter, + Data = bar + }; + _bars.Add(line); + } + + barsPerSeries += 10; + + var legend = new SvgLegend() + { + Index = colorcounter, + Labels = item.Name + }; + colorcounter++; + _legends.Add(legend); + } + } +} diff --git a/Components/Chart/Charts/Donut.razor b/Components/Chart/Charts/Donut.razor new file mode 100644 index 0000000..37acf52 --- /dev/null +++ b/Components/Chart/Charts/Donut.razor @@ -0,0 +1,22 @@ +@namespace Connected.Components +@using System.Globalization +@inherits Chart + + + + + @foreach (var item in _circles.ToList()) + { + + + } + + + @ChartParent?.CustomGraphics + + diff --git a/Components/Chart/Charts/Donut.razor.cs b/Components/Chart/Charts/Donut.razor.cs new file mode 100644 index 0000000..44299f6 --- /dev/null +++ b/Components/Chart/Charts/Donut.razor.cs @@ -0,0 +1,60 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class Donut : Chart +{ + [CascadingParameter] public Chart ChartParent { get; set; } + + private List _circles = new(); + private List _legends = new(); + + protected string ParentWidth => ChartParent?.Width; + protected string ParentHeight => ChartParent?.Height; + + protected override void OnParametersSet() + { + _circles.Clear(); + _legends.Clear(); + double counterClockwiseOffset = 25; + double totalPercent = 0; + double offset; + + var counter = 0; + foreach (var data in GetNormalizedData()) + { + var percent = data * 100; + var reversePercent = 100 - percent; + offset = 100 - totalPercent + counterClockwiseOffset; + totalPercent += percent; + + var circle = new SvgCircle() + { + Index = counter, + CX = 21, + CY = 21, + Radius = 15.91549430918954, + StrokeDashArray = $"{ToS(percent)} {ToS(reversePercent)}", + StrokeDashOffset = offset + }; + _circles.Add(circle); + + + var labels = ""; + if (counter < InputLabels.Length) + { + labels = InputLabels[counter]; + } + var legend = new SvgLegend() + { + Index = counter, + Labels = labels, + Data = data.ToString() + }; + _legends.Add(legend); + + counter += 1; + } + } + +} diff --git a/Components/Chart/Charts/Line.razor b/Components/Chart/Charts/Line.razor new file mode 100644 index 0000000..75bd73b --- /dev/null +++ b/Components/Chart/Charts/Line.razor @@ -0,0 +1,44 @@ +@namespace Connected.Components +@using System.Globalization; +@inherits Chart + + + + + @foreach (var horizontalLine in _horizontalLines) + { + + } + + @if (ChartParent?.ChartOptions.XAxisLines==true) + { + + @foreach (var verticalLine in _verticalLines) + { + + } + + } + + + @foreach (var horizontalLineValue in _horizontalValues) + { + @((MarkupString)$"{horizontalLineValue.Value.ToString(CultureInfo.InvariantCulture)}") + } + + + @foreach (var verticalLineValue in _verticalValues) + { + @((MarkupString)$"{verticalLineValue.Value.ToString(CultureInfo.InvariantCulture)}") + } + + + @foreach (var chartLine in _chartLines) + { + + } + + + @ChartParent?.CustomGraphics + + diff --git a/Components/Chart/Charts/Line.razor.cs b/Components/Chart/Charts/Line.razor.cs new file mode 100644 index 0000000..1833cba --- /dev/null +++ b/Components/Chart/Charts/Line.razor.cs @@ -0,0 +1,231 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class Line : Chart +{ + private const int MaxHorizontalGridLines = 100; + + [CascadingParameter] public Chart ChartParent { get; set; } + + private List _horizontalLines = new(); + private List _horizontalValues = new(); + + private List _verticalLines = new(); + private List _verticalValues = new(); + + private List _legends = new(); + private List _series = new(); + + private List _chartLines = new(); + + protected override void OnParametersSet() + { + base.OnParametersSet(); + _horizontalLines.Clear(); + _verticalLines.Clear(); + _horizontalValues.Clear(); + _verticalValues.Clear(); + _legends.Clear(); + _chartLines.Clear(); + + if (ChartParent != null) + _series = ChartParent.ChartSeries; + + var maxY = 0.0; + var numValues = 0; + var numXLabels = XAxisLabels.Length; + foreach (var item in _series) + { + if (numValues < item.Data.Length) + { + numValues = item.Data.Length; + } + foreach (int i in item.Data) + { + if (maxY < i) + { + maxY = i; + } + } + } + + var boundHeight = 350.0; + var boundWidth = 650.0; + + double gridYUnits = ChartParent?.ChartOptions.YAxisTicks ?? 20; + if (gridYUnits <= 0) + gridYUnits = 20; + int maxYTicks = ChartParent?.ChartOptions.MaxNumYAxisTicks ?? 100; + double gridXUnits = 30; + + var numVerticalLines = numValues - 1; + + var numHorizontalLines = ((int)(maxY / gridYUnits)) + 1; + + // this is a safeguard against millions of gridlines which might arise with very high values + while (numHorizontalLines > maxYTicks) + { + gridYUnits *= 2; + numHorizontalLines = ((int)(maxY / gridYUnits)) + 1; + } + + var verticalStartSpace = 25.0; + var horizontalStartSpace = 30.0; + var verticalEndSpace = 25.0; + var horizontalEndSpace = 30.0; + + var verticalSpace = (boundHeight - verticalStartSpace - verticalEndSpace) / (numHorizontalLines); + var horizontalSpace = (boundWidth - horizontalStartSpace - horizontalEndSpace) / (numVerticalLines); + var interpolationOption = ChartParent?.ChartOptions.InterpolationOption ?? InterpolationOption.Straight; + + //Horizontal Grid Lines + var y = verticalStartSpace; + double startGridY = 0; + for (var counter = 0; counter <= numHorizontalLines; counter++) + { + var line = new SvgPath() + { + Index = counter, + Data = $"M {ToS(horizontalStartSpace)} {ToS((boundHeight - y))} L {ToS((boundWidth - horizontalEndSpace))} {ToS((boundHeight - y))}" + }; + _horizontalLines.Add(line); + + var lineValue = new SvgText() { X = (horizontalStartSpace - 10), Y = (boundHeight - y + 5), Value = ToS(startGridY, ChartParent?.ChartOptions.YAxisFormat) }; + _horizontalValues.Add(lineValue); + + startGridY += gridYUnits; + y += verticalSpace; + } + + //Vertical Grid Lines + var x = horizontalStartSpace; + double startGridX = 0; + for (var counter = 0; counter <= numVerticalLines; counter++) + { + + var line = new SvgPath() + { + Index = counter, + Data = $"M {ToS(x)} {ToS((boundHeight - verticalStartSpace))} L {ToS(x)} {ToS(verticalEndSpace)}" + }; + _verticalLines.Add(line); + + var xLabels = ""; + if (counter < numXLabels) + { + xLabels = XAxisLabels[counter]; + } + + var lineValue = new SvgText() { X = x, Y = boundHeight - 2, Value = xLabels }; + _verticalValues.Add(lineValue); + + startGridX += gridXUnits; + x += horizontalSpace; + } + + + //Chart Lines + var colorcounter = 0; + foreach (var item in _series) + { + var chartLine = ""; + double gridValueX = 0; + double gridValueY = 0; + var firstTime = true; + double[] XValues = new double[item.Data.Length]; + double[] YValues = new double[item.Data.Length]; + ILineInterpolator interpolator; + for (var i = 0; i <= item.Data.Length - 1; i++) + { + if (i == 0) + XValues[i] = 30; + else + XValues[i] = XValues[i - 1] + horizontalSpace; + + var gridValue = (item.Data[i]) * verticalSpace / gridYUnits; + YValues[i] = boundHeight - (verticalStartSpace + gridValue); + + } + switch (interpolationOption) + { + case InterpolationOption.NaturalSpline: + interpolator = new NaturalSpline(XValues, YValues); + break; + case InterpolationOption.EndSlope: + interpolator = new EndSlopeSpline(XValues, YValues); + break; + case InterpolationOption.Periodic: + interpolator = new PeriodicSpline(XValues, YValues); + break; + case InterpolationOption.Straight: + default: + interpolator = new NoInterpolation(); + break; + } + + if (interpolator?.InterpolationRequired == true) + { + horizontalSpace = (boundWidth - horizontalStartSpace - horizontalEndSpace) / interpolator.InterpolatedXs.Length; + foreach (var yValue in interpolator.InterpolatedYs) + { + + if (firstTime) + { + + chartLine += "M "; + firstTime = false; + gridValueX = horizontalStartSpace; + gridValueY = verticalStartSpace; + } + else + { + chartLine += " L "; + gridValueX += horizontalSpace; + gridValueY = verticalStartSpace; + } + gridValueY = yValue; + chartLine = chartLine + ToS(gridValueX) + " " + ToS(gridValueY); + } + } + else + { + foreach (var dataLine in item.Data) + { + if (firstTime) + { + chartLine += "M "; + firstTime = false; + gridValueX = horizontalStartSpace; + gridValueY = verticalStartSpace; + } + else + { + chartLine += " L "; + gridValueX += horizontalSpace; + gridValueY = verticalStartSpace; + } + + var gridValue = ((double)dataLine) * verticalSpace / gridYUnits; + gridValueY = boundHeight - (gridValueY + gridValue); + chartLine = chartLine + ToS(gridValueX) + " " + ToS(gridValueY); + } + } + + var line = new SvgPath() + { + Index = colorcounter, + Data = chartLine + }; + + var legend = new SvgLegend() + { + Index = colorcounter, + Labels = item.Name + }; + colorcounter++; + _chartLines.Add(line); + _legends.Add(legend); + } + } +} diff --git a/Components/Chart/Charts/Pie.razor b/Components/Chart/Charts/Pie.razor new file mode 100644 index 0000000..83cf0bd --- /dev/null +++ b/Components/Chart/Charts/Pie.razor @@ -0,0 +1,14 @@ +@namespace Connected.Components +@using System.Globalization +@inherits Chart + + + + @foreach (var item in _paths.ToList()) + { + + } + + @ChartParent?.CustomGraphics + + diff --git a/Components/Chart/Charts/Pie.razor.cs b/Components/Chart/Charts/Pie.razor.cs new file mode 100644 index 0000000..665d684 --- /dev/null +++ b/Components/Chart/Charts/Pie.razor.cs @@ -0,0 +1,55 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +partial class Pie : Chart +{ + [CascadingParameter] public Chart ChartParent { get; set; } + + private List _paths = new(); + private List _legends = new(); + + protected override void OnParametersSet() + { + _paths.Clear(); + _legends.Clear(); + double startx, starty, endx, endy; + var ndata = GetNormalizedData(); + double cumulativeRadians = 0; + for (var i = 0; i < ndata.Length; i++) + { + var data = ndata[i]; + startx = Math.Cos(cumulativeRadians); + starty = Math.Sin(cumulativeRadians); + cumulativeRadians += 2 * Math.PI * data; + endx = Math.Cos(cumulativeRadians); + endy = Math.Sin(cumulativeRadians); + var largeArcFlag = data > 0.5 ? 1 : 0; + var path = new SvgPath() + { + Index = i, + Data = $"M {ToS(startx)} {ToS(starty)} A 1 1 0 {ToS(largeArcFlag)} 1 {ToS(endx)} {ToS(endy)} L 0 0" + }; + _paths.Add(path); + } + + var counter = 0; + foreach (var data in ndata) + { + var percent = data * 100; + var labels = ""; + if (counter < InputLabels.Length) + { + labels = InputLabels[counter]; + } + var legend = new SvgLegend() + { + Index = counter, + Labels = labels, + Data = ToS(Math.Round(percent, 1)) + }; + _legends.Add(legend); + counter += 1; + } + } +} diff --git a/Components/Chart/Interpolation/EndSlopeSpline.cs b/Components/Chart/Interpolation/EndSlopeSpline.cs new file mode 100644 index 0000000..88a795f --- /dev/null +++ b/Components/Chart/Interpolation/EndSlopeSpline.cs @@ -0,0 +1,75 @@ +/* + * Work in this file is derived from code originally written by Hans-Peter Moser: + * http://www.mosismath.com/AngleSplines/EndSlopeSplines.html + */ + +namespace Connected.Components; + +public class EndSlopeSpline : SplineInterpolator +{ + public EndSlopeSpline(double[] xs, double[] ys, + int resolution = 10, double firstSlopeDegrees = 0, double lastSlopeDegrees = 0) : + base(xs, ys, resolution) + { + m = new Matrix(n); + gauss = new MatrixSolver(n, m); + + a = new double[n]; + b = new double[n]; + c = new double[n]; + d = new double[n]; + h = new double[n]; + + CalcParameters(firstSlopeDegrees, lastSlopeDegrees); + Integrate(); + Interpolate(); + } + + public void CalcParameters(double alpha, double beta) + { + for (int i = 0; i < n; i++) + a[i] = GivenYs[i]; + + for (int i = 0; i < n - 1; i++) + h[i] = GivenXs[i + 1] - GivenXs[i]; + + m.a[0, 0] = 2.0 * h[0]; + m.a[0, 1] = h[0]; + m.y[0] = 3 * ((a[1] - a[0]) / h[0] - Math.Tan(alpha * Math.PI / 180)); + + for (int i = 0; i < n - 2; i++) + { + m.a[i + 1, i] = h[i]; + m.a[i + 1, i + 1] = 2.0 * (h[i] + h[i + 1]); + if (i < n - 2) + m.a[i + 1, i + 2] = h[i + 1]; + + if ((h[i] != 0.0) && (h[i + 1] != 0.0)) + m.y[i + 1] = ((a[i + 2] - a[i + 1]) / h[i + 1] - (a[i + 1] - a[i]) / h[i]) * 3.0; + else + m.y[i + 1] = 0.0; + } + + m.a[n - 1, n - 2] = h[n - 2]; + m.a[n - 1, n - 1] = 2.0 * h[n - 2]; + m.y[n - 1] = 3.0 * (Math.Tan(beta * Math.PI / 180) - (a[n - 1] - a[n - 2]) / h[n - 2]); + + if (gauss.Eliminate() == false) + throw new InvalidOperationException(); + + gauss.Solve(); + + for (int i = 0; i < n; i++) + { + c[i] = m.x[i]; + } + for (int i = 0; i < n; i++) + { + if (h[i] != 0.0) + { + d[i] = 1.0 / 3.0 / h[i] * (c[i + 1] - c[i]); + b[i] = 1.0 / h[i] * (a[i + 1] - a[i]) - h[i] / 3.0 * (c[i + 1] + 2 * c[i]); + } + } + } +} diff --git a/Components/Chart/Interpolation/ILineInterpolator.cs b/Components/Chart/Interpolation/ILineInterpolator.cs new file mode 100644 index 0000000..a9ac2e4 --- /dev/null +++ b/Components/Chart/Interpolation/ILineInterpolator.cs @@ -0,0 +1,11 @@ +namespace Connected.Components; + +public interface ILineInterpolator +{ + public double[] GivenYs { get; set; } + public double[] GivenXs { get; set; } + public double[] InterpolatedXs { get; set; } + public double[] InterpolatedYs { get; set; } + public bool InterpolationRequired { get; set; } + +} diff --git a/Components/Chart/Interpolation/Matrix.cs b/Components/Chart/Interpolation/Matrix.cs new file mode 100644 index 0000000..761b904 --- /dev/null +++ b/Components/Chart/Interpolation/Matrix.cs @@ -0,0 +1,15 @@ +namespace Connected.Components; + +public class Matrix +{ + public double[,] a; + public double[] y; + public double[] x; + + public Matrix(int size) + { + a = new double[size, size]; + y = new double[size]; + x = new double[size]; + } +} diff --git a/Components/Chart/Interpolation/MatrixSolver.cs b/Components/Chart/Interpolation/MatrixSolver.cs new file mode 100644 index 0000000..562598c --- /dev/null +++ b/Components/Chart/Interpolation/MatrixSolver.cs @@ -0,0 +1,89 @@ +/* + * Work in this file is derived from code originally written by Hans-Peter Moser: + * http://www.mosismath.com/Basics/Basics.html + * http://www.mosismath.com/Matrix_Gauss/MatrixGauss.html + */ + +namespace Connected.Components; + +// Matrix equation solver using the Gaussian elimination algorithm +public class MatrixSolver +{ + public readonly Matrix m; + public readonly int maxOrder; + public bool calcError; + + public MatrixSolver(int size, Matrix mi) + { + maxOrder = size; + m = mi; + } + + void SwitchRows(int n) + { + double tempD; + int i, j; + for (i = n; i <= maxOrder - 2; i++) + { + for (j = 0; j <= maxOrder - 1; j++) + { + tempD = m.a[i, j]; + m.a[i, j] = m.a[i + 1, j]; + m.a[i + 1, j] = tempD; + } + tempD = m.y[i]; + m.y[i] = m.y[i + 1]; + m.y[i + 1] = tempD; + } + } + + public bool Eliminate() + { + int i, k, l; + calcError = false; + for (k = 0; k <= maxOrder - 2; k++) + { + for (i = k; i <= maxOrder - 2; i++) + { + if (Math.Abs(m.a[i + 1, i]) < 1e-8) + { + SwitchRows(i + 1); + } + if (m.a[i + 1, k] != 0.0) + { + for (l = k + 1; l <= maxOrder - 1; l++) + { + if (!calcError) + { + m.a[i + 1, l] = m.a[i + 1, l] * m.a[k, k] - m.a[k, l] * m.a[i + 1, k]; + if (m.a[i + 1, l] > 10E260) + { + m.a[i + 1, k] = 0; + calcError = true; + } + } + } + m.y[i + 1] = m.y[i + 1] * m.a[k, k] - m.y[k] * m.a[i + 1, k]; + m.a[i + 1, k] = 0; + } + } + } + return !calcError; + } + + public void Solve() + { + int k, l; + for (k = maxOrder - 1; k >= 0; k--) + { + for (l = maxOrder - 1; l >= k; l--) + { + m.y[k] = m.y[k] - m.x[l] * m.a[k, l]; + } + if (m.a[k, k] != 0) + m.x[k] = m.y[k] / m.a[k, k]; + else + m.x[k] = 0; + } + } +} diff --git a/Components/Chart/Interpolation/NaturalSpline.cs b/Components/Chart/Interpolation/NaturalSpline.cs new file mode 100644 index 0000000..d230bb9 --- /dev/null +++ b/Components/Chart/Interpolation/NaturalSpline.cs @@ -0,0 +1,87 @@ +/* + * Work in this file is derived from code originally written by Hans-Peter Moser: + * http://www.mosismath.com/NaturalSplines/NaturalSplines.html + */ + +namespace Connected.Components; + +public class NaturalSpline : SplineInterpolator +{ + /// + /// Natural Spline data interpolator + /// + public NaturalSpline(double[] xs, double[] ys, int resolution = 10) : base(xs, ys, resolution) + { + m = new Matrix(n - 2); + gauss = new MatrixSolver(n - 2, m); + + a = new double[n]; + b = new double[n]; + c = new double[n]; + d = new double[n]; + h = new double[n - 1]; + + CalcParameters(); + Integrate(); + Interpolate(); + } + public void CalcParameters() + { + for (int i = 0; i < n; i++) + a[i] = GivenYs[i]; + + for (int i = 0; i < n - 1; i++) + h[i] = GivenXs[i + 1] - GivenXs[i]; + + for (int i = 0; i < n - 2; i++) + { + for (int k = 0; k < n - 2; k++) + { + m.a[i, k] = 0.0; + m.y[i] = 0.0; + m.x[i] = 0.0; + } + } + + for (int i = 0; i < n - 2; i++) + { + if (i == 0) + { + m.a[i, 0] = 2.0 * (h[0] + h[1]); + m.a[i, 1] = h[1]; + } + else + { + m.a[i, i - 1] = h[i]; + m.a[i, i] = 2.0 * (h[i] + h[i + 1]); + if (i < n - 3) + m.a[i, i + 1] = h[i + 1]; + } + + if ((h[i] != 0.0) && (h[i + 1] != 0.0)) + m.y[i] = ((a[i + 2] - a[i + 1]) / h[i + 1] - (a[i + 1] - a[i]) / h[i]) * 3.0; + else + m.y[i] = 0.0; + } + + if (gauss.Eliminate() == false) + throw new InvalidOperationException("error in matrix calculation"); + + gauss.Solve(); + + c[0] = 0.0; + c[n - 1] = 0.0; + + for (int i = 1; i < n - 1; i++) + c[i] = m.x[i - 1]; + + for (int i = 0; i < n - 1; i++) + { + if (h[i] != 0.0) + { + d[i] = 1.0 / 3.0 / h[i] * (c[i + 1] - c[i]); + b[i] = 1.0 / h[i] * (a[i + 1] - a[i]) - h[i] / 3.0 * (c[i + 1] + 2 * c[i]); + } + } + } +} diff --git a/Components/Chart/Interpolation/NoInterpolation.cs b/Components/Chart/Interpolation/NoInterpolation.cs new file mode 100644 index 0000000..1a7797c --- /dev/null +++ b/Components/Chart/Interpolation/NoInterpolation.cs @@ -0,0 +1,10 @@ +namespace Connected.Components; + +public class NoInterpolation : ILineInterpolator +{ + public double[] GivenYs { get; set; } + public double[] GivenXs { get; set; } + public double[] InterpolatedXs { get; set; } + public double[] InterpolatedYs { get; set; } + public bool InterpolationRequired { get; set; } = false; +} diff --git a/Components/Chart/Interpolation/PeriodicSpline.cs b/Components/Chart/Interpolation/PeriodicSpline.cs new file mode 100644 index 0000000..e84b561 --- /dev/null +++ b/Components/Chart/Interpolation/PeriodicSpline.cs @@ -0,0 +1,86 @@ +/* + * Work in this file is derived from code originally written by Hans-Peter Moser: + * http://www.mosismath.com/PeriodicSplines/PeriodicSplines.html + */ + +namespace Connected.Components; + +public class PeriodicSpline : SplineInterpolator +{ + public PeriodicSpline(double[] xs, double[] ys, int resolution = 10) : base(xs, ys, resolution) + { + m = new Matrix(n - 1); + gauss = new MatrixSolver(n - 1, m); + + a = new double[n + 1]; + b = new double[n + 1]; + c = new double[n + 1]; + d = new double[n + 1]; + h = new double[n]; + + CalcParameters(); + Integrate(); + Interpolate(); + } + + public void CalcParameters() + { + for (int i = 0; i < n; i++) + a[i] = GivenYs[i]; + + for (int i = 0; i < n - 1; i++) + h[i] = GivenXs[i + 1] - GivenXs[i]; + + a[n] = GivenYs[1]; + h[n - 1] = h[0]; + + for (int i = 0; i < n - 1; i++) + for (int k = 0; k < n - 1; k++) + { + m.a[i, k] = 0.0; + m.y[i] = 0.0; + m.x[i] = 0.0; + } + + for (int i = 0; i < n - 1; i++) + { + if (i == 0) + { + m.a[i, 0] = 2.0 * (h[0] + h[1]); + m.a[i, 1] = h[1]; + } + else + { + m.a[i, i - 1] = h[i]; + m.a[i, i] = 2.0 * (h[i] + h[i + 1]); + if (i < n - 2) + m.a[i, i + 1] = h[i + 1]; + } + if ((h[i] != 0.0) && (h[i + 1] != 0.0)) + m.y[i] = ((a[i + 2] - a[i + 1]) / h[i + 1] - (a[i + 1] - a[i]) / h[i]) * 3.0; + else + m.y[i] = 0.0; + } + + m.a[0, n - 2] = h[0]; + m.a[n - 2, 0] = h[0]; + + if (gauss.Eliminate() == false) + throw new InvalidOperationException(); + + gauss.Solve(); + + for (int i = 1; i < n; i++) + c[i] = m.x[i - 1]; + c[0] = c[n - 1]; + + for (int i = 0; i < n; i++) + { + if (h[i] != 0.0) + { + d[i] = 1.0 / 3.0 / h[i] * (c[i + 1] - c[i]); + b[i] = 1.0 / h[i] * (a[i + 1] - a[i]) - h[i] / 3.0 * (c[i + 1] + 2 * c[i]); + } + } + } +} diff --git a/Components/Chart/Interpolation/SplineInterpolator.cs b/Components/Chart/Interpolation/SplineInterpolator.cs new file mode 100644 index 0000000..13f14f7 --- /dev/null +++ b/Components/Chart/Interpolation/SplineInterpolator.cs @@ -0,0 +1,83 @@ +namespace Connected.Components; + +public abstract class SplineInterpolator : ILineInterpolator +{ + protected Matrix m; + protected MatrixSolver gauss; + + protected readonly int n; + protected double[] a, b, c, d, h; + + public double[] GivenYs { get; set; } + public double[] GivenXs { get; set; } + public double[] InterpolatedXs { get; set; } + public double[] InterpolatedYs { get; set; } + public bool InterpolationRequired { get; set; } = true; + + public SplineInterpolator(double[] xs, double[] ys, int resolution = 10) + { + if (xs is null || ys is null) + throw new ArgumentException("xs and ys cannot be null"); + + if (xs.Length != ys.Length) + throw new ArgumentException("xs and ys must have the same length"); + + if (xs.Length < 4) + throw new ArgumentException("xs and ys must have a length of 4 or greater"); + + if (resolution < 1) + throw new ArgumentException("resolution must be 1 or greater"); + + GivenXs = xs; + GivenYs = ys; + n = xs.Length; + + InterpolatedXs = new double[n * resolution]; + InterpolatedYs = new double[n * resolution]; + } + public void Interpolate() + { + int resolution = InterpolatedXs.Length / n; + for (int i = 0; i < h.Length; i++) + { + for (int k = 0; k < resolution; k++) + { + double deltaX = (double)k / resolution * h[i]; + double termA = a[i]; + double termB = b[i] * deltaX; + double termC = c[i] * deltaX * deltaX; + double termD = d[i] * deltaX * deltaX * deltaX; + int interpolatedIndex = i * resolution + k; + InterpolatedXs[interpolatedIndex] = deltaX + GivenXs[i]; + InterpolatedYs[interpolatedIndex] = termA + termB + termC + termD; + } + } + + // After interpolation the last several values of the interpolated arrays + // contain uninitialized data. This section identifies the values which are + // populated with values and copies just the useful data into new arrays. + int pointsToKeep = resolution * (n - 1) + 1; + double[] interpolatedXsCopy = new double[pointsToKeep]; + double[] interpolatedYsCopy = new double[pointsToKeep]; + Array.Copy(InterpolatedXs, 0, interpolatedXsCopy, 0, pointsToKeep - 1); + Array.Copy(InterpolatedYs, 0, interpolatedYsCopy, 0, pointsToKeep - 1); + InterpolatedXs = interpolatedXsCopy; + InterpolatedYs = interpolatedYsCopy; + InterpolatedXs[pointsToKeep - 1] = GivenXs[n - 1]; + InterpolatedYs[pointsToKeep - 1] = GivenYs[n - 1]; + } + + public double Integrate() + { + double integral = 0; + for (int i = 0; i < h.Length; i++) + { + double termA = a[i] * h[i]; + double termB = b[i] * Math.Pow(h[i], 2) / 2.0; + double termC = c[i] * Math.Pow(h[i], 3) / 3.0; + double termD = d[i] * Math.Pow(h[i], 4) / 4.0; + integral += termA + termB + termC + termD; + } + return integral; + } +} diff --git a/Components/Chart/Models/ChartOptions.cs b/Components/Chart/Models/ChartOptions.cs new file mode 100644 index 0000000..4fc7497 --- /dev/null +++ b/Components/Chart/Models/ChartOptions.cs @@ -0,0 +1,40 @@ +namespace Connected.Components; + +public class ChartOptions +{ + /// + /// Spacing of Y-axis ticks. + /// + public int YAxisTicks { get; set; } = 20; + + /// + /// Maximum number of Y-axis ticks. The ticks will be thinned out if the value range is leading to too many ticks. + /// + public int MaxNumYAxisTicks { get; set; } = 20; + + public string YAxisFormat { get; set; } + public bool YAxisLines { get; set; } = true; + public bool XAxisLines { get; set; } + + /// + /// If true, legend will not be displayed. + /// + public bool DisableLegend { get; set; } + public string[] ChartPalette { get; set; } = { Colors.Blue.Accent3, Colors.Teal.Accent3, Colors.Amber.Accent3, Colors.Orange.Accent3, Colors.Red.Accent3, Colors.DeepPurple.Accent3, + Colors.Green.Accent3, Colors.LightBlue.Accent3, Colors.Teal.Lighten1, Colors.Amber.Lighten1, Colors.Orange.Lighten1, Colors.Red.Lighten1, + Colors.DeepPurple.Lighten1, Colors.Green.Lighten1, Colors.LightBlue.Lighten1, Colors.Amber.Darken2, Colors.Orange.Darken2, + Colors.Red.Darken2, Colors.DeepPurple.Darken2, Colors.Grey.Darken2 }; + public InterpolationOption InterpolationOption { get; set; } = InterpolationOption.Straight; + + /// + /// Line width of series in px + /// + public double LineStrokeWidth { get; set; } = 3; +} +public enum InterpolationOption +{ + NaturalSpline, + EndSlope, + Periodic, + Straight +} diff --git a/Components/Chart/Models/ChartSeries.cs b/Components/Chart/Models/ChartSeries.cs new file mode 100644 index 0000000..f49f747 --- /dev/null +++ b/Components/Chart/Models/ChartSeries.cs @@ -0,0 +1,8 @@ +namespace Connected.Components; + +public class ChartSeries +{ + public string Name { get; set; } + + public double[] Data { get; set; } +} diff --git a/Components/Chart/Parts/Filters.razor b/Components/Chart/Parts/Filters.razor new file mode 100644 index 0000000..80a95cd --- /dev/null +++ b/Components/Chart/Parts/Filters.razor @@ -0,0 +1,5 @@ +@namespace Connected.Components + + + + \ No newline at end of file diff --git a/Components/Chart/Parts/Legend.razor b/Components/Chart/Parts/Legend.razor new file mode 100644 index 0000000..97d609a --- /dev/null +++ b/Components/Chart/Parts/Legend.razor @@ -0,0 +1,15 @@ +@namespace Connected.Components +@inherits Chart + +@if (ChartParent?.ChartOptions.DisableLegend != true) +{ +
    + @foreach (var item in Data) + { +
    { if (ChartParent!=null) { ChartParent.SelectedIndex=item.Index; }}) @onclick:stopPropagation=@(ChartParent!=null)> + + @item.Labels +
    + } +
    +} diff --git a/Components/Chart/Parts/Legend.razor.cs b/Components/Chart/Parts/Legend.razor.cs new file mode 100644 index 0000000..3b59843 --- /dev/null +++ b/Components/Chart/Parts/Legend.razor.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Legend : Chart +{ + [CascadingParameter] public Chart ChartParent { get; set; } + [Parameter] public List Data { get; set; } = new List(); +} diff --git a/Components/Chart/Svg/SvgCircle.cs b/Components/Chart/Svg/SvgCircle.cs new file mode 100644 index 0000000..b31a88d --- /dev/null +++ b/Components/Chart/Svg/SvgCircle.cs @@ -0,0 +1,11 @@ +namespace Connected.Components; + +public class SvgCircle +{ + public int Index { get; set; } + public double CX { get; set; } + public double CY { get; set; } + public double Radius { get; set; } + public string StrokeDashArray { get; set; } + public double StrokeDashOffset { get; set; } +} diff --git a/Components/Chart/Svg/SvgLegend.cs b/Components/Chart/Svg/SvgLegend.cs new file mode 100644 index 0000000..381d30d --- /dev/null +++ b/Components/Chart/Svg/SvgLegend.cs @@ -0,0 +1,8 @@ +namespace Connected.Components; + +public class SvgLegend +{ + public int Index { get; set; } + public string Labels { get; set; } + public string Data { get; set; } +} diff --git a/Components/Chart/Svg/SvgPath.cs b/Components/Chart/Svg/SvgPath.cs new file mode 100644 index 0000000..aee9908 --- /dev/null +++ b/Components/Chart/Svg/SvgPath.cs @@ -0,0 +1,7 @@ +namespace Connected.Components; + +public class SvgPath +{ + public int Index { get; set; } + public string Data { get; set; } +} diff --git a/Components/Chart/Svg/SvgText.cs b/Components/Chart/Svg/SvgText.cs new file mode 100644 index 0000000..47638fb --- /dev/null +++ b/Components/Chart/Svg/SvgText.cs @@ -0,0 +1,8 @@ +namespace Connected.Components; + +public class SvgText +{ + public double X { get; set; } + public double Y { get; set; } + public string Value { get; set; } +} diff --git a/Components/CheckBox/CheckBox.razor b/Components/CheckBox/CheckBox.razor new file mode 100644 index 0000000..bf022f6 --- /dev/null +++ b/Components/CheckBox/CheckBox.razor @@ -0,0 +1,25 @@ +@namespace Connected.Components +@inherits BooleanInput +@typeparam T + + + + + + \ No newline at end of file diff --git a/Components/CheckBox/CheckBox.razor.cs b/Components/CheckBox/CheckBox.razor.cs new file mode 100644 index 0000000..ca80d3b --- /dev/null +++ b/Components/CheckBox/CheckBox.razor.cs @@ -0,0 +1,254 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class CheckBox : BooleanInput +{ + protected string Classname => + new CssBuilder("mud-input-control-boolean-input") + .AddClass(Class) + .Build(); + + protected string LabelClassname => + new CssBuilder("mud-checkbox") + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-readonly", ReadOnly) + .AddClass(LabelPosition == LabelPosition.End ? "mud-ltr" : "mud-rtl", true) + .Build(); + + protected string CheckBoxClassname => + new CssBuilder("mud-button-root mud-icon-button") + .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", UnCheckedColor == null || (UnCheckedColor != null && BoolValue == true)) + .AddClass($"mud-{UnCheckedColor?.ToDescriptionString()}-text hover:mud-{UnCheckedColor?.ToDescriptionString()}-hover", UnCheckedColor != null && BoolValue == false) + .AddClass($"mud-checkbox-dense", Dense) + .AddClass($"mud-ripple mud-ripple-checkbox", !DisableRipple && !ReadOnly && !Disabled) + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-readonly", ReadOnly) + .Build(); + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The base color of the component in its none active/unchecked state. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public ThemeColor? UnCheckedColor { get; set; } = null; + + /// + /// The text/label will be displayed next to the checkbox if set. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Label { get; set; } + + /// + /// The position of the text/label. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public LabelPosition LabelPosition { get; set; } = LabelPosition.End; + + /// + /// If true, the checkbox can be controlled with the keyboard. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool KeyboardEnabled { get; set; } = true; + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// If true, compact padding will be applied. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool Dense { get; set; } + + /// + /// The Size of the component. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Custom checked icon, leave null for default. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string CheckedIcon { get; set; } = Icons.Material.Filled.CheckBox; + + /// + /// Custom unchecked icon, leave null for default. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string UncheckedIcon { get; set; } = Icons.Material.Filled.CheckBoxOutlineBlank; + + /// + /// Custom indeterminate icon, leave null for default. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string IndeterminateIcon { get; set; } = Icons.Material.Filled.IndeterminateCheckBox; + + /// + /// Define if the checkbox can cycle again through indeterminate status. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public bool TriState { get; set; } + + private string GetIcon() + { + if (BoolValue == true) + { + return CheckedIcon; + } + + if (BoolValue == false) + { + return UncheckedIcon; + } + + return IndeterminateIcon; + } + + protected override Task OnChange(ChangeEventArgs args) + { + Touched = true; + + // Apply only when TriState parameter is set to true and T is bool? + if (TriState && typeof(T) == typeof(bool?)) + { + // The cycle is forced with the following steps: true, false, indeterminate, true, false, indeterminate... + if (!((bool?)(object)_value).HasValue) + { + return SetBoolValueAsync(true); + } + else + { + return ((bool?)(object)_value).Value ? SetBoolValueAsync(false) : SetBoolValueAsync(default); + } + } + else + { + return SetBoolValueAsync((bool?)args.Value); + } + } + + protected void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly || !KeyboardEnabled) + return; + switch (obj.Key) + { + case "Delete": + SetBoolValueAsync(false); + break; + case "Enter": + case "NumpadEnter": + SetBoolValueAsync(true); + break; + case "Backspace": + if (TriState) + { + SetBoolValueAsync(null); + } + break; + case " ": + if (BoolValue == null) + { + SetBoolValueAsync(true); + } + else if (BoolValue == true) + { + SetBoolValueAsync(false); + } + else if (BoolValue == false) + { + if (TriState == true) + { + SetBoolValueAsync(null); + } + else + { + SetBoolValueAsync(true); + } + } + break; + } + } + + private IKeyInterceptor _keyInterceptor; + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + private string _elementId = "checkbox" + Guid.NewGuid().ToString().Substring(0, 8); + + protected override void OnInitialized() + { + base.OnInitialized(); + + if (Label == null && For != null) + Label = For.GetLabelString(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _keyInterceptor = _keyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-button-root", + Keys = { + new KeyOptions { Key=" ", PreventDown = "key+none", PreventUp = "key+none" }, // prevent scrolling page + new KeyOptions { Key="Enter", PreventDown = "key+none" }, + new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, + new KeyOptions { Key="Backspace", PreventDown = "key+none" }, + }, + }); + _keyInterceptor.KeyDown += HandleKeyDown; + } + await base.OnAfterRenderAsync(firstRender); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.Dispose(); + } + } + } +} diff --git a/Components/Chip/Chip.razor b/Components/Chip/Chip.razor new file mode 100644 index 0000000..23b509c --- /dev/null +++ b/Components/Chip/Chip.razor @@ -0,0 +1,33 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @if (!String.IsNullOrEmpty(Avatar)) + { + + + + } + else if (!String.IsNullOrEmpty(Icon) && !IsChecked) + { + + } + else if (IsChecked) + { + + } + + @if (ChildContent == null) + { + @Text + } + else + { + @ChildContent + } + @if (OnClose.HasDelegate || ChipSet?.AllClosable==true) + { + + } + +
    diff --git a/Components/Chip/Chip.razor.cs b/Components/Chip/Chip.razor.cs new file mode 100644 index 0000000..9b81931 --- /dev/null +++ b/Components/Chip/Chip.razor.cs @@ -0,0 +1,335 @@ +using System.Diagnostics.CodeAnalysis; +using System.Windows.Input; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Chip : UIComponent, IDisposable +{ + private bool _isSelected; + [Inject] public NavigationManager UriHelper { get; set; } + + [Inject] public IJsApiService JsApiService { get; set; } + + protected string Classname => + new CssBuilder("mud-chip") + .AddClass($"mud-chip-{GetVariant().ToDescriptionString()}") + .AddClass($"mud-chip-size-{Size.ToDescriptionString()}") + .AddClass($"mud-chip-color-{GetColor().ToDescriptionString()}") + .AddClass("mud-clickable", !ChipSet?.ReadOnly ?? OnClick.HasDelegate) + .AddClass("mud-ripple", !ChipSet?.ReadOnly ?? OnClick.HasDelegate && !DisableRipple) + .AddClass("mud-chip-label", Label) + .AddClass("mud-disabled", Disabled) + .AddClass("mud-chip-selected", IsSelected) + .AddClass(Class) + .Build(); + + //Cannot test the get variant (last line) + [ExcludeFromCodeCoverage] + private Variant GetVariant() + { + return Variant switch + { + Variant.Text => IsSelected ? Variant.Filled : Variant.Text, + Variant.Filled => IsSelected ? Variant.Text : Variant.Filled, + Variant.Outlined => Variant.Outlined, + _ => Variant + }; + } + + private ThemeColor GetColor() + { + if (IsSelected && SelectedColor != ThemeColor.Inherit) + { + return SelectedColor; + } + else if (IsSelected && SelectedColor == ThemeColor.Inherit) + { + return Color; + } + else + { + return Color; + } + } + + [CascadingParameter] ChipSet ChipSet { get; set; } + + /// + /// The color of the component. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The size of the button. small is equivalent to the dense button styling. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public Variant Variant { get; set; } = Variant.Filled; + + /// + /// The selected color to use when selected, only works together with ChipSet, Color.Inherit for default value. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public ThemeColor SelectedColor { get; set; } = ThemeColor.Inherit; + + /// + /// Avatar Icon, Overrides the regular Icon if set. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public string Avatar { get; set; } + + /// + /// Avatar CSS Class, appends to Chips default avatar classes. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public string AvatarClass { get; set; } + + /// + /// Removes circle edges and applies theme default. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public bool Label { get; set; } + + /// + /// If true, the chip will be displayed in disabled state and no events possible. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public bool Disabled { get; set; } + + /// + /// Sets the Icon to use. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public string Icon { get; set; } + + /// + /// Custom checked icon. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public string CheckedIcon { get; set; } = Icons.Material.Filled.Check; + + /// + /// The color of the icon. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// Overrides the default close icon, only shown if OnClose is set. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public string CloseIcon { get; set; } + + /// + /// If true, disables ripple effect, ripple effect is only applied to clickable chips. + /// + [Parameter] + [Category(CategoryTypes.Chip.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where (Obsolete replaced by Href) + /// + [Obsolete("Use Href Instead.", false)] + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public string Link + { + get => Href; + set => Href = value; + } + + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where + /// + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public string Href { get; set; } + + /// + /// The target attribute specifies where to open the link, if Href is specified. Possible values: _blank | _self | _parent | _top | framename + /// + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public string Target { get; set; } + + /// + /// A string you want to associate with the chip. If the ChildContent is not set this will be shown as chip text. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public string Text { get; set; } + + /// + /// A value that should be managed in the SelectedValues collection. + /// Note: do not change the value during the chip's lifetime + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public object Value { get; set; } + + /// + /// If true, force browser to redirect outside component router-space. + /// + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public bool ForceLoad { get; set; } + + /// + /// If true, this chip is selected by default if used in a ChipSet. + /// + [Parameter] + [Category(CategoryTypes.Chip.Behavior)] + public bool? Default { get; set; } + + /// + /// Command executed when the user clicks on an element. + /// + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public ICommand Command { get; set; } + + /// + /// Command parameter. + /// + [Parameter] + [Category(CategoryTypes.Chip.ClickAction)] + public object CommandParameter { get; set; } + + /// + /// Chip click event, if set the chip focus, hover and click effects are applied. + /// + [Parameter] public EventCallback OnClick { get; set; } + + /// + /// Chip delete event, if set the delete icon will be visible. + /// + [Parameter] public EventCallback OnClose { get; set; } + + /// + /// Set by MudChipSet + /// + public bool IsChecked + { + get => _isSelected && ChipSet?.Filter == true; + } + + /// + /// If false, this chip has not been seen before + /// + public bool DefaultProcessed { get; set; } + + /// + /// Set by MudChipSet + /// + public bool IsSelected + { + get => _isSelected; + set + { + if (_isSelected == value) + return; + _isSelected = value; + StateHasChanged(); + } + } + + protected override void OnInitialized() + { + base.OnInitialized(); + if (Value == null) + Value = this; + } + + protected internal async Task OnClickHandler(MouseEventArgs ev) + { + if (ChipSet?.ReadOnly == true) + { + return; + } + if (ChipSet != null) + { + _ = ChipSet.OnChipClicked(this); + } + if (Href != null) + { + // TODO: use MudElement to render and this code can be removed. we know that it has potential problems on iOS + if (string.IsNullOrWhiteSpace(Target)) + UriHelper.NavigateTo(Href, ForceLoad); + else + await JsApiService.Open(Href, Target); + } + else + { + await OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + } + + protected async Task OnCloseHandler(MouseEventArgs ev) + { + if (ChipSet?.ReadOnly == true) + { + return; + } + await OnClose.InvokeAsync(this); + ChipSet?.OnChipDeleted(this); + StateHasChanged(); + } + + protected override Task OnInitializedAsync() + { + ChipSet?.Add(this); + return base.OnInitializedAsync(); + } + + internal void ForceRerender() => StateHasChanged(); + + //Exclude because we don't test to catching exception yet + [ExcludeFromCodeCoverage] + public void Dispose() + { + try + { + ChipSet?.Remove(this); + } + catch (Exception) + { + /* ignore! */ + } + } + +} diff --git a/Components/ChipSet/ChipSet.razor b/Components/ChipSet/ChipSet.razor new file mode 100644 index 0000000..a2b95fb --- /dev/null +++ b/Components/ChipSet/ChipSet.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + @ChildContent + +
    diff --git a/Components/ChipSet/ChipSet.razor.cs b/Components/ChipSet/ChipSet.razor.cs new file mode 100644 index 0000000..f0c41c3 --- /dev/null +++ b/Components/ChipSet/ChipSet.razor.cs @@ -0,0 +1,342 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ChipSet : UIComponent, IDisposable +{ + + protected string Classname => + new CssBuilder("mud-chipset") + .AddClass(Class) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Allows to select more than one chip. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public bool MultiSelection { get; set; } = false; + + /// + /// Will not allow to deselect the selected chip in single selection mode. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public bool Mandatory { get; set; } = false; + + /// + /// Will make all chips closable. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public bool AllClosable { get; set; } = false; + + /// + /// Will show a check-mark for the selected components. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Appearance)] + public bool Filter + { + get => _filter; + set + { + if (_filter == value) + return; + _filter = value; + StateHasChanged(); + foreach (var chip in _chips) + chip.ForceRerender(); + } + } + + /// + /// Will make all chips read only. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public bool ReadOnly { get; set; } = false; + + /// + /// The currently selected chip in Choice mode + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public Chip SelectedChip + { + get { return _chips.OfType().FirstOrDefault(x => x.IsSelected); } + set + { + if (value == null) + { + foreach (var chip in _chips) + { + chip.IsSelected = false; + } + } + else + { + foreach (var chip in _chips) + { + chip.IsSelected = (chip == value); + } + } + this.InvokeAsync(StateHasChanged); + } + } + + /// + /// Called when the selected chip changes, in Choice mode + /// + [Parameter] + public EventCallback SelectedChipChanged { get; set; } + + /// + /// The currently selected chips in Filter mode + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public Chip[] SelectedChips + { + get { return _chips.OfType().Where(x => x.IsSelected).ToArray(); } + set + { + if (value == null || value.Length == 0) + { + foreach (var chip in _chips) + { + chip.IsSelected = false; + } + } + else + { + var selected = new HashSet(value); + foreach (var chip in _chips) + { + chip.IsSelected = selected.Contains(chip); + } + } + StateHasChanged(); + } + } + + protected override void OnInitialized() + { + base.OnInitialized(); + if (_selectedValues == null) + _selectedValues = new HashSet(_comparer); + _initialSelectedValues = new HashSet(_selectedValues, _comparer); + } + + private IEqualityComparer _comparer; + private HashSet _selectedValues; + private HashSet _initialSelectedValues; + + /// + /// The Comparer to use for comparing selected values internally. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public IEqualityComparer Comparer + { + get => _comparer; + set + { + _comparer = value; + // Apply comparer and refresh selected values + _selectedValues = new HashSet(_selectedValues, _comparer); + SelectedValues = _selectedValues; + } + } + + /// + /// Called when the selection changed, in Filter mode + /// + [Parameter] + public EventCallback SelectedChipsChanged { get; set; } + + /// + /// The current selected value. + /// Note: make the list Clickable for item selection to work. + /// + [Parameter] + [Category(CategoryTypes.ChipSet.Behavior)] + public ICollection SelectedValues + { + get => _selectedValues; + set + { + if (value == null) + SetSelectedValues(new object[0]); + else + SetSelectedValues(value.ToArray()).AndForget(); + } + } + + /// + /// Called whenever the selection changed + /// + [Parameter] public EventCallback> SelectedValuesChanged { get; set; } + + internal Task SetSelectedValues(object[] values) + { + HashSet newValues = null; + if (values == null) + values = new object[0]; + if (MultiSelection) + newValues = new HashSet(values, _comparer); + else + { + newValues = new HashSet(_comparer); + if (values.Length > 0) + newValues.Add(values.First()); + } + // avoid update with same values + if (_selectedValues.IsEqualTo(newValues)) + return Task.CompletedTask; + _selectedValues = newValues; + foreach (var chip in _chips.ToArray()) + { + var isSelected = _selectedValues.Contains(chip.Value); + chip.IsSelected = isSelected; + } + return NotifySelection(); + } + + /// + /// Called when a Chip was deleted (by click on the close icon) + /// + [Parameter] + public EventCallback OnClose { get; set; } + + internal Task Add(Chip chip) + { + _chips.Add(chip); + if (_selectedValues.Contains(chip.Value)) + chip.IsSelected = true; + return CheckDefault(chip); + } + + internal void Remove(Chip chip) + { + _chips.Remove(chip); + if (chip.IsSelected) + { + _selectedValues.Remove(chip.Value); + NotifySelection().AndForget(); + } + } + + private async Task CheckDefault(Chip chip) + { + if (!MultiSelection) + return; + if (chip.DefaultProcessed) + return; + chip.DefaultProcessed = true; + if (chip.Default == null) + return; + var oldSelected = chip.IsSelected; + chip.IsSelected = chip.Default == true; + if (chip.IsSelected != oldSelected) + { + if (chip.IsSelected) + _selectedValues.Add(chip.Value); + else + _selectedValues.Remove(chip.Value); + await NotifySelection(); + } + } + + private HashSet _chips = new(); + private bool _filter; + + internal Task OnChipClicked(Chip chip) + { + var wasSelected = chip.IsSelected; + if (MultiSelection) + { + chip.IsSelected = !chip.IsSelected; + } + else + { + foreach (var ch in _chips) + { + ch.IsSelected = (ch == chip); // <-- exclusively select the one chip only, thus all others must be deselected + } + if (!Mandatory) + chip.IsSelected = !wasSelected; + } + UpdateSelectedValues(); + return NotifySelection(); + } + + private void UpdateSelectedValues() + { + _selectedValues = new HashSet(_chips.Where(x => x.IsSelected).Select(x => x.Value), _comparer); + } + + private object[] _lastSelectedValues = null; + + private async Task NotifySelection() + { + if (_disposed) + return; + // to avoid endless notification loops we check if selection has really changed + if (_selectedValues.IsEqualTo(_lastSelectedValues)) + return; + _lastSelectedValues = _selectedValues.ToArray(); + await SelectedChipChanged.InvokeAsync(SelectedChip); + await SelectedChipsChanged.InvokeAsync(SelectedChips); + await SelectedValuesChanged.InvokeAsync(SelectedValues); + StateHasChanged(); + } + + public void OnChipDeleted(Chip chip) + { + Remove(chip); + OnClose.InvokeAsync(chip); + } + + protected override async void OnAfterRender(bool firstRender) + { + if (firstRender) + await SelectDefaultChips(); + base.OnAfterRender(firstRender); + } + + private async Task SelectDefaultChips() + { + if (!MultiSelection) + { + var anySelected = false; + var defaultChip = _chips.LastOrDefault(chip => chip.Default == true); + if (defaultChip != null) + { + defaultChip.IsSelected = true; + anySelected = true; + } + if (anySelected) + { + UpdateSelectedValues(); + await NotifySelection(); + } + } + } + + private bool _disposed; + + public void Dispose() + { + _disposed = true; + } +} diff --git a/Components/Collapse/Collapse.razor b/Components/Collapse/Collapse.razor new file mode 100644 index 0000000..771453d --- /dev/null +++ b/Components/Collapse/Collapse.razor @@ -0,0 +1,11 @@ +@namespace Connected.Components +@inherits UIComponent +@using System.Globalization; + +
    +
    +
    + @ChildContent +
    +
    +
    diff --git a/Components/Collapse/Collapse.razor.cs b/Components/Collapse/Collapse.razor.cs new file mode 100644 index 0000000..8bdaa75 --- /dev/null +++ b/Components/Collapse/Collapse.razor.cs @@ -0,0 +1,146 @@ +using System.Globalization; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected.Components; + +public partial class Collapse : UIComponent +{ + internal enum CollapseState + { + Entering, Entered, Exiting, Exited + } + + internal double _height; + private bool _expanded, _isRendered, _updateHeight; + private ElementReference _wrapper; + internal CollapseState _state = CollapseState.Exited; + + protected string Stylename => + new StyleBuilder() + .AddStyle("max-height", MaxHeight.ToPx(), MaxHeight != null) + .AddStyle("height", "auto", _state == CollapseState.Entered) + .AddStyle("height", _height.ToPx(), _state is CollapseState.Entering or CollapseState.Exiting) + .AddStyle("animation-duration", $"{CalculatedAnimationDuration.ToString("#.##", CultureInfo.InvariantCulture)}s", _state == CollapseState.Entering) + .AddStyle(Style) + .Build(); + + protected string Classname => + new CssBuilder("mud-collapse-container") + .AddClass($"mud-collapse-entering", _state == CollapseState.Entering) + .AddClass($"mud-collapse-entered", _state == CollapseState.Entered) + .AddClass($"mud-collapse-exiting", _state == CollapseState.Exiting) + .AddClass(Class) + .Build(); + + /// + /// If true, expands the panel, otherwise collapse it. Setting this prop enables control over the panel. + /// + [Parameter] + public bool Expanded + { + get => _expanded; + set + { + if (_expanded == value) + return; + _expanded = value; + + if (_isRendered) + { + _state = _expanded ? CollapseState.Entering : CollapseState.Exiting; + _ = UpdateHeight(); + _updateHeight = true; + } + else if (_expanded) + { + _state = CollapseState.Entered; + } + + _ = ExpandedChanged.InvokeAsync(_expanded); + } + } + + /// + /// Explicitly sets the height for the Collapse element to override the css default. + /// + [Parameter] public int? MaxHeight { get; set; } + + /// + /// Child content of component. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + [Parameter] public EventCallback OnAnimationEnd { get; set; } + + [Parameter] public EventCallback ExpandedChanged { get; set; } + + /// + /// Modified Animation duration that scales with height parameter. + /// Basic implementation for now but should be a math formula to allow it to scale between 0.1s and 1s for the effect to be consistently smooth. + /// + private double CalculatedAnimationDuration + { + get + { + if (MaxHeight != null) + { + if (MaxHeight <= 200) return 0.2; + else if (MaxHeight <= 600) return 0.4; + else if (MaxHeight <= 1400) return 0.6; + return 1; + } + return Math.Min(_height / 800.0, 1); + } + set { } + } + + internal async Task UpdateHeight() + { + try + { + _height = (await _wrapper.MudGetBoundingClientRectAsync())?.Height ?? 0; + } + catch (Exception ex) when (ex is JSDisconnectedException || ex is TaskCanceledException) + { + _height = 0; + } + + if (MaxHeight != null && _height > MaxHeight) + { + _height = MaxHeight.Value; + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _isRendered = true; + await UpdateHeight(); + } + else if (_updateHeight && _state is CollapseState.Entering or CollapseState.Exiting) + { + _updateHeight = false; + await UpdateHeight(); + StateHasChanged(); + } + await base.OnAfterRenderAsync(firstRender); + } + + public void AnimationEnd() + { + if (_state == CollapseState.Entering) + { + _state = CollapseState.Entered; + StateHasChanged(); + } + else if (_state == CollapseState.Exiting) + { + _state = CollapseState.Exited; + StateHasChanged(); + } + OnAnimationEnd.InvokeAsync(Expanded); + } +} diff --git a/Components/ColorPicker/ColorPicker.razor b/Components/ColorPicker/ColorPicker.razor new file mode 100644 index 0000000..7f361a0 --- /dev/null +++ b/Components/ColorPicker/ColorPicker.razor @@ -0,0 +1,151 @@ +@namespace Connected.Components +@using System.Globalization; +@using Connected.Utilities; +@inherits Picker + +@Render + +@code { + + protected override RenderFragment PickerContent => + @ + + @if (PickerVariant != PickerVariant.Static) + { + + } + + + + + + + @if (!DisableColorField) + { +
    + @if (_activeColorPickerView == ColorPickerView.Spectrum) + { +
    +
    +
    +
    + + + + + + + + + + + + +
    +
    +
    +
    + } + @if (_activeColorPickerView is ColorPickerView.Grid or ColorPickerView.GridCompact) + { +
    + @foreach (var item in _gridList) + { +
    + } +
    + } +
    + } + @if (_activeColorPickerView != ColorPickerView.GridCompact) + { + @if (!DisableSliders || !DisableInputs || !DisablePreview) + { +
    + @if (!DisableSliders || !DisablePreview) + { +
    + @if (!DisablePreview) + { +
    +
    +
    + } + @if (!DisableSliders && !_collectionOpen) + { +
    + @if (_activeColorPickerView != ColorPickerView.Grid) + { + + } + @if (!DisableAlpha) + { + + } +
    + } + @if (_collectionOpen) + { +
    + @foreach (var item in Palette.Take(5)) + { +
    + } +
    + } +
    + } + @if (!DisableInputs) + { +
    +
    + @switch (ColorPickerMode) + { + case ColorPickerMode.RGB: + + + + break; + case ColorPickerMode.HSL: + + + + break; + case ColorPickerMode.HEX: + + break; + default: + break; + } + + @if (!DisableAlpha && ColorPickerMode != ColorPickerMode.HEX) + { + + } +
    + @if (!DisableModeSwitch) + { +
    + +
    + } +
    + } +
    + } + @if (_activeColorPickerView == ColorPickerView.Palette) + { +
    +
    + @foreach (var item in Palette) + { +
    + } +
    +
    + } + } +
    +
    ; + +} diff --git a/Components/ColorPicker/ColorPicker.razor.cs b/Components/ColorPicker/ColorPicker.razor.cs new file mode 100644 index 0000000..c85450d --- /dev/null +++ b/Components/ColorPicker/ColorPicker.razor.cs @@ -0,0 +1,597 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Globalization; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class ColorPicker : Picker, IAsyncDisposable +{ + public ColorPicker() : base(new DefaultConverter()) + { + AdornmentIcon = Icons.Material.Outlined.Palette; + DisableToolbar = true; + Value = "#594ae2"; //MudBlazor Blue + Text = GetColorTextValue(); + AdornmentAriaLabel = "Open Color Picker"; + } + + #region Fields + + private static Dictionary r, Func g, Func b, string dominantColorPart)> _rgbToHueMapper = new() + { + { 0, ((x) => 255, x => x, x => 0, "rb") }, + { 1, ((x) => 255 - x, x => 255, x => 0, "gb") }, + { 2, ((x) => 0, x => 255, x => x, "gr") }, + { 3, ((x) => 0, x => 255 - x, x => 255, "br") }, + { 4, ((x) => x, x => 0, x => 255, "bg") }, + { 5, ((x) => 255, x => 0, x => 255 - x, "rg") }, + }; + + private const double _maxY = 250; + private const double _maxX = 312; + private const double _selctorSize = 26.0; + + private double _selectorX; + private double _selectorY; + private bool _skipFeedback = false; + + private Color _baseColor; + private Color _color; + + private bool _collectionOpen; + + private readonly Guid _id = Guid.NewGuid(); + private Guid _throttledMouseOverEventId; + + private IEventListener _throttledEventManager; + [Inject] IEventListenerFactory ThrottledEventManagerFactory { get; set; } + + #endregion + + #region Parameters + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + private bool _disableAlpha = false; + + /// + /// If true, Alpha options will not be displayed and color output will be RGB, HSL or HEX and not RGBA, HSLA or HEXA. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableAlpha + { + get => _disableAlpha; + set + { + if (value != _disableAlpha) + { + _disableAlpha = value; + + if (value == true) + { + Value = Value.SetAlpha(1.0); + } + + Text = GetColorTextValue(); + } + } + } + + /// + /// If true, the color field will not be displayed. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableColorField { get; set; } = false; + + /// + /// If true, the switch to change color mode will not be displayed. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableModeSwitch { get; set; } = false; + + /// + /// If true, textfield inputs and color mode switch will not be displayed. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableInputs { get; set; } = false; + + /// + /// If true, hue and alpha sliders will not be displayed. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableSliders { get; set; } = false; + + /// + /// If true, the preview color box will not be displayed, note that the preview color functions as a button as well for collection colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisablePreview { get; set; } = false; + + /// + /// The initial mode (RGB, HSL or HEX) the picker should open. Defaults to RGB + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public ColorPickerMode ColorPickerMode { get; set; } = ColorPickerMode.RGB; + + private ColorPickerView _colorPickerView = ColorPickerView.Spectrum; + private ColorPickerView _activeColorPickerView = ColorPickerView.Spectrum; + + /// + /// The initial view of the picker. Views can be changed if toolbar is enabled. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public ColorPickerView ColorPickerView + { + get => _colorPickerView; + set + { + if (value != _colorPickerView) + { + _colorPickerView = value; + ChangeView(value).AndForget(); + } + } + } + + /// + /// If true, binding changes occurred also when HSL values changed without a corresponding RGB change + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool UpdateBindingIfOnlyHSLChanged { get; set; } = false; + + /// + /// A two-way bindable property representing the selected value. MudColor is a utility class that can be used to get the value as RGB, HSL, hex or other value + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public Color Value + { + get => _color; + set + { + if (value == null) { return; } + + var rgbChanged = value != _color; + var hslChanged = _color == null ? false : value.HslChanged(_color); + _color = value; + + if (rgbChanged) + { + if (_skipFeedback == false) + { + UpdateBaseColor(); + UpdateColorSelectorBasedOnRgb(); + } + + SetTextAsync(GetColorTextValue(), false).AndForget(); + ValueChanged.InvokeAsync(value).AndForget(); + FieldChanged(value); + } + + if (rgbChanged == false && UpdateBindingIfOnlyHSLChanged && hslChanged == true) + { + SetTextAsync(GetColorTextValue(), false).AndForget(); + ValueChanged.InvokeAsync(value).AndForget(); + FieldChanged(value); + } + } + } + + [Parameter] public EventCallback ValueChanged { get; set; } + + /// + /// MudColor list of predefined colors. The first five colors will show up as the quick colors on preview dot click. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public IEnumerable Palette { get; set; } = new Color[] + { "#424242", "#2196f3", "#00c853", "#ff9800", "#f44336", + "#f6f9fb", "#9df1fa", "#bdffcf", "#fff0a3", "#ffd254", + "#e6e9eb", "#27dbf5", "#7ef7a0", "#ffe273", "#ffb31f", + "#c9cccf", "#13b8e8", "#14dc71", "#fdd22f", "#ff9102", + "#858791", "#0989c2", "#1bbd66", "#ebb323", "#fe6800", + "#585b62", "#17698e", "#17a258", "#d9980d", "#dc3f11", + "#353940", "#113b53", "#127942", "#bf7d11", "#aa0000" + }; + + private IEnumerable _gridList = new Color[] + { + "#FFFFFF","#ebebeb","#d6d6d6","#c2c2c2","#adadad","#999999","#858586","#707070","#5c5c5c","#474747","#333333","#000000", + "#133648","#071d53","#0f0638","#2a093b","#370c1b","#541107","#532009","#53350d","#523e0f","#65611b","#505518","#2b3d16", + "#1e4c63","#0f2e76","#180b4e","#3f1256","#4e1629","#781e0e","#722f10","#734c16","#73591a","#8c8629","#707625","#3f5623", + "#2e6c8c","#1841a3","#280c72","#591e77","#6f223d","#a62c17","#a0451a","#a06b23","#9f7d28","#c3bc3c","#9da436","#587934", + "#3c8ab0","#2155ce","#331c8e","#702898","#8d2e4f","#d03a20","#ca5a24","#c8862e","#c99f35","#f3ec4e","#c6d047","#729b44", + "#479fd3","#2660f5","#4725ab","#8c33b5","#aa395d","#eb512e","#ed732e","#f3ae3d","#f5c944","#fefb67","#ddeb5c","#86b953", + "#59c4f7","#4e85f6","#5733e2","#af43eb","#d44a7a","#ed6c59","#ef8c56","#f3b757","#f6cd5b","#fef881","#e6ee7a","#a3d16e", + "#78d3f8","#7fa6f8","#7e52f5","#c45ff6","#de789d","#f09286","#f2a984","#f6c983","#f9da85","#fef9a1","#ebf29b","#badc94", + "#a5e1fa","#adc5fa","#ab8df7","#d696f8","#e8a7bf","#f4b8b1","#f6c7af","#f9daae","#fae5af","#fefbc0","#f3f7be","#d2e7ba", + "#d2effd","#d6e1fc","#d6c9fa","#e9cbfb","#f3d4df","#f9dcd9","#fae3d8","#fcecd7","#fdf2d8","#fefce0","#f7fade","#e3edd6" + }; + + /// + /// When set to true, no mouse move events in the spectrum mode will be captured, so the selector circle won't fellow the mouse. + /// Under some conditions like long latency the visual representation might not reflect the user behaviour anymore. So, it can be disabled + /// Enabled by default + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool DisableDragEffect { get; set; } = false; + + /// + /// Custom close icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string CloseIcon { get; set; } = Icons.Material.Filled.Close; + + /// + /// Custom spectrum icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string SpectrumIcon { get; set; } = Icons.Material.Filled.Tune; + + /// + /// Custom grid icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string GridIcon { get; set; } = Icons.Material.Filled.Apps; + + /// + /// Custom palette icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string PaletteIcon { get; set; } = Icons.Material.Filled.Palette; + + /// + /// Custom import/export icont. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string ImportExportIcon { get; set; } = Icons.Material.Filled.ImportExport; + + #endregion + + private void ToggleCollection() + { + _collectionOpen = !_collectionOpen; + } + + private void SelectPaletteColor(Color color) + { + Value = color; + _collectionOpen = false; + + if ( + IsAnyControlVisible() == false || _activeColorPickerView is ColorPickerView.GridCompact or ColorPickerView.Palette) + { + Close(); + } + } + + public void ChangeMode() => + ColorPickerMode = ColorPickerMode switch + { + ColorPickerMode.RGB => ColorPickerMode.HSL, + ColorPickerMode.HSL => ColorPickerMode.HEX, + ColorPickerMode.HEX => ColorPickerMode.RGB, + _ => ColorPickerMode.RGB, + }; + + public async Task ChangeView(ColorPickerView value) + { + + var oldValue = _activeColorPickerView; + + _activeColorPickerView = value; + Text = GetColorTextValue(); + + if (oldValue == ColorPickerView.Spectrum) + { + await RemoveMouseOverEvent(); + } + + if (value == ColorPickerView.Spectrum) + { + _attachedMouseEvent = true; + } + } + + private void UpdateBaseColorSlider(int value) + { + var diff = Math.Abs(value - (int)Value.H); + if (diff == 0) { return; } + + Value = Value.SetH(value); + } + + private void UpdateBaseColor() + { + var index = (int)_color.H / 60; + if (index == 6) + { + index = 5; + } + + var valueInDeg = (int)_color.H - (index * 60); + var value = (int)(MathExtensions.Map(0, 60, 0, 255, valueInDeg)); + var section = _rgbToHueMapper[index]; + + _baseColor = new(section.r(value), section.g(value), section.b(value), 255); + } + + private void UpdateColorBaseOnSelection() + { + var x = _selectorX / _maxX; + + var r_x = 255 - (int)((255 - _baseColor.R) * x); + var g_x = 255 - (int)((255 - _baseColor.G) * x); + var b_x = 255 - (int)((255 - _baseColor.B) * x); + + var y = 1.0 - _selectorY / _maxY; + + var r = r_x * y; + var g = g_x * y; + var b = b_x * y; + + _skipFeedback = true; + //in this mode, H is expected to be stable, so copy H value + Value = new Color((byte)r, (byte)g, (byte)b, _color); + _skipFeedback = false; + } + + private void UpdateColorSelectorBasedOnRgb() + { + var hueValue = (int)MathExtensions.Map(0, 360, 0, 6 * 255, _color.H); + var index = hueValue / 255; + if (index == 6) + { + index = 5; + } + + var section = _rgbToHueMapper[index]; + + var colorValues = section.dominantColorPart switch + { + "rb" => (_color.R, _color.B), + "rg" => (_color.R, _color.G), + "gb" => (_color.G, _color.B), + "gr" => (_color.G, _color.R), + "br" => (_color.B, _color.R), + "bg" => (_color.B, _color.G), + _ => (255, 255) + }; + + var primaryDiff = 255 - colorValues.Item1; + var primaryDiffDelta = colorValues.Item1 / 255.0; + + _selectorY = MathExtensions.Map(0, 255, 0, _maxY, primaryDiff); + + var secondaryColorX = colorValues.Item2 * (1.0 / primaryDiffDelta); + var relation = (255 - secondaryColorX) / 255.0; + + _selectorX = relation * _maxX; + } + + #region mouse interactions + + private void HandleColorOverlayClicked() + { + UpdateColorBaseOnSelection(); + + if (IsAnyControlVisible() == false) + { + Close(); + } + } + + private void OnSelectorClicked(MouseEventArgs e) + { + SetSelectorBasedOnMouseEvents(e, false); + HandleColorOverlayClicked(); + } + + private void OnColorOverlayClick(MouseEventArgs e) + { + SetSelectorBasedOnMouseEvents(e, true); + HandleColorOverlayClicked(); + } + + private void OnMouseOver(MouseEventArgs e) + { + if (e.Buttons == 1) + { + SetSelectorBasedOnMouseEvents(e, true); + UpdateColorBaseOnSelection(); + } + } + + private void SetSelectorBasedOnMouseEvents(MouseEventArgs e, bool offsetIsAbsolute) + { + _selectorX = (offsetIsAbsolute == true ? e.OffsetX : (e.OffsetX - _selctorSize / 2.0) + _selectorX).EnsureRange(_maxX); + _selectorY = (offsetIsAbsolute == true ? e.OffsetY : (e.OffsetY - _selctorSize / 2.0) + _selectorY).EnsureRange(_maxY); + } + + #endregion + + #region updating inputs + + /// + /// Set the R (red) component of the color picker + /// + /// A value between 0 (no red) or 255 (max red) + public void SetR(int value) => Value = Value.SetR(value); + + /// + /// Set the G (green) component of the color picker + /// + /// A value between 0 (no green) or 255 (max green) + public void SetG(int value) => Value = Value.SetG(value); + + /// + /// Set the B (blue) component of the color picker + /// + /// A value between 0 (no blue) or 255 (max blue) + public void SetB(int value) => Value = Value.SetB(value); + + /// + /// Set the H (hue) component of the color picker + /// + /// A value between 0 and 360 (degrees) + public void SetH(double value) => Value = Value.SetH(value); + + /// + /// Set the S (saturation) component of the color picker + /// + /// A value between 0.0 (no saturation) and 1.0 (max saturation) + public void SetS(double value) => Value = Value.SetS(value); + + /// + /// Set the L (Lightness) component of the color picker + /// + /// A value between 0.0 (no light, black) and 1.0 (max light, white) + public void SetL(double value) => Value = Value.SetL(value); + + /// + /// Set the Alpha (transparency) component of the color picker + /// + /// A value between 0.0 (full transparent) and 1.0 (solid) + public void SetAlpha(double value) => Value = Value.SetAlpha(value); + + /// + /// Set the Alpha (transparency) component of the color picker + /// + /// A value between 0 (full transparent) and 1 (solid) + public void SetAlpha(int value) => Value = Value.SetAlpha(value); + + /// + /// Set the color of the picker based on the string input + /// + /// Accepting different formats for a color representation such as rbg, rgba, # + public void SetInputString(string input) + { + Color color; + try + { + color = new Color(input); + } + catch (Exception) + { + return; + } + + Value = color; + } + + protected override Task StringValueChanged(string value) + { + SetInputString(value); + return Task.CompletedTask; + } + + private bool _attachedMouseEvent = false; + + protected override void OnPickerOpened() + { + base.OnPickerOpened(); + _attachedMouseEvent = true; + StateHasChanged(); + } + + protected override void OnPickerClosed() + { + base.OnPickerClosed(); + RemoveMouseOverEvent().AndForget(); + } + + #endregion + + #region helper + + private string GetSelectorLocation() => $"translate({Math.Round(_selectorX, 2).ToString(CultureInfo.InvariantCulture)}px, {Math.Round(_selectorY, 2).ToString(CultureInfo.InvariantCulture)}px);"; + private string GetColorTextValue() => (DisableAlpha == true || _activeColorPickerView is ColorPickerView.Palette or ColorPickerView.GridCompact) ? _color.ToString(ColorOutputFormats.Hex) : _color.ToString(ColorOutputFormats.HexA); + private int GetHexColorInputMaxLength() => DisableAlpha ? 7 : 9; + + private EventCallback GetEventCallback() => EventCallback.Factory.Create(this, () => Close()); + private bool IsAnyControlVisible() => !(DisablePreview && DisableSliders && DisableInputs); + private EventCallback GetSelectPaletteColorCallback(Color color) => new EventCallbackFactory().Create(this, (MouseEventArgs e) => SelectPaletteColor(color)); + + private ThemeColor GetButtonColor(ColorPickerView view) => _activeColorPickerView == view ? ThemeColor.Primary : ThemeColor.Inherit; + private string GetColorDotClass(Color color) => new CssBuilder("mud-picker-color-dot").AddClass("selected", color == Value).ToString(); + private string AlphaSliderStyle => new StyleBuilder().AddStyle($"background-image: linear-gradient(to {(RightToLeft ? "left" : "right")}, transparent, {_color.ToString(ColorOutputFormats.RGB)})").Build(); + + #endregion + + #region life cycle hooks + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender == true) + { + if (PickerVariant == PickerVariant.Static) + { + await AddMouseOverEvent(); + } + } + + if (_attachedMouseEvent == true) + { + _attachedMouseEvent = false; + await AddMouseOverEvent(); + } + } + + private async Task AddMouseOverEvent() + { + if (DisableDragEffect == true) { return; } + + if (_throttledEventManager == null) + { + _throttledEventManager = ThrottledEventManagerFactory.Create(); + } + + _throttledMouseOverEventId = await + _throttledEventManager.Subscribe("mousemove", _id.ToString(), "mudEventProjections.correctOffset", 10, async (x) => + { + var e = x as MouseEventArgs; + await InvokeAsync(() => OnMouseOver(e)); + StateHasChanged(); + }); + } + + private Task RemoveMouseOverEvent() + { + if (_throttledMouseOverEventId == default) { return Task.CompletedTask; } + + return _throttledEventManager.Unsubscribe(_throttledMouseOverEventId); + } + + public async ValueTask DisposeAsync() + { + if (_throttledEventManager == null) { return; } + + await _throttledEventManager.DisposeAsync(); + } + + #endregion +} diff --git a/Components/ColumnBase.cs b/Components/ColumnBase.cs new file mode 100644 index 0000000..2640034 --- /dev/null +++ b/Components/ColumnBase.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public abstract class ColumnBase : ComponentBase +{ + public enum Rendermode + { + Header, Item, Edit, Footer + } + + [CascadingParameter(Name = "Mode")] + public Rendermode Mode { get; set; } + + [Parameter] public bool Visible { get; set; } = true; + [Parameter] public string HeaderText { get; set; } + + protected bool IsDefault(T value) + { + return EqualityComparer.Default.Equals(value, default(T)); + } +} diff --git a/Components/Container/Container.razor b/Components/Container/Container.razor new file mode 100644 index 0000000..4c2962c --- /dev/null +++ b/Components/Container/Container.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components + +@inherits UIComponent + +
    + @ChildContent +
    \ No newline at end of file diff --git a/Components/Container/Container.razor.cs b/Components/Container/Container.razor.cs new file mode 100644 index 0000000..496b9d7 --- /dev/null +++ b/Components/Container/Container.razor.cs @@ -0,0 +1,36 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; +public partial class Container : UIComponent +{ + protected string Classname => + new CssBuilder("container") + .AddClass($"container-fixed", Fixed) + .AddClass($"container-maxwidth-{MaxWidth.ToDescriptionString()}", !Fixed) + .AddClass(Class) + .Build(); + + /// + /// Set the max-width to match the min-width of the current breakpoint. This is useful if you'd prefer to design for a fixed set of sizes instead of trying to accommodate a fully fluid viewport. It's fluid by default. + /// + [Parameter] + [Category(CategoryTypes.Container.Behavior)] + public bool Fixed { get; set; } = false; + + /// + /// Determine the max-width of the container. The container width grows with the size of the screen. Set to false to disable maxWidth. + /// + [Parameter] + [Category(CategoryTypes.Container.Behavior)] + public MaxWidth MaxWidth { get; set; } = MaxWidth.Large; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Container.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/DataGrid/AggregateDefinition.cs b/Components/DataGrid/AggregateDefinition.cs new file mode 100644 index 0000000..2aa97cf --- /dev/null +++ b/Components/DataGrid/AggregateDefinition.cs @@ -0,0 +1,145 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq.Expressions; + +namespace Connected.Components; + +public class AggregateDefinition +{ + public AggregateType Type { get; set; } = AggregateType.Count; + public string DisplayFormat { get; set; } = "{value}"; + public Func, string> CustomAggregate { get; set; } + + private AggregateType? _cachedType; + private Func _compiledAvgExpression; + private Func _compiledMinMaxExpression; + private Func _compiledSumExpression; + + public string GetValue(string field, IEnumerable items) + { + if (items == null || items.Count() == 0) + { + return DisplayFormat.Replace("{value}", "0"); + } + + object value = null; + + if (_cachedType != Type) + { + _cachedType = Type; + + if (Type == AggregateType.Avg) + { + var parameter = Expression.Parameter(typeof(T), "x"); + var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(decimal)); + _compiledAvgExpression = Expression.Lambda>(f, parameter).Compile(); + value = items.Average(_compiledAvgExpression); + } + else if (Type == AggregateType.Count) + { + value = items.Count(); + } + else if (Type == AggregateType.Custom) + { + return CustomAggregate.Invoke(items); + } + else if (Type == AggregateType.Max) + { + var parameter = Expression.Parameter(typeof(T), "x"); + var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(object)); + _compiledMinMaxExpression = Expression.Lambda>(f, parameter).Compile(); + value = items.Max(_compiledMinMaxExpression); + } + else if (Type == AggregateType.Min) + { + var parameter = Expression.Parameter(typeof(T), "x"); + var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(object)); + _compiledMinMaxExpression = Expression.Lambda>(f, parameter).Compile(); + value = items.Min(_compiledMinMaxExpression); + } + else if (Type == AggregateType.Sum) + { + var parameter = Expression.Parameter(typeof(T), "x"); + var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(decimal)); + _compiledSumExpression = Expression.Lambda>(f, parameter).Compile(); + value = items.Sum(_compiledSumExpression); + } + } + else + { + if (Type == AggregateType.Avg) + { + value = items.Average(_compiledAvgExpression); + } + else if (Type == AggregateType.Count) + { + value = items.Count(); + } + else if (Type == AggregateType.Custom) + { + return CustomAggregate.Invoke(items); + } + else if (Type == AggregateType.Max) + { + value = items.Max(_compiledMinMaxExpression); + } + else if (Type == AggregateType.Min) + { + value = items.Min(_compiledMinMaxExpression); + } + else if (Type == AggregateType.Sum) + { + value = items.Sum(_compiledSumExpression); + } + } + + return DisplayFormat.Replace("{value}", (value ?? "").ToString()); + } + + public static AggregateDefinition SimpleAvg() + { + return new AggregateDefinition + { + Type = AggregateType.Avg, + DisplayFormat = "Average {value}" + }; + } + + public static AggregateDefinition SimpleCount() + { + return new AggregateDefinition + { + Type = AggregateType.Count, + DisplayFormat = "Total {value}" + }; + } + + public static AggregateDefinition SimpleMax() + { + return new AggregateDefinition + { + Type = AggregateType.Max, + DisplayFormat = "Max {value}" + }; + } + + public static AggregateDefinition SimpleMin() + { + return new AggregateDefinition + { + Type = AggregateType.Min, + DisplayFormat = "Min {value}" + }; + } + + public static AggregateDefinition SimpleSum() + { + return new AggregateDefinition + { + Type = AggregateType.Sum, + DisplayFormat = "Sum {value}" + }; + } +} diff --git a/Components/DataGrid/AggregateType.cs b/Components/DataGrid/AggregateType.cs new file mode 100644 index 0000000..5defad5 --- /dev/null +++ b/Components/DataGrid/AggregateType.cs @@ -0,0 +1,15 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public enum AggregateType +{ + Avg, + Count, + Custom, + Max, + Min, + Sum +} diff --git a/Components/DataGrid/Cell.cs b/Components/DataGrid/Cell.cs new file mode 100644 index 0000000..c469c99 --- /dev/null +++ b/Components/DataGrid/Cell.cs @@ -0,0 +1,167 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using Connected.Utilities; + +namespace Connected.Components; + +[RequiresUnreferencedCode(CodeMessage.SerializationUnreferencedCodeMessage)] +internal class Cell +{ + private readonly DataGrid _dataGrid; + private readonly Column _column; + internal T _item; + internal string valueString; + internal double? valueNumber; + internal bool isEditing; + internal CellContext cellContext; + + #region Computed Properties + + internal object ComputedValue + { + get + { + if (_item == null || _column.Field == null) + return null; + + // Handle case where T is IDictionary. + if (typeof(T) == typeof(IDictionary)) + { + if (_column.FieldType == null) + throw new ArgumentNullException(nameof(_column.FieldType)); + + if (_column.FieldType.IsEnum) + { + var o = ((IDictionary)_item)[_column.Field]; + + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + var json = (JsonElement)o; + return Enum.ToObject(_column.FieldType, json.GetInt32()); + } + else + { + return Enum.ToObject(_column.FieldType, o); + } + } + + return ((IDictionary)_item)[_column.Field]; + } + + var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field); + return property.GetValue(_item); + } + } + internal string computedClass + { + get + { + return new CssBuilder(_column.CellClassFunc?.Invoke(_item)) + .AddClass(_column.CellClass) + .AddClass("mud-table-cell") + .AddClass("mud-table-cell-hide", _column.HideSmall) + .AddClass("sticky-left", _column.StickyLeft) + .AddClass("sticky-right", _column.StickyRight) + .AddClass($"edit-mode-cell", _dataGrid.EditMode == DataGridEditMode.Cell && _column.IsEditable) + .Build(); + } + } + internal string computedStyle + { + get + { + return new StyleBuilder() + .AddStyle(_column.CellStyleFunc?.Invoke(_item)) + .AddStyle(_column.CellStyle) + .Build(); + } + } + + #endregion + + public Cell(DataGrid dataGrid, Column column, T item) + { + _dataGrid = dataGrid; + _column = column; + _item = item; + + OnStartedEditingItem(); + + // Create the CellContext + cellContext = new CellContext(_dataGrid, _item); + } + + public async Task StringValueChangedAsync(string value) + { + var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field); + property.SetValue(_item, value); + + // If the edit mode is Cell, we update immediately. + if (_dataGrid.EditMode == DataGridEditMode.Cell) + await _dataGrid.CommitItemChangesAsync(_item); + } + + public async Task NumberValueChangedAsync(double? value) + { + var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field); + property.SetValue(_item, ChangeType(value, property.PropertyType)); + + // If the edit mode is Cell, we update immediately. + if (_dataGrid.EditMode == DataGridEditMode.Cell) + await _dataGrid.CommitItemChangesAsync(_item); + } + + private void OnStartedEditingItem() + { + + if (ComputedValue != null) + { + if (ComputedValue.GetType() == typeof(JsonElement)) + { + if (_column.dataType == typeof(string)) + { + valueString = ((JsonElement)ComputedValue).GetString(); + } + else if (_column.isNumber) + { + valueNumber = ((JsonElement)ComputedValue).GetDouble(); + } + } + else + { + if (_column.dataType == typeof(string)) + { + valueString = (string)ComputedValue; + } + else if (_column.isNumber) + { + valueNumber = Convert.ToDouble(ComputedValue); + } + } + } + } + + private object ChangeType(object value, Type conversion) + { + var t = conversion; + + if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) + { + if (value == null) + { + return null; + } + + t = Nullable.GetUnderlyingType(t); + } + + return Convert.ChangeType(value, t); + } +} diff --git a/Components/DataGrid/CellContext.cs b/Components/DataGrid/CellContext.cs new file mode 100644 index 0000000..73497b1 --- /dev/null +++ b/Components/DataGrid/CellContext.cs @@ -0,0 +1,47 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class CellContext +{ + internal HashSet selection; + internal HashSet openHierarchies; + public T Item { get; set; } + public CellActions Actions { get; internal set; } + public bool IsSelected + { + get + { + if (selection != null) + { + return selection.Contains(Item); + } + + return false; + } + } + + public CellContext(DataGrid dataGrid, T item) + { + selection = dataGrid.Selection; + openHierarchies = dataGrid._openHierarchies; + Item = item; + Actions = new CellContext.CellActions + { + SetSelectedItem = async (x) => await dataGrid.SetSelectedItemAsync(x, item), + StartEditingItem = async () => await dataGrid.SetEditingItemAsync(item), + CancelEditingItem = async () => await dataGrid.CancelEditingItemAsync(), + ToggleHierarchyVisibilityForItem = async () => await dataGrid.ToggleHierarchyVisibilityAsync(item), + }; + } + + public class CellActions + { + public Action SetSelectedItem { get; internal set; } + public Action StartEditingItem { get; internal set; } + public Action CancelEditingItem { get; internal set; } + public Action ToggleHierarchyVisibilityForItem { get; internal set; } + } +} diff --git a/Components/DataGrid/Column.cs b/Components/DataGrid/Column.cs new file mode 100644 index 0000000..3ddb929 --- /dev/null +++ b/Components/DataGrid/Column.cs @@ -0,0 +1,403 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq.Expressions; +using System.Text.Json; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +[RequiresUnreferencedCode(CodeMessage.SerializationUnreferencedCodeMessage)] +public partial class Column : UIComponent +{ + [CascadingParameter] public DataGrid DataGrid { get; set; } + + //[CascadingParameter(Name = "HeaderCell")] public HeaderCell HeaderCell { get; set; } + + [Parameter] public T Value { get; set; } + [Parameter] public EventCallback ValueChanged { get; set; } + + //[Parameter] public bool Visible { get; set; } = true; + + /// + /// Specifies the name of the object's property bound to the column + /// + [Parameter] public string Field { get; set; } + + [Parameter] public Type FieldType { get; set; } + [Parameter] public string Title { get; set; } + [Parameter] public bool HideSmall { get; set; } + [Parameter] public int FooterColSpan { get; set; } = 1; + [Parameter] public int HeaderColSpan { get; set; } = 1; + [Parameter] public RenderFragment ChildContent { get; set; } + [Parameter] public RenderFragment> HeaderTemplate { get; set; } + [Parameter] public RenderFragment> CellTemplate { get; set; } + [Parameter] public RenderFragment> FooterTemplate { get; set; } + [Parameter] public RenderFragment> GroupTemplate { get; set; } + [Parameter] public Func GroupBy { get; set; } + + #region HeaderCell Properties + + [Parameter] public string HeaderClass { get; set; } + [Parameter] public Func HeaderClassFunc { get; set; } + [Parameter] public string HeaderStyle { get; set; } + [Parameter] public Func HeaderStyleFunc { get; set; } + + /// + /// Determines whether this columns data can be sorted. This overrides the Sortable parameter on the DataGrid. + /// + [Parameter] public bool? Sortable { get; set; } + + [Parameter] public bool? Resizable { get; set; } + + /// + /// Determines whether this columns data can be filtered. This overrides the Filterable parameter on the DataGrid. + /// + [Parameter] public bool? Filterable { get; set; } + + [Parameter] public bool? ShowFilterIcon { get; set; } + + /// + /// Determines whether this column can be hidden. This overrides the Hideable parameter on the DataGrid. + /// + [Parameter] public bool? Hideable { get; set; } + + [Parameter] public bool Hidden { get; set; } + [Parameter] public EventCallback HiddenChanged { get; set; } + + /// + /// Determines whether to show or hide column options. This overrides the ShowColumnOptions parameter on the DataGrid. + /// + [Parameter] public bool? ShowColumnOptions { get; set; } + + [Parameter] + public Func SortBy + { + get + { + return GetLocalSortFunc(); + } + set + { + _sortBy = value; + } + } + + [Parameter] public SortDirection InitialDirection { get; set; } = SortDirection.None; + [Parameter] public string SortIcon { get; set; } = Icons.Material.Filled.ArrowUpward; + + /// + /// Specifies whether the column can be grouped. + /// + [Parameter] public bool? Groupable { get; set; } + + /// + /// Specifies whether the column is grouped. + /// + [Parameter] public bool Grouping { get; set; } + + /// + /// Specifies whether the column is sticky. + /// + [Parameter] public bool StickyLeft { get; set; } + + [Parameter] public bool StickyRight { get; set; } + + [Parameter] public RenderFragment> FilterTemplate { get; set; } + + private CultureInfo _culture; + /// + /// The culture used to represent this column and by the filtering input field. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public CultureInfo Culture + { + get => _culture ?? DataGrid?.Culture; + set + { + _culture = value; + } + } + #endregion + + #region Cell Properties + + [Parameter] public string CellClass { get; set; } + [Parameter] public Func CellClassFunc { get; set; } + [Parameter] public string CellStyle { get; set; } + [Parameter] public Func CellStyleFunc { get; set; } + [Parameter] public bool IsEditable { get; set; } = true; + [Parameter] public RenderFragment> EditTemplate { get; set; } + + #endregion + + #region FooterCell Properties + + [Parameter] public string FooterClass { get; set; } + [Parameter] public Func FooterClassFunc { get; set; } + [Parameter] public string FooterStyle { get; set; } + [Parameter] public Func FooterStyleFunc { get; set; } + [Parameter] public bool EnableFooterSelection { get; set; } + [Parameter] public AggregateDefinition AggregateDefinition { get; set; } + + #endregion + + public Action ColumnStateHasChanged { get; set; } + + internal string headerClassname => + new CssBuilder("mud-table-cell") + .AddClass("mud-table-cell-hide", HideSmall) + .AddClass("sticky-left", StickyLeft) + .AddClass("sticky-right", StickyRight) + .AddClass(Class) + .Build(); + + internal string cellClassname; + //internal string cellClassname => + // new CssBuilder("mud-table-cell") + // .AddClass("mud-table-cell-hide", HideSmall) + // .AddClass("sticky-right", StickyRight) + // .AddClass(Class) + // .Build(); + + internal string footerClassname => + new CssBuilder("mud-table-cell") + .AddClass("mud-table-cell-hide", HideSmall) + .AddClass(Class) + .Build(); + + internal bool grouping; + + #region Computed Properties + + internal Type dataType + { + get + { + if (FieldType != null) + return FieldType; + + if (Field == null) + return typeof(object); + + if (typeof(T) == typeof(IDictionary) && FieldType == null) + throw new ArgumentNullException(nameof(FieldType)); + + var t = typeof(T).GetProperty(Field).PropertyType; + return Nullable.GetUnderlyingType(t) ?? t; + } + } + + // This returns the data type for an object when T is an IDictionary. + internal Type innerDataType + { + get + { + // Handle case where T is IDictionary. + if (typeof(T) == typeof(IDictionary)) + { + // We need to get the actual type here so we need to look at actual data. + // get the first item where we have a non-null value in the field to be filtered. + var first = DataGrid.Items.FirstOrDefault(x => ((IDictionary)x)[Field] != null); + + if (first != null) + { + return ((IDictionary)first)[Field].GetType(); + } + else + { + return typeof(object); + } + } + + return dataType; + } + } + + internal bool isNumber + { + get + { + return FilterOperator.NumericTypes.Contains(dataType); + } + } + + internal string computedTitle + { + get + { + return Title ?? Field; + } + } + + internal bool groupable + { + get + { + return Groupable ?? DataGrid?.Groupable ?? false; + } + } + + internal bool filterable + { + get + { + return Filterable ?? DataGrid?.Filterable ?? false; + } + } + + #endregion + + internal int SortIndex { get; set; } = -1; + internal HeaderCell HeaderCell { get; set; } + + private Func _sortBy; + internal Func groupBy; + internal HeaderContext headerContext; + internal FilterContext filterContext; + internal FooterContext footerContext; + + [UnconditionalSuppressMessage("Trimming", "IL2046: 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.", Justification = "Suppressing because we annotating the whole component with RequiresUnreferencedCodeAttribute for information that generic type must be preserved.")] + protected override void OnInitialized() + { + if (!Hideable.HasValue) + Hideable = DataGrid?.Hideable; + + groupBy = GroupBy; + CompileGroupBy(); + + if (groupable && Grouping) + grouping = Grouping; + + if (null != DataGrid) + DataGrid.AddColumn(this); + + // Add the HeaderContext + headerContext = new HeaderContext(DataGrid); + + // Add the FilterContext + if (filterable) + { + filterContext = new FilterContext(DataGrid); + var operators = FilterOperator.GetOperatorByDataType(dataType); + filterContext.FilterDefinition = new FilterDefinition() + { + DataGrid = this.DataGrid, + Field = Field, + FieldType = FieldType, + Title = Title, + Operator = operators.FirstOrDefault() + }; + } + + // Add the FooterContext + footerContext = new FooterContext(DataGrid); + } + + internal Func GetLocalSortFunc() + { + if (null == _sortBy) + { + var type = typeof(T); + + // set the default SortBy + if (type == typeof(IDictionary)) + { + if (FieldType == null) + throw new ArgumentNullException(nameof(FieldType)); + + var innerType = innerDataType; + + if (innerType == typeof(JsonElement)) + { + _sortBy = x => + { + var json = (JsonElement)(x as IDictionary)[Field]; + + if (FieldType == typeof(string)) + return json.GetString(); + else if (isNumber) + return json.GetDouble(); + else + return json.GetRawText(); + }; + } + else + { + _sortBy = x => Convert.ChangeType((x as IDictionary)[Field], FieldType); + } + } + else + { + var parameter = Expression.Parameter(type, "x"); + var field = Expression.Convert(Expression.Property(parameter, type.GetProperty(Field)), typeof(object)); + _sortBy = Expression.Lambda>(field, parameter).Compile(); + } + } + + return _sortBy; + } + + internal void CompileGroupBy() + { + if (groupBy == null && !string.IsNullOrWhiteSpace(Field)) + { + var type = typeof(T); + + // set the default GroupBy + if (type == typeof(IDictionary)) + { + groupBy = x => (x as IDictionary)[Field]; + } + else + { + var parameter = Expression.Parameter(type, "x"); + var field = Expression.Convert(Expression.Property(parameter, type.GetProperty(Field)), typeof(object)); + groupBy = Expression.Lambda>(field, parameter).Compile(); + } + } + } + + // Allows child components to change column grouping. + internal void SetGrouping(bool g) + { + if (groupable) + { + grouping = g; + DataGrid?.ChangedGrouping(this); + } + } + + /// + /// This method's sole purpose is for the DataGrid to remove grouping in mass. + /// + internal void RemoveGrouping() + { + grouping = false; + } + + public async Task HideAsync() + { + Hidden = true; + await HiddenChanged.InvokeAsync(Hidden); + } + + public async Task ShowAsync() + { + Hidden = false; + await HiddenChanged.InvokeAsync(Hidden); + } + + public async Task ToggleAsync() + { + Hidden = !Hidden; + await HiddenChanged.InvokeAsync(Hidden); + DataGrid.ExternalStateHasChanged(); + } +} diff --git a/Components/DataGrid/DataGrid.razor b/Components/DataGrid/DataGrid.razor new file mode 100644 index 0000000..8cead3e --- /dev/null +++ b/Components/DataGrid/DataGrid.razor @@ -0,0 +1,512 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T +@using Connected.Utilities + +@Columns + + +
    + @if (Items != null || ServerData != null) + { + @if (ToolBarContent != null) + { + + @ToolBarContent + @if (ShowMenuIcon) + { + @ToolbarMenu(this) + } + + } + else + { + @if (ShowMenuIcon) + { + @*Add the default toolbar.*@ + + + @ToolbarMenu(this) + + } + } +
    + + @if (ColGroup != null) + { + + @ColGroup + + } + + + @Header + + + @foreach (var column in RenderedColumns) + { + + } + + @if (_filtersMenuVisible && FilterMode == DataGridFilterMode.Simple) + { + + + @if (FilterTemplate == null) + { + + @foreach (var f in FilterDefinitions) + { + @Filter(f, null) + } + + + @if (ServerData != null) + { + + } + + } + else + { + @FilterTemplate(FilterDefinitions) + } + + } + @if (_columnsPanelVisible) + { + + + + @foreach (var column in RenderedColumns) + { + + + + } + + + + + + + + + + } + @if (Filterable && FilterMode == DataGridFilterMode.ColumnFilterRow) + { + + @foreach (var column in RenderedColumns) + { + + } + + } + + + @if (Loading) + { + + + + } + + @{var resolvedPageItems = CurrentPageItems.ToList();} + @if (resolvedPageItems != null && resolvedPageItems.Count > 0) + { + if (GroupedColumn != null) + { + foreach (var g in _groups) + { + + @{ var groupClass = new CssBuilder(GroupClass).AddClass(GroupClassFunc?.Invoke(g)).Build(); } + @{ var groupStyle = new StyleBuilder().AddStyle(GroupStyle).AddStyle(GroupStyleFunc?.Invoke(g)).Build(); } + + + + var rowIndex = 0; + + @if (g.IsExpanded) + { + + @{ var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, rowIndex)).Build(); } + @{ var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, rowIndex)).Build(); } + @{ var tmpRowIndex = rowIndex; } + + + @foreach (var column in RenderedColumns) + { + if (!column.Hidden) + { + @Cell(column, item) + } + } + + + @if (ChildRowContent != null && (_openHierarchies.Contains(item) || !hasHierarchyColumn)) + { + + + + } + @{ rowIndex++; } + + @*Group Footer*@ + + @FooterCells(g.Grouping.ToList()) + + } + } + } + else + { + var rowIndex = 0; + + @{ var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, rowIndex)).Build(); } + @{ var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, rowIndex)).Build(); } + @{ var tmpRowIndex = rowIndex; } + + + @foreach (var column in RenderedColumns) + { + if (!column.Hidden) + { + @Cell(column, item) + } + } + + + @if (ChildRowContent != null && (_openHierarchies.Contains(item) || !hasHierarchyColumn)) + { + + + + } + @{ rowIndex++; } + + } + } + else if(Loading ? LoadingContent != null : NoRecordsContent != null) + { + + + + } + + + + @FooterCells(resolvedPageItems) + + +
    + +
    + + + @if (GroupedColumn.GroupTemplate == null) + { + @GroupedColumn.computedTitle: @g.Grouping.Key + } + else + { + @GroupedColumn.GroupTemplate(@g) + } +
    + @ChildRowContent(new CellContext(this, item)) +
    + @ChildRowContent(new CellContext(this, item)) +
    +
    + @if(Loading) + { + @LoadingContent + } + else + { + @NoRecordsContent + } +
    +
    +
    + @if (PagerContent != null) + { +
    + @PagerContent +
    + } + } +
    + + + + Edit + + + +
    + @foreach (var column in RenderedColumns) + { + var cell = new Cell(this, column, _editingItem); + + if (column.EditTemplate != null) + { + @column.EditTemplate(cell.cellContext) + } + else + { + if (column.dataType == typeof(string)) + { + + } + else if (column.isNumber) + { + + } + } + } + +
    + + + + +
    +
    + +@code { + internal RenderFragment ToolbarMenu(DataGrid __this) + { + return + @ + + Columns + @if (__this.Groupable) + { + Expand All Groups + Collapse All Groups + } + @if(__this.ServerData != null) + { + Refresh Data + } + + ; + } + + internal RenderFragment FooterCells(IEnumerable currentItems) + { + return + @ + @if (currentItems != null) + { + foreach (var column in RenderedColumns) + { + if (!column.Hidden) + { + if (column.AggregateDefinition != null || column.FooterTemplate != null || hasFooter) + { + + } + } + } + } + ; + } + + internal RenderFragment Cell(Column column, T item) + { + return + @ + @{ + var cell = new Cell(this, column, item); + } + + @if (column.IsEditable && !ReadOnly && DataGridEditMode.Cell == EditMode) + { + if (column.EditTemplate != null) + { + @column.EditTemplate(cell.cellContext) + } + else + { + if (column.dataType == typeof(string)) + { + + } + else if (column.isNumber) + { + + } + } + } + else + { + if (column.CellTemplate != null) + { + @column.CellTemplate(cell.cellContext) + } + else if (column.Culture != null && column.isNumber) + { + @cell.valueNumber?.ToString(column.Culture) + } + else + { + @cell.ComputedValue + } + } + + + ; + } + + internal RenderFragment Filter(FilterDefinition f, Column column) + { + return + @ + @{ + var filter = new Filter(this, f, column); + } + @if (column == null) + { + + + + + + + + + + + @if (filter.dataType == typeof(string) && !(f.Operator ?? "").EndsWith("empty")) + { + + } + else if (filter.isNumber && !(f.Operator ?? "").EndsWith("empty")) + { + + } + else if (filter.isEnum) + { + + } + else if (filter.dataType == typeof(bool)) + { + + } + else if (filter.dataType == typeof(DateTime) && !(f.Operator ?? "").EndsWith("empty")) + { + + + + + + + + + } + else if (filter.dataType == typeof(Guid)) + { + + } + + } + else + { + + + + + @if (filter.dataType == typeof(string) && !(f.Operator ?? "").EndsWith("empty")) + { + + } + else if (filter.isNumber && !(f.Operator ?? "").EndsWith("empty")) + { + + } + else if (filter.isEnum) + { + + } + else if (filter.dataType == typeof(bool)) + { + + } + else if (filter.dataType == typeof(DateTime) && !(f.Operator ?? "").EndsWith("empty")) + { + + + + + + + + + } + else if (filter.dataType == typeof(Guid)) + { + + } + + } + + ; + } +} \ No newline at end of file diff --git a/Components/DataGrid/DataGrid.razor.cs b/Components/DataGrid/DataGrid.razor.cs new file mode 100644 index 0000000..d436468 --- /dev/null +++ b/Components/DataGrid/DataGrid.razor.cs @@ -0,0 +1,1328 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Reflection; +using System.Text.Json; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +[RequiresUnreferencedCode(CodeMessage.SerializationUnreferencedCodeMessage)] +public partial class DataGrid : UIComponent +{ + private int _currentPage = 0; + internal int? _rowsPerPage; + private bool _isFirstRendered = false; + private bool _filtersMenuVisible = false; + private bool _columnsPanelVisible = false; + private IEnumerable _items; + private T _selectedItem; + internal HashSet _groupExpansions = new HashSet(); + private List> _groups = new List>(); + internal HashSet _openHierarchies = new HashSet(); + private PropertyInfo[] _properties = typeof(T).GetProperties(); + + protected string _classname => + new CssBuilder("mud-table") + .AddClass("mud-data-grid") + .AddClass("mud-xs-table", Breakpoint == Breakpoint.Xs) + .AddClass("mud-sm-table", Breakpoint == Breakpoint.Sm) + .AddClass("mud-md-table", Breakpoint == Breakpoint.Md) + .AddClass("mud-lg-table", Breakpoint == Breakpoint.Lg || Breakpoint == Breakpoint.Always) + .AddClass("mud-xl-table", Breakpoint == Breakpoint.Xl || Breakpoint == Breakpoint.Always) + .AddClass("mud-table-dense", Dense) + .AddClass("mud-table-hover", Hover) + .AddClass("mud-table-bordered", Bordered) + .AddClass("mud-table-striped", Striped) + .AddClass("mud-table-outlined", Outlined) + .AddClass("mud-table-square", Square) + .AddClass("mud-table-sticky-header", FixedHeader) + .AddClass("mud-table-sticky-footer", FixedFooter) + .AddClass($"mud-elevation-{Elevation}", !Outlined) + .AddClass(Class) + .Build(); + + protected string _style => + new StyleBuilder() + .AddStyle("overflow-x", "auto", when: HorizontalScrollbar || ColumnResizeMode == ResizeMode.Container) + .AddStyle("position", "relative", when: hasStickyColumns) + .AddStyle(Style) + .Build(); + + protected string _tableStyle => + new StyleBuilder() + .AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) + .AddStyle("width", "max-content", when: (HorizontalScrollbar || ColumnResizeMode == ResizeMode.Container) && !hasStickyColumns) + .AddStyle("display", "block", when: HorizontalScrollbar) + .Build(); + + protected string _tableClass => + new CssBuilder("mud-table-container") + .AddClass("cursor-col-resize", when: IsResizing) + .Build(); + + protected string _headClassname => new CssBuilder("mud-table-head") + .AddClass(HeaderClass).Build(); + + protected string _footClassname => new CssBuilder("mud-table-foot") + .AddClass(FooterClass).Build(); + + internal SortDirection GetColumnSortDirection(string columnName) + { + if (columnName == null) + { + return SortDirection.None; + } + else + { + SortDefinition sortDefinition = null; + var ok = SortDefinitions.TryGetValue(columnName, out sortDefinition); + + if (ok) + { + return sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending; + } + else + { + return SortDirection.None; + } + } + } + + protected int numPages + { + get + { + if (ServerData != null) + return (int)Math.Ceiling(_server_data.TotalItems / (double)RowsPerPage); + + return (int)Math.Ceiling(FilteredItems.Count() / (double)RowsPerPage); + } + } + + public readonly List> RenderedColumns = new List>(); + internal T _editingItem; + + //internal int editingItemHash; + internal T editingSourceItem; + + internal T _previousEditingItem; + internal bool isEditFormOpen; + + // converters + private Converter _oppositeBoolConverter = new Converter + { + SetFunc = value => value ? false : true, + GetFunc = value => value.HasValue ? !value.Value : true, + }; + + #region Notify Children Delegates + + internal Action>, HashSet> SortChangedEvent { get; set; } + internal Action> SelectedItemsChangedEvent { get; set; } + internal Action SelectedAllItemsChangedEvent { get; set; } + internal Action StartedEditingItemEvent { get; set; } + internal Action EditingCancelledEvent { get; set; } + public Action PagerStateHasChangedEvent { get; set; } + + #endregion + + #region EventCallbacks + + /// + /// Callback is called when a row has been clicked and returns the selected item. + /// + [Parameter] public EventCallback SelectedItemChanged { get; set; } + + /// + /// Callback is called whenever items are selected or deselected in multi selection mode. + /// + [Parameter] public EventCallback> SelectedItemsChanged { get; set; } + + /// + /// Callback is called whenever a row is clicked. + /// + [Parameter] public EventCallback> RowClick { get; set; } + + /// + /// Callback is called when an item has begun to be edited. Returns the item being edited. + /// + [Parameter] public EventCallback StartedEditingItem { get; set; } + + /// + /// Callback is called when the process of editing an item has been cancelled. Returns the item which was previously in edit mode. + /// + [Parameter] public EventCallback CancelledEditingItem { get; set; } + + /// + /// Callback is called when the changes to an item are committed. Returns the item whose changes were committed. + /// + [Parameter] public EventCallback CommittedItemChanges { get; set; } + + /// + /// Callback is called when a field changes in the dialog MudForm. Only works in EditMode.Form + /// + [Parameter] public EventCallback FormFieldChanged { get; set; } + + #endregion + + #region Parameters + + /// + /// Controls whether data in the DataGrid can be sorted. This is overridable by each column. + /// + [Parameter] public SortMode SortMode { get; set; } = SortMode.Multiple; + + /// + /// Controls whether data in the DataGrid can be filtered. This is overridable by each column. + /// + [Parameter] public bool Filterable { get; set; } = false; + + /// + /// Controls whether columns in the DataGrid can be hidden. This is overridable by each column. + /// + [Parameter] public bool Hideable { get; set; } = false; + + /// + /// Controls whether to hide or show the column options. This is overridable by each column. + /// + [Parameter] public bool ShowColumnOptions { get; set; } = true; + + /// + /// At what breakpoint the table should switch to mobile layout. Takes None, Xs, Sm, Md, Lg and Xl the default behavior is breaking on Xs. + /// + [Parameter] public Breakpoint Breakpoint { get; set; } = Breakpoint.Xs; + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] public int Elevation { set; get; } = 1; + + /// + /// Set true to disable rounded corners + /// + [Parameter] public bool Square { get; set; } + + /// + /// If true, table will be outlined. + /// + [Parameter] public bool Outlined { get; set; } + + /// + /// If true, table's cells will have left/right borders. + /// + [Parameter] public bool Bordered { get; set; } + + /// + /// Specifies a group of one or more columns in a table for formatting. + /// Ex: + /// table + /// colgroup + /// col span="2" style="background-color:red" + /// col style="background-color:yellow" + /// colgroup + /// header + /// body + /// table + /// + [Parameter] public RenderFragment ColGroup { get; set; } + + /// + /// Set true for rows with a narrow height + /// + [Parameter] public bool Dense { get; set; } + + /// + /// Set true to see rows hover on mouse-over. + /// + [Parameter] public bool Hover { get; set; } + + /// + /// If true, striped table rows will be used. + /// + [Parameter] public bool Striped { get; set; } + + /// + /// When true, the header will stay in place when the table is scrolled. Note: set Height to make the table scrollable. + /// + [Parameter] public bool FixedHeader { get; set; } + + /// + /// When true, the footer will be visible is not scrolled to the bottom. Note: set Height to make the table scrollable. + /// + [Parameter] public bool FixedFooter { get; set; } + + [Parameter] public bool ShowFilterIcons { get; set; } = true; + + [Parameter] public DataGridFilterMode FilterMode { get; set; } + + [Parameter] public DataGridFilterCaseSensitivity FilterCaseSensitivity { get; set; } + + [Parameter] public RenderFragment>> FilterTemplate { get; set; } + + /// + /// The list of FilterDefinitions that have been added to the data grid. FilterDefinitions are managed by the data + /// grid automatically when using the built in filter UI. You can also programmatically manage these definitions + /// through this collection. + /// + [Parameter] public List> FilterDefinitions { get; set; } = new List>(); + + /// + /// The list of SortDefinitions that have been added to the data grid. SortDefinitions are managed by the data + /// grid automatically when using the built in filter UI. You can also programmatically manage these definitions + /// through this collection. + /// + [Parameter] public Dictionary> SortDefinitions { get; set; } = new Dictionary>(); + + /// + /// If true, the results are displayed in a Virtualize component, allowing a boost in rendering speed. + /// + [Parameter] public bool Virtualize { get; set; } + + /// + /// Gets or sets a value that determines how many additional items will be rendered + /// before and after the visible region. This help to reduce the frequency of rendering + /// during scrolling. However, higher values mean that more elements will be present + /// in the page. + /// Only used for virtualization. + /// + [Parameter] public int OverscanCount { get; set; } = 3; + + /// + /// CSS class for the table rows. Note, many CSS settings are overridden by MudTd though + /// + [Parameter] public string RowClass { get; set; } + + /// + /// CSS styles for the table rows. Note, many CSS settings are overridden by MudTd though + /// + [Parameter] public string RowStyle { get; set; } + + /// + /// Returns the class that will get joined with RowClass. Takes the current item and row index. + /// + [Parameter] public Func RowClassFunc { get; set; } + + /// + /// Returns the class that will get joined with RowClass. Takes the current item and row index. + /// + [Parameter] public Func RowStyleFunc { get; set; } + + /// + /// Set to true to enable selection of multiple rows. + /// + [Parameter] public bool MultiSelection { get; set; } + + /// + /// When the grid is not read only, you can specify what type of editing mode to use. + /// + [Parameter] public DataGridEditMode? EditMode { get; set; } + + /// + /// Allows you to specify the action that will trigger an edit when the EditMode is Form. + /// + [Parameter] public DataGridEditTrigger? EditTrigger { get; set; } = DataGridEditTrigger.Manual; + + /// + /// Fine tune the edit dialog. + /// + [Parameter] public DialogOptions EditDialogOptions { get; set; } + + /// + /// The data to display in the table. MudTable will render one row per item + /// + /// + [Parameter] + public IEnumerable Items + { + get => _items; + set + { + if (_items == value) + return; + + _items = value; + + if (PagerStateHasChangedEvent != null) + InvokeAsync(PagerStateHasChangedEvent); + + // set initial grouping + if (Groupable) + { + GroupItems(); + } + + // Setup ObservableCollection functionality. + if (_items is INotifyCollectionChanged) + { + (_items as INotifyCollectionChanged).CollectionChanged += (s, e) => + { + if (Groupable) + GroupItems(); + }; + } + } + } + + /// + /// Show a loading animation, if true. + /// + [Parameter] public bool Loading { get; set; } + + /// + /// Define if Cancel button is present or not for inline editing. + /// + [Parameter] public bool CanCancelEdit { get; set; } = true; + + /// + /// The color of the loading progress if used. It supports the theme colors. + /// + [Parameter] public ThemeColor LoadingProgressColor { get; set; } = ThemeColor.Info; + + /// + /// Optional. Add any kind of toolbar to this render fragment. + /// + [Parameter] public RenderFragment ToolBarContent { get; set; } + + /// + /// Defines if the table has a horizontal scrollbar. + /// + [Parameter] public bool HorizontalScrollbar { get; set; } + + /// + /// Defines if columns of the grid can be resized. + /// + [Parameter] public ResizeMode ColumnResizeMode { get; set; } + + /// + /// Add a class to the thead tag + /// + [Parameter] public string HeaderClass { get; set; } + + /// + /// Setting a height will allow to scroll the table. If not set, it will try to grow in height. You can set this to any CSS value that the + /// attribute 'height' accepts, i.e. 500px. + /// + [Parameter] public string Height { get; set; } + + /// + /// Add a class to the tfoot tag + /// + [Parameter] public string FooterClass { get; set; } + + /// + /// A function that returns whether or not an item should be displayed in the table. You can use this to implement your own search function. + /// + [Parameter] public Func QuickFilter { get; set; } = null; + + /// + /// Allows adding a custom header beyond that specified in the Column component. Add HeaderCell + /// components to add a custom header. + /// + [Parameter] public RenderFragment Header { get; set; } + + /// + /// The Columns that make up the data grid. Add Column components to this RenderFragment. + /// + [Parameter] public RenderFragment Columns { get; set; } + + /// + /// The culture used to represent numeric columns and his filtering input fields. + /// Each column can override this DataGrid Culture. + /// + [Parameter] + public CultureInfo Culture { get; set; } + + /// + /// Row Child content of the component. + /// + [Parameter] public RenderFragment> ChildRowContent { get; set; } + + /// + /// Defines the table body content when there are no matching records found + /// + [Parameter] public RenderFragment NoRecordsContent { get; set; } + + /// + /// Defines the table body content the table has no rows and is loading + /// + [Parameter] public RenderFragment LoadingContent { get; set; } + + /// + /// Add MudTablePager here to enable breaking the rows in to multiple pages. + /// + [Parameter] public RenderFragment PagerContent { get; set; } + + /// + /// Supply an async function which (re)loads filtered, paginated and sorted data from server. + /// Table will await this func and update based on the returned TableData. + /// Used only with ServerData + /// + [Parameter] public Func, Task>> ServerData { get; set; } + + /// + /// If the table has more items than this number, it will break the rows into pages of said size. + /// Note: requires a MudTablePager in PagerContent. + /// + [Parameter] + public int RowsPerPage + { + get => _rowsPerPage ?? 10; + set + { + if (_rowsPerPage == null) + InvokeAsync(() => SetRowsPerPageAsync(value)); + } + } + + /// + /// The page index of the currently displayed page (Zero based). Usually called by MudTablePager. + /// Note: requires a MudTablePager in PagerContent. + /// + [Parameter] + public int CurrentPage + { + get => _currentPage; + set + { + if (_currentPage == value) + return; + _currentPage = value; + InvokeAsync(StateHasChanged); + + if (_isFirstRendered) + InvokeAsync(InvokeServerLoadFunc); + } + } + + /// + /// Locks Inline Edit mode, if true. + /// + [Parameter] public bool ReadOnly { get; set; } = true; + + /// + /// If MultiSelection is true, this returns the currently selected items. You can bind this property and the initial content of the HashSet you bind it to will cause these rows to be selected initially. + /// + [Parameter] + public HashSet SelectedItems + { + get + { + if (!MultiSelection) + if (_selectedItem is null) + return new HashSet(Array.Empty()); + else + return new HashSet(new T[] { _selectedItem }); + else + return Selection; + } + set + { + if (value == Selection) + return; + if (value == null) + { + if (Selection.Count == 0) + return; + Selection = new HashSet(); + } + else + Selection = value; + SelectedItemsChangedEvent?.Invoke(Selection); + SelectedItemsChanged.InvokeAsync(Selection); + InvokeAsync(StateHasChanged); + } + } + + /// + /// Returns the item which was last clicked on in single selection mode (that is, if MultiSelection is false) + /// + [Parameter] + public T SelectedItem + { + get => _selectedItem; + set + { + if (EqualityComparer.Default.Equals(SelectedItem, value)) + return; + _selectedItem = value; + SelectedItemChanged.InvokeAsync(value); + } + } + + /// + /// Determines whether grouping of columns is allowed in the data grid. + /// + [Parameter] + public bool Groupable + { + get { return _groupable; } + set + { + if (_groupable != value) + { + _groupable = value; + + if (!_groupable) + { + _groups.Clear(); + _groupExpansions.Clear(); + + foreach (var column in RenderedColumns) + column.RemoveGrouping(); + } + } + } + } + + private bool _groupable = false; + + /// + /// If set, a grouped column will be expanded by default. + /// + [Parameter] public bool GroupExpanded { get; set; } + + /// + /// CSS class for the groups. + /// + [Parameter] public string GroupClass { get; set; } + + /// + /// CSS styles for the groups. + /// + [Parameter] public string GroupStyle { get; set; } + + /// + /// Returns the class that will get joined with GroupClass. + /// + [Parameter] public Func, string> GroupClassFunc { get; set; } + + /// + /// Returns the class that will get joined with GroupStyle. + /// + [Parameter] public Func, string> GroupStyleFunc { get; set; } + + /// + /// When true, displays the built-in menu icon in the header of the data grid. + /// + [Parameter] public bool ShowMenuIcon { get; set; } = false; + + #endregion + + #region Properties + + internal IEnumerable CurrentPageItems + { + get + { + if (@PagerContent == null) + { + return FilteredItems; // we have no pagination + } + if (ServerData == null) + { + var filteredItemCount = GetFilteredItemsCount(); + int lastPageNo; + if (filteredItemCount == 0) + lastPageNo = 0; + else + lastPageNo = (filteredItemCount / RowsPerPage) - (filteredItemCount % RowsPerPage == 0 ? 1 : 0); + CurrentPage = lastPageNo < CurrentPage ? lastPageNo : CurrentPage; + } + + return GetItemsOfPage(CurrentPage, RowsPerPage); + } + } + + public HashSet Selection { get; set; } = new HashSet(); + public bool HasPager { get; set; } + private GridData _server_data = new GridData() { TotalItems = 0, Items = Array.Empty() }; + + public IEnumerable FilteredItems + { + get + { + var items = ServerData != null + ? _server_data.Items + : Items; + + // Quick filtering + if (QuickFilter != null) + { + items = items.Where(QuickFilter); + } + + foreach (var f in FilterDefinitions) + { + f.DataGrid = this; + var filterFunc = f.GenerateFilterFunction(); + items = items.Where(filterFunc); + } + + return Sort(items); + } + } + + public IForm Validator { get; set; } = new DataGridRowValidator(); + + internal Column GroupedColumn + { + get + { + return RenderedColumns.FirstOrDefault(x => x.grouping); + } + } + + #endregion + + #region Computed Properties + + private bool hasFooter + { + get + { + return RenderedColumns.Any(x => !x.Hidden && (x.FooterTemplate != null || x.AggregateDefinition != null)); + } + } + + private bool hasStickyColumns + { + get + { + return RenderedColumns.Any(x => x.StickyLeft || x.StickyRight); + } + } + + private bool hasHierarchyColumn + { + get + { + return RenderedColumns.Any(x => x.Tag?.ToString() == "hierarchy-column"); + } + } + + #endregion + + [UnconditionalSuppressMessage("Trimming", "IL2046: 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.", Justification = "Suppressing because we annotating the whole component with RequiresUnreferencedCodeAttribute for information that generic type must be preserved.")] + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _isFirstRendered = true; + GroupItems(); + await InvokeServerLoadFunc(); + } + else + { + PagerStateHasChangedEvent?.Invoke(); + } + + await base.OnAfterRenderAsync(firstRender); + } + + [UnconditionalSuppressMessage("Trimming", "IL2046: 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.", Justification = "Suppressing because we annotating the whole component with RequiresUnreferencedCodeAttribute for information that generic type must be preserved.")] + public override async Task SetParametersAsync(ParameterView parameters) + { + var sortModeBefore = SortMode; + await base.SetParametersAsync(parameters); + + if (parameters.TryGetValue(nameof(SortMode), out SortMode sortMode) && sortMode != sortModeBefore) + await ClearCurrentSortings(); + } + + #region Methods + + protected IEnumerable GetItemsOfPage(int page, int pageSize) + { + if (page < 0 || pageSize <= 0) + return Array.Empty(); + + if (ServerData != null) + { + return QuickFilter != null + ? _server_data.Items.Where(QuickFilter) + : _server_data.Items; + } + + return FilteredItems.Skip(page * pageSize).Take(pageSize); + } + + internal async Task InvokeServerLoadFunc() + { + if (ServerData == null) + return; + + Loading = true; + StateHasChanged(); + + var state = new GridState + { + Page = CurrentPage, + PageSize = RowsPerPage, + SortDefinitions = SortDefinitions.Values.OrderBy(sd => sd.Index).ToList(), + // Additional ToList() here to decouple clients from internal list avoiding runtime issues + FilterDefinitions = FilterDefinitions.ToList() + }; + + _server_data = await ServerData(state); + + if (CurrentPage * RowsPerPage > _server_data.TotalItems) + CurrentPage = 0; + + Loading = false; + StateHasChanged(); + PagerStateHasChangedEvent?.Invoke(); + } + + internal void AddColumn(Column column) + { + if (column.Tag?.ToString() == "hierarchy-column") + { + RenderedColumns.Insert(0, column); + } + else if (column.Tag?.ToString() == "select-column") + { + // Position SelectColumn after HierarchyColumn if present + if (RenderedColumns.Select(x => x.Tag).Contains("hierarchy-column")) + { + RenderedColumns.Insert(1, column); + } + else + { + RenderedColumns.Insert(0, column); + } + } + else + { + RenderedColumns.Add(column); + } + } + + /// + /// Called by the DataGrid when the "Add Filter" button is pressed. + /// + internal void AddFilter() + { + var column = RenderedColumns.FirstOrDefault(x => x.filterable); + FilterDefinitions.Add(new FilterDefinition + { + Id = Guid.NewGuid(), + DataGrid = this, + Field = column?.Field, + Title = column?.Title, + FieldType = column?.FieldType + }); + _filtersMenuVisible = true; + StateHasChanged(); + } + + internal void ApplyFilters() + { + _filtersMenuVisible = false; + InvokeServerLoadFunc().AndForget(); + } + + internal void ClearFilters() + { + FilterDefinitions.Clear(); + } + + internal void AddFilter(Guid id, string field) + { + var column = RenderedColumns.FirstOrDefault(x => x.Field == field && x.filterable); + FilterDefinitions.Add(new FilterDefinition + { + Id = id, + DataGrid = this, + Field = field, + Title = column?.Title, + FieldType = column?.FieldType, + }); + _filtersMenuVisible = true; + StateHasChanged(); + } + + internal void RemoveFilter(Guid id) + { + FilterDefinitions.RemoveAll(x => x.Id == id); + GroupItems(); + } + + internal async Task SetSelectedItemAsync(bool value, T item) + { + if (value) + Selection.Add(item); + else + Selection.Remove(item); + + await InvokeAsync(() => SelectedItemsChangedEvent.Invoke(SelectedItems)); + await SelectedItemsChanged.InvokeAsync(SelectedItems); + await InvokeAsync(StateHasChanged); + } + + internal async Task SetSelectAllAsync(bool value) + { + if (value) + Selection = new HashSet(Items); + else + Selection.Clear(); + + SelectedItemsChangedEvent?.Invoke(SelectedItems); + SelectedAllItemsChangedEvent?.Invoke(value); + await SelectedItemsChanged.InvokeAsync(SelectedItems); + StateHasChanged(); + } + + internal IEnumerable Sort(IEnumerable items) + { + if (null == items || !items.Any()) + return items; + + if (null == SortDefinitions || 0 == SortDefinitions.Count) + return items; + + IOrderedEnumerable orderedEnumerable = null; + + foreach (var sortDefinition in SortDefinitions.Values.Where(sd => null != sd.SortFunc).OrderBy(sd => sd.Index)) + { + if (null == orderedEnumerable) + orderedEnumerable = sortDefinition.Descending ? items.OrderByDescending(item => sortDefinition.SortFunc(item)) + : items.OrderBy(item => sortDefinition.SortFunc(item)); + else + orderedEnumerable = sortDefinition.Descending ? orderedEnumerable.ThenByDescending(item => sortDefinition.SortFunc(item)) + : orderedEnumerable.ThenBy(item => sortDefinition.SortFunc(item)); + } + + return orderedEnumerable ?? items; + } + + internal void ClearEditingItem() + { + _editingItem = default; + editingSourceItem = default; + } + + /// + /// This method notifies the consumer that changes to the data have been committed + /// and what those changes are. This variation of the method is only used by the Cell + /// when the EditMode is set to cell. + /// + /// + /// + internal async Task CommitItemChangesAsync(T item) + { + // Here, we need to validate at the cellular level... + await CommittedItemChanges.InvokeAsync(item); + } + + /// + /// This method notifies the consumer that changes to the data have been committed + /// and what those changes are. This variation of the method is used when the EditMode + /// is anything but Cell since the _editingItem is used. + /// + /// + internal async Task CommitItemChangesAsync() + { + // Here, we need to validate at the cellular level... + + if (editingSourceItem != null) + { + foreach (var property in _properties) + { + if (property.CanWrite) + property.SetValue(editingSourceItem, property.GetValue(_editingItem)); + } + + await CommittedItemChanges.InvokeAsync(editingSourceItem); + ClearEditingItem(); + isEditFormOpen = false; + } + } + + internal async Task OnRowClickedAsync(MouseEventArgs args, T item, int rowIndex) + { + await RowClick.InvokeAsync(new DataGridRowClickEventArgs + { + MouseEventArgs = args, + Item = item, + RowIndex = rowIndex + }); + + if (EditMode != DataGridEditMode.Cell && EditTrigger == DataGridEditTrigger.OnRowClick) + await SetEditingItemAsync(item); + + await SetSelectedItemAsync(item); + } + + /// + /// Gets the total count of filtered items in the data grid. + /// + /// + public int GetFilteredItemsCount() + { + if (ServerData != null) + return _server_data.TotalItems; + return FilteredItems.Count(); + } + + /// + /// Navigates to a specific page when the data grid has an attached data pager. + /// + /// + public void NavigateTo(Page page) + { + switch (page) + { + case Page.First: + CurrentPage = 0; + break; + + case Page.Last: + CurrentPage = Math.Max(0, numPages - 1); + break; + + case Page.Next: + CurrentPage = Math.Min(numPages - 1, CurrentPage + 1); + break; + + case Page.Previous: + CurrentPage = Math.Max(0, CurrentPage - 1); + break; + } + + GroupItems(); + } + + /// + /// Sets the rows displayed per page when the data grid has an attached data pager. + /// + /// + public async Task SetRowsPerPageAsync(int size) + { + if (_rowsPerPage == size) + return; + + _rowsPerPage = size; + CurrentPage = 0; + StateHasChanged(); + + if (_isFirstRendered) + await InvokeAsync(InvokeServerLoadFunc); + } + + /// + /// Sets the sort on the data grid. + /// + /// The field. + /// The direction. + /// The sort function. + public async Task SetSortAsync(string field, SortDirection direction, Func sortFunc) + { + var removedSortDefinitions = new HashSet(SortDefinitions.Keys); + SortDefinitions.Clear(); + + var newDefinition = new SortDefinition(field, direction == SortDirection.Descending, 0, sortFunc); + SortDefinitions[field] = newDefinition; + + // In case sort is just updated make sure to not mark the field as removed + removedSortDefinitions.Remove(field); + + await InvokeSortUpdates(SortDefinitions, removedSortDefinitions); + } + + public async Task ExtendSortAsync(string field, SortDirection direction, Func sortFunc) + { + // If SortMode is not multiple, use the default set approach and don't extend. + if (SortMode != SortMode.Multiple) + { + await SetSortAsync(field, direction, sortFunc); + return; + } + + // in case it already exists, just update the current entry + if (SortDefinitions.TryGetValue(field, out var sortDefinition)) + SortDefinitions[field] = sortDefinition with { Descending = direction == SortDirection.Descending, SortFunc = sortFunc }; + else + { + var newDefinition = new SortDefinition(field, direction == SortDirection.Descending, SortDefinitions.Count, sortFunc); + SortDefinitions[field] = newDefinition; + } + + await InvokeSortUpdates(SortDefinitions, null); + } + + public async Task RemoveSortAsync(string field) + { + if (!string.IsNullOrWhiteSpace(field) && SortDefinitions.TryGetValue(field, out var definition)) + { + SortDefinitions.Remove(field); + foreach (var defToUpdate in SortDefinitions.Where(kvp => kvp.Value.Index > definition.Index).ToList()) + SortDefinitions[defToUpdate.Key] = defToUpdate.Value with { Index = defToUpdate.Value.Index - 1 }; + + await InvokeSortUpdates(SortDefinitions, new HashSet() { field }); + } + } + + private async Task ClearCurrentSortings() + { + var removedSortDefinitions = new HashSet(SortDefinitions.Keys); + SortDefinitions.Clear(); + await InvokeSortUpdates(SortDefinitions, removedSortDefinitions); + } + + private async Task InvokeSortUpdates(Dictionary> activeSortDefinitions, HashSet removedSortDefinitions) + { + SortChangedEvent?.Invoke(activeSortDefinitions, removedSortDefinitions); + await InvokeServerLoadFunc(); + StateHasChanged(); + } + + /// + /// Set the currently selected item in the data grid. + /// + /// + /// + public async Task SetSelectedItemAsync(T item) + { + if (MultiSelection) + { + if (Selection.Contains(item)) + { + Selection.Remove(item); + } + else + { + Selection.Add(item); + } + + SelectedItemsChangedEvent?.Invoke(SelectedItems); + await SelectedItemsChanged.InvokeAsync(SelectedItems); + } + + SelectedItem = item; + } + + /// + /// Set an item to be edited. + /// + /// + /// + [UnconditionalSuppressMessage("Trimming", "IL2026: Using member 'System.Text.Json.JsonSerializer.Deserialize(string, System.Text.Json.JsonSerializerOptions?)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.", Justification = "Suppressing because T is a type supplied by the user and it is unlikely that it is not referenced by their code.")] + public async Task SetEditingItemAsync(T item) + { + if (ReadOnly) return; + + editingSourceItem = item; + EditingCancelledEvent?.Invoke(); + _previousEditingItem = _editingItem; + _editingItem = JsonSerializer.Deserialize(JsonSerializer.Serialize(item)); + StartedEditingItemEvent?.Invoke(); + await StartedEditingItem.InvokeAsync(_editingItem); + isEditFormOpen = true; + } + + /// + /// Cancel editing an item. + /// + public async Task CancelEditingItemAsync() + { + EditingCancelledEvent?.Invoke(); + await CancelledEditingItem.InvokeAsync(_editingItem); + ClearEditingItem(); + isEditFormOpen = false; + } + + /// + /// Opens or closes the filter panel. + /// + public void ToggleFiltersMenu() + { + _filtersMenuVisible = !_filtersMenuVisible; + StateHasChanged(); + } + + /// + /// Call this to reload the server-filtered, -sorted and -paginated items + /// + public Task ReloadServerData() + { + return InvokeServerLoadFunc(); + } + + /// + /// Opens the filter panel. + /// + public void OpenFilters() + { + _filtersMenuVisible = true; + StateHasChanged(); + } + + internal async Task HideAllColumnsAsync() + { + foreach (var column in RenderedColumns) + { + if (column.Hideable ?? false) + await column.HideAsync(); + } + + StateHasChanged(); + } + + internal async Task ShowAllColumnsAsync() + { + foreach (var column in RenderedColumns) + { + if (column.Hideable ?? false) + await column.ShowAsync(); + } + + StateHasChanged(); + } + + public void ShowColumnsPanel() + { + _columnsPanelVisible = true; + StateHasChanged(); + } + + public void HideColumnsPanel() + { + _columnsPanelVisible = false; + StateHasChanged(); + } + + internal void ExternalStateHasChanged() + { + StateHasChanged(); + } + + public void GroupItems() + { + if (GroupedColumn == null) + { + _groups = new List>(); + StateHasChanged(); + return; + } + + var groupings = CurrentPageItems.GroupBy(GroupedColumn.groupBy); + + if (_groupExpansions.Count == 0) + { + if (GroupExpanded) + { + // We need to initially expand all groups. + foreach (var group in groupings) + { + _groupExpansions.Add(group.Key); + } + } + + _groupExpansions.Add("__initial__"); + } + + // construct the groups + _groups = groupings.Select(x => new GroupDefinition(x, + _groupExpansions.Contains(x.Key))).ToList(); + + StateHasChanged(); + } + + internal void ChangedGrouping(Column column) + { + foreach (var c in RenderedColumns) + { + if (c.Field != column.Field) + c.RemoveGrouping(); + } + + GroupItems(); + } + + internal void ToggleGroupExpansion(GroupDefinition g) + { + if (_groupExpansions.Contains(g.Grouping.Key)) + { + _groupExpansions.Remove(g.Grouping.Key); + } + else + { + _groupExpansions.Add(g.Grouping.Key); + } + + GroupItems(); + } + + public void ExpandAllGroups() + { + foreach (var group in _groups) + { + group.IsExpanded = true; + _groupExpansions.Add(group.Grouping.Key); + } + } + + public void CollapseAllGroups() + { + foreach (var group in _groups) + { + group.IsExpanded = false; + } + } + + #endregion + + internal async Task ToggleHierarchyVisibilityAsync(T item) + { + if (_openHierarchies.Contains(item)) + { + _openHierarchies.Remove(item); + } + else + { + _openHierarchies.Add(item); + } + + await InvokeAsync(StateHasChanged); + } + + #region Resize feature + + [Inject] private IEventListener EventListener { get; set; } + internal bool IsResizing { get; set; } + + private ElementReference _gridElement; + private DataGridColumnResizeService _resizeService; + + internal DataGridColumnResizeService ResizeService + { + get + { + if (null == _resizeService) + { + _resizeService = new DataGridColumnResizeService(this, EventListener); + } + + return _resizeService; + } + } + + internal async Task StartResizeColumn(HeaderCell headerCell, double clientX) + => await ResizeService.StartResizeColumn(headerCell, clientX, RenderedColumns, ColumnResizeMode); + + internal async Task GetActualHeight() + { + var gridRect = await _gridElement.MudGetBoundingClientRectAsync(); + var gridHeight = gridRect.Height; + return gridHeight; + } + + #endregion +} diff --git a/Components/DataGrid/DataGridColumnResizeService.cs b/Components/DataGrid/DataGridColumnResizeService.cs new file mode 100644 index 0000000..e1f598c --- /dev/null +++ b/Components/DataGrid/DataGridColumnResizeService.cs @@ -0,0 +1,138 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +internal sealed class DataGridColumnResizeService +{ + private const string EventMouseMove = "mousemove"; + private const string EventMouseUp = "mouseup"; + + private readonly DataGrid _dataGrid; + private readonly IEventListener _eventListener; + private ResizeMode _resizeMode; + + private IList> _columns; + private double _currentX; + private double _startWidth; + private double _nextStartWidth; + private Column _startColumn; + private Column _nextColumn; + private Guid _mouseMoveSubscriptionId; + private Guid _mouseUpSubscriptionId; + + public DataGridColumnResizeService(DataGrid dataGrid, IEventListener eventListener) + { + _dataGrid = dataGrid; + _eventListener = eventListener; + } + + internal async Task StartResizeColumn(HeaderCell headerCell, double clientX, IList> columns, ResizeMode columnResizeMode) + { + if ((headerCell?.Column?.Resizable ?? false) || columnResizeMode == ResizeMode.None || _mouseMoveSubscriptionId != default || _mouseUpSubscriptionId != default) + return false; + + _columns = columns; + _resizeMode = columnResizeMode; + _currentX = clientX; + + _startWidth = await headerCell.GetCurrentCellWidth(); + _startColumn = headerCell.Column; + + if (_resizeMode == ResizeMode.Column) + { + // In case resize mode is column, we have to find any column right of the current one that can also be resized and is not hidden. + var nextResizableColumn = _columns.Skip(_columns.IndexOf(headerCell.Column) + 1).FirstOrDefault(c => c.Resizable ?? true && !c.Hidden); + if (null == nextResizableColumn) + return false; + + _nextStartWidth = await nextResizableColumn.HeaderCell.GetCurrentCellWidth(); + _nextColumn = nextResizableColumn; + } + + _mouseMoveSubscriptionId = await _eventListener.SubscribeGlobal(EventMouseMove, 0, OnApplicationMouseMove); + _mouseUpSubscriptionId = await _eventListener.SubscribeGlobal(EventMouseUp, 0, OnApplicationMouseUp); + + _dataGrid.IsResizing = true; + _dataGrid.ExternalStateHasChanged(); + return true; + } + + private async Task OnApplicationMouseMove(object eventArgs) + { + await ResizeColumn(eventArgs, false); + } + + private async Task OnApplicationMouseUp(object eventArgs) + { + var requiresUpdate = _mouseMoveSubscriptionId != default || _mouseUpSubscriptionId != default; + + _dataGrid.IsResizing = false; + _dataGrid.ExternalStateHasChanged(); + await UnsubscribeApplicationEvents(); + + if (requiresUpdate) + { + await ResizeColumn(eventArgs, true); + } + } + + private async Task UnsubscribeApplicationEvents() + { + if (_mouseMoveSubscriptionId != default) + { + await _eventListener.Unsubscribe(_mouseMoveSubscriptionId); + _mouseMoveSubscriptionId = default; + } + + if (_mouseUpSubscriptionId != default) + { + await _eventListener.Unsubscribe(_mouseUpSubscriptionId); + _mouseUpSubscriptionId = default; + } + } + + private async Task ResizeColumn(object eventArgs, bool finish) + { + if (eventArgs is MouseEventArgs mouseEventArgs) + { + // Need to update height, because resizing of columns can lead to height changes in grid (due to line-breaks) + var gridHeight = await _dataGrid.GetActualHeight(); + + var deltaX = mouseEventArgs.ClientX - _currentX; + var targetWidth = _startWidth + deltaX; + + // Easy case: ResizeMode is container, we simply update the width of the resized column + if (_resizeMode == ResizeMode.Container) + { + await _startColumn.HeaderCell.UpdateColumnWidth(targetWidth, gridHeight, finish); + return; + } + + // In case of column resize mode, we have to find another column that can be resized to + // enlarge/shrink this other column by the same amount, the current column shall be shrinked/enlarged. + var nextTargetWidth = _nextStartWidth - deltaX; + + // In case we shrink the current column, make sure to not shrink further after min width has been reached: + if (deltaX < 0) + await ResizeColumns(_startColumn, _nextColumn, targetWidth, nextTargetWidth, gridHeight, finish); + // In case we enlarge, we first shrink the following column and ensure it is not shrinked beyond min width: + else + await ResizeColumns(_nextColumn, _startColumn, nextTargetWidth, targetWidth, gridHeight, finish); + } + } + + private static async Task ResizeColumns(Column columnToShrink, Column columnToEnlarge, + double shrinkedWidth, double enlargedWidth, double gridHeight, bool finish) + { + var actualWidth = await columnToShrink.HeaderCell.UpdateColumnWidth(shrinkedWidth, gridHeight, finish); + // Use actualWidth to see if the column could be made smaller or if it reached its min size. + if (actualWidth >= shrinkedWidth) + enlargedWidth -= (actualWidth - shrinkedWidth); + + await columnToEnlarge.HeaderCell.UpdateColumnWidth(enlargedWidth, gridHeight, finish); + } +} diff --git a/Components/DataGrid/DataGridEditMode.cs b/Components/DataGrid/DataGridEditMode.cs new file mode 100644 index 0000000..913f493 --- /dev/null +++ b/Components/DataGrid/DataGridEditMode.cs @@ -0,0 +1,11 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public enum DataGridEditMode +{ + Cell, + Form +} diff --git a/Components/DataGrid/DataGridEditTrigger.cs b/Components/DataGrid/DataGridEditTrigger.cs new file mode 100644 index 0000000..e2b6f0c --- /dev/null +++ b/Components/DataGrid/DataGridEditTrigger.cs @@ -0,0 +1,11 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public enum DataGridEditTrigger +{ + OnRowClick, + Manual +} diff --git a/Components/DataGrid/DataGridFilterCaseSensitivity.cs b/Components/DataGrid/DataGridFilterCaseSensitivity.cs new file mode 100644 index 0000000..c5a0169 --- /dev/null +++ b/Components/DataGrid/DataGridFilterCaseSensitivity.cs @@ -0,0 +1,11 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; +public enum DataGridFilterCaseSensitivity +{ + Default, + + CaseInsensitive +} diff --git a/Components/DataGrid/DataGridFilterMode.cs b/Components/DataGrid/DataGridFilterMode.cs new file mode 100644 index 0000000..8f60f38 --- /dev/null +++ b/Components/DataGrid/DataGridFilterMode.cs @@ -0,0 +1,12 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + + public enum DataGridFilterMode + { + Simple, + ColumnFilterMenu, + ColumnFilterRow, + } diff --git a/Components/DataGrid/DataGridPager.razor b/Components/DataGrid/DataGridPager.razor new file mode 100644 index 0000000..274e3d2 --- /dev/null +++ b/Components/DataGrid/DataGridPager.razor @@ -0,0 +1,29 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + +
    + @if (!DisableRowsPerPage) + { + + @RowsPerPageString + + + } + + @Info + +
    + + + + +
    +
    + diff --git a/Components/DataGrid/DataGridPager.razor.cs b/Components/DataGrid/DataGridPager.razor.cs new file mode 100644 index 0000000..645bd93 --- /dev/null +++ b/Components/DataGrid/DataGridPager.razor.cs @@ -0,0 +1,79 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class DataGridPager : UIComponent, IDisposable +{ + [CascadingParameter] public DataGrid DataGrid { get; set; } + + /// + /// Set true to hide the part of the pager which allows to change the page size. + /// + [Parameter] public bool DisableRowsPerPage { get; set; } + + /// + /// Set true to disable user interaction with the backward/forward buttons + /// and the part of the pager which allows to change the page size. + /// + [Parameter] public bool Disabled { get; set; } + + /// + /// Define a list of available page size options for the user to choose from + /// + [Parameter] public int[] PageSizeOptions { get; set; } = new int[] { 10, 25, 50, 100 }; + + /// + /// Format string for the display of the current page, which you can localize to your language. Available variables are: + /// {first_item}, {last_item} and {all_items} which will replaced with the indices of the page's first and last item, as well as the total number of items. + /// Default: "{first_item}-{last_item} of {all_items}" which is transformed into "0-25 of 77". + /// + [Parameter] public string InfoFormat { get; set; } = "{first_item}-{last_item} of {all_items}"; + + /// + /// The localizable "Rows per page:" text. + /// + [Parameter] public string RowsPerPageString { get; set; } = "Rows per page:"; + + private string Info => DataGrid == null ? "DataGrid==null" : InfoFormat + .Replace("{first_item}", $"{DataGrid?.CurrentPage * DataGrid.RowsPerPage + 1}") + .Replace("{last_item}", $"{Math.Min((DataGrid.CurrentPage + 1) * DataGrid.RowsPerPage, DataGrid.GetFilteredItemsCount())}") + .Replace("{all_items}", $"{DataGrid.GetFilteredItemsCount()}"); + + private bool BackButtonsDisabled => Disabled || (DataGrid == null ? false : DataGrid.CurrentPage == 0); + + private bool ForwardButtonsDisabled => Disabled || (DataGrid == null ? false : (DataGrid.CurrentPage + 1) * DataGrid.RowsPerPage >= DataGrid.GetFilteredItemsCount()); + + protected string Classname => + new CssBuilder("mud-table-pagination-toolbar") + .AddClass(Class) + .Build(); + + private async Task SetRowsPerPageAsync(string size) + { + await DataGrid?.SetRowsPerPageAsync(int.Parse(size)); + } + + protected override async Task OnInitializedAsync() + { + if (DataGrid != null) + { + DataGrid.HasPager = true; + DataGrid.PagerStateHasChangedEvent += StateHasChanged; + var size = DataGrid._rowsPerPage ?? PageSizeOptions.First(); + await DataGrid.SetRowsPerPageAsync(size); + } + } + + public void Dispose() + { + if (DataGrid != null) + { + DataGrid.PagerStateHasChangedEvent -= StateHasChanged; + } + } +} diff --git a/Components/DataGrid/DataGridRowClickEventArgs.cs b/Components/DataGrid/DataGridRowClickEventArgs.cs new file mode 100644 index 0000000..dd5a581 --- /dev/null +++ b/Components/DataGrid/DataGridRowClickEventArgs.cs @@ -0,0 +1,16 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + + public class DataGridRowClickEventArgs : EventArgs + { + public MouseEventArgs MouseEventArgs { get; set; } + public T Item { get; set; } + public int RowIndex { get; set; } + + } diff --git a/Components/DataGrid/DataGridRowValidator.cs b/Components/DataGrid/DataGridRowValidator.cs new file mode 100644 index 0000000..0aa8a54 --- /dev/null +++ b/Components/DataGrid/DataGridRowValidator.cs @@ -0,0 +1,69 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; + +namespace Connected.Components; + +public class DataGridRowValidator : IForm +{ + public bool IsValid + { + get + { + Validate(); + return Errors.Length <= 0; + } + } + + public string[] Errors + { + get => _errors.ToArray(); + } + +#nullable enable + [ExcludeFromCodeCoverage] + public object? Model { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } +#nullable disable + + protected HashSet _errors = new HashSet(); + + + void IForm.FieldChanged(IFormComponent formControl, object newValue) + { + //implement in future for DataGrid + } + + void IForm.Add(IFormComponent formControl) + { + _formControls.Add(formControl); + } + + void IForm.Remove(IFormComponent formControl) + { + _formControls.Remove(formControl); + } + + void IForm.Update(IFormComponent formControl) + { + //Validate(formControl); + } + + protected HashSet _formControls = new HashSet(); + + [ExcludeFromCodeCoverage] + public void Validate() + { + _errors.Clear(); + foreach (var formControl in _formControls.ToArray()) + { + formControl.Validate(); + foreach (var err in formControl.ValidationErrors) + { + _errors.Add(err); + } + } + } + +} diff --git a/Components/DataGrid/Filter.cs b/Components/DataGrid/Filter.cs new file mode 100644 index 0000000..be0530a --- /dev/null +++ b/Components/DataGrid/Filter.cs @@ -0,0 +1,166 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +internal class Filter +{ + private readonly DataGrid _dataGrid; + private readonly FilterDefinition _filterDefinition; + private readonly Column _column; + + internal string _valueString; + internal double? _valueNumber; + internal Enum _valueEnum = null; + internal bool? _valueBool; + internal DateTime? _valueDate; + internal TimeSpan? _valueTime; + + internal Type dataType + { + get + { + if (_column != null) + return _column.dataType; + + if (_filterDefinition.FieldType != null) + return _filterDefinition.FieldType; + + if (_filterDefinition.Field == null) + return typeof(object); + + if (typeof(T) == typeof(IDictionary) && _filterDefinition.FieldType == null) + throw new ArgumentNullException(nameof(_filterDefinition.FieldType)); + + var t = typeof(T).GetProperty(_filterDefinition.Field).PropertyType; + return Nullable.GetUnderlyingType(t) ?? t; + } + } + internal bool isNumber + { + get + { + return FilterOperator.IsNumber(dataType); + } + } + internal bool isEnum + { + get + { + return FilterOperator.IsEnum(dataType); + } + } + + internal Column filterColumn => + _column != null + ? _column + : _dataGrid.RenderedColumns?.FirstOrDefault(c => c.Field == _filterDefinition.Field); + + public Filter(DataGrid dataGrid, FilterDefinition filterDefinition, Column column) + { + _dataGrid = dataGrid; + _filterDefinition = filterDefinition; + _column = column; + + if (dataType == typeof(string)) + _valueString = _filterDefinition.Value == null ? null : _filterDefinition.Value.ToString(); + else if (isNumber) + _valueNumber = _filterDefinition.Value == null ? null : Convert.ToDouble(_filterDefinition.Value); + else if (isEnum) + _valueEnum = _filterDefinition.Value == null ? null : (Enum)_filterDefinition.Value; + else if (dataType == typeof(bool)) + _valueBool = _filterDefinition.Value == null ? null : Convert.ToBoolean(_filterDefinition.Value); + else if (dataType == typeof(DateTime) || dataType == typeof(DateTime?)) + { + var dateTime = Convert.ToDateTime(_filterDefinition.Value); + _valueDate = _filterDefinition.Value == null ? null : dateTime; + _valueTime = _filterDefinition.Value == null ? null : dateTime.TimeOfDay; + } + } + + internal void RemoveFilter() + { + _dataGrid.RemoveFilter(_filterDefinition.Id); + } + + internal void FieldChanged(string field) + { + _filterDefinition.Field = field; + var operators = FilterOperator.GetOperatorByDataType(dataType); + _filterDefinition.Operator = operators.FirstOrDefault(); + _filterDefinition.Value = null; + } + + internal void StringValueChanged(string value) + { + _valueString = value; + _filterDefinition.Value = _valueString; + _dataGrid.GroupItems(); + } + + internal void NumberValueChanged(double? value) + { + _valueNumber = value; + _filterDefinition.Value = _valueNumber; + _dataGrid.GroupItems(); + } + + internal void EnumValueChanged(Enum value) + { + _valueEnum = value; + _filterDefinition.Value = _valueEnum; + _dataGrid.GroupItems(); + } + + internal void BoolValueChanged(bool? value) + { + _valueBool = value; + _filterDefinition.Value = _valueBool; + _dataGrid.GroupItems(); + } + + internal void DateValueChanged(DateTime? value) + { + _valueDate = value; + + if (value != null) + { + var date = value.Value.Date; + + // get the time component and add it to the date. + if (_valueTime != null) + { + date.Add(_valueTime.Value); + } + + _filterDefinition.Value = date; + } + else + _filterDefinition.Value = value; + + _dataGrid.GroupItems(); + } + + internal void TimeValueChanged(TimeSpan? value) + { + _valueTime = value; + + if (_valueDate != null) + { + var date = _valueDate.Value.Date; + + + // get the time component and add it to the date. + if (_valueTime != null) + { + date = date.Add(_valueTime.Value); + } + + _filterDefinition.Value = date; + } + + _dataGrid.GroupItems(); + } + +} diff --git a/Components/DataGrid/FilterContext.cs b/Components/DataGrid/FilterContext.cs new file mode 100644 index 0000000..a61d1a6 --- /dev/null +++ b/Components/DataGrid/FilterContext.cs @@ -0,0 +1,47 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class FilterContext +{ + internal DataGrid _dataGrid; + internal HeaderCell _headerCell; + public IEnumerable Items + { + get + { + return _dataGrid.Items; + } + } + public List> FilterDefinitions + { + get + { + return _dataGrid.FilterDefinitions; + } + } + internal FilterDefinition FilterDefinition { get; set; } + public FilterActions Actions { get; internal set; } + + public FilterContext(DataGrid dataGrid) + { + _dataGrid = dataGrid; + Actions = new FilterContext.FilterActions + { + ApplyFilter = x => _headerCell.ApplyFilter(x), + ApplyFilters = x => _headerCell.ApplyFilters(x), + ClearFilter = x => _headerCell.ClearFilter(x), + ClearFilters = x => _headerCell.ClearFilters(x), + }; + } + + public class FilterActions + { + public Action> ApplyFilter { get; internal set; } + public Action>> ApplyFilters { get; internal set; } + public Action> ClearFilter { get; internal set; } + public Action>> ClearFilters { get; internal set; } + } +} diff --git a/Components/DataGrid/FilterDefinition.cs b/Components/DataGrid/FilterDefinition.cs new file mode 100644 index 0000000..1e23d03 --- /dev/null +++ b/Components/DataGrid/FilterDefinition.cs @@ -0,0 +1,781 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.Linq.Expressions; +using System.Text.Json; +using Connected.Utilities; + +namespace Connected.Components; + +[RequiresUnreferencedCode(CodeMessage.SerializationUnreferencedCodeMessage)] +public class FilterDefinition +{ + internal DataGrid DataGrid { get; set; } + + public Guid Id { get; set; } = Guid.NewGuid(); + public string Field { get; set; } + public string Title { get; set; } + public Type FieldType { get; set; } + public string Operator { get; set; } + public object Value { get; set; } + public Func FilterFunction { get; set; } + + private Type dataType + { + get + { + if (FieldType != null) + return FieldType; + + if (Field == null) + return typeof(object); + + if (typeof(T) == typeof(IDictionary) && FieldType == null) + throw new ArgumentNullException(nameof(FieldType)); + + return typeof(T).GetProperty(Field).PropertyType; + } + } + + private bool isNumber + { + get + { + return FilterOperator.IsNumber(dataType); + } + } + + private bool isEnum + { + get + { + return FilterOperator.IsEnum(dataType); + } + } + + private bool isDateTime + { + get + { + return FilterOperator.IsDateTime(dataType); + } + } + + private bool isBoolean + { + get + { + return FilterOperator.IsBoolean(dataType); + } + } + + private bool isGuid + { + get + { + return FilterOperator.IsGuid(dataType); + } + } + + public Func GenerateFilterFunction() + { + if (FilterFunction != null) + return FilterFunction; + + // Handle case where we have an IDictionary. + if (typeof(T) == typeof(IDictionary)) + { + if (dataType == typeof(string)) + { + return GenerateFilterForStringTypeInIDictionary(); + } + else if (isNumber) + { + return GenerateFilterForNumericTypesInIDictionary(); + } + else if (isEnum) + { + return GenerateFilterForEnumTypesInIDictionary(); + } + else if (isBoolean) + { + return GenerateFilterForBooleanTypeInIDictionary(); + } + else if (isDateTime) + { + return GenerateFilterForDateTimeTypeInIDictionary(); + } + else if (isGuid) + { + return GenerateFilterForGuidTypeInIDictionary(); + } + + return x => true; + } + else + { + var expression = GenerateFilterExpression(); + + return expression.Compile(); + } + } + + public Expression> GenerateFilterExpression() + { + var parameter = Expression.Parameter(typeof(T), "x"); + Expression expression; + + if (dataType == typeof(string)) + { + expression = GenerateFilterExpressionForStringType(parameter); + } + else if (isNumber) + { + expression = GenerateFilterExpressionForNumericTypes(parameter); + } + else if (isEnum) + { + expression = GenerateFilterExpressionForEnumTypes(parameter); + } + else if (isBoolean) + { + expression = GenerateFilterExpressionForBooleanTypes(parameter); + } + else if (isDateTime) + { + expression = GenerateFilterExpressionForDateTimeTypes(parameter); + } + else if (isGuid) + { + expression = GenerateFilterExpressionForGuidTypes(parameter); + } + else + { + expression = Expression.Constant(true, typeof(bool)); + } + + return Expression.Lambda>(expression, parameter); + } + + private Expression GenerateFilterExpressionForDateTimeTypes(ParameterExpression parameter) + { + var field = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(Field)), typeof(DateTime?)); + DateTime? valueDateTime = Value == null ? null : (DateTime)Value; + var isnotnull = Expression.NotEqual(field, Expression.Constant(null)); + var isnull = Expression.Equal(field, Expression.Constant(null)); + var notNullDateTime = Expression.Convert(field, typeof(DateTime)); + var valueDateTimeConstant = Expression.Constant(valueDateTime); + + return Operator switch + { + FilterOperator.DateTime.Is when null != Value => + Expression.AndAlso(isnotnull, + Expression.Equal(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.IsNot when null != Value => + Expression.OrElse(isnull, + Expression.NotEqual(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.After when null != Value => + Expression.AndAlso(isnotnull, + Expression.GreaterThan(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.OnOrAfter when null != Value => + Expression.AndAlso(isnotnull, + Expression.GreaterThanOrEqual(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.Before when null != Value => + Expression.AndAlso(isnotnull, + Expression.LessThan(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.OnOrBefore when null != Value => + Expression.AndAlso(isnotnull, + Expression.LessThanOrEqual(notNullDateTime, valueDateTimeConstant)), + + FilterOperator.DateTime.Empty => isnull, + FilterOperator.DateTime.NotEmpty => isnotnull, + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + private Expression GenerateFilterExpressionForBooleanTypes(ParameterExpression parameter) + { + var field = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(Field)), typeof(bool?)); + bool? valueBool = Value == null ? null : Convert.ToBoolean(Value); + var isnotnull = Expression.NotEqual(field, Expression.Constant(null)); + var notNullBool = Expression.Convert(field, typeof(bool)); + + return Operator switch + { + FilterOperator.Enum.Is when Value != null => Expression.AndAlso(isnotnull, + Expression.Equal(notNullBool, Expression.Constant(valueBool))), + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + private Expression GenerateFilterExpressionForGuidTypes(ParameterExpression parameter) + { + var field = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(Field)), typeof(Guid?)); + Guid? valueGuid = Value == null ? null : ParseGuid((String)Value); + var isnotnull = Expression.IsTrue(Expression.Property(field, typeof(Guid?), "HasValue")); + var isnull = Expression.IsFalse(Expression.Property(field, typeof(Guid?), "HasValue")); + var notNullGuid = Expression.Convert(field, typeof(Guid)); + + return Operator switch + { + FilterOperator.Guid.Equal when valueGuid != null => + Expression.AndAlso(isnotnull, + Expression.Equal(notNullGuid, Expression.Constant(valueGuid))), + + FilterOperator.Guid.NotEqual when valueGuid != null => + Expression.OrElse( + isnull, + Expression.NotEqual(notNullGuid, Expression.Constant(valueGuid))), + + // filtered value is not a valid GUID + _ when valueGuid == null && Value != null => + Expression.Constant(false), + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + private Expression GenerateFilterExpressionForEnumTypes(ParameterExpression parameter) + { + var field = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(Field)), dataType); + var valueEnum = Value == null ? null : (Enum)Value; + var _null = Expression.Convert(Expression.Constant(null), dataType); + var isnull = Expression.Equal(field, _null); + var isnotnull = Expression.NotEqual(field, _null); + var valueEnumConstant = Expression.Convert(Expression.Constant(valueEnum), dataType); + + return Operator switch + { + FilterOperator.Enum.Is when Value != null => + IsNullableEnum(dataType) ? Expression.AndAlso(isnotnull, + Expression.Equal(field, valueEnumConstant)) + : Expression.Equal(field, valueEnumConstant), + + FilterOperator.Enum.IsNot when Value != null => + IsNullableEnum(dataType) ? Expression.OrElse(isnull, + Expression.NotEqual(field, valueEnumConstant)) + : Expression.NotEqual(field, valueEnumConstant), + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + private Expression GenerateFilterExpressionForNumericTypes(ParameterExpression parameter) + { + var field = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(Field)), typeof(double?)); + double? valueNumber = Value == null ? null : Convert.ToDouble(Value); + var isnotnull = Expression.NotEqual(field, Expression.Constant(null)); + var isnull = Expression.Equal(field, Expression.Constant(null)); + var notNullNumber = Expression.Convert(field, typeof(double)); + var valueNumberConstant = Expression.Constant(valueNumber); + + return Operator switch + { + FilterOperator.Number.Equal when Value != null => + Expression.AndAlso(isnotnull, + Expression.Equal(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.NotEqual when Value != null => + Expression.OrElse(isnull, + Expression.NotEqual(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.GreaterThan when Value != null => + Expression.AndAlso(isnotnull, + Expression.GreaterThan(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.GreaterThanOrEqual when Value != null => + Expression.AndAlso(isnotnull, + Expression.GreaterThanOrEqual(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.LessThan when Value != null => + Expression.AndAlso(isnotnull, + Expression.LessThan(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.LessThanOrEqual when Value != null => + Expression.AndAlso(isnotnull, + Expression.LessThanOrEqual(notNullNumber, valueNumberConstant)), + + FilterOperator.Number.Empty => isnull, + FilterOperator.Number.NotEmpty => isnotnull, + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + private Expression GenerateFilterExpressionForStringType(ParameterExpression parameter) + { + var field = Expression.Property(parameter, typeof(T).GetProperty(Field)); + var valueString = Value?.ToString(); + var trim = Expression.Call(field, dataType.GetMethod("Trim", Type.EmptyTypes)); + var isnull = Expression.Equal(field, Expression.Constant(null)); + var isnotnull = Expression.NotEqual(field, Expression.Constant(null)); + + return Operator switch + { + FilterOperator.String.Contains when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("Contains", new[] { dataType }), Expression.Constant(valueString))), + + FilterOperator.String.Contains when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("Contains", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + + FilterOperator.String.NotContains when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Not(Expression.Call(field, dataType.GetMethod("Contains", new[] { dataType }), Expression.Constant(valueString)))), + + FilterOperator.String.NotContains when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Not(Expression.Call(field, dataType.GetMethod("Contains", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) }))), + + FilterOperator.String.Equal when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Equal(field, Expression.Constant(valueString))), + + FilterOperator.String.Equal when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("Equals", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + + FilterOperator.String.NotEqual when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Not(Expression.Equal(field, Expression.Constant(valueString)))), + + FilterOperator.String.NotEqual when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Not(Expression.Call(field, dataType.GetMethod("Equals", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) }))), + + FilterOperator.String.StartsWith when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("StartsWith", new[] { dataType }), Expression.Constant(valueString))), + + FilterOperator.String.StartsWith when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("StartsWith", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + + FilterOperator.String.EndsWith when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("EndsWith", new[] { dataType }), Expression.Constant(valueString))), + + FilterOperator.String.EndsWith when Value != null && DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.CaseInsensitive => + Expression.AndAlso(isnotnull, + Expression.Call(field, dataType.GetMethod("EndsWith", new[] { dataType, typeof(StringComparison) }), new[] { Expression.Constant(valueString), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + + FilterOperator.String.Empty => + Expression.OrElse(isnull, + Expression.Equal(trim, Expression.Constant(string.Empty, dataType))), + + FilterOperator.String.NotEmpty => + Expression.AndAlso(isnotnull, + Expression.NotEqual(trim, Expression.Constant(string.Empty, dataType))), + + _ => Expression.Constant(true, typeof(bool)) + }; + } + + #region IDictionary Filters + + private Func GenerateFilterForStringTypeInIDictionary() + { + var valueString = Value?.ToString(); + + var caseSensitivity = DataGrid.FilterCaseSensitivity == DataGridFilterCaseSensitivity.Default ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; + + return Operator switch + { + FilterOperator.String.Contains when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return v != null && v.Contains(valueString, caseSensitivity); + } + , + FilterOperator.String.NotContains when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return v != null && !v.Contains(valueString, caseSensitivity); + } + , + + FilterOperator.String.Equal when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return v != null && v.Equals(valueString, caseSensitivity); + } + , + + FilterOperator.String.NotEqual when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return !valueString.Equals(v, caseSensitivity); + } + , + + FilterOperator.String.StartsWith when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return v != null && v.StartsWith(valueString, caseSensitivity); + } + , + + FilterOperator.String.EndsWith when Value != null => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return v != null && v.EndsWith(valueString, caseSensitivity); + } + , + + FilterOperator.String.Empty => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return string.IsNullOrWhiteSpace(v); + } + , + + FilterOperator.String.NotEmpty => x => + { + string v = GetStringFromObject(((IDictionary)x)[Field]); + + return !string.IsNullOrWhiteSpace(v); + } + , + + _ => x => true + }; + } + + private Func GenerateFilterForNumericTypesInIDictionary() + { + double? valueNumber = Value == null ? null : Convert.ToDouble(Value); + + return Operator switch + { + FilterOperator.Number.Equal when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v == valueNumber; + } + , + + FilterOperator.Number.NotEqual when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v != valueNumber; + } + , + + FilterOperator.Number.GreaterThan when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v > valueNumber; + } + , + + FilterOperator.Number.GreaterThanOrEqual when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v >= valueNumber; + } + , + + FilterOperator.Number.LessThan when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v < valueNumber; + } + , + + FilterOperator.Number.LessThanOrEqual when Value != null => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v <= valueNumber; + } + , + + FilterOperator.Number.Empty => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v == null; + } + , + + FilterOperator.Number.NotEmpty => x => + { + double? v = GetDoubleFromObject(((IDictionary)x)[Field]); + + return v != null; + } + , + + _ => x => true + }; + } + + private Func GenerateFilterForEnumTypesInIDictionary() + { + return Operator switch + { + FilterOperator.Enum.Is when Value != null => x => + { + var v = GetEnumFromObject(((IDictionary)x)[Field]); + + return object.Equals(v, Value); + } + , + + FilterOperator.Enum.IsNot when Value != null => x => + { + var v = GetEnumFromObject(((IDictionary)x)[Field]); + + return !object.Equals(v, Value); + } + , + + _ => x => true + }; + } + + private Func GenerateFilterForBooleanTypeInIDictionary() + { + return Operator switch + { + FilterOperator.Enum.Is when Value != null => x => + { + var v = GetBoolFromObject(((IDictionary)x)[Field]); + + return object.Equals(v, Value); + } + , + + _ => x => true + }; + } + + private Func GenerateFilterForGuidTypeInIDictionary() + { + Guid? valueGuid = Value == null ? null : ParseGuid((string)Value); + return Operator switch + { + FilterOperator.Guid.Equal when Value != null => x => + { + var v = GetGuidFromObject(((IDictionary)x)[Field]); + + return v == valueGuid; + } + , + FilterOperator.Guid.NotEqual when Value != null => x => + { + var v = GetGuidFromObject(((IDictionary)x)[Field]); + + return v != valueGuid; + } + , + + _ => x => true + }; + } + + private Func GenerateFilterForDateTimeTypeInIDictionary() + { + DateTime? valueDateTime = Value == null ? null : (DateTime)Value; + + return Operator switch + { + FilterOperator.DateTime.Is when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v == valueDateTime; + } + , + + FilterOperator.DateTime.IsNot when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v != valueDateTime; + } + , + + FilterOperator.DateTime.After when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v > valueDateTime; + } + , + + FilterOperator.DateTime.OnOrAfter when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v >= valueDateTime; + } + , + + FilterOperator.DateTime.Before when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v < valueDateTime; + } + , + + FilterOperator.DateTime.OnOrBefore when Value != null => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v <= valueDateTime; + } + , + + FilterOperator.DateTime.Empty => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v == null; + } + , + + FilterOperator.DateTime.NotEmpty => x => + { + var v = GetDateTimeFromObject(((IDictionary)x)[Field]); + + return v != null; + } + , + + _ => x => true + }; + } + + #endregion + + private static bool IsNullableEnum(Type t) + { + Type u = Nullable.GetUnderlyingType(t); + return (u != null) && u.IsEnum; + } + + private string GetStringFromObject(object o) + { + if (o == null) + return null; + else if (o.GetType() == typeof(JsonElement)) + { + return ((JsonElement)o).GetString(); + } + else + { + return (string)o; + } + } + + private double? GetDoubleFromObject(object o) + { + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + return ((JsonElement)o).GetDouble(); + } + else + { + return Convert.ToDouble(o); + } + } + + private Enum GetEnumFromObject(object o) + { + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + return (Enum)Enum.ToObject(FieldType, ((JsonElement)o).GetInt32()); + } + else + { + return (Enum)Enum.ToObject(FieldType, o); + } + } + + private bool? GetBoolFromObject(object o) + { + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + return ((JsonElement)o).GetBoolean(); + } + else + { + return Convert.ToBoolean(o); + } + } + + private DateTime? GetDateTimeFromObject(object o) + { + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + return ((JsonElement)o).GetDateTime(); + } + else + { + return Convert.ToDateTime(o); + } + } + + private Guid? GetGuidFromObject(object o) + { + if (o == null) + return null; + + if (o.GetType() == typeof(JsonElement)) + { + return ParseGuid(((JsonElement)o).GetString()); + } + else + { + return ParseGuid(Convert.ToString(o)); + } + } + + private Guid? ParseGuid(string value) + { + if (value != null && Guid.TryParse(value, out Guid guid)) + { + return guid; + } + else + { + return null; + } + } +} diff --git a/Components/DataGrid/FilterHeaderCell.razor b/Components/DataGrid/FilterHeaderCell.razor new file mode 100644 index 0000000..1a28e47 --- /dev/null +++ b/Components/DataGrid/FilterHeaderCell.razor @@ -0,0 +1,65 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + + @if (null != Column && Column.filterable) + { + @if (Column.FilterTemplate != null) + { + @Column.FilterTemplate(Column.filterContext) + } + else + { + + @if (dataType == typeof(string) && !(_operator ?? "").EndsWith("empty")) + { + + } + else if (isNumber && !(_operator ?? "").EndsWith("empty")) + { + + } + else if (isEnum) + { + + } + else if (dataType == typeof(bool)) + { + + } + else if (dataType == typeof(DateTime) && !(_operator ?? "").EndsWith("empty")) + { + + + + + + + + + } + + @foreach (var o in operators) + { + if (!string.IsNullOrWhiteSpace(o)) + { + @o + } + } + + + + } + } + diff --git a/Components/DataGrid/FilterHeaderCell.razor.cs b/Components/DataGrid/FilterHeaderCell.razor.cs new file mode 100644 index 0000000..2d5060b --- /dev/null +++ b/Components/DataGrid/FilterHeaderCell.razor.cs @@ -0,0 +1,217 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class FilterHeaderCell : UIComponent +{ + [CascadingParameter] public DataGrid DataGrid { get; set; } + + [Parameter] public Column Column { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } + + private string _classname => + new CssBuilder(Column?.HeaderClass) + .AddClass(Column?.headerClassname) + .AddClass(Class) + .AddClass("filter-header-cell") + .Build(); + + private string _style => + new StyleBuilder() + .AddStyle(Column?.HeaderStyle) + .AddStyle(Style) + .Build(); + + private string _valueString; + private double? _valueNumber; + private Enum _valueEnum = null; + private bool? _valueBool; + private DateTime? _valueDate; + private TimeSpan? _valueTime; + + #region Computed Properties and Functions + + private bool hasFilter + { + get + { + if (DataGrid == null) + return false; + + return DataGrid.FilterDefinitions.Any(x => x.Field == Column.Field && x.Operator != null && x.Value != null); + } + } + + private Type dataType + { + get + { + return Column?.dataType; + } + } + + private string[] operators + { + get + { + return FilterOperator.GetOperatorByDataType(dataType); + } + } + + private string _operator; + + private string chosenOperatorStyle(string o) + { + return o == _operator ? "color:var(--mud-palette-primary-text);background-color:var(--mud-palette-primary)" : ""; + } + + private bool isNumber + { + get + { + return FilterOperator.IsNumber(dataType); + } + } + + private bool isEnum + { + get + { + return FilterOperator.IsEnum(dataType); + } + } + + #endregion + + protected override void OnInitialized() + { + _operator = operators.FirstOrDefault(); + } + + #region Events + + private void ChangeOperator(string o) + { + _operator = o; + Column.filterContext.FilterDefinition.Operator = _operator; + ApplyFilter(Column.filterContext.FilterDefinition); + } + + internal void StringValueChanged(string value) + { + _valueString = value; + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = value; + ApplyFilter(Column.filterContext.FilterDefinition); + } + + internal void NumberValueChanged(double? value) + { + _valueNumber = value; + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = value; + ApplyFilter(Column.filterContext.FilterDefinition); + } + + internal void EnumValueChanged(Enum value) + { + _valueEnum = value; + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = value; + ApplyFilter(Column.filterContext.FilterDefinition); + } + + internal void BoolValueChanged(bool? value) + { + _valueBool = value; + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = value; + ApplyFilter(Column.filterContext.FilterDefinition); + } + + internal void DateValueChanged(DateTime? value) + { + _valueDate = value; + + if (value != null) + { + var date = value.Value.Date; + + // get the time component and add it to the date. + if (_valueTime != null) + { + date.Add(_valueTime.Value); + } + + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = date; + ApplyFilter(Column.filterContext.FilterDefinition); + } + else + { + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = value; + ApplyFilter(Column.filterContext.FilterDefinition); + } + } + + internal void TimeValueChanged(TimeSpan? value) + { + _valueTime = value; + + if (_valueDate != null) + { + var date = _valueDate.Value.Date; + + // get the time component and add it to the date. + if (_valueTime != null) + { + date = date.Add(_valueTime.Value); + } + + Column.filterContext.FilterDefinition.Operator = _operator; + Column.filterContext.FilterDefinition.Value = date; + ApplyFilter(Column.filterContext.FilterDefinition); + } + } + + internal void ApplyFilter(FilterDefinition filterDefinition) + { + if (!DataGrid.FilterDefinitions.Any(x => x.Id == filterDefinition.Id)) + DataGrid.FilterDefinitions.Add(filterDefinition); + + DataGrid.GroupItems(); + DataGrid.ExternalStateHasChanged(); + } + + private void ClearFilter() + { + ClearFilter(Column.filterContext.FilterDefinition); + + if (dataType == typeof(string)) + _valueString = null; + else if (isNumber) + _valueNumber = null; + else if (isEnum) + _valueEnum = null; + else if (dataType == typeof(bool)) + _valueBool = null; + else if (dataType == typeof(DateTime) || dataType == typeof(DateTime?)) + { + _valueDate = null; + _valueTime = null; + } + } + + internal void ClearFilter(FilterDefinition filterDefinition) + { + DataGrid.RemoveFilter(filterDefinition.Id); + } + + #endregion +} diff --git a/Components/DataGrid/FilterOperator.cs b/Components/DataGrid/FilterOperator.cs new file mode 100644 index 0000000..9849b3f --- /dev/null +++ b/Components/DataGrid/FilterOperator.cs @@ -0,0 +1,191 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.Numerics; + +namespace Connected.Components; + +public static class FilterOperator +{ + public static class String + { + public const string Contains = "contains"; + public const string NotContains = "not contains"; + public const string Equal = "equals"; + public const string NotEqual = "not equals"; + public const string StartsWith = "starts with"; + public const string EndsWith = "ends with"; + public const string Empty = "is empty"; + public const string NotEmpty = "is not empty"; + + internal static string[] Values = GetFields(typeof(String)); + } + + public static class Number + { + public const string Equal = "="; + public const string NotEqual = "!="; + public const string GreaterThan = ">"; + public const string GreaterThanOrEqual = ">="; + public const string LessThan = "<"; + public const string LessThanOrEqual = "<="; + public const string Empty = "is empty"; + public const string NotEmpty = "is not empty"; + + internal static string[] Values = GetFields(typeof(Number)); + } + + public static class Enum + { + public const string Is = "is"; + public const string IsNot = "is not"; + + internal static string[] Values = GetFields(typeof(Enum)); + } + + public static class Boolean + { + public const string Is = "is"; + + internal static string[] Values = GetFields(typeof(Boolean)); + } + + public static class DateTime + { + public const string Is = "is"; + public const string IsNot = "is not"; + public const string After = "is after"; + public const string OnOrAfter = "is on or after"; + public const string Before = "is before"; + public const string OnOrBefore = "is on or before"; + public const string Empty = "is empty"; + public const string NotEmpty = "is not empty"; + + internal static string[] Values = GetFields(typeof(DateTime)); + } + + public static class Guid + { + public const string Equal = "equals"; + public const string NotEqual = "not equals"; + + internal static string[] Values = GetFields(typeof(Guid)); + } + + internal static string[] GetOperatorByDataType(Type type) + { + if (type == typeof(string)) + { + return String.Values; + } + if (IsNumber(type)) + { + return Number.Values; + } + if (IsEnum(type)) + { + return Enum.Values; + } + if (type == typeof(bool)) + { + return Boolean.Values; + } + if (type == typeof(System.DateTime)) + { + return DateTime.Values; + } + if (type == typeof(System.Guid)) + { + return Guid.Values; + } + + // default + return new string[] { }; + } + + internal static string[] GetFields([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + { + List fields = new List(); + + foreach (var field in type.GetFields().Where(fi => fi.IsLiteral)) + { + fields.Add((string)field.GetValue(null)); + } + + return fields.ToArray(); + } + + internal static readonly HashSet NumericTypes = new HashSet + { + typeof(int), + typeof(double), + typeof(decimal), + typeof(long), + typeof(short), + typeof(sbyte), + typeof(byte), + typeof(ulong), + typeof(ushort), + typeof(uint), + typeof(float), + typeof(BigInteger), + typeof(int?), + typeof(double?), + typeof(decimal?), + typeof(long?), + typeof(short?), + typeof(sbyte?), + typeof(byte?), + typeof(ulong?), + typeof(ushort?), + typeof(uint?), + typeof(float?), + typeof(BigInteger?), + }; + + internal static bool IsNumber([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + { + return NumericTypes.Contains(type); + } + + internal static bool IsEnum([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + { + if (null == type) + return false; + + if (type.IsEnum) + return true; + + Type u = Nullable.GetUnderlyingType(type); + return (u != null) && u.IsEnum; + } + + internal static bool IsDateTime([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + { + if (type == typeof(System.DateTime)) + return true; + + Type u = Nullable.GetUnderlyingType(type); + return (u != null) && u == typeof(System.DateTime); + } + + internal static bool IsBoolean([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + { + if (type == typeof(bool)) + return true; + + Type u = Nullable.GetUnderlyingType(type); + return (u != null) && u == typeof(bool); + } + + internal static bool IsGuid(Type type) + { + if (type == typeof(System.Guid)) + return true; + + Type u = Nullable.GetUnderlyingType(type); + return (u != null) && u == typeof(System.Guid); + } +} diff --git a/Components/DataGrid/FooterCell.razor b/Components/DataGrid/FooterCell.razor new file mode 100644 index 0000000..d5e966c --- /dev/null +++ b/Components/DataGrid/FooterCell.razor @@ -0,0 +1,17 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + +@if (Column is not null) +{ + + @if (Column.AggregateDefinition != null) + { + @Column.AggregateDefinition?.GetValue(Column.Field, items) + } + else if (Column.FooterTemplate != null) + { + @Column.FooterTemplate(Column.footerContext) + } + +} \ No newline at end of file diff --git a/Components/DataGrid/FooterCell.razor.cs b/Components/DataGrid/FooterCell.razor.cs new file mode 100644 index 0000000..9c5c7d8 --- /dev/null +++ b/Components/DataGrid/FooterCell.razor.cs @@ -0,0 +1,38 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class FooterCell : UIComponent +{ + [CascadingParameter] public DataGrid DataGrid { get; set; } + + [Parameter] public Column Column { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } + [Parameter] public IEnumerable CurrentItems { get; set; } + + private string _classname => + new CssBuilder("footer-cell") + .AddClass(Column?.FooterClass) + .AddClass(Column?.footerClassname) + .AddClass(Class) + .Build(); + private string _style => + new StyleBuilder() + .AddStyle(Column?.FooterStyle) + .AddStyle(Style) + .AddStyle("font-weight", "600") + .Build(); + + internal IEnumerable items + { + get + { + return CurrentItems ?? DataGrid?.CurrentPageItems; + } + } +} diff --git a/Components/DataGrid/FooterContext.cs b/Components/DataGrid/FooterContext.cs new file mode 100644 index 0000000..f9263e4 --- /dev/null +++ b/Components/DataGrid/FooterContext.cs @@ -0,0 +1,45 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class FooterContext +{ + internal DataGrid _dataGrid; + public IEnumerable Items + { + get + { + return _dataGrid.Items; + } + } + public FooterActions Actions { get; internal set; } + public bool IsAllSelected + { + get + { + + if (_dataGrid.Selection != null && Items != null) + { + return _dataGrid.Selection.Count == Items.Count(); + } + + return false; + } + } + + public FooterContext(DataGrid dataGrid) + { + _dataGrid = dataGrid; + Actions = new FooterContext.FooterActions + { + SetSelectAll = async (x) => await _dataGrid.SetSelectAllAsync(x), + }; + } + + public class FooterActions + { + public Action SetSelectAll { get; internal set; } + } +} diff --git a/Components/DataGrid/GridState.cs b/Components/DataGrid/GridState.cs new file mode 100644 index 0000000..3e473a5 --- /dev/null +++ b/Components/DataGrid/GridState.cs @@ -0,0 +1,22 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class GridState +{ + public int Page { get; set; } + + public int PageSize { get; set; } + + public ICollection> SortDefinitions { get; set; } + + public ICollection> FilterDefinitions { get; set; } +} + +public class GridData +{ + public IEnumerable Items { get; set; } + public int TotalItems { get; set; } +} diff --git a/Components/DataGrid/GroupDefinition.cs b/Components/DataGrid/GroupDefinition.cs new file mode 100644 index 0000000..afaa9dc --- /dev/null +++ b/Components/DataGrid/GroupDefinition.cs @@ -0,0 +1,17 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class GroupDefinition +{ + public IGrouping Grouping { get; set; } + public bool IsExpanded { get; set; } + + public GroupDefinition(IGrouping grouping, bool isExpanded) + { + Grouping = grouping; + IsExpanded = isExpanded; + } +} diff --git a/Components/DataGrid/HeaderCell.razor b/Components/DataGrid/HeaderCell.razor new file mode 100644 index 0000000..a2679de --- /dev/null +++ b/Components/DataGrid/HeaderCell.razor @@ -0,0 +1,124 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + +@if (IsOnlyHeader) +{ + + @ChildContent + +} +else if (Column != null && !Column.Hidden) +{ + + + @if (sortable) + { + + @if (Column.HeaderTemplate != null) + { + @Column.HeaderTemplate(Column.headerContext) + } + else + { + @computedTitle + } + + } + else + { + @if (Column.HeaderTemplate != null) + { + @Column.HeaderTemplate(Column.headerContext) + } + else + { + @computedTitle + } + } + + @if (sortable) + { + if (_initialDirection == SortDirection.None) + { + + } + else + { + + if(DataGrid.SortMode == SortMode.Multiple) + { + @(Column.SortIndex + 1) + } + } + } + + @if (DataGrid.FilterMode != DataGridFilterMode.ColumnFilterRow) + { + if (hasFilter) + { + + } + else if (showFilterIcon) + { + + } + } + + @if (showColumnOptions) + { + + Unsort + @if (filterable && DataGrid.FilterMode != DataGridFilterMode.ColumnFilterRow) + { + Filter + } + @if (hideable) + { + Hide + } + @if (groupable) + { + if (Column?.grouping ?? false) + { + Ungroup + } + else + { + Group + } + } + + } + + + @if (resizable) + { +
    + } + + @if (filterable && DataGrid.FilterMode == DataGridFilterMode.ColumnFilterMenu) + { + + + @if (Column.FilterTemplate != null) + { + @Column.FilterTemplate(Column.filterContext) + } + else + { + + + @DataGrid.Filter(Column.filterContext.FilterDefinition, Column) + + + + + + + } + + } + +} \ No newline at end of file diff --git a/Components/DataGrid/HeaderCell.razor.cs b/Components/DataGrid/HeaderCell.razor.cs new file mode 100644 index 0000000..bd85f98 --- /dev/null +++ b/Components/DataGrid/HeaderCell.razor.cs @@ -0,0 +1,421 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class HeaderCell : UIComponent, IDisposable +{ + [CascadingParameter] public DataGrid DataGrid { get; set; } + [CascadingParameter(Name = "IsOnlyHeader")] public bool IsOnlyHeader { get; set; } = false; + + [Parameter] public Column Column { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } + + private SortDirection _initialDirection; + private Type _dataType; + private bool _isSelected; + + [Parameter] + public SortDirection SortDirection + { + get => _initialDirection; + set + { + _initialDirection = value; + } + } + + private string _classname => + new CssBuilder(Column?.HeaderClass) + .AddClass(Column?.headerClassname) + .AddClass(Class) + .Build(); + + private string _style => + new StyleBuilder() + .AddStyle(Column?.HeaderStyle) + .AddStyle("width", _width?.ToPx(), when: _width.HasValue) + .AddStyle(Style) + .Build(); + + private string _resizerStyle => + new StyleBuilder() + .AddStyle("height", _resizerHeight?.ToPx() ?? "100%") + .AddStyle(Style) + .Build(); + + private string _resizerClass => + new CssBuilder() + .AddClass("mud-resizing", when: _isResizing) + .AddClass("mud-resizer") + .Build(); + + private string _sortHeaderClass => + new CssBuilder() + .AddClass("sortable-column-header") + .AddClass("cursor-pointer", when: !_isResizing) + .Build(); + + private string _optionsClass => + new CssBuilder() + .AddClass("column-options") + .AddClass("cursor-pointer", when: !_isResizing) + .Build(); + + private ElementReference _headerElement; + + private double? _width; + private double? _resizerHeight; + private bool _isResizing; + private bool _filtersMenuVisible; + + #region Computed Properties and Functions + + private string computedTitle + { + get + { + return Column.Title ?? Column.Field; + } + } + + private bool sortable + { + get + { + return Column?.Sortable ?? DataGrid?.SortMode != SortMode.None; + } + } + + private bool resizable + { + get + { + return Column?.Resizable ?? DataGrid.ColumnResizeMode != ResizeMode.None; + } + } + + private bool filterable + { + get + { + return Column?.Filterable ?? DataGrid?.Filterable ?? true; + } + } + + private bool showFilterIcon + { + get + { + if (!filterable) + return false; + + return Column?.ShowFilterIcon ?? DataGrid?.ShowFilterIcons ?? true; + } + } + + private bool hideable + { + get + { + return Column?.Hideable ?? DataGrid?.Hideable ?? false; + } + } + + private bool groupable + { + get + { + return Column?.Groupable ?? DataGrid?.Groupable ?? false; + } + } + + private bool showColumnOptions + { + get + { + if (!sortable && !filterable && !groupable) + return false; + + return Column?.ShowColumnOptions ?? DataGrid?.ShowColumnOptions ?? true; + } + } + + private string sortIconClass + { + get + { + if (_initialDirection == SortDirection.Descending) + { + return "sort-direction-icon mud-direction-desc"; + } + else if (_initialDirection == SortDirection.Ascending) + { + return "sort-direction-icon mud-direction-asc"; + } + else + { + return "sort-direction-icon"; + } + } + } + + private bool hasFilter + { + get + { + if (DataGrid == null) + return false; + + return DataGrid.FilterDefinitions.Any(x => x.Field == Column.Field && x.Operator != null && x.Value != null); + } + } + + #endregion + + protected override async Task OnInitializedAsync() + { + _initialDirection = Column?.InitialDirection ?? SortDirection.None; + + if (_initialDirection != SortDirection.None) + { + // set initial sort + await InvokeAsync(() => DataGrid.ExtendSortAsync(Column.Field, _initialDirection, Column.GetLocalSortFunc())); + } + + if (DataGrid != null) + { + DataGrid.SortChangedEvent += OnGridSortChanged; + DataGrid.SelectedAllItemsChangedEvent += OnSelectedAllItemsChanged; + DataGrid.SelectedItemsChangedEvent += OnSelectedItemsChanged; + } + + if (null != Column) + { + Column.HeaderCell = this; + + if (Column.filterable) + { + Column.filterContext._headerCell = this; + } + } + } + + internal void GetDataType() + { + var p = typeof(T).GetProperty(Column?.Field); + _dataType = p.GetType(); + } + + #region Events + + /// + /// This is triggered by the DataGrid when a sort is applied + /// e.g. from another HeaderCell. + /// + /// The active sorts. + /// The removed sorts. + private void OnGridSortChanged(Dictionary> activeSorts, HashSet removedSorts) + { + if ((Column.Sortable.HasValue && !Column.Sortable.Value) || string.IsNullOrWhiteSpace(Column.Field)) + return; + + if (null != removedSorts && removedSorts.Contains(Column.Field)) + MarkAsUnsorted(); + else if (activeSorts.TryGetValue(Column.Field, out var sortDefinition)) + Column.SortIndex = sortDefinition.Index; + } + + private void OnSelectedAllItemsChanged(bool value) + { + _isSelected = value; + StateHasChanged(); + } + + private void OnSelectedItemsChanged(HashSet items) + { + _isSelected = items.Count == DataGrid.GetFilteredItemsCount(); + StateHasChanged(); + } + + private async Task OnResizerMouseDown(MouseEventArgs args) + { + if (!resizable) + return; + + if (args.Detail > 1) // Double click clears the width, hence setting it to minimum size. + { + _width = null; + return; + } + + _isResizing = await DataGrid.StartResizeColumn(this, args.ClientX); + } + + private async Task OnResizerMouseOver() + { + if (!_isResizing) + _resizerHeight = await DataGrid?.GetActualHeight(); + } + + private void OnResizerMouseLeave() + { + if (!_isResizing) + _resizerHeight = null; + } + + internal async Task UpdateColumnWidth(double targetWidth, double gridHeight, bool finishResize) + { + if (targetWidth > 0) + { + _resizerHeight = gridHeight; + _width = targetWidth; + if (finishResize) + { + _isResizing = false; + } + + await InvokeAsync(StateHasChanged); + } + + return await GetCurrentCellWidth(); + } + + internal async Task GetCurrentCellWidth() + { + var boundingRect = await _headerElement.MudGetBoundingClientRectAsync(); + return boundingRect.Width; + } + + internal async Task SortChangedAsync(MouseEventArgs args) + { + if (args.AltKey) + { + if (_initialDirection != SortDirection.None) + await RemoveSortAsync(); + + return; + } + + _initialDirection = _initialDirection switch + { + SortDirection.Ascending => SortDirection.Descending, + _ => SortDirection.Ascending + }; + + if (args.CtrlKey && DataGrid.SortMode == SortMode.Multiple) + await InvokeAsync(() => DataGrid.ExtendSortAsync(Column.Field, _initialDirection, Column.GetLocalSortFunc())); + else + await InvokeAsync(() => DataGrid.SetSortAsync(Column.Field, _initialDirection, Column.GetLocalSortFunc())); + } + + internal async Task RemoveSortAsync() + { + await InvokeAsync(() => DataGrid.RemoveSortAsync(Column.Field)); + MarkAsUnsorted(); + } + + internal void AddFilter() + { + if (DataGrid.FilterMode == DataGridFilterMode.Simple) + DataGrid.AddFilter(Guid.NewGuid(), Column?.Field); + else if (DataGrid.FilterMode == DataGridFilterMode.ColumnFilterMenu) + _filtersMenuVisible = true; + } + + internal void OpenFilters() + { + if (DataGrid.FilterMode == DataGridFilterMode.Simple) + DataGrid.OpenFilters(); + else if (DataGrid.FilterMode == DataGridFilterMode.ColumnFilterMenu) + _filtersMenuVisible = true; + } + + internal void ApplyFilter() + { + DataGrid.FilterDefinitions.Add(Column.filterContext.FilterDefinition); + DataGrid.ExternalStateHasChanged(); + _filtersMenuVisible = false; + } + + internal void ApplyFilter(FilterDefinition filterDefinition) + { + DataGrid.FilterDefinitions.Add(filterDefinition); + DataGrid.ExternalStateHasChanged(); + _filtersMenuVisible = false; + } + + internal void ApplyFilters(IEnumerable> filterDefinitions) + { + DataGrid.FilterDefinitions.AddRange(filterDefinitions); + DataGrid.ExternalStateHasChanged(); + _filtersMenuVisible = false; + } + + internal void ClearFilter() + { + DataGrid.RemoveFilter(Column.filterContext.FilterDefinition.Id); + Column.filterContext.FilterDefinition.Value = null; + _filtersMenuVisible = false; + } + + internal void ClearFilter(FilterDefinition filterDefinition) + { + DataGrid.RemoveFilter(filterDefinition.Id); + _filtersMenuVisible = false; + } + + internal void ClearFilters(IEnumerable> filterDefinitions) + { + DataGrid.FilterDefinitions.RemoveAll(x => filterDefinitions.Any(y => y.Id == x.Id)); + DataGrid.ExternalStateHasChanged(); + _filtersMenuVisible = false; + } + + private async Task CheckedChangedAsync(bool value) + { + await DataGrid?.SetSelectAllAsync(value); + } + + internal async Task HideColumnAsync() + { + if (Column != null) + { + await Column.HideAsync(); + DataGrid.ExternalStateHasChanged(); + } + } + + internal void GroupColumn() + { + Column?.SetGrouping(true); + } + + internal void UngroupColumn() + { + Column?.SetGrouping(false); + } + + private void MarkAsUnsorted() + { + _initialDirection = SortDirection.None; + Column.SortIndex = -1; + } + + #endregion + + public void Dispose() + { + if (DataGrid != null) + { + DataGrid.SortChangedEvent -= OnGridSortChanged; + DataGrid.SelectedAllItemsChangedEvent -= OnSelectedAllItemsChanged; + DataGrid.SelectedItemsChangedEvent -= OnSelectedItemsChanged; + } + } +} diff --git a/Components/DataGrid/HeaderContext.cs b/Components/DataGrid/HeaderContext.cs new file mode 100644 index 0000000..0abbe6e --- /dev/null +++ b/Components/DataGrid/HeaderContext.cs @@ -0,0 +1,46 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class HeaderContext +{ + internal DataGrid _dataGrid; + public IEnumerable Items + { + get + { + return _dataGrid.Items; + } + } + public HeaderActions Actions { get; internal set; } + public bool IsAllSelected + { + get + { + + if (_dataGrid.Selection != null && Items != null) + { + return _dataGrid.Selection.Count == Items.Count(); + } + + return false; + } + } + + public HeaderContext(DataGrid dataGrid) + { + _dataGrid = dataGrid; + Actions = new HeaderContext.HeaderActions + { + SetSelectAll = async (x) => await _dataGrid.SetSelectAllAsync(x), + }; + + } + + public class HeaderActions + { + public Action SetSelectAll { get; internal set; } + } +} diff --git a/Components/DataGrid/HierarchyColumn.razor b/Components/DataGrid/HierarchyColumn.razor new file mode 100644 index 0000000..0a4b704 --- /dev/null +++ b/Components/DataGrid/HierarchyColumn.razor @@ -0,0 +1,23 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + + + + + + +@code { + [Parameter] public string ClosedIcon { get; set; } = Icons.Material.Filled.ChevronRight; + [Parameter] public string OpenIcon { get; set; } = Icons.Material.Filled.ExpandMore; + [Parameter] public Size IconSize { get; set; } = Size.Medium; + [Parameter] public Func ButtonDisabledFunc { get; set; } = x => false; +} \ No newline at end of file diff --git a/Components/DataGrid/Row.razor b/Components/DataGrid/Row.razor new file mode 100644 index 0000000..27fa32b --- /dev/null +++ b/Components/DataGrid/Row.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + \ No newline at end of file diff --git a/Components/DataGrid/Row.razor.cs b/Components/DataGrid/Row.razor.cs new file mode 100644 index 0000000..bfc3acc --- /dev/null +++ b/Components/DataGrid/Row.razor.cs @@ -0,0 +1,16 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Row : UIComponent +{ + [Parameter] public RenderFragment ChildContent { get; set; } + + protected string Classname => new CssBuilder("mud-table-row") + .AddClass(Class).Build(); +} diff --git a/Components/DataGrid/SelectColumn.razor b/Components/DataGrid/SelectColumn.razor new file mode 100644 index 0000000..0f1f54a --- /dev/null +++ b/Components/DataGrid/SelectColumn.razor @@ -0,0 +1,28 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + + + @if (ShowInHeader) + { + + } + + + + + + @if (ShowInFooter) + { + + } + + + +@code { + [Parameter] public bool ShowInHeader { get; set; } = true; + [Parameter] public bool ShowInFooter { get; set; } = true; + [Parameter] public Size Size { get; set; } = Size.Medium; +} \ No newline at end of file diff --git a/Components/DataGrid/SortDefinition.cs b/Components/DataGrid/SortDefinition.cs new file mode 100644 index 0000000..0b2837e --- /dev/null +++ b/Components/DataGrid/SortDefinition.cs @@ -0,0 +1,7 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public sealed record SortDefinition(string SortBy, bool Descending, int Index, Func SortFunc); diff --git a/Components/DatePicker/DatePicker.cs b/Components/DatePicker/DatePicker.cs new file mode 100644 index 0000000..cc05db5 --- /dev/null +++ b/Components/DatePicker/DatePicker.cs @@ -0,0 +1,313 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public class DatePicker : DatePickerBase +{ + private DateTime? _selectedDate; + + /// + /// Fired when the DateFormat changes. + /// + [Parameter] public EventCallback DateChanged { get; set; } + + /// + /// The currently selected date (two-way bindable). If null, then nothing was selected. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public DateTime? Date + { + get => _value; + set => SetDateAsync(value, true).AndForget(); + } + + protected async Task SetDateAsync(DateTime? date, bool updateValue) + { + if (_value != date) + { + Touched = true; + + if (date is not null && IsDateDisabledFunc(date.Value.Date)) + { + await SetTextAsync(null, false); + return; + } + + _value = date; + if (updateValue) + { + Converter.GetError = false; + await SetTextAsync(Converter.Set(_value), false); + } + await DateChanged.InvokeAsync(_value); + BeginValidate(); + FieldChanged(_value); + } + } + + protected override Task DateFormatChanged(string newFormat) + { + Touched = true; + return SetTextAsync(Converter.Set(_value), false); + } + + protected override Task StringValueChanged(string value) + { + Touched = true; + // Update the date property (without updating back the Value property) + return SetDateAsync(Converter.Get(value), false); + } + + protected override string GetDayClasses(int month, DateTime day) + { + var b = new CssBuilder("mud-day"); + b.AddClass(AdditionalDateClassesFunc?.Invoke(day) ?? string.Empty); + if (day < GetMonthStart(month) || day > GetMonthEnd(month)) + return b.AddClass("mud-hidden").Build(); + if ((Date?.Date == day && _selectedDate == null) || _selectedDate?.Date == day) + return b.AddClass("mud-selected").AddClass($"mud-theme-{Color.ToDescriptionString()}").Build(); + if (day == DateTime.Today) + return b.AddClass("mud-current mud-button-outlined").AddClass($"mud-button-outlined-{Color.ToDescriptionString()} mud-{Color.ToDescriptionString()}-text").Build(); + return b.Build(); + } + + protected override async void OnDayClicked(DateTime dateTime) + { + _selectedDate = dateTime; + if (PickerActions == null || AutoClose || PickerVariant == PickerVariant.Static) + { + Submit(); + + if (PickerVariant != PickerVariant.Static) + { + await Task.Delay(ClosingDelay); + Close(false); + } + } + } + + /// + /// user clicked on a month + /// + /// + protected override void OnMonthSelected(DateTime month) + { + PickerMonth = month; + var nextView = GetNextView(); + if (nextView == null) + { + _selectedDate = _selectedDate.HasValue ? + //everything has to be set because a value could already defined -> fix values can be ignored as they are set in submit anyway + new DateTime(month.Year, month.Month, _selectedDate.Value.Day, _selectedDate.Value.Hour, _selectedDate.Value.Minute, _selectedDate.Value.Second, _selectedDate.Value.Millisecond, _selectedDate.Value.Kind) + //We can assume day here, as it was not set yet. If a fix value is set, it will be overriden in Submit + : new DateTime(month.Year, month.Month, 1); + SubmitAndClose(); + } + else + { + CurrentView = (OpenTo)nextView; + } + } + + /// + /// user clicked on a year + /// + /// + protected override void OnYearClicked(int year) + { + var current = GetMonthStart(0); + PickerMonth = new DateTime(year, current.Month, 1); + var nextView = GetNextView(); + if (nextView == null) + { + _selectedDate = _selectedDate.HasValue ? + //everything has to be set because a value could already defined -> fix values can be ignored as they are set in submit anyway + new DateTime(_selectedDate.Value.Year, _selectedDate.Value.Month, _selectedDate.Value.Day, _selectedDate.Value.Hour, _selectedDate.Value.Minute, _selectedDate.Value.Second, _selectedDate.Value.Millisecond, _selectedDate.Value.Kind) + //We can assume month and day here, as they were not set yet + : new DateTime(year, 1, 1); + SubmitAndClose(); + } + else + { + CurrentView = (OpenTo)nextView; + } + } + + protected override void OnOpened() + { + _selectedDate = null; + + base.OnOpened(); + } + + protected internal override async void Submit() + { + if (ReadOnly) + return; + if (_selectedDate == null) + return; + + if (FixYear.HasValue || FixMonth.HasValue || FixDay.HasValue) + _selectedDate = new DateTime(FixYear ?? _selectedDate.Value.Year, + FixMonth ?? _selectedDate.Value.Month, + FixDay ?? _selectedDate.Value.Day, + _selectedDate.Value.Hour, + _selectedDate.Value.Minute, + _selectedDate.Value.Second, + _selectedDate.Value.Millisecond); + + await SetDateAsync(_selectedDate, true); + _selectedDate = null; + } + + public override async void Clear(bool close = true) + { + _selectedDate = null; + await SetDateAsync(null, true); + + if (AutoClose == true) + { + Close(false); + } + } + + protected override string GetTitleDateString() + { + return FormatTitleDate(_selectedDate ?? Date); + } + + protected override DateTime GetCalendarStartOfMonth() + { + var date = StartMonth ?? Date ?? DateTime.Today; + return date.StartOfMonth(Culture); + } + + protected override int GetCalendarYear(int year) + { + var date = Date ?? DateTime.Today; + var diff = date.Year - year; + var calenderYear = Culture.Calendar.GetYear(date); + return calenderYear - diff; + } + + //To be completed on next PR + protected internal override void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + base.HandleKeyDown(obj); + switch (obj.Key) + { + case "ArrowRight": + if (IsOpen) + { + + } + break; + case "ArrowLeft": + if (IsOpen) + { + + } + break; + case "ArrowUp": + if (IsOpen == false && Editable == false) + { + IsOpen = true; + } + else if (obj.AltKey == true) + { + IsOpen = false; + } + else if (obj.ShiftKey == true) + { + + } + else + { + + } + break; + case "ArrowDown": + if (IsOpen == false && Editable == false) + { + IsOpen = true; + } + else if (obj.ShiftKey == true) + { + + } + else + { + + } + break; + case "Escape": + ReturnDateBackUp(); + break; + case "Enter": + case "NumpadEnter": + if (!IsOpen) + { + Open(); + } + else + { + Submit(); + Close(); + _inputReference?.SetText(Text); + } + break; + case " ": + if (!Editable) + { + if (!IsOpen) + { + Open(); + } + else + { + Submit(); + Close(); + _inputReference?.SetText(Text); + } + } + break; + } + } + + private void ReturnDateBackUp() + { + Close(); + } + + /// + /// Scrolls to the date. + /// + public void GoToDate() + { + if (Date.HasValue) + { + PickerMonth = new DateTime(Date.Value.Year, Date.Value.Month, 1); + ScrollToYear(); + } + } + + /// + /// Scrolls to the defined date. + /// + public async Task GoToDate(DateTime date, bool submitDate = true) + { + PickerMonth = new DateTime(date.Year, date.Month, 1); + if (submitDate) + { + await SetDateAsync(date, true); + ScrollToYear(); + } + } +} diff --git a/Components/DatePicker/DatePickerBase.razor b/Components/DatePicker/DatePickerBase.razor new file mode 100644 index 0000000..fd3c4f1 --- /dev/null +++ b/Components/DatePicker/DatePickerBase.razor @@ -0,0 +1,152 @@ +@namespace Connected.Components +@inherits Picker + +@Render + +@code { + + protected override RenderFragment PickerContent => + @ + + + + + +
    + @{ + int dayId = 0; + @if (_picker_month.HasValue && _picker_month.Value.Year == 1 && _picker_month.Value.Month == 1) + { + dayId = -1; + } + } + @for (int displayMonth = 0; displayMonth < DisplayMonths; ++displayMonth) + { + int tempMonth = displayMonth; //without local variable month names are wrong + +
    + @if (tempMonth == 0 && CurrentView == OpenTo.Year) + { +
    + @for (int i = GetMinYear(); i <= GetMaxYear(); i++) + { + var year = i; +
    + @GetCalendarYear(year) +
    + } +
    + } + else if (tempMonth == 0 && CurrentView == OpenTo.Month) + { + var calendarYear = GetCalendarYear(PickerMonth?.Year ?? DateTime.Today.Year); + var prevLabel = $"Go to previous year {calendarYear - 1}"; + var nextLabel = $"Go to next year {calendarYear + 1}"; + +
    +
    + @if (!FixYear.HasValue) + { + + + + } + else + { + @calendarYear + } +
    +
    +
    + @foreach (var month in GetAllMonths()) + { + + } +
    + } + else if (CurrentView == OpenTo.Date || tempMonth > 0) + { + var prevLabel = $"Go to previous month {GetMonthName((tempMonth - 1) % 12)}"; + var nextLabel = $"Go to next month {GetMonthName((tempMonth + 1) % 12)}"; + +
    +
    + @if (!FixMonth.HasValue) + { + + + + } + else + { + @GetMonthName(tempMonth) + } +
    +
    + @if (ShowWeekNumbers) + { +
    + +
    + } + @foreach (var dayname in GetAbbreviatedDayNames()) + { + @dayname + } +
    +
    +
    +
    + @for (int week = 0; week < 6; week++) + { + int tempWeek = week; + var firstMonthFirstYear = _picker_month.HasValue && _picker_month.Value.Year == 1 && _picker_month.Value.Month == 1; + + @if (ShowWeekNumbers) + { +
    + @GetWeekNumber(tempMonth, tempWeek) +
    + } + @foreach (var day in GetWeek(tempMonth, tempWeek)) + { + var tempId = ++dayId; + + @if (tempId != 0 || !firstMonthFirstYear) + { + var selectedDay = !firstMonthFirstYear ? day : day.AddDays(-1); + + } + else + { + + } + } + } +
    +
    + } +
    + } +
    +
    +
    ; +} \ No newline at end of file diff --git a/Components/DatePicker/DatePickerBase.razor.cs b/Components/DatePicker/DatePickerBase.razor.cs new file mode 100644 index 0000000..f9eef35 --- /dev/null +++ b/Components/DatePicker/DatePickerBase.razor.cs @@ -0,0 +1,600 @@ +using System.Globalization; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public abstract partial class DatePickerBase : Picker +{ + private bool _dateFormatTouched; + + protected DatePickerBase() : base(new DefaultConverter + { + Format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern, + Culture = CultureInfo.CurrentCulture + }) + { + AdornmentAriaLabel = "Open Date Picker"; + } + + [Inject] protected IScrollManager ScrollManager { get; set; } + + /// + /// Max selectable date. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public DateTime? MaxDate { get; set; } + + /// + /// Min selectable date. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public DateTime? MinDate { get; set; } + + /// + /// First view to show in the MudDatePicker. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public OpenTo OpenTo { get; set; } = OpenTo.Date; + + /// + /// String Format for selected date view + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string DateFormat + { + get + { + return (Converter as DefaultConverter)?.Format; + } + set + { + if (Converter is DefaultConverter defaultConverter) + { + defaultConverter.Format = value; + _dateFormatTouched = true; + } + DateFormatChanged(value); + } + } + + /// + /// Date format value change hook for descendants. + /// + protected virtual Task DateFormatChanged(string newFormat) + { + return Task.CompletedTask; + } + + protected override bool SetCulture(CultureInfo value) + { + if (!base.SetCulture(value)) + return false; + + if (!_dateFormatTouched && Converter is DefaultConverter defaultConverter) + defaultConverter.Format = value.DateTimeFormat.ShortDatePattern; + + return true; + } + + /// + /// Defines on which day the week starts. Depends on the value of Culture. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public DayOfWeek? FirstDayOfWeek { get; set; } = null; + + /// + /// The current month of the date picker (two-way bindable). This changes when the user browses through the calender. + /// The month is represented as a DateTime which is always the first day of that month. You can also set this to define which month is initially shown. If not set, the current month is shown. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public DateTime? PickerMonth + { + get => _picker_month; + set + { + if (value == _picker_month) + return; + _picker_month = value; + InvokeAsync(StateHasChanged); + PickerMonthChanged.InvokeAsync(value); + } + } + + private DateTime? _picker_month; + + /// + /// Fired when the date changes. + /// + [Parameter] public EventCallback PickerMonthChanged { get; set; } + + /// + /// Sets the amount of time in milliseconds to wait before closing the picker. This helps the user see that the date was selected before the popover disappears. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int ClosingDelay { get; set; } = 100; + + /// + /// Number of months to display in the calendar + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int DisplayMonths { get; set; } = 1; + + /// + /// Maximum number of months in one row + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public int? MaxMonthColumns { get; set; } + + /// + /// Start month when opening the picker. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public DateTime? StartMonth { get; set; } + + /// + /// Display week numbers according to the Culture parameter. If no culture is defined, CultureInfo.CurrentCulture will be used. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool ShowWeekNumbers { get; set; } + + /// + /// Format of the selected date in the title. By default, this is "ddd, dd MMM" which abbreviates day and month names. + /// For instance, display the long names like this "dddd, dd. MMMM". + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public string TitleDateFormat { get; set; } = "ddd, dd MMM"; + + /// + /// If AutoClose is set to true and PickerActions are defined, selecting a day will close the MudDatePicker. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool AutoClose { get; set; } + + /// + /// Function to determine whether a date is disabled + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public Func IsDateDisabledFunc + { + get => _isDateDisabledFunc; + set + { + _isDateDisabledFunc = value ?? (_ => false); + } + } + private Func _isDateDisabledFunc = _ => false; + + /// + /// Function to conditionally apply new classes to specific days + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Func AdditionalDateClassesFunc { get; set; } + + /// + /// Custom previous icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string PreviousIcon { get; set; } = Icons.Material.Filled.ChevronLeft; + + /// + /// Custom next icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string NextIcon { get; set; } = Icons.Material.Filled.ChevronRight; + + /// + /// Set a predefined fix year - no year can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int? FixYear { get; set; } + /// + /// Set a predefined fix month - no month can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int? FixMonth { get; set; } + /// + /// Set a predefined fix day - no day can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int? FixDay { get; set; } + + protected virtual bool IsRange { get; } = false; + + protected OpenTo CurrentView; + + protected override void OnPickerOpened() + { + base.OnPickerOpened(); + if (Editable == true && Text != null) + { + DateTime? a = Converter.Get(Text); + if (a.HasValue) + { + a = new DateTime(a.Value.Year, a.Value.Month, 1); + PickerMonth = a; + } + } + if (OpenTo == OpenTo.Date && FixDay.HasValue) + { + OpenTo = OpenTo.Month; + } + if (OpenTo == OpenTo.Date && FixDay.HasValue && FixMonth.HasValue) + { + OpenTo = OpenTo.Year; + } + CurrentView = OpenTo; + if (CurrentView == OpenTo.Year) + _scrollToYearAfterRender = true; + } + + /// + /// Get the first of the month to display + /// + /// + protected DateTime GetMonthStart(int month) + { + var monthStartDate = _picker_month ?? DateTime.Today.StartOfMonth(Culture); + // Return the min supported datetime of the calendar when this is year 1 and first month! + if (_picker_month.HasValue && _picker_month.Value.Year == 1 && _picker_month.Value.Month == 1) + { + return Culture.Calendar.MinSupportedDateTime; + } + return Culture.Calendar.AddMonths(monthStartDate, month); + } + + /// + /// Get the last of the month to display + /// + /// + protected DateTime GetMonthEnd(int month) + { + var monthStartDate = _picker_month ?? DateTime.Today.StartOfMonth(Culture); + return Culture.Calendar.AddMonths(monthStartDate, month).EndOfMonth(Culture); + } + + protected DayOfWeek GetFirstDayOfWeek() + { + if (FirstDayOfWeek.HasValue) + return FirstDayOfWeek.Value; + return Culture.DateTimeFormat.FirstDayOfWeek; + } + + /// + /// Gets the n-th week of the currently displayed month. + /// + /// offset from _picker_month + /// between 0 and 4 + /// + protected IEnumerable GetWeek(int month, int index) + { + if (index is < 0 or > 5) + throw new ArgumentException("Index must be between 0 and 5"); + var month_first = GetMonthStart(month); + var week_first = month_first.AddDays(index * 7).StartOfWeek(GetFirstDayOfWeek()); + for (var i = 0; i < 7; i++) + yield return week_first.AddDays(i); + } + + private string GetWeekNumber(int month, int index) + { + if (index is < 0 or > 5) + throw new ArgumentException("Index must be between 0 and 5"); + var month_first = GetMonthStart(month); + var week_first = month_first.AddDays(index * 7).StartOfWeek(GetFirstDayOfWeek()); + //january 1st + if (month_first.Month == 1 && index == 0) + { + week_first = month_first; + } + + if (week_first.Month != month_first.Month && week_first.AddDays(6).Month != month_first.Month) + return ""; + + return Culture.Calendar.GetWeekOfYear(week_first, + Culture.DateTimeFormat.CalendarWeekRule, FirstDayOfWeek ?? Culture.DateTimeFormat.FirstDayOfWeek).ToString(); + } + + protected virtual OpenTo? GetNextView() + { + OpenTo? nextView = CurrentView switch + { + OpenTo.Year => !FixMonth.HasValue ? OpenTo.Month : !FixDay.HasValue ? OpenTo.Date : null, + OpenTo.Month => !FixDay.HasValue ? OpenTo.Date : null, + _ => null, + }; + return nextView; + } + + protected virtual async void SubmitAndClose() + { + if (PickerActions == null) + { + Submit(); + + if (PickerVariant != PickerVariant.Static) + { + await Task.Delay(ClosingDelay); + Close(false); + } + } + } + + protected abstract string GetDayClasses(int month, DateTime day); + + /// + /// User clicked on a day + /// + protected abstract void OnDayClicked(DateTime dateTime); + + /// + /// user clicked on a month + /// + /// + protected virtual void OnMonthSelected(DateTime month) + { + PickerMonth = month; + var nextView = GetNextView(); + if (nextView != null) + { + CurrentView = (OpenTo)nextView; + } + } + + /// + /// user clicked on a year + /// + /// + protected virtual void OnYearClicked(int year) + { + var current = GetMonthStart(0); + PickerMonth = new DateTime(year, current.Month, 1); + var nextView = GetNextView(); + if (nextView != null) + { + CurrentView = (OpenTo)nextView; + } + } + + /// + /// user clicked on a month + /// + protected virtual void OnMonthClicked(int month) + { + CurrentView = OpenTo.Month; + _picker_month = _picker_month?.AddMonths(month); + StateHasChanged(); + } + + /// + /// return Mo, Tu, We, Th, Fr, Sa, Su in the right culture + /// + /// + protected IEnumerable GetAbbreviatedDayNames() + { + var dayNamesNormal = Culture.DateTimeFormat.AbbreviatedDayNames; + var dayNamesShifted = Shift(dayNamesNormal, (int)GetFirstDayOfWeek()); + return dayNamesShifted; + } + + /// + /// Shift array and cycle around from the end + /// + private static T[] Shift(T[] array, int positions) + { + var copy = new T[array.Length]; + Array.Copy(array, 0, copy, array.Length - positions, positions); + Array.Copy(array, positions, copy, 0, array.Length - positions); + return copy; + } + + protected string GetMonthName(int month) + { + return GetMonthStart(month).ToString(Culture.DateTimeFormat.YearMonthPattern, Culture); + } + + protected abstract string GetTitleDateString(); + + protected string FormatTitleDate(DateTime? date) + { + return date?.ToString(TitleDateFormat ?? "ddd, dd MMM", Culture) ?? ""; + } + + protected string GetFormattedYearString() + { + return GetMonthStart(0).ToString("yyyy", Culture); + } + + private void OnPreviousMonthClick() + { + // It is impossible to go further into the past after the first year and the first month! + if (PickerMonth.HasValue && PickerMonth.Value.Year == 1 && PickerMonth.Value.Month == 1) + { + return; + } + PickerMonth = GetMonthStart(0).AddDays(-1).StartOfMonth(Culture); + } + + private void OnNextMonthClick() + { + PickerMonth = GetMonthEnd(0).AddDays(1); + } + + private void OnPreviousYearClick() + { + PickerMonth = GetMonthStart(0).AddYears(-1); + } + + private void OnNextYearClick() + { + PickerMonth = GetMonthStart(0).AddYears(1); + } + + private void OnYearClick() + { + if (!FixYear.HasValue) + { + CurrentView = OpenTo.Year; + StateHasChanged(); + _scrollToYearAfterRender = true; + } + } + + /// + /// We need a random id for the year items in the year list so we can scroll to the item safely in every DatePicker. + /// + private string _componentId = Guid.NewGuid().ToString(); + + /// + /// Is set to true to scroll to the actual year after the next render + /// + private bool _scrollToYearAfterRender = false; + + public async void ScrollToYear() + { + _scrollToYearAfterRender = false; + var id = $"{_componentId}{GetMonthStart(0).Year}"; + await ScrollManager.ScrollToYearAsync(id); + StateHasChanged(); + } + + private int GetMinYear() + { + if (MinDate.HasValue) + return MinDate.Value.Year; + return DateTime.Today.Year - 100; + } + + private int GetMaxYear() + { + if (MaxDate.HasValue) + return MaxDate.Value.Year; + return DateTime.Today.Year + 100; + } + + private string GetYearClasses(int year) + { + if (year == GetMonthStart(0).Year) + return $"mud-picker-year-selected mud-{Color.ToDescriptionString()}-text"; + return null; + } + + private string GetCalendarHeaderClasses(int month) + { + return new CssBuilder("mud-picker-calendar-header") + .AddClass($"mud-picker-calendar-header-{month + 1}") + .AddClass($"mud-picker-calendar-header-last", month == DisplayMonths - 1) + .Build(); + } + + private Typo GetYearTypo(int year) + { + if (year == GetMonthStart(0).Year) + return Typo.h5; + return Typo.subtitle1; + } + + private void OnFormattedDateClick() + { + // todo: raise an event the user can handle + } + + + private IEnumerable GetAllMonths() + { + var current = GetMonthStart(0); + var calendarYear = Culture.Calendar.GetYear(current); + var firstOfCalendarYear = Culture.Calendar.ToDateTime(calendarYear, 1, 1, 0, 0, 0, 0); + for (var i = 0; i < Culture.Calendar.GetMonthsInYear(calendarYear); i++) + yield return Culture.Calendar.AddMonths(firstOfCalendarYear, i); + } + + private string GetAbbreviatedMonthName(DateTime month) + { + var calendarMonth = Culture.Calendar.GetMonth(month); + return Culture.DateTimeFormat.AbbreviatedMonthNames[calendarMonth - 1]; + } + + private string GetMonthName(DateTime month) + { + var calendarMonth = Culture.Calendar.GetMonth(month); + return Culture.DateTimeFormat.MonthNames[calendarMonth - 1]; + } + + private string GetMonthClasses(DateTime month) + { + if (GetMonthStart(0) == month) + return $"mud-picker-month-selected mud-{Color.ToDescriptionString()}-text"; + return null; + } + + private Typo GetMonthTypo(DateTime month) + { + if (GetMonthStart(0) == month) + return Typo.h5; + return Typo.subtitle1; + } + + + + protected override void OnInitialized() + { + base.OnInitialized(); + CurrentView = OpenTo; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender) + { + _picker_month ??= GetCalendarStartOfMonth(); + } + + if (firstRender && CurrentView == OpenTo.Year) + { + ScrollToYear(); + return; + } + + if (_scrollToYearAfterRender) + ScrollToYear(); + } + + protected abstract DateTime GetCalendarStartOfMonth(); + + private int GetCalendarDayOfMonth(DateTime date) + { + return Culture.Calendar.GetDayOfMonth(date); + } + + /// + /// Converts gregorian year into whatever year it is in the provided culture + /// + /// Gregorian year + /// Year according to culture + protected abstract int GetCalendarYear(int year); +} diff --git a/Components/DatePicker/DateRange.cs b/Components/DatePicker/DateRange.cs new file mode 100644 index 0000000..fbae1b3 --- /dev/null +++ b/Components/DatePicker/DateRange.cs @@ -0,0 +1,71 @@ +namespace Connected.Components; + +public class DateRange : Range, IEquatable +{ + public DateRange() : base(null, null) + { + } + + public DateRange(DateTime? start, DateTime? end) : base(start, end) + { + } + + public string ToString(Converter converter) + { + if (Start == null || End == null) + return string.Empty; + + return RangeConverter.Join(converter.Set(Start.Value), converter.Set(End.Value)); + } + + public string ToIsoDateString() + { + if (Start == null || End == null) + return string.Empty; + + return RangeConverter.Join(Start.ToIsoDateString(), End.ToIsoDateString()); + } + + public static bool TryParse(string value, Converter converter, out DateRange date) + { + date = null; + + if (!RangeConverter.Split(value, out var start, out var end)) + return false; + + return TryParse(start, end, converter, out date); + } + + public static bool TryParse(string start, string end, Converter converter, out DateRange date) + { + date = null; + + var endDate = converter.Get(end); + if (converter.GetError) + return false; + + var startDate = converter.Get(start); + if (converter.GetError) + return false; + + date = new DateRange(startDate, endDate); + return true; + } + + public override int GetHashCode() => HashCode.Combine(Start, End); + public override bool Equals(object obj) => Equals(obj as DateRange); + + public bool Equals(DateRange other) => other != null && Start == other.Start && End == other.End; + + public static bool operator ==(DateRange dateRange1, DateRange dateRange2) + { + if (ReferenceEquals(dateRange1, dateRange2)) + return true; + if (dateRange1 is null || dateRange2 is null) + return false; + + return dateRange1.Equals(dateRange2); + } + + public static bool operator !=(DateRange dateRange1, DateRange dateRange2) => !(dateRange1 == dateRange2); +} diff --git a/Components/DatePicker/DateRangePicker.razor b/Components/DatePicker/DateRangePicker.razor new file mode 100644 index 0000000..e5f0e3e --- /dev/null +++ b/Components/DatePicker/DateRangePicker.razor @@ -0,0 +1,19 @@ +@namespace Connected.Components +@inherits DatePickerBase + +@Render + +@code{ + + protected override RenderFragment InputContent=> + @ + + + + ; + +} diff --git a/Components/DatePicker/DateRangePicker.razor.cs b/Components/DatePicker/DateRangePicker.razor.cs new file mode 100644 index 0000000..d970e56 --- /dev/null +++ b/Components/DatePicker/DateRangePicker.razor.cs @@ -0,0 +1,304 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class DateRangePicker : DatePickerBase +{ + private DateTime? _firstDate = null, _secondDate; + private DateRange _dateRange; + private Range _rangeText; + + protected override bool IsRange => true; + + public DateRangePicker() + { + DisplayMonths = 2; + AdornmentAriaLabel = "Open Date Range Picker"; + } + + /// + /// Fired when the DateFormat changes. + /// + [Parameter] public EventCallback DateRangeChanged { get; set; } + + /// + /// The currently selected range (two-way bindable). If null, then nothing was selected. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public DateRange DateRange + { + get => _dateRange; + set => SetDateRangeAsync(value, true).AndForget(); + } + + protected async Task SetDateRangeAsync(DateRange range, bool updateValue) + { + if (_dateRange != range) + { + var doesRangeContainDisabledDates = range?.Start != null && range?.End != null && Enumerable + .Range(0, int.MaxValue) + .Select(index => range.Start.Value.AddDays(index)) + .TakeWhile(date => date <= range.End.Value) + .Any(date => IsDateDisabledFunc(date.Date)); + + if (doesRangeContainDisabledDates) + { + _rangeText = null; + await SetTextAsync(null, false); + return; + } + + _dateRange = range; + _value = range?.End; + + if (updateValue) + { + Converter.GetError = false; + if (_dateRange == null) + { + _rangeText = null; + await SetTextAsync(null, false); + } + else + { + _rangeText = new Range( + Converter.Set(_dateRange.Start), + Converter.Set(_dateRange.End)); + await SetTextAsync(_dateRange.ToString(Converter), false); + } + } + + await DateRangeChanged.InvokeAsync(_dateRange); + BeginValidate(); + } + } + + private Range RangeText + { + get => _rangeText; + set + { + if (_rangeText?.Equals(value) ?? value == null) + return; + + Touched = true; + _rangeText = value; + SetDateRangeAsync(ParseDateRangeValue(value?.Start, value?.End), false).AndForget(); + } + } + + private RangeInput _rangeInput; + + /// + /// Focuses the start date of MudDateRangePicker + /// + /// + public ValueTask FocusStartAsync() => _rangeInput.FocusStartAsync(); + + /// + /// Selects the start date of MudDateRangePicker + /// + /// + public ValueTask SelectStartAsync() => _rangeInput.SelectStartAsync(); + + /// + /// Selects the specified range of the start date text + /// + /// Start position of the selection + /// End position of the selection + /// + public ValueTask SelectRangeStartAsync(int pos1, int pos2) => _rangeInput.SelectRangeStartAsync(pos1, pos2); + + /// + /// Focuses the end date of MudDateRangePicker + /// + /// + public ValueTask FocusEndAsync() => _rangeInput.FocusEndAsync(); + + /// + /// Selects the end date of MudDateRangePicker + /// + /// + public ValueTask SelectEndAsync() => _rangeInput.SelectEndAsync(); + + /// + /// Selects the specified range of the end date text + /// + /// Start position of the selection + /// End position of the selection + /// + public ValueTask SelectRangeEndAsync(int pos1, int pos2) => _rangeInput.SelectRangeEndAsync(pos1, pos2); + + protected override Task DateFormatChanged(string newFormat) + { + Touched = true; + return SetTextAsync(_dateRange?.ToString(Converter), false); + } + + protected override Task StringValueChanged(string value) + { + Touched = true; + // Update the daterange property (without updating back the Value property) + return SetDateRangeAsync(ParseDateRangeValue(value), false); + } + + protected override bool HasValue(DateTime? value) + { + return null != value && value.HasValue; + } + + private DateRange ParseDateRangeValue(string value) + { + return DateRange.TryParse(value, Converter, out var dateRange) ? dateRange : null; + } + + private DateRange ParseDateRangeValue(string start, string end) + { + return DateRange.TryParse(start, end, Converter, out var dateRange) ? dateRange : null; + } + + protected override void OnPickerClosed() + { + _firstDate = null; + base.OnPickerClosed(); + } + + protected override string GetDayClasses(int month, DateTime day) + { + var b = new CssBuilder("mud-day"); + if (day < GetMonthStart(month) || day > GetMonthEnd(month)) + { + return b.AddClass("mud-hidden").Build(); + } + + if ((_firstDate != null && _secondDate != null && _firstDate < day && _secondDate > day) || + (_firstDate == null && _dateRange != null && _dateRange.Start < day && _dateRange.End > day)) + { + return b + .AddClass("mud-range") + .AddClass("mud-range-between") + .Build(); + } + + if ((_firstDate != null && day == _firstDate) || + (_firstDate == null && _dateRange != null && _dateRange.Start == day && DateRange.End != day)) + { + return b.AddClass("mud-selected") + .AddClass("mud-range") + .AddClass("mud-range-start-selected") + .AddClass("mud-range-selection", _firstDate != null) + .AddClass($"mud-theme-{Color.ToDescriptionString()}") + .Build(); + } + + if ((_firstDate != null && _secondDate != null && day == _secondDate) || + (_firstDate == null && _dateRange != null && _dateRange.Start != day && _dateRange.End == day)) + { + return b.AddClass("mud-selected") + .AddClass("mud-range") + .AddClass("mud-range-end-selected") + .AddClass($"mud-theme-{Color.ToDescriptionString()}") + .Build(); + } + + if (_firstDate == null && _dateRange != null && _dateRange.Start == _dateRange.End && _dateRange.Start == day) + { + return b.AddClass("mud-selected").AddClass($"mud-theme-{Color.ToDescriptionString()}").Build(); + } + else if (_firstDate != null && day > _firstDate) + { + return b.AddClass("mud-range") + .AddClass("mud-range-selection", _secondDate == null) + .AddClass($"mud-range-selection-{Color.ToDescriptionString()}", _firstDate != null) + .Build(); + } + + if (day == DateTime.Today) + { + return b.AddClass("mud-current") + .AddClass("mud-range", _firstDate != null && day > _firstDate) + .AddClass("mud-range-selection", _firstDate != null && day > _firstDate) + .AddClass($"mud-range-selection-{Color.ToDescriptionString()}", _firstDate != null && day > _firstDate) + .AddClass($"mud-{Color.ToDescriptionString()}-text") + .Build(); + } + + return b.Build(); + } + + protected override async void OnDayClicked(DateTime dateTime) + { + if (_firstDate == null || _firstDate > dateTime || _secondDate != null) + { + _secondDate = null; + _firstDate = dateTime; + return; + } + + _secondDate = dateTime; + if (PickerActions == null || AutoClose) + { + Submit(); + + if (PickerVariant != PickerVariant.Static) + { + await Task.Delay(ClosingDelay); + Close(false); + } + } + } + + protected override void OnOpened() + { + _secondDate = null; + base.OnOpened(); + } + + protected internal override async void Submit() + { + if (ReadOnly) + return; + if (_firstDate == null || _secondDate == null) + return; + + await SetDateRangeAsync(new DateRange(_firstDate, _secondDate), true); + + _firstDate = null; + _secondDate = null; + } + + public override void Clear(bool close = true) + { + DateRange = null; + _firstDate = _secondDate = null; + base.Clear(); + } + + protected override string GetTitleDateString() + { + if (_firstDate != null) + return $"{FormatTitleDate(_firstDate)} - {FormatTitleDate(_secondDate)}"; + + return DateRange?.Start != null + ? $"{FormatTitleDate(DateRange.Start)} - {FormatTitleDate(DateRange.End)}" + : ""; + } + + protected override DateTime GetCalendarStartOfMonth() + { + var date = StartMonth ?? DateRange?.Start ?? DateTime.Today; + return date.StartOfMonth(Culture); + } + + protected override int GetCalendarYear(int year) + { + var date = DateRange?.Start ?? DateTime.Today; + var diff = date.Year - year; + var calenderYear = Culture.Calendar.GetYear(date); + return calenderYear - diff; + } +} diff --git a/Components/Dialog/Dialog.razor b/Components/Dialog/Dialog.razor new file mode 100644 index 0000000..351277d --- /dev/null +++ b/Components/Dialog/Dialog.razor @@ -0,0 +1,22 @@ +@namespace Connected.Components + +@inherits UIComponent + +@*this makes dialog inlineable, it will only render inside a DialogInstance*@ +@if (!IsInline) +{ + + +
    + @DialogContent +
    + + @if (DialogActions != null) + { +
    + @DialogActions +
    + } + +
    +} diff --git a/Components/Dialog/Dialog.razor.cs b/Components/Dialog/Dialog.razor.cs new file mode 100644 index 0000000..45d0ae7 --- /dev/null +++ b/Components/Dialog/Dialog.razor.cs @@ -0,0 +1,200 @@ +// License: MIT +// Copyright (c) 2019 Blazored - See https://github.com/Blazored +// Copyright (c) 2020 Jonny Larsson and Meinrad Recheis + +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Dialog : UIComponent +{ + protected string ContentClass => new CssBuilder("mud-dialog-content") + .AddClass($"mud-dialog-no-side-padding", DisableSidePadding) + .AddClass(ClassContent) + .Build(); + + protected string ActionClass => new CssBuilder("mud-dialog-actions") + .AddClass(ClassActions) + .Build(); + + [CascadingParameter] private DialogInstance DialogInstance { get; set; } + + [Inject] public IDialogService DialogService { get; set; } + + /// + /// Define the dialog title as a renderfragment (overrides Title) + /// + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public RenderFragment TitleContent { get; set; } + + /// + /// Define the dialog body here + /// + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public RenderFragment DialogContent { get; set; } + + /// + /// Define the action buttons here + /// + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public RenderFragment DialogActions { get; set; } + + /// + /// Default options to pass to Show(), if none are explicitly provided. + /// Typically useful on inline dialogs. + /// + [Parameter] + [Category(CategoryTypes.Dialog.Misc)] // Behavior and Appearance + public DialogOptions Options { get; set; } + + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public Action OnBackdropClick { get; set; } + + /// + /// No padding at the sides + /// + [Parameter] + [Category(CategoryTypes.Dialog.Appearance)] + public bool DisableSidePadding { get; set; } + + /// + /// CSS class that will be applied to the dialog content + /// + [Parameter] + [Category(CategoryTypes.Dialog.Appearance)] + public string ClassContent { get; set; } + + /// + /// CSS class that will be applied to the action buttons container + /// + [Parameter] + [Category(CategoryTypes.Dialog.Appearance)] + public string ClassActions { get; set; } + + /// + /// CSS styles to be applied to the dialog content + /// + [Parameter] + [Category(CategoryTypes.Dialog.Appearance)] + public string ContentStyle { get; set; } + + /// + /// Bind this two-way to show and close an inlined dialog. Has no effect on opened dialogs + /// + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public bool IsVisible + { + get => _isVisible; + set + { + if (_isVisible == value) + return; + _isVisible = value; + IsVisibleChanged.InvokeAsync(value); + } + } + private bool _isVisible; + + /// + /// Raised when the inline dialog's display status changes. + /// + [Parameter] public EventCallback IsVisibleChanged { get; set; } + + + /// + /// Define the dialog title as a renderfragment (overrides Title) + /// + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public DefaultFocus DefaultFocus { get; set; } + + private bool IsInline => DialogInstance == null; + + private IDialogReference _reference; + + /// + /// Show this inlined dialog + /// + /// + /// + /// + public IDialogReference Show(string title = null, DialogOptions options = null) + { + if (!IsInline) + throw new InvalidOperationException("You can only show an inlined dialog."); + if (_reference != null) + Close(); + var parameters = new DialogParameters() + { + [nameof(Class)] = Class, + [nameof(Style)] = Style, + [nameof(Tag)] = Tag, + [nameof(TitleContent)] = TitleContent, + [nameof(DialogContent)] = DialogContent, + [nameof(DialogActions)] = DialogActions, + [nameof(DisableSidePadding)] = DisableSidePadding, + [nameof(ClassContent)] = ClassContent, + [nameof(ClassActions)] = ClassActions, + [nameof(ContentStyle)] = ContentStyle, + }; + _reference = DialogService.Show(title, parameters, options ?? Options); + _reference.Result.ContinueWith(t => + { + _isVisible = false; + InvokeAsync(() => IsVisibleChanged.InvokeAsync(false)); + }); + return _reference; + } + + protected override void OnAfterRender(bool firstRender) + { + if (IsInline) + { + if (_isVisible && _reference == null) + { + Show(); // if isVisible and we don't have any reference we need to call Show + } + else if (_reference != null) + { + if (IsVisible) + (_reference.Dialog as Dialog)?.ForceUpdate(); // forward render update to instance + else + Close(); // if we still have reference but it's not visible call Close + } + } + base.OnAfterRender(firstRender); + } + + /// + /// Used for forwarding state changes from inlined dialog to its instance + /// + internal void ForceUpdate() + { + StateHasChanged(); + } + + /// + /// Close the currently open inlined dialog + /// + /// + public void Close(DialogResult result = null) + { + if (!IsInline || _reference == null) + return; + _reference.Close(result); + _reference = null; + } + + protected override void OnInitialized() + { + base.OnInitialized(); + DialogInstance?.Register(this); + } +} diff --git a/Components/Dialog/DialogInstance.razor b/Components/Dialog/DialogInstance.razor new file mode 100644 index 0000000..2a0e157 --- /dev/null +++ b/Components/Dialog/DialogInstance.razor @@ -0,0 +1,28 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + +
    diff --git a/Components/Dialog/DialogInstance.razor.cs b/Components/Dialog/DialogInstance.razor.cs new file mode 100644 index 0000000..92aa8cb --- /dev/null +++ b/Components/Dialog/DialogInstance.razor.cs @@ -0,0 +1,354 @@ +// Copyright (c) 2019 Blazored +// Copyright (c) 2020 Adapted by Jonny Larsson, Meinrad Recheis and Contributors + +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class DialogInstance : UIComponent, IDisposable +{ + private DialogOptions _options = new(); + private string _elementId = "dialog_" + Guid.NewGuid().ToString().Substring(0, 8); + private IKeyInterceptor _keyInterceptor; + + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + [CascadingParameter] private DialogProvider Parent { get; set; } + [CascadingParameter] private DialogOptions GlobalDialogOptions { get; set; } = new DialogOptions(); + + [Parameter] + [Category(CategoryTypes.Dialog.Misc)] // Behavior and Appearance + public DialogOptions Options + { + get + { + if (_options == null) + _options = new DialogOptions(); + return _options; + } + set => _options = value; + } + + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public string Title { get; set; } + + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public RenderFragment TitleContent { get; set; } + + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public RenderFragment Content { get; set; } + + [Parameter] + [Category(CategoryTypes.Dialog.Behavior)] + public Guid Id { get; set; } + + /// + /// Custom close icon. + /// + [Parameter] + [Category(CategoryTypes.Dialog.Appearance)] + public string CloseIcon { get; set; } = Icons.Material.Filled.Close; + + private string Position { get; set; } + private string DialogMaxWidth { get; set; } + private bool DisableBackdropClick { get; set; } + private bool CloseOnEscapeKey { get; set; } + private bool NoHeader { get; set; } + private bool CloseButton { get; set; } + private bool FullScreen { get; set; } + private bool FullWidth { get; set; } + + + protected override void OnInitialized() + { + ConfigureInstance(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + //Since CloseOnEscapeKey is the only thing to be handled, turn interceptor off + if (CloseOnEscapeKey) + { + _keyInterceptor = _keyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + TargetClass = "mud-dialog", + Keys = { + new KeyOptions { Key="Escape", SubscribeDown = true }, + }, + }); + _keyInterceptor.KeyDown += HandleKeyDown; + } + } + await base.OnAfterRenderAsync(firstRender); + } + + internal void HandleKeyDown(KeyboardEventArgs args) + { + switch (args.Key) + { + case "Escape": + if (CloseOnEscapeKey) + { + Cancel(); + } + break; + } + } + + public void SetOptions(DialogOptions options) + { + Options = options; + ConfigureInstance(); + StateHasChanged(); + } + + public void SetTitle(string title) + { + Title = title; + StateHasChanged(); + } + + /// + /// Close and return null. + /// + /// This is a shorthand of Close(DialogResult.Ok((object)null)); + /// + public void Close() + { + Close(DialogResult.Ok(null)); + } + + /// + /// Close with dialog result. + /// + /// Usage: Close(DialogResult.Ok(returnValue)) + /// + public void Close(DialogResult dialogResult) + { + Parent.DismissInstance(Id, dialogResult); + } + + /// + /// Close and directly pass a return value. + /// + /// This is a shorthand for Close(DialogResult.Ok(returnValue)) + /// + /// + /// + public void Close(T returnValue) + { + var dialogResult = DialogResult.Ok(returnValue); + Parent.DismissInstance(Id, dialogResult); + } + + /// + /// Cancel the dialog. DialogResult.Cancelled will be set to true + /// + public void Cancel() + { + Close(DialogResult.Cancel()); + } + + private void ConfigureInstance() + { + Position = SetPosition(); + DialogMaxWidth = SetMaxWidth(); + NoHeader = SetHideHeader(); + CloseButton = SetCloseButton(); + FullWidth = SetFullWidth(); + FullScreen = SetFulScreen(); + DisableBackdropClick = SetDisableBackdropClick(); + CloseOnEscapeKey = SetCloseOnEscapeKey(); + Class = Classname; + } + + private string SetPosition() + { + DialogPosition position; + + if (Options.Position.HasValue) + { + position = Options.Position.Value; + } + else if (GlobalDialogOptions.Position.HasValue) + { + position = GlobalDialogOptions.Position.Value; + } + else + { + position = DialogPosition.Center; + } + return $"mud-dialog-{position.ToDescriptionString()}"; + } + + private string SetMaxWidth() + { + MaxWidth maxWidth; + + if (Options.MaxWidth.HasValue) + { + maxWidth = Options.MaxWidth.Value; + } + else if (GlobalDialogOptions.MaxWidth.HasValue) + { + maxWidth = GlobalDialogOptions.MaxWidth.Value; + } + else + { + maxWidth = MaxWidth.Small; + } + return $"mud-dialog-width-{maxWidth.ToDescriptionString()}"; + } + + private bool SetFullWidth() + { + if (Options.FullWidth.HasValue) + return Options.FullWidth.Value; + + if (GlobalDialogOptions.FullWidth.HasValue) + return GlobalDialogOptions.FullWidth.Value; + + return false; + } + + private bool SetFulScreen() + { + if (Options.FullScreen.HasValue) + return Options.FullScreen.Value; + + if (GlobalDialogOptions.FullScreen.HasValue) + return GlobalDialogOptions.FullScreen.Value; + + return false; + } + + protected string Classname => + new CssBuilder("mud-dialog") + .AddClass(DialogMaxWidth, !FullScreen) + .AddClass("mud-dialog-width-full", FullWidth && !FullScreen) + .AddClass("mud-dialog-fullscreen", FullScreen) + .AddClass("mud-dialog-rtl", RightToLeft) + .AddClass(_dialog?.Class) + .Build(); + + private bool SetHideHeader() + { + if (Options.NoHeader.HasValue) + return Options.NoHeader.Value; + + if (GlobalDialogOptions.NoHeader.HasValue) + return GlobalDialogOptions.NoHeader.Value; + + return false; + } + + private bool SetCloseButton() + { + if (Options.CloseButton.HasValue) + return Options.CloseButton.Value; + + if (GlobalDialogOptions.CloseButton.HasValue) + return GlobalDialogOptions.CloseButton.Value; + + return false; + } + + private bool SetDisableBackdropClick() + { + if (Options.DisableBackdropClick.HasValue) + return Options.DisableBackdropClick.Value; + + if (GlobalDialogOptions.DisableBackdropClick.HasValue) + return GlobalDialogOptions.DisableBackdropClick.Value; + + return false; + } + + private bool SetCloseOnEscapeKey() + { + if (Options.CloseOnEscapeKey.HasValue) + return Options.CloseOnEscapeKey.Value; + + if (GlobalDialogOptions.CloseOnEscapeKey.HasValue) + return GlobalDialogOptions.CloseOnEscapeKey.Value; + + return false; + } + + private void HandleBackgroundClick() + { + if (DisableBackdropClick) + return; + + if (_dialog?.OnBackdropClick == null) + { + Cancel(); + return; + } + + _dialog?.OnBackdropClick.Invoke(); + } + + private Dialog _dialog; + private bool _disposedValue; + + public void Register(Dialog dialog) + { + if (dialog == null) + return; + _dialog = dialog; + Class = dialog.Class; + Style = dialog.Style; + TitleContent = dialog.TitleContent; + StateHasChanged(); + } + + public void ForceRender() + { + StateHasChanged(); + } + + /// + /// Cancels all dialogs in dialog provider collection. + /// + public void CancelAll() + { + Parent?.DismissAll(); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.Dispose(); + } + } + + _disposedValue = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} diff --git a/Components/Dialog/DialogOptions.cs b/Components/Dialog/DialogOptions.cs new file mode 100644 index 0000000..d95fe31 --- /dev/null +++ b/Components/Dialog/DialogOptions.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2020 Jonny Larsson +// License: MIT +// See https://github.com/MudBlazor/MudBlazor +// Modified version of Blazored Modal +// Copyright (c) 2019 Blazored +// License: MIT +// See https://github.com/Blazored + + +using System.ComponentModel; + +namespace Connected.Components; + +public class DialogOptions +{ + public DialogPosition? Position { get; set; } + + public MaxWidth? MaxWidth { get; set; } + + public bool? DisableBackdropClick { get; set; } + public bool? CloseOnEscapeKey { get; set; } + public bool? NoHeader { get; set; } + public bool? CloseButton { get; set; } + public bool? FullScreen { get; set; } + public bool? FullWidth { get; set; } +} + +public enum DialogPosition +{ + [Description("center")] + Center, + [Description("centerleft")] + CenterLeft, + [Description("centerright")] + CenterRight, + [Description("topcenter")] + TopCenter, + [Description("topleft")] + TopLeft, + [Description("topright")] + TopRight, + [Description("bottomcenter")] + BottomCenter, + [Description("bottomleft")] + BottomLeft, + [Description("bottomright")] + BottomRight, + [Description("custom")] + Custom +} diff --git a/Components/Dialog/DialogParameters.cs b/Components/Dialog/DialogParameters.cs new file mode 100644 index 0000000..8e26c09 --- /dev/null +++ b/Components/Dialog/DialogParameters.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2019 - Blazored +// Copyright (c) 2020 - Adaptations by Jonny Larsson and Meinrad Recheis + +using System.Collections; + +namespace Connected.Components; + +public class DialogParameters : IEnumerable> +{ + internal Dictionary _parameters; + + public DialogParameters() + { + _parameters = new Dictionary(); + } + + public void Add(string parameterName, object value) + { + _parameters[parameterName] = value; + } + + public T Get(string parameterName) + { + if (_parameters.TryGetValue(parameterName, out var value)) + { + return (T)value; + } + + throw new KeyNotFoundException($"{parameterName} does not exist in Dialog parameters"); + } + + public T TryGet(string parameterName) + { + if (_parameters.TryGetValue(parameterName, out var value)) + { + return (T)value; + } + + return default; + } + + public int Count => + _parameters.Count; + + public object this[string parameterName] + { + get => Get(parameterName); + set => _parameters[parameterName] = value; + } + + public IEnumerator> GetEnumerator() + { + return _parameters.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _parameters.GetEnumerator(); + } +} diff --git a/Components/Dialog/DialogProvider.razor b/Components/Dialog/DialogProvider.razor new file mode 100644 index 0000000..dd899a7 --- /dev/null +++ b/Components/Dialog/DialogProvider.razor @@ -0,0 +1,10 @@ +@namespace Connected.Components + + + + @foreach (var dialogReference in _dialogs.Where(x => !x.Result.IsCompleted)) + { + @dialogReference.RenderFragment + } + + diff --git a/Components/Dialog/DialogProvider.razor.cs b/Components/Dialog/DialogProvider.razor.cs new file mode 100644 index 0000000..b44d2fd --- /dev/null +++ b/Components/Dialog/DialogProvider.razor.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2020 Jonny Larsson +// License: MIT +// See https://github.com/MudBlazor/MudBlazor +// Modified version of Blazored Modal +// Copyright (c) 2019 Blazored +// License: MIT +// See https://github.com/Blazored + +using System.Collections.ObjectModel; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; + +namespace Connected.Components; + +public partial class DialogProvider : IDisposable +{ + [Inject] private IDialogService DialogService { get; set; } + [Inject] private NavigationManager NavigationManager { get; set; } + + [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? NoHeader { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseButton { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? DisableBackdropClick { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseOnEscapeKey { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Appearance)] public bool? FullWidth { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Appearance)] public DialogPosition? Position { get; set; } + [Parameter][Category(CategoryTypes.Dialog.Appearance)] public MaxWidth? MaxWidth { get; set; } + + private readonly Collection _dialogs = new(); + private readonly DialogOptions _globalDialogOptions = new(); + + protected override void OnInitialized() + { + DialogService.OnDialogInstanceAdded += AddInstance; + DialogService.OnDialogCloseRequested += DismissInstance; + NavigationManager.LocationChanged += LocationChanged; + + _globalDialogOptions.DisableBackdropClick = DisableBackdropClick; + _globalDialogOptions.CloseOnEscapeKey = CloseOnEscapeKey; + _globalDialogOptions.CloseButton = CloseButton; + _globalDialogOptions.NoHeader = NoHeader; + _globalDialogOptions.Position = Position; + _globalDialogOptions.FullWidth = FullWidth; + _globalDialogOptions.MaxWidth = MaxWidth; + } + + protected override Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + { + foreach (var dialogReference in _dialogs.Where(x => !x.Result.IsCompleted)) + { + dialogReference.RenderCompleteTaskCompletionSource.TrySetResult(true); + } + } + + return base.OnAfterRenderAsync(firstRender); + } + + internal void DismissInstance(Guid id, DialogResult result) + { + var reference = GetDialogReference(id); + if (reference != null) + DismissInstance(reference, result); + } + + private void AddInstance(IDialogReference dialog) + { + _dialogs.Add(dialog); + StateHasChanged(); + } + + public void DismissAll() + { + _dialogs.ToList().ForEach(r => DismissInstance(r, DialogResult.Cancel())); + StateHasChanged(); + } + + private void DismissInstance(IDialogReference dialog, DialogResult result) + { + if (!dialog.Dismiss(result)) return; + + _dialogs.Remove(dialog); + StateHasChanged(); + } + + private IDialogReference GetDialogReference(Guid id) + { + return _dialogs.SingleOrDefault(x => x.Id == id); + } + + private void LocationChanged(object sender, LocationChangedEventArgs args) + { + DismissAll(); + } + + public void Dispose() + { + if (NavigationManager != null) + NavigationManager.LocationChanged -= LocationChanged; + + if (DialogService != null) + { + DialogService.OnDialogInstanceAdded -= AddInstance; + DialogService.OnDialogCloseRequested -= DismissInstance; + } + } +} diff --git a/Components/Dialog/DialogReference.cs b/Components/Dialog/DialogReference.cs new file mode 100644 index 0000000..6b9732e --- /dev/null +++ b/Components/Dialog/DialogReference.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2019 Blazored (https://github.com/Blazored) +// Copyright (c) 2020 Jonny Larsson (https://github.com/MudBlazor/MudBlazor) +// Copyright (c) 2021 improvements by Meinrad Recheis +// See https://github.com/Blazored +// License: MIT + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public class DialogReference : IDialogReference +{ + private readonly TaskCompletionSource _resultCompletion = new(); + + private readonly IDialogService _dialogService; + + public DialogReference(Guid dialogInstanceId, IDialogService dialogService) + { + Id = dialogInstanceId; + _dialogService = dialogService; + } + + public void Close() + { + _dialogService.Close(this); + } + + public void Close(DialogResult result) + { + _dialogService.Close(this, result); + } + + public virtual bool Dismiss(DialogResult result) + { + return _resultCompletion.TrySetResult(result); + } + + public Guid Id { get; } + + public object Dialog { get; private set; } + public RenderFragment RenderFragment { get; set; } + + public Task Result => _resultCompletion.Task; + + TaskCompletionSource IDialogReference.RenderCompleteTaskCompletionSource { get; } = new(); + + public void InjectDialog(object inst) + { + Dialog = inst; + } + + public void InjectRenderFragment(RenderFragment rf) + { + RenderFragment = rf; + } + + public async Task GetReturnValueAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() + { + var result = await Result; + try + { + return (T)result.Data; + } + catch (InvalidCastException) + { + Debug.WriteLine($"Could not cast return value to {typeof(T)}, returning default."); + return default; + } + } + +} diff --git a/Components/Dialog/IDialogReference.cs b/Components/Dialog/IDialogReference.cs new file mode 100644 index 0000000..cf9e088 --- /dev/null +++ b/Components/Dialog/IDialogReference.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2019 Blazored (https://github.com/Blazored) +// Copyright (c) 2020 Jonny Larsson (https://github.com/MudBlazor/MudBlazor) +// Copyright (c) 2021 improvements by Meinrad Recheis +// See https://github.com/Blazored +// License: MIT + +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public interface IDialogReference +{ + Guid Id { get; } + + RenderFragment RenderFragment { get; set; } + + [Obsolete("This will always return true"), ExcludeFromCodeCoverage] + bool AreParametersRendered { get => true; set { } } + + Task Result { get; } + + internal TaskCompletionSource RenderCompleteTaskCompletionSource { get; } + + void Close(); + + void Close(DialogResult result); + + bool Dismiss(DialogResult result); + + object Dialog { get; } + + void InjectRenderFragment(RenderFragment rf); + + void InjectDialog(object inst); + + Task GetReturnValueAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(); +} diff --git a/Components/Dialog/IDialogService.cs b/Components/Dialog/IDialogService.cs new file mode 100644 index 0000000..cf138c2 --- /dev/null +++ b/Components/Dialog/IDialogService.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2019 Blazored (https://github.com/Blazored) +// Copyright (c) 2020 Jonny Larsson (https://github.com/MudBlazor/MudBlazor) +// Copyright (c) 2021 improvements by Meinrad Recheis +// See https://github.com/Blazored +// License: MIT + + +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public interface IDialogService +{ + public event Action OnDialogInstanceAdded; + public event Action OnDialogCloseRequested; + + IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>() where TComponent : ComponentBase; + + IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title) where TComponent : ComponentBase; + + IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogOptions options) where TComponent : ComponentBase; + + IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogParameters parameters) where TComponent : ComponentBase; + + IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogParameters parameters, DialogOptions options) where TComponent : ComponentBase; + + IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component); + + IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title); + + IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogOptions options); + + IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogParameters parameters); + + IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogParameters parameters, DialogOptions options); + + Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>() where TComponent : ComponentBase; + + Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title) where TComponent : ComponentBase; + + Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogOptions options) where TComponent : ComponentBase; + + Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogParameters parameters) where TComponent : ComponentBase; + + Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>(string title, DialogParameters parameters, DialogOptions options) where TComponent : ComponentBase; + + Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component); + + Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title); + + Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogOptions options); + + Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogParameters parameters); + + Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component, string title, DialogParameters parameters, DialogOptions options); + + IDialogReference CreateReference(); + + Task ShowMessageBox(string title, string message, string yesText = "OK", + string noText = null, string cancelText = null, DialogOptions options = null); + + Task ShowMessageBox(string title, MarkupString markupMessage, string yesText = "OK", + string noText = null, string cancelText = null, DialogOptions options = null); + + Task ShowMessageBox(MessageBoxOptions messageBoxOptions, DialogOptions options = null); + + void Close(DialogReference dialog); + + void Close(DialogReference dialog, DialogResult result); +} diff --git a/Components/Divider/Divider.razor b/Components/Divider/Divider.razor new file mode 100644 index 0000000..f4a6e5f --- /dev/null +++ b/Components/Divider/Divider.razor @@ -0,0 +1,4 @@ +@namespace Connected.Components +@inherits UIComponent + +
    \ No newline at end of file diff --git a/Components/Divider/Divider.razor.cs b/Components/Divider/Divider.razor.cs new file mode 100644 index 0000000..b6ddc13 --- /dev/null +++ b/Components/Divider/Divider.razor.cs @@ -0,0 +1,53 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; +public partial class Divider : UIComponent +{ + protected string Classname => + new CssBuilder("mud-divider") + .AddClass($"mud-divider-absolute", Absolute) + .AddClass($"mud-divider-flexitem", FlexItem) + .AddClass($"mud-divider-light", Light) + .AddClass($"mud-divider-vertical", Vertical) + .AddClass($"mud-divider-{DividerType.ToDescriptionString()}", when: () => DividerType != DividerType.FullWidth) + .AddClass(Class) + .Build(); + + /// + /// Sets absolute position to the component. + /// + [Parameter] + [Category(CategoryTypes.Divider.Appearance)] + public bool Absolute { get; set; } + + /// + /// If true, a vertical divider will have the correct height when used in flex container. + /// + [Parameter] + [Category(CategoryTypes.Divider.Appearance)] + public bool FlexItem { get; set; } + + /// + /// If true, the divider will have a lighter color. + /// + [Parameter] + [Category(CategoryTypes.Divider.Appearance)] + public bool Light { get; set; } + + /// + /// If true, the divider is displayed vertically. + /// + [Parameter] + [Category(CategoryTypes.Divider.Appearance)] + public bool Vertical { get; set; } + + /// + /// The Divider type to use. + /// + [Parameter] + [Category(CategoryTypes.Divider.Appearance)] + public DividerType DividerType { get; set; } = DividerType.FullWidth; +} diff --git a/Components/Drawer/Drawer.razor b/Components/Drawer/Drawer.razor new file mode 100644 index 0000000..799424c --- /dev/null +++ b/Components/Drawer/Drawer.razor @@ -0,0 +1,11 @@ +@namespace Connected.Components +@inherits UIComponent + + + \ No newline at end of file diff --git a/Components/Drawer/Drawer.razor.cs b/Components/Drawer/Drawer.razor.cs new file mode 100644 index 0000000..ead3b25 --- /dev/null +++ b/Components/Drawer/Drawer.razor.cs @@ -0,0 +1,412 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver +{ + private double _height; + private ElementReference _contentRef; + private DrawerClipMode _clipMode; + private bool? _isOpenWhenLarge = null; + private bool _open, _rtl, _isRendered, _initial = true, _keepInitialState, _fixed = true; + private Breakpoint _breakpoint = Breakpoint.Md, _screenBreakpoint = Breakpoint.None; + private Guid _breakpointListenerSubscriptionId; + + private bool OverlayVisible => _open && !DisableOverlay && + (Variant == DrawerVariant.Temporary || + (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Mini) || + (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Responsive)); + + protected string Classname => + new CssBuilder("mud-drawer") + .AddClass($"mud-drawer-fixed", Fixed) + .AddClass($"mud-drawer-pos-{GetPosition()}") + .AddClass($"mud-drawer--open", Open) + .AddClass($"mud-drawer--closed", !Open) + .AddClass($"mud-drawer--initial", _initial) + .AddClass($"mud-drawer-{Breakpoint.ToDescriptionString()}") + .AddClass($"mud-drawer-clipped-{_clipMode.ToDescriptionString()}") + .AddClass($"mud-theme-{Color.ToDescriptionString()}", Color != ThemeColor.Default) + .AddClass($"mud-elevation-{Elevation}") + .AddClass($"mud-drawer-{Variant.ToDescriptionString()}") + .AddClass(Class) + .Build(); + + protected string OverlayClass => + new CssBuilder("mud-drawer-overlay mud-overlay-drawer") + .AddClass($"mud-drawer-pos-{GetPosition()}") + .AddClass($"mud-drawer-overlay--open", Open) + .AddClass($"mud-drawer-overlay-{Variant.ToDescriptionString()}") + .AddClass($"mud-drawer-overlay-{Breakpoint.ToDescriptionString()}") + .AddClass($"mud-drawer-overlay--initial", _initial) + .Build(); + + protected string Stylename => + new StyleBuilder() + //.AddStyle("width", Width, !string.IsNullOrWhiteSpace(Width) && !Fixed) + .AddStyle("--mud-drawer-width", Width, !string.IsNullOrWhiteSpace(Width) && (!Fixed || Variant == DrawerVariant.Temporary)) + .AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) + .AddStyle("--mud-drawer-content-height", + string.IsNullOrWhiteSpace(Height) ? _height.ToPx() : Height, + Anchor == Anchor.Bottom || Anchor == Anchor.Top) + .AddStyle("visibility", "hidden", string.IsNullOrWhiteSpace(Height) && _height == 0 && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)) + .AddStyle(Style) + .Build(); + + [Inject] public IBreakpointService Breakpointistener { get; set; } + + [CascadingParameter] DrawerContainer DrawerContainer { get; set; } + + [CascadingParameter(Name = "RightToLeft")] + bool RightToLeft + { + get => _rtl; + set + { + if (_rtl != value) + { + _rtl = value; + DrawerContainer?.FireDrawersChanged(); + } + } + } + + /// + /// If true, drawer position will be fixed. (CSS position: fixed;) + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool Fixed + { + get => _fixed && DrawerContainer is Layout; + set + { + if (_fixed == value) + return; + _fixed = value; + } + } + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// Side from which the drawer will appear. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public Anchor Anchor { get; set; } = Anchor.Start; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// Variant of the drawer. It specifies how the drawer will be displayed. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public DrawerVariant Variant { get; set; } = DrawerVariant.Responsive; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Show overlay for responsive and temporary drawers. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool DisableOverlay { get; set; } = false; + + /// + /// Preserve open state for responsive drawer when window resized above . + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool PreserveOpenState { get; set; } = false; + + /// + /// Open drawer automatically on mouse enter when parameter is set to . + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool OpenMiniOnHover { get; set; } + + /// + /// Switching point for responsive drawers + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public Breakpoint Breakpoint + { + get => _breakpoint; + set + { + if (value == _breakpoint) + return; + + _breakpoint = value; + if (_isRendered) + { + UpdateBreakpointState(_screenBreakpoint); + } + + DrawerContainer?.FireDrawersChanged(); + } + } + + /// + /// Sets the opened state on the drawer. Can be used with two-way binding to close itself on navigation. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool Open + { + get => _open; + set + { + if (_open == value) + { + return; + } + _open = value; + if (_isRendered && _initial && !_keepInitialState) + { + _initial = false; + } + if (_keepInitialState) + { + _keepInitialState = false; + } + if (_isRendered && value && (Anchor == Anchor.Top || Anchor == Anchor.Bottom)) + { + _ = UpdateHeight(); + } + + DrawerContainer?.FireDrawersChanged(); + OpenChanged.InvokeAsync(_open); + } + } + + [Parameter] public EventCallback OpenChanged { get; set; } + + /// + /// Width of left/right drawer. Only for non-fixed drawers. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public string Width { get; set; } + + /// + /// Width of left/right drawer. Only for non-fixed drawers. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public string MiniWidth { get; set; } + + /// + /// Height of top/bottom temporary drawer + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public string Height { get; set; } + + /// + /// Specify how the drawer should behave inside a MudLayout. It affects the position relative to MudAppbar + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public DrawerClipMode ClipMode + { + get => _clipMode; + set + { + if (_clipMode == value) + { + return; + } + _clipMode = value; + if (Fixed) + { + DrawerContainer?.FireDrawersChanged(); + } + StateHasChanged(); + } + } + + protected override void OnInitialized() + { + if (Variant != DrawerVariant.Temporary) + { + DrawerContainer?.Add(this); + } + base.OnInitialized(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await UpdateHeight(); + var result = await Breakpointistener.Subscribe(UpdateBreakpointState); + var currentBreakpoint = result.Breakpoint; + + _breakpointListenerSubscriptionId = result.SubscriptionId; + + _screenBreakpoint = result.Breakpoint; + if (_screenBreakpoint < Breakpoint && _open) + { + _keepInitialState = true; + await OpenChanged.InvokeAsync(false); + } + + _isRendered = true; + if (string.IsNullOrWhiteSpace(Height) && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)) + { + StateHasChanged(); + } + } + + await base.OnAfterRenderAsync(firstRender); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + int _disposeCount; + public virtual void Dispose(bool disposing) + { + if (Interlocked.Increment(ref _disposeCount) == 1) + { + if (disposing) + { + DrawerContainer?.Remove(this); + + if (_breakpointListenerSubscriptionId != default) + { + Breakpointistener.Unsubscribe(_breakpointListenerSubscriptionId).AndForget(); + } + } + } + } + + private void CloseDrawer() + { + if (Open) + { + OpenChanged.InvokeAsync(false); + } + } + + public async Task OnNavigation() + { + if (Variant == DrawerVariant.Temporary || + (Variant == DrawerVariant.Responsive && await Breakpointistener.GetBreakpoint() < Breakpoint)) + { + await OpenChanged.InvokeAsync(false); + } + } + + private void ResizeListener_OnBreakpointChanged(object sender, Breakpoint breakpoint) + { + if (!_isRendered) + return; + + InvokeAsync(() => UpdateBreakpointState(breakpoint)); + } + + private async Task UpdateHeight() + { + _height = (await _contentRef.MudGetBoundingClientRectAsync())?.Height ?? 0; + } + + private async void UpdateBreakpointState(Breakpoint breakpoint) + { + var isStateChanged = false; + if (breakpoint == Breakpoint.None) + { + breakpoint = await Breakpointistener.GetBreakpoint(); + } + + if (breakpoint < Breakpoint && _screenBreakpoint >= Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) + { + _isOpenWhenLarge = Open; + + await OpenChanged.InvokeAsync(false); + isStateChanged = true; + } + else if (breakpoint >= Breakpoint && _screenBreakpoint < Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) + { + if (Open && PreserveOpenState) + { + DrawerContainer?.FireDrawersChanged(); + isStateChanged = true; + } + else if (_isOpenWhenLarge != null) + { + await OpenChanged.InvokeAsync(_isOpenWhenLarge.Value); + _isOpenWhenLarge = null; + isStateChanged = true; + } + } + + _screenBreakpoint = breakpoint; + if (isStateChanged) + { + StateHasChanged(); + } + } + + internal string GetPosition() + { + switch (Anchor) + { + case Anchor.Start: + return RightToLeft ? "right" : "left"; + case Anchor.End: + return RightToLeft ? "left" : "right"; + default: break; + } + + return Anchor.ToDescriptionString(); + } + + + private bool closeOnMouseLeave = false; + + public async void OnMouseEnter() + { + if (Variant == DrawerVariant.Mini && !Open && OpenMiniOnHover) + { + closeOnMouseLeave = true; + await OpenChanged.InvokeAsync(true); + } + } + + public async void OnMouseLeave() + { + if (Variant == DrawerVariant.Mini && Open && closeOnMouseLeave) + { + closeOnMouseLeave = false; + await OpenChanged.InvokeAsync(false); + } + } +} diff --git a/Components/Drawer/DrawerContainer.razor b/Components/Drawer/DrawerContainer.razor new file mode 100644 index 0000000..dbcbbce --- /dev/null +++ b/Components/Drawer/DrawerContainer.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + @ChildContent + +
    diff --git a/Components/Drawer/DrawerContainer.razor.cs b/Components/Drawer/DrawerContainer.razor.cs new file mode 100644 index 0000000..8dea516 --- /dev/null +++ b/Components/Drawer/DrawerContainer.razor.cs @@ -0,0 +1,108 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class DrawerContainer : UIComponent +{ + protected bool Fixed { get; set; } = false; + private List _drawers = new(); + + protected virtual string Classname => + new CssBuilder() + .AddClass(GetDrawerClass(FindLeftDrawer())) + .AddClass(GetDrawerClass(FindRightDrawer())) + .AddClass(Class) + .Build(); + + protected string Stylename => + new StyleBuilder() + .AddStyle("--mud-drawer-width-left", GetDrawerWidth(FindLeftDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindLeftDrawer()))) + .AddStyle("--mud-drawer-width-right", GetDrawerWidth(FindRightDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindRightDrawer()))) + .AddStyle("--mud-drawer-width-mini-left", GetMiniDrawerWidth(FindLeftMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindLeftMiniDrawer()))) + .AddStyle("--mud-drawer-width-mini-right", GetMiniDrawerWidth(FindRightMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindRightMiniDrawer()))) + .AddStyle(Style) + .Build(); + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public RenderFragment ChildContent { get; set; } + + internal void FireDrawersChanged() => StateHasChanged(); + + internal void Add(Drawer drawer) + { + if (Fixed && !drawer.Fixed) + return; + + _drawers.Add(drawer); + StateHasChanged(); + } + + internal void Remove(Drawer drawer) + { + _drawers.Remove(drawer); + StateHasChanged(); + } + + private string GetDrawerClass(Drawer drawer) + { + if (drawer == null) + return string.Empty; + + var className = $"mud-drawer-{(drawer.Open ? "open" : "close")}-{drawer.Variant.ToDescriptionString()}"; + if (drawer.Variant is DrawerVariant.Responsive or DrawerVariant.Mini) + { + className += $"-{drawer.Breakpoint.ToDescriptionString()}"; + } + className += $"-{drawer.GetPosition()}"; + + className += $" mud-drawer-{drawer.GetPosition()}-clipped-{drawer.ClipMode.ToDescriptionString()}"; + + return className; + } + + private string GetDrawerWidth(Drawer drawer) + { + if (drawer == null) + return string.Empty; + + return drawer.Width; + } + + private string GetMiniDrawerWidth(Drawer drawer) + { + if (drawer == null) + return string.Empty; + + return drawer.MiniWidth; + } + + private Drawer FindLeftDrawer() + { + var anchor = RightToLeft ? Anchor.End : Anchor.Start; + return _drawers.FirstOrDefault(d => d.Anchor == anchor || d.Anchor == Anchor.Left); + } + + private Drawer FindRightDrawer() + { + var anchor = RightToLeft ? Anchor.Start : Anchor.End; + return _drawers.FirstOrDefault(d => d.Anchor == anchor || d.Anchor == Anchor.Right); + } + + private Drawer FindLeftMiniDrawer() + { + var anchor = RightToLeft ? Anchor.End : Anchor.Start; + return _drawers.FirstOrDefault(d => d.Variant == DrawerVariant.Mini && (d.Anchor == anchor || d.Anchor == Anchor.Left)); + } + + private Drawer FindRightMiniDrawer() + { + var anchor = RightToLeft ? Anchor.Start : Anchor.End; + return _drawers.FirstOrDefault(d => d.Variant == DrawerVariant.Mini && (d.Anchor == anchor || d.Anchor == Anchor.Right)); + } +} diff --git a/Components/Drawer/DrawerHeader.razor b/Components/Drawer/DrawerHeader.razor new file mode 100644 index 0000000..dd3efea --- /dev/null +++ b/Components/Drawer/DrawerHeader.razor @@ -0,0 +1,15 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (LinkToIndex) +{ + + @ChildContent + +} +else +{ +
    + @ChildContent +
    +} diff --git a/Components/Drawer/DrawerHeader.razor.cs b/Components/Drawer/DrawerHeader.razor.cs new file mode 100644 index 0000000..df85e22 --- /dev/null +++ b/Components/Drawer/DrawerHeader.razor.cs @@ -0,0 +1,34 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; +public partial class DrawerHeader : UIComponent +{ + protected string Classname => + new CssBuilder("mud-drawer-header") + .AddClass($"mud-drawer-header-dense", Dense) + .AddClass(Class) + .Build(); + + /// + /// If true, compact padding will be used, same as the Appbar. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Appearance)] + public bool Dense { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If true, the component will link to index page with an a element instead of div. + /// + [Parameter] + [Category(CategoryTypes.Drawer.Behavior)] + public bool LinkToIndex { get; set; } +} diff --git a/Components/DropZone/DropContainer.razor b/Components/DropZone/DropContainer.razor new file mode 100644 index 0000000..64a45e4 --- /dev/null +++ b/Components/DropZone/DropContainer.razor @@ -0,0 +1,11 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + +
    + @ChildContent +
    +
    \ No newline at end of file diff --git a/Components/DropZone/DropContainer.razor.cs b/Components/DropZone/DropContainer.razor.cs new file mode 100644 index 0000000..779fc27 --- /dev/null +++ b/Components/DropZone/DropContainer.razor.cs @@ -0,0 +1,348 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public class DragAndDropIndexChangedEventArgs : EventArgs +{ + public DragAndDropIndexChangedEventArgs(string zoneIdentifier, string oldZoneIdentifier, int index) + { + ZoneIdentifier = zoneIdentifier; + Index = index; + OldZoneIdentifier = oldZoneIdentifier; + } + + public string ZoneIdentifier { get; } + public int Index { get; } + public string OldZoneIdentifier { get; } +} + +/// +/// Used to encapsulate data for a drag and drop transaction +/// +/// +public class DragAndDropItemTransaction +{ + private Func _commitCallback; + private Func _cancelCallback; + + /// + /// The Item that is dragged during the transaction + /// + public T Item { get; init; } + + /// + /// The index of the item in the current drop zone + /// + public int Index { get; private set; } + + /// + /// The index of the item when the transaction started + /// + public int SourceIndex { get; private set; } + + /// + /// Identifier for drop zone where the transaction started + /// + public string SourceZoneIdentifier { get; init; } + + public string CurrentZone { get; private set; } + + /// + /// create a new instance of a drag and drop transaction encapsulating the item and source + /// + /// The item of this transaction + /// The identifier of the drop zone, where the transaction started + /// The source index + /// A callback that is invokde when the transaction has been successful + /// A callback that is inviked when the transaction has been cancelled + public DragAndDropItemTransaction(T item, string identifier, int index, Func commitCallback, Func cancelCallback) + { + Item = item; + SourceZoneIdentifier = identifier; + CurrentZone = identifier; + Index = index; + SourceIndex = index; + + _commitCallback = commitCallback; + _cancelCallback = cancelCallback; + } + + /// + /// Cancel the transaction + /// + /// + public async Task Cancel() => await _cancelCallback.Invoke(); + + /// + /// Commit this transaction as succesful + /// + /// + public async Task Commit() => await _commitCallback.Invoke(); + + internal bool UpdateIndex(int index) + { + if (Index == index) { return false; } + + Index = index; + return true; + } + + internal bool UpdateZone(string idenfifer) + { + if (CurrentZone == idenfifer) { return false; } + + CurrentZone = idenfifer; + Index = -1; + return true; + } +} + +/// +/// Record encaplusalting data regaring a completed transaction +/// +/// Type of dragged item +/// The dragged item during the transaction +/// Identifier of the zone where the transaction started +/// The index of the item within in the dropzone +public record ItemDropInfo(T Item, string DropzoneIdentifier, int IndexInZone); + +public class DragAndDropTransactionFinishedEventArgs : EventArgs +{ + public DragAndDropTransactionFinishedEventArgs(DragAndDropItemTransaction transaction) : + this(string.Empty, false, transaction) + { + + } + + public DragAndDropTransactionFinishedEventArgs(string destinationDropzoneIdentifier, bool success, DragAndDropItemTransaction transaction) + { + Item = transaction.Item; + Success = success; + OriginatedDropzoneIdentifier = transaction.SourceZoneIdentifier; + DestinationDropzoneIdentifier = destinationDropzoneIdentifier; + OriginIndex = transaction.SourceIndex; + DestinationIndex = transaction.Index; + } + + public T Item { get; } + public bool Success { get; } + public string OriginatedDropzoneIdentifier { get; } + public string DestinationDropzoneIdentifier { get; } + public int OriginIndex { get; } + public int DestinationIndex { get; } +} + + +/// +/// The container of a drag and drop zones +/// +/// Datetype of items +public partial class DropContainer : UIComponent +{ + private DragAndDropItemTransaction _transaction; + + protected string Classname => + new CssBuilder("mud-drop-container") + .AddClass(Class) + .Build(); + + /// + /// Child content of component. This should include the drop zones + /// + [Parameter] + [Category(CategoryTypes.DropZone.Appearance)] + public RenderFragment ChildContent { get; set; } + + /// + /// The items that can be drag and dropped within the container + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public IEnumerable Items { get; set; } + + /// + /// The render fragment (template) that should be used to render the items within a drop zone + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public RenderFragment ItemRenderer { get; set; } + + /// + /// The method is used to determinate if an item can be dropped within a drop zone + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public Func ItemsSelector { get; set; } + + /// + /// Callback that indicates that an item has been dropped on a drop zone. Should be used to update the "status" of the data item + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public EventCallback> ItemDropped { get; set; } + + /// + /// The method is used to determinate if an item can be dropped within a drop zone + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public Func CanDrop { get; set; } + + /// + /// The CSS class(es), that is applied to drop zones that are a valid target for drag and drop transaction + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public string CanDropClass { get; set; } + + /// + /// The CSS class(es), that is applied to drop zones that are NOT valid target for drag and drop transaction + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public string NoDropClass { get; set; } + + /// + /// If true, drop classes CanDropClass or NoDropClass or applied as soon, as a transaction has started + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public bool ApplyDropClassesOnDragStarted { get; set; } = false; + + /// + /// The method is used to determinate if an item should be disabled for dragging. Defaults to allow all items + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public Func ItemIsDisabled { get; set; } + + /// + /// If a drop item is disabled (determinate by ). This class is applied to the element + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public string DisabledClass { get; set; } = "disabled"; + + /// + /// An additional class that is applied to the drop zone where a drag operation started + /// + [Parameter] + [Category(CategoryTypes.DropZone.DraggingClass)] + public string DraggingClass { get; set; } + + /// + /// An additional class that is applied to an drop item, when it is dragged + /// + [Parameter] + [Category(CategoryTypes.DropZone.DraggingClass)] + public string ItemDraggingClass { get; set; } + + public event EventHandler> TransactionStarted; + public event EventHandler TransactionIndexChanged; + + public event EventHandler> TransactionEnded; + public event EventHandler RefreshRequested; + + public void StartTransaction(T item, string identifier, int index, Func commitCallback, Func cancelCallback) + { + _transaction = new DragAndDropItemTransaction(item, identifier, index, commitCallback, cancelCallback); + TransactionStarted?.Invoke(this, _transaction); + } + + public T GetTransactionItem() => _transaction.Item; + + public bool TransactionInProgress() => _transaction != null; + public string GetTransactionOrignZoneIdentiifer() => _transaction?.SourceZoneIdentifier ?? string.Empty; + public string GetTransactionCurrentZoneIdentiifer() => _transaction?.CurrentZone ?? string.Empty; + public bool IsTransactionOriginatedFromInside(string identifier) => _transaction.SourceZoneIdentifier == identifier; + + public int GetTransactionIndex() => _transaction?.Index ?? -1; + public bool IsItemMovedDownwards() => _transaction.Index > _transaction.SourceIndex; + public bool HasTransactionIndexChanged() + { + if (_transaction == null) + { + return false; + } + + if (_transaction.CurrentZone != _transaction.SourceZoneIdentifier) + { + return true; + } + + return _transaction.Index != _transaction.SourceIndex; + } + + public bool IsOrign(int index, string identifier) + { + if (_transaction == null) + { + return false; + } + + if (identifier != _transaction.SourceZoneIdentifier) + { + return false; + } + + return _transaction.SourceIndex == index || _transaction.SourceIndex - 1 == index; + } + + public async Task CommitTransaction(string dropzoneIdentifier, bool reorderIsAllowed) + { + await _transaction.Commit(); + var index = -1; + if (reorderIsAllowed == true) + { + index = GetTransactionIndex() + 1; + if (_transaction.SourceZoneIdentifier == _transaction.CurrentZone && IsItemMovedDownwards() == true) + { + index -= 1; + } + } + + await ItemDropped.InvokeAsync(new ItemDropInfo(_transaction.Item, dropzoneIdentifier, index)); + var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs(dropzoneIdentifier, true, _transaction); + _transaction = null; + TransactionEnded?.Invoke(this, transactionFinishedEventArgs); + } + + public async Task CancelTransaction() + { + await _transaction.Cancel(); + var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs(_transaction); + _transaction = null; + TransactionEnded?.Invoke(this, transactionFinishedEventArgs); + } + + public void UpdateTransactionIndex(int index) + { + var changed = _transaction.UpdateIndex(index); + if (changed == false) { return; } + + TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, _transaction.CurrentZone, _transaction.Index)); + } + + internal void UpdateTransactionZone(string identifier) + { + var oldValue = _transaction.CurrentZone; + var changed = _transaction.UpdateZone(identifier); + if (changed == false) { return; } + + TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, oldValue, _transaction.Index)); + } + + + /// + /// Refreshes the dropzone and all items within. This is neded in case of adding items to the collection or changed values of items + /// + public void Refresh() => RefreshRequested?.Invoke(this, EventArgs.Empty); + + +} diff --git a/Components/DropZone/DropZone.razor b/Components/DropZone/DropZone.razor new file mode 100644 index 0000000..25f1213 --- /dev/null +++ b/Components/DropZone/DropZone.razor @@ -0,0 +1,69 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + + +
    + + @ChildContent + + @if (OnlyZone != true) + { + int index = 0; + var transactionIndex = Container?.GetTransactionIndex() ?? -1; + var items = GetItems(); + + @if (AllowReorder == true) + { + @if (items.Any() == false) + { +
    + } + else + { + if (transactionIndex == -1) + { +
    + } + + } + } + @foreach (var item in items) + { + var indexCopy = index; + + + @{ + var renderer = GetItemTemplate(); + } + + @renderer(item) + + + + + if (transactionIndex == indexCopy && IsOrign(indexCopy) == false ) + { +
    + } + + index++; + } + } +
    \ No newline at end of file diff --git a/Components/DropZone/DropZone.razor.cs b/Components/DropZone/DropZone.razor.cs new file mode 100644 index 0000000..cd28a9a --- /dev/null +++ b/Components/DropZone/DropZone.razor.cs @@ -0,0 +1,435 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected.Components; + +public partial class DropZone : UIComponent, IDisposable +{ + private bool _containerIsInitialized = false; + private bool _canDrop = false; + private bool _dragInProgress = false; + private bool _disposedValue = false; + private Guid _id = Guid.NewGuid(); + + private Dictionary _indicies = new(); + + [Inject] private IJSRuntime JsRuntime { get; set; } + + [CascadingParameter] + protected DropContainer Container { get; set; } + + /// + /// Child content of component + /// + [Parameter] + [Category(CategoryTypes.DropZone.Appearance)] + public RenderFragment ChildContent { get; set; } + + /// + /// The unique identifier of this drop zone. It is used within transaction to + /// + [Parameter] + [Category(CategoryTypes.DropZone.Appearance)] + public string Identifier { get; set; } + + /// + /// The render fragment (template) that should be used to render the items within a drop zone. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public RenderFragment ItemRenderer { get; set; } + + /// + /// The method is used to determinate if an item can be dropped within a drop zone. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.Items)] + public Func ItemsSelector { get; set; } + + /// + /// The method is used to determinate if an item can be dropped within a drop zone. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public Func CanDrop { get; set; } + + /// + /// The CSS class(es), that is applied to drop zones that are a valid target for drag and drop transaction. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public string CanDropClass { get; set; } + + /// + /// The CSS class(es), that is applied to drop zones that are NOT valid target for drag and drop transaction. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public string NoDropClass { get; set; } + + /// + /// If true, drop classes CanDropClass or NoDropClass or applied as soon, as a transaction has started. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.DropRules)] + public bool? ApplyDropClassesOnDragStarted { get; set; } + + /// + /// The method is used to determinate if an item should be disabled for dragging. Defaults to allow all items. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public Func ItemIsDisabled { get; set; } + + /// + /// If a drop item is disabled (determinate by ). This class is applied to the element. Overrides value provided by drop container + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public string DisabledClass { get; set; } + + /// + /// An additional class that is applied to the drop zone where a drag operation started + /// + [Parameter] + [Category(CategoryTypes.DropZone.DraggingClass)] + public string DraggingClass { get; set; } + + /// + /// An additional class that is applied to an drop item, when it is dragged + /// + [Parameter] + [Category(CategoryTypes.DropZone.DraggingClass)] + public string ItemDraggingClass { get; set; } + + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public bool AllowReorder { get; set; } + + /// + /// If true, will only act as a dropable zone and not render any items. + /// + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public bool OnlyZone { get; set; } + + #region view helper + + private int GetItemIndex(T item) + { + if (_indicies.ContainsKey(item) == false) + { + _indicies.Add(item, _indicies.Count); + } + + return _indicies[item]; + } + + private IEnumerable GetItems() + { + Func predicate = (item) => Container.ItemsSelector(item, Identifier ?? string.Empty); + if (ItemsSelector != null) + { + predicate = ItemsSelector; + } + + return (Container?.Items ?? Array.Empty()).Where(predicate).OrderBy(x => GetItemIndex(x)).ToArray(); + } + + private RenderFragment GetItemTemplate() => ItemRenderer ?? Container?.ItemRenderer; + + private string GetDragginClass() + { + if (string.IsNullOrEmpty(DraggingClass) == true) + { + return Container?.DraggingClass ?? string.Empty; + } + + return DraggingClass; + } + + private string GetItemDraggingClass() + { + if (string.IsNullOrEmpty(ItemDraggingClass) == false) + { + return ItemDraggingClass; + } + + return Container?.ItemDraggingClass ?? string.Empty; + } + + private bool GetApplyDropClassesOnDragStarted() => (ApplyDropClassesOnDragStarted ?? Container?.ApplyDropClassesOnDragStarted) ?? false; + + private bool GetItemDisabledStatus(T item) + { + var result = false; + var predicate = ItemIsDisabled ?? Container?.ItemIsDisabled; + if (predicate != null) + { + result = predicate(item); + } + + return result; + } + + protected string Classname => + new CssBuilder("mud-drop-zone") + //.AddClass("mud-drop-zone-drag-block", Container?.TransactionInProgress() == true && Container.GetTransactionOrignZoneIdentiifer() != Identifier) + .AddClass(CanDropClass ?? Container?.CanDropClass, Container?.TransactionInProgress() == true && Container.GetTransactionOrignZoneIdentiifer() != Identifier && _canDrop == true && (_dragCounter > 0 || GetApplyDropClassesOnDragStarted() == true)) + .AddClass(NoDropClass ?? Container?.NoDropClass, Container?.TransactionInProgress() == true && Container.GetTransactionOrignZoneIdentiifer() != Identifier && _canDrop == false && (_dragCounter > 0 || GetApplyDropClassesOnDragStarted() == true)) + .AddClass(GetDragginClass(), _dragInProgress == true) + .AddClass(Class) + .Build(); + + protected string PlaceholderClassname => + new CssBuilder("border-2 mud-border-primary border-dashed mud-chip-text mud-chip-color-primary pa-4 mud-dropitem-placeholder") + .AddClass("d-none", AllowReorder == false || (Container?.TransactionInProgress() == false || Container.GetTransactionCurrentZoneIdentiifer() != Identifier)) + .Build(); + + #endregion + + #region helper + + private (T, bool) ItemCanBeDropped() + { + if (Container == null || Container.TransactionInProgress() == false) + { + return (default(T), false); + } + + var item = Container.GetTransactionItem(); + + var result = true; + if (CanDrop != null) + { + result = CanDrop(item); + } + else if (Container.CanDrop != null) + { + result = Container.CanDrop(item, Identifier); + } + + return (item, result); + } + + private bool IsOrign(int index) => Container.IsOrign(index, Identifier); + + #endregion + + #region container event handling + + private void Container_TransactionEnded(object sender, DragAndDropTransactionFinishedEventArgs e) + { + _dragCounter = 0; + + if (GetApplyDropClassesOnDragStarted() == true) + { + _canDrop = false; + } + + if (e.Success == true) + { + if (e.OriginatedDropzoneIdentifier == Identifier && e.DestinationDropzoneIdentifier != e.OriginatedDropzoneIdentifier) + { + _indicies.Remove(e.Item); + } + + if (e.OriginatedDropzoneIdentifier == Identifier || e.DestinationDropzoneIdentifier == Identifier) + { + int index = 0; + + foreach (var item in _indicies.OrderBy(x => x.Value).ToArray()) + { + _indicies[item.Key] = index++; + } + } + } + + StateHasChanged(); + } + + private void Container_TransactionStarted(object sender, DragAndDropItemTransaction e) + { + if (GetApplyDropClassesOnDragStarted() == true) + { + var dropResult = ItemCanBeDropped(); + _canDrop = dropResult.Item2; + } + + StateHasChanged(); + } + + private void Container_RefreshRequested(object sender, EventArgs e) + { + _indicies.Clear(); + InvokeAsync(StateHasChanged); + } + + #endregion + + #region handling event callbacks + + private int _dragCounter = 0; + + private void HandleDragEnter() + { + _dragCounter++; + + var (context, isValidZone) = ItemCanBeDropped(); + if (context == null) + { + return; + } + + _canDrop = isValidZone; + + Container.UpdateTransactionZone(Identifier); + } + + private void HandleDragLeave() + { + _dragCounter--; + + var (context, _) = ItemCanBeDropped(); + if (context == null) + { + return; + } + } + + private async Task HandleDrop() + { + var (context, isValidZone) = ItemCanBeDropped(); + if (context == null) + { + return; + } + + _dragCounter = 0; + + if (isValidZone == false) + { + await Container.CancelTransaction(); + return; + } + + if (AllowReorder == true) + { + if (Container.HasTransactionIndexChanged() == true) + { + var newIndex = Container.GetTransactionIndex() + 1; + + if (Container.IsTransactionOriginatedFromInside(this.Identifier) == true) + { + var oldIndex = _indicies[context]; + + if (Container.IsItemMovedDownwards() == true) + { + newIndex -= 1; + + foreach (var item in _indicies.Where(x => x.Value >= oldIndex + 1 && x.Value <= newIndex).ToArray()) + { + _indicies[item.Key] -= 1; + } + } + else + { + foreach (var item in _indicies.Where(x => x.Value >= newIndex && x.Value < oldIndex).ToArray()) + { + _indicies[item.Key] += 1; + } + } + + _indicies[context] = newIndex; + } + else + { + foreach (var item in _indicies.Where(x => x.Value >= newIndex).ToArray()) + { + _indicies[item.Key] = item.Value + 1; + } + + _indicies.Add(context, newIndex); + } + } + } + else + { + _indicies.Clear(); + } + + await Container.CommitTransaction(Identifier, AllowReorder); + } + + private void FinishedDragOperation() => _dragInProgress = false; + private void DragOperationStarted() => _dragInProgress = true; + + #endregion + + #region life cycle + + protected override void OnParametersSet() + { + if (Container != null && _containerIsInitialized == false) + { + _containerIsInitialized = true; + Container.TransactionStarted += Container_TransactionStarted; + Container.TransactionEnded += Container_TransactionEnded; + Container.RefreshRequested += Container_RefreshRequested; + Container.TransactionIndexChanged += Container_TransactionIndexChanged; + } + + base.OnParametersSet(); + } + + private void Container_TransactionIndexChanged(object sender, DragAndDropIndexChangedEventArgs e) + { + if (e.ZoneIdentifier != Identifier && e.OldZoneIdentifier != Identifier) { return; } + + StateHasChanged(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender == true) + { + await JsRuntime.InvokeVoidAsyncWithErrorHandling("mudDragAndDrop.initDropZone", _id.ToString()); + } + + await base.OnAfterRenderAsync(firstRender); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + if (Container != null) + { + Container.TransactionStarted -= Container_TransactionStarted; + Container.TransactionEnded -= Container_TransactionEnded; + Container.RefreshRequested -= Container_RefreshRequested; + Container.TransactionIndexChanged -= Container_TransactionIndexChanged; + + } + } + + _disposedValue = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + #endregion +} diff --git a/Components/DropZone/DynamicDropItem.razor b/Components/DropZone/DynamicDropItem.razor new file mode 100644 index 0000000..998aadf --- /dev/null +++ b/Components/DropZone/DynamicDropItem.razor @@ -0,0 +1,16 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + +
    + @if (HideContent == false) + { + @ChildContent + } +
    \ No newline at end of file diff --git a/Components/DropZone/DynamicDropItem.razor.cs b/Components/DropZone/DynamicDropItem.razor.cs new file mode 100644 index 0000000..0e3cfb2 --- /dev/null +++ b/Components/DropZone/DynamicDropItem.razor.cs @@ -0,0 +1,143 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class DynamicDropItem : UIComponent +{ + private bool _dragOperationIsInProgress = false; + + [CascadingParameter] + protected DropContainer Container { get; set; } + + /// + /// The zone identifier of the corresponding drop zone + /// + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public string ZoneIdentifier { get; set; } + + /// + /// the data item that is represneted by this item + /// + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public T Item { get; set; } + + /// + /// Child content of component + /// + [Parameter] + [Category(CategoryTypes.DropZone.Appearance)] + public RenderFragment ChildContent { get; set; } + + /// + /// An additional class that is applied to this element when a drag operation is in progress + /// + [Parameter] + [Category(CategoryTypes.DropZone.DraggingClass)] + public string DraggingClass { get; set; } + + /// + /// An event callback set fires, when a drag operation has been started + /// + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public EventCallback OnDragStarted { get; set; } + + /// + /// An event callback set fires, when a drag operation has been eneded. This included also a cancelled transaction + /// + [Parameter] + [Category(CategoryTypes.DropZone.Behavior)] + public EventCallback OnDragEnded { get; set; } + + /// + /// When true, the item can't be dragged. defaults to false + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public bool Disabled { get; set; } = false; + + /// + /// The class that is applied when disabled is set to true + /// + [Parameter] + [Category(CategoryTypes.DropZone.Disabled)] + public string DisabledClass { get; set; } + + [Parameter] + [Category(CategoryTypes.DropZone.Sorting)] + public int Index { get; set; } = -1; + + [Parameter] + [Category(CategoryTypes.DropZone.Sorting)] + public bool HideContent { get; set; } + + #region Event handling and callbacks + + private async Task DragStarted() + { + if (Container == null) { return; } + + _dragOperationIsInProgress = true; + Container.StartTransaction(Item, ZoneIdentifier ?? string.Empty, Index, OnDroppedSucceeded, OnDroppedCanceled); + await OnDragStarted.InvokeAsync(); + } + + private async Task OnDroppedSucceeded() + { + _dragOperationIsInProgress = false; + + await OnDragEnded.InvokeAsync(Item); + StateHasChanged(); + } + + private async Task OnDroppedCanceled() + { + _dragOperationIsInProgress = false; + + await OnDragEnded.InvokeAsync(Item); + StateHasChanged(); + } + + private async Task DragEnded(DragEventArgs e) + { + if (_dragOperationIsInProgress == true) + { + _dragOperationIsInProgress = false; + await Container?.CancelTransaction(); + } + else + { + await OnDragEnded.InvokeAsync(Item); + } + } + + private void HandleDragEnter() + { + if (Container == null || Container.TransactionInProgress() == false) { return; } + + Container.UpdateTransactionIndex(Index); + } + + private void HandleDragLeave() + { + } + + #endregion + + protected string Classname => + new CssBuilder("mud-drop-item") + .AddClass(DraggingClass, _dragOperationIsInProgress == true) + .AddClass(DisabledClass, Disabled == true) + .AddClass(Class) + .Build(); + +} diff --git a/Components/Element/Element.cs b/Components/Element/Element.cs new file mode 100644 index 0000000..edf9d84 --- /dev/null +++ b/Components/Element/Element.cs @@ -0,0 +1,84 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +/// +/// Primitive component which allows rendering any HTML element we want +/// through the HtmlTag property +/// +public class Element : UIComponent +{ + /// + /// Child content + /// + [Parameter] + [Category(CategoryTypes.Element.Misc)] + public RenderFragment ChildContent { get; set; } + + /// + /// The HTML element that will be rendered in the root by the component + /// + [Parameter] + [Category(CategoryTypes.Element.Misc)] + public string HtmlTag { get; set; } = "span"; + /// + /// The ElementReference to bind to. + /// Use like @bind-Ref="myRef" + /// + [Parameter] + [Category(CategoryTypes.Element.Misc)] + public ElementReference? Ref { get; set; } + + [Parameter] public EventCallback RefChanged { get; set; } + + /// + /// Calling StateHasChanged to refresh the component's state + /// + public void Refresh() => StateHasChanged(); + + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + base.BuildRenderTree(builder); + //Open + builder.OpenElement(0, HtmlTag); + + //splatted attributes + foreach (var attribute in UserAttributes) + { + // checking if the value is null, we can get rid of null event handlers + // for example `@onmouseenter=@(IsOpen ? HandleEnter : null)` + // this is a powerful feature that in normal HTML elements doesn't work, because + // Blazor adds always the attribute value and creates an EventCallback + if (attribute.Value != null) + builder.AddAttribute(1, attribute.Key, attribute.Value); + } + //Class + builder.AddAttribute(2, "class", Class); + //Style + builder.AddAttribute(3, "style", Style); + + // StopPropagation + // the order matters. This has to be before content is added + if (HtmlTag == "button") + builder.AddEventStopPropagationAttribute(5, "onclick", true); + + //Reference capture + if (Ref != null) + { + builder.AddElementReferenceCapture(6, async capturedRef => + { + Ref = capturedRef; + await RefChanged.InvokeAsync(Ref.Value); + }); + } + + //Content + builder.AddContent(10, ChildContent); + + //Close + builder.CloseElement(); + } +} diff --git a/Components/ExpansionPanel/ExpansionPanel.razor b/Components/ExpansionPanel/ExpansionPanel.razor new file mode 100644 index 0000000..d30885b --- /dev/null +++ b/Components/ExpansionPanel/ExpansionPanel.razor @@ -0,0 +1,26 @@ +@namespace Connected.Components +@inherits UIComponent + +
    +
    +
    + @if (TitleContent != null) + { + @TitleContent + } + else + { + @Text + } +
    + @if (!HideIcon) + { + + } +
    + +
    + @ChildContent +
    +
    +
    diff --git a/Components/ExpansionPanel/ExpansionPanel.razor.cs b/Components/ExpansionPanel/ExpansionPanel.razor.cs new file mode 100644 index 0000000..359616d --- /dev/null +++ b/Components/ExpansionPanel/ExpansionPanel.razor.cs @@ -0,0 +1,199 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ExpansionPanel : UIComponent, IDisposable +{ + private bool _nextPanelExpanded; + private bool _isExpanded; + private bool _collapseIsExpanded; + + [CascadingParameter] private ExpansionPanels Parent { get; set; } + + protected string Classname => + new CssBuilder("mud-expand-panel") + .AddClass("mud-panel-expanded", IsExpanded) + .AddClass("mud-panel-next-expanded", NextPanelExpanded) + .AddClass("mud-disabled", Disabled) + .AddClass($"mud-elevation-{Parent?.Elevation.ToString()}") + .AddClass($"mud-expand-panel-border", Parent?.DisableBorders != true) + .AddClass(Class) + .Build(); + + protected string PanelContentClassname => + new CssBuilder("mud-expand-panel-content") + .AddClass("mud-expand-panel-gutters", DisableGutters || Parent?.DisableGutters == true) + .AddClass("mud-expand-panel-dense", Dense || Parent?.Dense == true) + .Build(); + + /// + /// Explicitly sets the height for the Collapse element to override the css default. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public int? MaxHeight { get; set; } + + /// + /// RenderFragment to be displayed in the expansion panel which will override header text if defined. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public RenderFragment TitleContent { get; set; } + + /// + /// The text to be displayed in the expansion panel. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public string Text { get; set; } + + /// + /// If true, expand icon will not show + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool HideIcon { get; set; } + + /// + /// Custom hide icon. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public string Icon { get; set; } = Icons.Material.Filled.ExpandMore; + + /// + /// If true, removes vertical padding from childcontent. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool Dense { get; set; } + + /// + /// If true, the left and right padding is removed from childcontent. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool DisableGutters { get; set; } + + /// + /// Raised when IsExpanded changes. + /// + [Parameter] public EventCallback IsExpandedChanged { get; set; } + + internal event Action NotifyIsExpandedChanged; + /// + /// Expansion state of the panel (two-way bindable) + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public bool IsExpanded + { + get => _isExpanded; + set + { + if (_isExpanded == value) + return; + _isExpanded = value; + + NotifyIsExpandedChanged?.Invoke(this); + IsExpandedChanged.InvokeAsync(_isExpanded).ContinueWith(t => + { + if (_collapseIsExpanded != _isExpanded) + { + _collapseIsExpanded = _isExpanded; + InvokeAsync(() => StateHasChanged()); + } + }); + } + } + + /// + /// Sets the initial expansion state. Do not use in combination with IsExpanded. + /// Combine with MultiExpansion to have more than one panel start open. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public bool IsInitiallyExpanded { get; set; } + + /// + /// If true, the component will be disabled. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public bool Disabled { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public RenderFragment ChildContent { get; set; } + + public bool NextPanelExpanded + { + get => _nextPanelExpanded; + set + { + if (_nextPanelExpanded == value) + return; + _nextPanelExpanded = value; + //InvokeAsync(StateHasChanged); + } + } + + public void ToggleExpansion() + { + if (Disabled) + { + return; + } + + IsExpanded = !IsExpanded; + } + + public void Expand(bool update_parent = true) + { + if (update_parent) + IsExpanded = true; + else + { + _isExpanded = true; + _collapseIsExpanded = true; + IsExpandedChanged.InvokeAsync(_isExpanded); + } + } + + public void Collapse(bool update_parent = true) + { + if (update_parent) + IsExpanded = false; + else + { + _isExpanded = false; + _collapseIsExpanded = false; + IsExpandedChanged.InvokeAsync(_isExpanded); + } + } + + protected override void OnInitialized() + { + // NOTE: we can't throw here because we need to be able to instanciate the type for the API Docs to infer default values + //if (Parent == null) + // throw new ArgumentNullException(nameof(Parent), "ExpansionPanel must exist within a ExpansionPanels component"); + base.OnInitialized(); + if (!IsExpanded && IsInitiallyExpanded) + { + _isExpanded = true; + _collapseIsExpanded = true; + } + + Parent?.AddPanel(this); + } + + public void Dispose() + { + Parent?.RemovePanel(this); + } +} diff --git a/Components/ExpansionPanel/ExpansionPanels.razor b/Components/ExpansionPanel/ExpansionPanels.razor new file mode 100644 index 0000000..a777bb5 --- /dev/null +++ b/Components/ExpansionPanel/ExpansionPanels.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + @ChildContent + +
    diff --git a/Components/ExpansionPanel/ExpansionPanels.razor.cs b/Components/ExpansionPanel/ExpansionPanels.razor.cs new file mode 100644 index 0000000..017ac8a --- /dev/null +++ b/Components/ExpansionPanel/ExpansionPanels.razor.cs @@ -0,0 +1,157 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ExpansionPanels : UIComponent +{ + protected string Classname => + new CssBuilder("mud-expansion-panels") + .AddClass($"mud-expansion-panels-square", Square) + .AddClass(Class) + .Build(); + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool Square { get; set; } + + /// + /// If true, multiple panels can be expanded at the same time. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public bool MultiExpansion { get; set; } + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// If true, removes vertical padding from all panels' childcontent. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool Dense { get; set; } + + /// + /// If true, the left and right padding is removed from all panels' childcontent. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool DisableGutters { get; set; } + + /// + /// If true, the borders around each panel will be removed. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Appearance)] + public bool DisableBorders { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ExpansionPanel.Behavior)] + public RenderFragment ChildContent { get; set; } + + private List _panels = new(); + + internal void AddPanel(ExpansionPanel panel) + { + if (MultiExpansion == false && _panels.Any(p => p.IsExpanded)) + { + panel.Collapse(update_parent: false); + } + + panel.NotifyIsExpandedChanged += UpdatePanelsOnPanelsChanged; + _panels.Add(panel); + } + + public void RemovePanel(ExpansionPanel panel) + { + panel.NotifyIsExpandedChanged -= UpdatePanelsOnPanelsChanged; + _panels.Remove(panel); + try + { + StateHasChanged(); + } + catch (InvalidOperationException) { /* this happens on page reload, probably a Blazor bug */ } + } + + internal void UpdatePanelsOnPanelsChanged(ExpansionPanel panel) + { + if (MultiExpansion == false && panel.IsExpanded) + { + CollapseAllExcept(panel); + return; + } + + UpdateAll(); + } + + public void UpdateAll() + { + ExpansionPanel last = null; + foreach (var panel in _panels) + { + if (last != null) + last.NextPanelExpanded = panel.IsExpanded; + last = panel; + } + StateHasChanged(); + } + + [Obsolete("Use CollapseAllExcept instead.")] + [ExcludeFromCodeCoverage] + public void CloseAllExcept(ExpansionPanel panel) + { + CollapseAllExcept(panel); + } + + /// + /// Collapses all panels except the given one. + /// + /// The panel not to collapse. + public void CollapseAllExcept(ExpansionPanel panel) + { + foreach (var p in _panels) + { + if (p == panel) + continue; + p.Collapse(update_parent: false); + } + this.InvokeAsync(UpdateAll); + } + + /// + /// Collapses all panels. + /// + public void CollapseAll() + { + foreach (var p in _panels) + { + p.Collapse(update_parent: false); + } + this.InvokeAsync(UpdateAll); + } + + /// + /// Expands all panels. + /// + public void ExpandAll() + { + foreach (var p in _panels) + { + p.Expand(update_parent: false); + } + this.InvokeAsync(UpdateAll); + } +} diff --git a/Components/Field/Field.razor b/Components/Field/Field.razor new file mode 100644 index 0000000..1650588 --- /dev/null +++ b/Components/Field/Field.razor @@ -0,0 +1,26 @@ +@namespace Connected.Components +@inherits UIComponent + + + +
    + @if (Adornment == Adornment.Start) + { + + } +
    + @ChildContent +
    + @if (Adornment == Adornment.End) + { + + } + @if (Variant == Variant.Outlined) + { +
    + } +
    +
    +
    + diff --git a/Components/Field/Field.razor.cs b/Components/Field/Field.razor.cs new file mode 100644 index 0000000..8402307 --- /dev/null +++ b/Components/Field/Field.razor.cs @@ -0,0 +1,160 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +//TODO Maybe can inherit from MudBaseInput? +public partial class Field : UIComponent +{ + protected string Classname => + new CssBuilder("mud-input") + .AddClass($"mud-input-{Variant.ToDescriptionString()}") + .AddClass($"mud-input-adorned-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-input-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .AddClass("mud-input-underline", when: () => DisableUnderLine == false && Variant != Variant.Outlined) + .AddClass("mud-shrink", when: () => !string.IsNullOrWhiteSpace(ChildContent?.ToString()) || Adornment == Adornment.Start) + .AddClass("mud-disabled", Disabled) + .AddClass("mud-input-error", Error && !string.IsNullOrEmpty(ErrorText)) + .Build(); + + protected string InnerClassname => + new CssBuilder("mud-input-slot") + .AddClass("mud-input-root") + .AddClass("mud-input-slot-nopadding", when: () => InnerPadding == false) + .AddClass($"mud-input-root-{Variant.ToDescriptionString()}") + .AddClass($"mud-input-adorned-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-input-root-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .Build(); + + protected string AdornmentClassname => + new CssBuilder("mud-input-adornment") + .AddClass($"mud-input-adornment-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-text", !string.IsNullOrEmpty(AdornmentText)) + .AddClass($"mud-input-root-filled-shrink", Variant == Variant.Filled) + .Build(); + + protected string InputControlClassname => + new CssBuilder("mud-field") + .AddClass(Class) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Field.Data)] + public RenderFragment ChildContent { get; set; } + + /// + /// Will adjust vertical spacing. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public Margin Margin { get; set; } = Margin.None; + + /// + /// If true, the label will be displayed in an error state. + /// + [Parameter] + [Category(CategoryTypes.Field.Validation)] + public bool Error { get; set; } + + /// + /// The ErrorText that will be displayed if Error true + /// + [Parameter] + [Category(CategoryTypes.Field.Validation)] + public string ErrorText { get; set; } + + /// + /// The HelperText will be displayed below the text field. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public string HelperText { get; set; } + + /// + /// If true, the field will take up the full width of its container. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public bool FullWidth { get; set; } + + /// + /// If string has value the label text will be displayed in the input, and scaled down at the top if the field has value. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public string Label { get; set; } + + /// + /// Variant can be Text, Filled or Outlined. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// If true, the input element will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public bool Disabled { get; set; } + + /// + /// Icon that will be used if Adornment is set to Start or End. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public string AdornmentIcon { get; set; } + + /// + /// Text that will be used if Adornment is set to Start or End, the Text overrides Icon. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public string AdornmentText { get; set; } + + /// + /// The Adornment if used. By default, it is set to None. + /// + [Parameter] + [Category(CategoryTypes.Field.Behavior)] + public Adornment Adornment { get; set; } = Adornment.None; + + /// + /// The color of the adornment if used. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor AdornmentColor { get; set; } = ThemeColor.Default; + + /// + /// Sets the Icon Size. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + /// + /// Button click event if set and Adornment used. + /// + [Parameter] public EventCallback OnAdornmentClick { get; set; } + + /// + /// If true, the inner contents padding is removed. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public bool InnerPadding { get; set; } = true; + + /// + /// If true, the field will not have an underline. + /// + [Parameter] + [Category(CategoryTypes.Field.Appearance)] + public bool DisableUnderLine { get; set; } +} diff --git a/Components/FileUpload/FileUpload.razor b/Components/FileUpload/FileUpload.razor new file mode 100644 index 0000000..55d5f44 --- /dev/null +++ b/Components/FileUpload/FileUpload.razor @@ -0,0 +1,18 @@ +@inherits FormComponent; +@typeparam T; +@namespace Connected.Components +@using Microsoft.AspNetCore.Components.Forms + + + + + \ No newline at end of file diff --git a/Components/FileUpload/FileUpload.razor.cs b/Components/FileUpload/FileUpload.razor.cs new file mode 100644 index 0000000..a3562e6 --- /dev/null +++ b/Components/FileUpload/FileUpload.razor.cs @@ -0,0 +1,123 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.Extensions.Logging; +using Connected.Utilities; + +namespace Connected.Components; + +public partial class FileUpload : FormComponent +{ + public FileUpload() : base(new DefaultConverter()) { } + + private readonly string _id = $"mud_fileupload_{Guid.NewGuid()}"; + + protected string Classname => + new CssBuilder("mud-file-upload") + .AddClass(Class) + .Build(); + + /// + /// The value of the MudFileUpload component. + /// If T is IBrowserFile, it represents a single file. + /// If T is IReadOnlyList<IBrowserFile>, it represents multiple files + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Behavior)] + public T Files + { + get => _value; + set + { + if (_value != null && _value.Equals(value)) + return; + _value = value; + } + } + /// + /// Triggered when the internal OnChange event fires + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Behavior)] + public EventCallback FilesChanged { get; set; } + + /// + /// Called when the internal files are changed + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Behavior)] + public EventCallback OnFilesChanged { get; set; } + /// + /// Renders the button that triggers the input. Required for functioning. + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Appearance)] + public RenderFragment ButtonTemplate { get; set; } + /// + /// Renders the selected files, if desired. + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Appearance)] + public RenderFragment SelectedTemplate { get; set; } + /// + /// If true, OnFilesChanged will not trigger if validation fails + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Behavior)] + public bool SuppressOnChangeWhenInvalid { get; set; } + /// + /// Sets the file types this input will accept + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Behavior)] + public string Accept { get; set; } + /// + /// If false, the inner FileInput will be visible + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Appearance)] + public bool Hidden { get; set; } = true; + /// + /// Css classes to apply to the internal InputFile + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Appearance)] + public string InputClass { get; set; } + /// + /// Style to apply to the internal InputFile + /// + [Parameter] + [Category(CategoryTypes.FileUpload.Appearance)] + public string InputStyle { get; set; } + + private async Task OnChange(InputFileChangeEventArgs args) + { + if (typeof(T) == typeof(IReadOnlyList)) + { + _value = (T)args.GetMultipleFiles(); + } + else if (typeof(T) == typeof(IBrowserFile)) + { + _value = (T)args.File; + } + else return; + + await FilesChanged.InvokeAsync(_value); + BeginValidate(); + FieldChanged(_value); + if (!Error || !SuppressOnChangeWhenInvalid) //only trigger FilesChanged if validation passes or SuppressOnChangeWhenInvalid is false + await OnFilesChanged.InvokeAsync(args); + } + + protected override void OnInitialized() + { + if (!(typeof(T) == typeof(IReadOnlyList) || typeof(T) == typeof(IBrowserFile))) + Logger.LogWarning("T must be of type {type1} or {type2}", typeof(IReadOnlyList), typeof(IBrowserFile)); + + base.OnInitialized(); + } +} diff --git a/Components/FocusTrap/FocusTrap.razor b/Components/FocusTrap/FocusTrap.razor new file mode 100644 index 0000000..92a0fd0 --- /dev/null +++ b/Components/FocusTrap/FocusTrap.razor @@ -0,0 +1,39 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + +
    +
    + +
    +
    + +
    +
    + + @ChildContent + +
    +
    + +
    +
    + +
    + +@code { + string TrapTabIndex => (Disabled? "-1" : "0"); +} \ No newline at end of file diff --git a/Components/FocusTrap/FocusTrap.razor.cs b/Components/FocusTrap/FocusTrap.razor.cs new file mode 100644 index 0000000..f99f3c0 --- /dev/null +++ b/Components/FocusTrap/FocusTrap.razor.cs @@ -0,0 +1,161 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class FocusTrap : IDisposable +{ + protected string Classname => + new CssBuilder("outline-none") + .AddClass(Class) + .Build(); + + protected ElementReference _firstBumper; + protected ElementReference _lastBumper; + protected ElementReference _fallback; + protected ElementReference _root; + + private bool _shiftDown; + private bool _disabled; + private bool _initialized; + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.FocusTrap.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If true, the focus will no longer loop inside the component. + /// + [Parameter] + [Category(CategoryTypes.FocusTrap.Behavior)] + public bool Disabled + { + get => _disabled; + set + { + if (_disabled != value) + { + _disabled = value; + _initialized = false; + } + } + } + + /// + /// Defines on which element to set the focus when the component is created or enabled. + /// When DefaultFocus.Element is used, the focus will be set to the FocusTrap itself, so the user will have to press TAB key once to focus the first tabbable element. + /// + [Parameter] + [Category(CategoryTypes.FocusTrap.Behavior)] + public DefaultFocus DefaultFocus { get; set; } = DefaultFocus.FirstChild; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender) + await SaveFocusAsync(); + + if (!_initialized) + await InitializeFocusAsync(); + } + + private Task OnBottomFocusAsync(FocusEventArgs args) + { + return FocusLastAsync(); + } + + private Task OnBumperFocusAsync(FocusEventArgs args) + { + return _shiftDown ? FocusLastAsync() : FocusFirstAsync(); + } + + private Task OnRootFocusAsync(FocusEventArgs args) + { + return FocusFallbackAsync(); + } + + private void OnRootKeyDown(KeyboardEventArgs args) + { + HandleKeyEvent(args); + } + + private void OnRootKeyUp(KeyboardEventArgs args) + { + HandleKeyEvent(args); + } + + private Task OnTopFocusAsync(FocusEventArgs args) + { + return FocusFirstAsync(); + } + + private Task InitializeFocusAsync() + { + _initialized = true; + + if (!_disabled) + { + switch (DefaultFocus) + { + case DefaultFocus.Element: return FocusFallbackAsync(); + case DefaultFocus.FirstChild: return FocusFirstAsync(); + case DefaultFocus.LastChild: return FocusLastAsync(); + } + } + return Task.CompletedTask; + } + + private Task FocusFallbackAsync() + { + return _fallback.FocusAsync().AsTask(); + } + + private Task FocusFirstAsync() + { + return _root.FocusFirstAsync(2, 4).AsTask(); + } + + private Task FocusLastAsync() + { + return _root.FocusLastAsync(2, 4).AsTask(); + } + + private void HandleKeyEvent(KeyboardEventArgs args) + { + _shouldRender = false; + if (args.Key == "Tab") + _shiftDown = args.ShiftKey; + } + + private Task RestoreFocusAsync() + { + return _root.RestoreFocusAsync().AsTask(); + } + + private Task SaveFocusAsync() + { + return _root.SaveFocusAsync().AsTask(); + } + + bool _shouldRender = true; + + protected override bool ShouldRender() + { + if (_shouldRender) + return true; + _shouldRender = true; // auto-reset _shouldRender to true + return false; + } + + public void Dispose() + { + if (!_disabled) + RestoreFocusAsync().AndForget(TaskOption.Safe); + } +} diff --git a/Components/Form/Form.razor b/Components/Form/Form.razor new file mode 100644 index 0000000..76af19e --- /dev/null +++ b/Components/Form/Form.razor @@ -0,0 +1,16 @@ +@namespace Connected.Components +@inherits UIComponent + + +
    + @if (SuppressImplicitSubmission) + { + + + + } + + @ChildContent + +
    + diff --git a/Components/Form/Form.razor.cs b/Components/Form/Form.razor.cs new file mode 100644 index 0000000..95f3747 --- /dev/null +++ b/Components/Form/Form.razor.cs @@ -0,0 +1,326 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Form : UIComponent, IDisposable, IForm +{ + protected string Classname => + new CssBuilder("mud-form") + .AddClass(Class) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Form.ValidatedData)] + public RenderFragment ChildContent { get; set; } + + /// + /// Validation status. True if the form is valid and without errors. This parameter is two-way bindable. + /// + [Parameter] + [Category(CategoryTypes.Form.ValidationResult)] + public bool IsValid + { + get => _valid && ChildForms.All(x => x.IsValid); + set + { + _valid = value; + } + } + + // Note: w/o any children the form is automatically valid. + // It stays valid, as long as non-required fields are added or + // a required field is added or the user touches a field that fails validation. + private bool _valid = true; + + private void SetIsValid(bool value) + { + if (IsValid == value) + return; + IsValid = value; + IsValidChanged.InvokeAsync(IsValid).AndForget(); + } + + // Note: w/o any children the form is automatically valid. + // It stays valid, as long as non-required fields are added or + // a required field is added or the user touches a field that fails validation. + + /// + /// True if any field of the field was touched. This parameter is readonly. + /// + [Parameter] + [Category(CategoryTypes.Form.Behavior)] + public bool IsTouched { get => _touched; set {/* readonly parameter! */ } } + + private bool _touched = false; + + /// + /// Validation debounce delay in milliseconds. This can help improve rendering performance of forms with real-time validation of inputs + /// i.e. when textfields have Immediate="true". + /// + [Parameter] + [Category(CategoryTypes.Form.Behavior)] + public int ValidationDelay { get; set; } = 300; + + /// + /// When true, the form will not re-render its child contents on validation updates (i.e. when IsValid changes). + /// This is an optimization which can be necessary especially for larger forms on older devices. + /// + [Parameter] + [Category(CategoryTypes.Form.Behavior)] + public bool SuppressRenderingOnValidation { get; set; } = false; + + /// + /// When true, will not cause a page refresh on Enter if any input has focus. + /// + /// + /// https://www.w3.org/TR/2018/SPSD-html5-20180327/forms.html#implicit-submission + /// Usually this is not wanted, as it can cause a page refresh in the middle of editing a form. + /// When the form is in a dialog this will cause the dialog to close. So by default we suppress it. + /// + [Parameter] + [Category(CategoryTypes.Form.Behavior)] + public bool SuppressImplicitSubmission { get; set; } = true; + + /// + /// Raised when IsValid changes. + /// + [Parameter] public EventCallback IsValidChanged { get; set; } + + /// + /// Raised when IsTouched changes. + /// + [Parameter] public EventCallback IsTouchedChanged { get; set; } + + /// + /// Raised when a contained IFormComponent changes its value + /// + [Parameter] public EventCallback FieldChanged { get; set; } + + // keeps track of validation. if the input was validated at least once the value will be true + protected HashSet _formControls = new(); + protected HashSet _errors = new(); + + /// + /// A default validation func or a validation attribute to use for form controls that don't have one. + /// Supported types are: + /// Func<T, bool> ... will output the standard error message "Invalid" if false + /// Func<T, string> ... outputs the result as error message, no error if null + /// Func<T, IEnumerable< string >> ... outputs all the returned error messages, no error if empty + /// Func<object, string, IEnumerable< string >> input Form.Model, Full Path of Member ... outputs all the returned error messages, no error if empty + /// Func<T, Task< bool >> ... will output the standard error message "Invalid" if false + /// Func<T, Task< string >> ... outputs the result as error message, no error if null + /// Func<T, Task<IEnumerable< string >>> ... outputs all the returned error messages, no error if empty + /// Func<object, string, Task<IEnumerable< string >>> input Form.Model, Full Path of Member ... outputs all the returned error messages, no error if empty + /// System.ComponentModel.DataAnnotations.ValidationAttribute instances + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public object Validation { get; set; } + + /// + /// If a field already has a validation, override it with . + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public bool? OverrideFieldValidation { get; set; } + + /// + /// Validation error messages. + /// + [Parameter] + [Category(CategoryTypes.Form.ValidationResult)] + public string[] Errors + { + get => _errors.ToArray(); + set { /* readonly */ } + } + + [Parameter] public EventCallback ErrorsChanged { get; set; } + + /// + /// Specifies the top-level model object for the form. Used with Fluent Validation + /// +#nullable enable + [Parameter] + [Category(CategoryTypes.Form.ValidatedData)] + public object? Model { get; set; } +#nullable disable + + private HashSet
    ChildForms { get; set; } = new HashSet(); + + [CascadingParameter] private Form ParentForm { get; set; } + + void IForm.FieldChanged(IFormComponent formControl, object newValue) + { + FieldChanged.InvokeAsync(new FormFieldChangedEventArgs { Field = formControl, NewValue = newValue }).AndForget(); + } + + void IForm.Add(IFormComponent formControl) + { + if (formControl.Required) + SetIsValid(false); + _formControls.Add(formControl); + SetDefaultControlValidation(formControl); + } + + void IForm.Remove(IFormComponent formControl) + { + _formControls.Remove(formControl); + } + + private Timer _timer; + + /// + /// Called by any input of the form to signal that its value changed. + /// + /// + void IForm.Update(IFormComponent formControl) + { + EvaluateForm(); + } + + private void EvaluateForm(bool debounce = true) + { + _timer?.Dispose(); + if (debounce && ValidationDelay > 0) + _timer = new Timer(OnTimerComplete, null, ValidationDelay, Timeout.Infinite); + else + _ = OnEvaluateForm(); + } + + private void OnTimerComplete(object stateInfo) => InvokeAsync(OnEvaluateForm); + + private bool _shouldRender = true; // <-- default is true, we need the form children to render + + protected async Task OnEvaluateForm() + { + _errors.Clear(); + foreach (var error in _formControls.SelectMany(control => control.ValidationErrors)) + _errors.Add(error); + // form can only be valid if: + // - none have an error + // - all required fields have been touched (and thus validated) + var no_errors = _formControls.All(x => x.HasErrors == false); + var required_all_touched = _formControls.Where(x => x.Required).All(x => x.Touched); + var valid = no_errors && required_all_touched; + + var old_touched = _touched; + _touched = _formControls.Any(x => x.Touched); + try + { + _shouldRender = false; + SetIsValid(valid); + await ErrorsChanged.InvokeAsync(Errors); + if (old_touched != _touched) + await IsTouchedChanged.InvokeAsync(_touched); + } + finally + { + _shouldRender = true; + } + } + + protected override bool ShouldRender() + { + if (!SuppressRenderingOnValidation) + return true; + return _shouldRender; + } + + /// + /// Force a validation of all form controls, even if they haven't been touched by the user yet. + /// + public async Task Validate() + { + await Task.WhenAll(_formControls.Select(x => x.Validate())); + + if (ChildForms.Count > 0) + { + await Task.WhenAll(ChildForms.Select(x => x.Validate())); + } + + EvaluateForm(debounce: false); + } + + /// + /// Reset all form controls and reset their validation state. + /// + public void Reset() + { + foreach (var control in _formControls.ToArray()) + { + control.Reset(); + } + + foreach (var form in ChildForms) + { + form.Reset(); + } + + EvaluateForm(debounce: false); + } + + /// + /// Reset the validation state but keep the values. + /// + public void ResetValidation() + { + foreach (var control in _formControls.ToArray()) + { + control.ResetValidation(); + } + + foreach (var form in ChildForms) + { + form.ResetValidation(); + } + + EvaluateForm(debounce: false); + } + + protected override Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + var valid = _formControls.All(x => x.Required == false); + if (valid != IsValid) + { + // the user probably bound a variable to IsValid and it conflicts with our state. + // let's set this right + SetIsValid(valid); + } + + } + return base.OnAfterRenderAsync(firstRender); + } + + private void SetDefaultControlValidation(IFormComponent formComponent) + { + if (Validation == null) return; + + if (!formComponent.IsForNull && (formComponent.Validation == null || (OverrideFieldValidation ?? true))) + { + formComponent.Validation = Validation; + } + } + + protected override void OnInitialized() + { + if (ParentForm != null) + { + ParentForm.ChildForms.Add(this); + } + + base.OnInitialized(); + } + + public void Dispose() + { + _timer?.Dispose(); + } +} diff --git a/Components/Form/FormComponent.cs b/Components/Form/FormComponent.cs new file mode 100644 index 0000000..1046404 --- /dev/null +++ b/Components/Form/FormComponent.cs @@ -0,0 +1,639 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using static System.String; + +namespace Connected.Components; + +public abstract class FormComponent : UIComponent, IFormComponent, IDisposable +{ + private Converter _converter; + + protected FormComponent(Converter converter) + { + _converter = converter ?? throw new ArgumentNullException(nameof(converter)); + _converter.OnError = OnConversionError; + } + + [CascadingParameter] internal IForm Form { get; set; } + + /// + /// If true, this is a top-level form component. If false, this input is a sub-component of another input (i.e. TextField, Select, etc). + /// If it is sub-component, it will NOT do form validation!! + /// + [CascadingParameter(Name = "SubscribeToParentForm")] + internal bool SubscribeToParentForm { get; set; } = true; + + /// + /// If true, this form input is required to be filled out. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public bool Required { get; set; } + + /// + /// The error text that will be displayed if the input is not filled out but required. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public string RequiredError { get; set; } = "Required"; + + /// + /// The ErrorText that will be displayed if Error true. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public string ErrorText { get; set; } + + /// + /// If true, the label will be displayed in an error state. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public bool Error { get; set; } + + /// + /// The ErrorId that will be used by aria-describedby if Error true + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public string ErrorId { get; set; } + + /// + /// The generic converter of the component. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public Converter Converter + { + get => _converter; + set => SetConverter(value); + } + + protected virtual bool SetConverter(Converter value) + { + var changed = (_converter != value); + if (changed) + { + _converter = value ?? throw new ArgumentNullException(nameof(value)); // converter is mandatory at all times + _converter.OnError = OnConversionError; + } + return changed; + } + + /// + /// The culture of the component. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public CultureInfo Culture + { + get => _converter.Culture; + set => SetCulture(value); + } + + protected virtual bool SetCulture(CultureInfo value) + { + var changed = (_converter.Culture != value); + if (changed) + { + _converter.Culture = value; + } + return changed; + } + + private void OnConversionError(string error) + { + // note: we need to update the form here because the conversion error might lead to not updating the value + // ... which leads to not updating the form + Touched = true; + Form?.Update(this); + OnConversionErrorOccurred(error); + } + + protected virtual void OnConversionErrorOccurred(string error) + { + /* Descendants can override this method to catch conversion errors */ + } + + /// + /// True if the conversion from string to T failed + /// + public bool ConversionError => _converter.GetError; + + /// + /// The error message of the conversion error from string to T. Null otherwise + /// + public string ConversionErrorMessage => _converter.GetErrorMessage; + + /// + /// True if the input has any of the following errors: An error set from outside, a conversion error or + /// one or more validation errors + /// + public bool HasErrors => Error || ConversionError || ValidationErrors.Count > 0; + + /// + /// Return the validation error text or the conversion error message. + /// + /// Error text/message + public string GetErrorText() + { + // ErrorText is either set from outside or the first validation error + if (!IsNullOrWhiteSpace(ErrorText)) + return ErrorText; + + if (!IsNullOrWhiteSpace(ConversionErrorMessage)) + return ConversionErrorMessage; + + return null; + } + + /// + /// This manages the state of having been "touched" by the user. A form control always starts out untouched + /// but becomes touched when the user performed input or the blur event was raised. + /// + /// The touched state is only relevant for inputs that have no value (i.e. empty text fields). Being untouched will + /// suppress RequiredError + /// + public bool Touched { get; protected set; } + + #region MudForm Validation + + public List ValidationErrors { get; set; } = new List(); + + /// + /// A validation func or a validation attribute. Supported types are: + /// Func<T, bool> ... will output the standard error message "Invalid" if false + /// Func<T, string> ... outputs the result as error message, no error if null + /// Func<T, IEnumerable< string >> ... outputs all the returned error messages, no error if empty + /// Func<object, string, IEnumerable< string >> input Form.Model, Full Path of Member ... outputs all the returned error messages, no error if empty + /// Func<T, Task< bool >> ... will output the standard error message "Invalid" if false + /// Func<T, Task< string >> ... outputs the result as error message, no error if null + /// Func<T, Task<IEnumerable< string >>> ... outputs all the returned error messages, no error if empty + /// Func<object, string, Task<IEnumerable< string >>> input Form.Model, Full Path of Member ... outputs all the returned error messages, no error if empty + /// System.ComponentModel.DataAnnotations.ValidationAttribute instances + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public object Validation { get; set; } + + /// + /// This is the form component's value. + /// + protected T _value; + + // These are the fire-and-forget methods to launch an async validation process. + // After each async step, we make sure the current Value of the component has not changed while + // async code was executed to avoid race condition which could lead to incorrect validation results. + protected void BeginValidateAfter(Task task) + { + Func execute = async () => + { + var value = _value; + + await task; + + // we validate only if the value hasn't changed while we waited for task. + // if it has in fact changed, another validate call will follow anyway + if (EqualityComparer.Default.Equals(value, _value)) + { + BeginValidate(); + } + }; + execute().AndForget(); + } + + protected void BeginValidate() + { + Func execute = async () => + { + var value = _value; + + await ValidateValue(); + + if (EqualityComparer.Default.Equals(value, _value)) + { + EditFormValidate(); + } + }; + execute().AndForget(); + } + + /// + /// Cause this component to validate its value. + /// + public Task Validate() + { + // when a validation is forced, we must set Touched to true, because for untouched fields with + // no value, validation does nothing due to the way forms are expected to work (display errors + // only after fields have been touched). + Touched = true; + return ValidateValue(); + } + + protected virtual async Task ValidateValue() + { + var changed = false; + var errors = new List(); + try + { + // conversion error + if (ConversionError) + errors.Add(ConversionErrorMessage); + // validation errors + if (Validation is ValidationAttribute) + ValidateWithAttribute(Validation as ValidationAttribute, _value, errors); + else if (Validation is Func) + ValidateWithFunc(Validation as Func, _value, errors); + else if (Validation is Func) + ValidateWithFunc(Validation as Func, _value, errors); + else if (Validation is Func>) + ValidateWithFunc(Validation as Func>, _value, errors); + else if (Validation is Func>) + ValidateModelWithFullPathOfMember(Validation as Func>, errors); + else + { + var value = _value; + + if (Validation is Func>) + await ValidateWithFunc(Validation as Func>, _value, errors); + else if (Validation is Func>) + await ValidateWithFunc(Validation as Func>, _value, errors); + else if (Validation is Func>>) + await ValidateWithFunc(Validation as Func>>, _value, errors); + else if (Validation is Func>>) + await ValidateModelWithFullPathOfMember(Validation as Func>>, errors); + + changed = !EqualityComparer.Default.Equals(value, _value); + } + + // Run each validation attributes of the property targeted with `For` + if (_validationAttrsFor != null) + { + foreach (var attr in _validationAttrsFor) + { + ValidateWithAttribute(attr, _value, errors); + } + } + + // required error (must be last, because it is least important!) + if (Required) + { + if (Touched && !HasValue(_value)) + errors.Add(RequiredError); + } + } + finally + { + // If Value has changed while we were validating it, ignore results and exit + if (!changed) + { + // this must be called in any case, because even if Validation is null the user might have set Error and ErrorText manually + // if Error and ErrorText are set by the user, setting them here will have no effect. + // if Error, create an error id that can be used by aria-describedby on input control + ValidationErrors = errors; + Error = errors.Count > 0; + ErrorText = errors.FirstOrDefault(); + ErrorId = HasErrors ? Guid.NewGuid().ToString() : null; + Form?.Update(this); + StateHasChanged(); + } + } + } + + protected virtual bool HasValue(T value) + { + if (typeof(T) == typeof(string)) + return !IsNullOrWhiteSpace(value as string); + + return value != null; + } + + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "In the context of EditContext.Model / FieldIdentifier.Model they won't get trimmed.")] + protected virtual void ValidateWithAttribute(ValidationAttribute attr, T value, List errors) + { + try + { + // The validation context is applied either on the `EditContext.Model`, '_fieldIdentifier.Model', or `this` as a stub subject. + // Complex validation with fields references (like `CompareAttribute`) should use an EditContext or For when not using EditContext. + var validationContextSubject = EditContext?.Model ?? _fieldIdentifier.Model ?? this; + var validationContext = new ValidationContext(validationContextSubject); + if (validationContext.MemberName is null && _fieldIdentifier.FieldName is not null) + validationContext.MemberName = _fieldIdentifier.FieldName; + var validationResult = attr.GetValidationResult(value, validationContext); + if (validationResult != ValidationResult.Success) + errors.Add(validationResult.ErrorMessage); + } + catch (Exception e) + { + // Maybe conditionally add full error message if `IWebAssemblyHostEnvironment.IsDevelopment()` + // Or log using proper logger. + errors.Add($"An unhandled exception occurred: {e.Message}"); + } + } + + protected virtual void ValidateWithFunc(Func func, T value, List errors) + { + try + { + if (!func(value)) + errors.Add("Invalid"); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual void ValidateWithFunc(Func func, T value, List errors) + { + try + { + var error = func(value); + if (error != null) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual void ValidateWithFunc(Func> func, T value, List errors) + { + try + { + foreach (var error in func(value)) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual void ValidateModelWithFullPathOfMember(Func> func, List errors) + { + try + { + if (Form?.Model == null) + { + return; + } + + if (For == null) + { + errors.Add($"For is null, please set parameter For on the form input component of type {GetType().Name}"); + return; + } + + foreach (var error in func(Form.Model, For.GetFullPathOfMember())) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual async Task ValidateWithFunc(Func> func, T value, List errors) + { + try + { + if (!await func(value)) + errors.Add("Invalid"); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual async Task ValidateWithFunc(Func> func, T value, List errors) + { + try + { + var error = await func(value); + if (error != null) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual async Task ValidateWithFunc(Func>> func, T value, List errors) + { + try + { + foreach (var error in await func(value)) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + protected virtual async Task ValidateModelWithFullPathOfMember(Func>> func, List errors) + { + try + { + if (Form?.Model == null) + { + return; + } + + if (For == null) + { + errors.Add($"For is null, please set parameter For on the form input component of type {GetType().Name}"); + return; + } + + foreach (var error in await func(Form.Model, For.GetFullPathOfMember())) + errors.Add(error); + } + catch (Exception e) + { + errors.Add("Error in validation func: " + e.Message); + } + } + + /// + /// Notify the Form that a field has changed if SubscribeToParentForm is true + /// + protected void FieldChanged(object newValue) + { + if (SubscribeToParentForm) + Form?.FieldChanged(this, newValue); + } + + /// + /// Reset the value and the validation. + /// + public void Reset() + { + ResetValue(); + ResetValidation(); + } + + protected virtual void ResetValue() + { + /* to be overridden */ + _value = default; + Touched = false; + StateHasChanged(); + } + + /// + /// Reset the validation. + /// + public void ResetValidation() + { + Error = false; + ValidationErrors.Clear(); + ErrorText = null; + StateHasChanged(); + } + + #endregion + + + #region --> Blazor EditForm validation support + + /// + /// This is the form validation context for Blazor's component + /// + [CascadingParameter] + EditContext EditContext { get; set; } = default!; + + /// + /// Triggers field to be validated. + /// + internal void EditFormValidate() + { + if (_fieldIdentifier.FieldName != null) + { + EditContext?.NotifyFieldChanged(_fieldIdentifier); + } + } + + /// + /// Specify an expression which returns the model's field for which validation messages should be displayed. + /// +#nullable enable + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public Expression>? For { get; set; } +#nullable disable + + public bool IsForNull => For == null; + + /// + /// Stores the list of validation attributes attached to the property targeted by . If is null, this property is null too. + /// +#nullable enable + private IEnumerable? _validationAttrsFor; +#nullable disable + + private void OnValidationStateChanged(object sender, ValidationStateChangedEventArgs e) + { + if (EditContext != null && !_fieldIdentifier.Equals(default(FieldIdentifier))) + { + var error_msgs = EditContext.GetValidationMessages(_fieldIdentifier).ToArray(); + Error = error_msgs.Length > 0; + ErrorText = (Error ? error_msgs[0] : null); + StateHasChanged(); + } + } + + /// + /// Points to a field of the model for which validation messages should be displayed. + /// + private FieldIdentifier _fieldIdentifier; + + /// + /// To find out whether or not For parameter has changed we keep a separate reference + /// +#nullable enable + private Expression>? _currentFor; +#nullable disable + + /// + /// To find out whether or not EditContext parameter has changed we keep a separate reference + /// +#nullable enable + private EditContext? _currentEditContext; +#nullable disable + + protected override void OnParametersSet() + { + if (For != null && For != _currentFor) + { + // Extract validation attributes + // Sourced from https://stackoverflow.com/a/43076222/4839162 + // and also https://stackoverflow.com/questions/59407225/getting-a-custom-attribute-from-a-property-using-an-expression + var expression = (MemberExpression)For.Body; + var propertyInfo = (PropertyInfo)expression.Expression?.Type.GetProperty(expression.Member.Name); + _validationAttrsFor = propertyInfo?.GetCustomAttributes(typeof(ValidationAttribute), true).Cast(); + + _fieldIdentifier = FieldIdentifier.Create(For); + _currentFor = For; + } + + if (EditContext != null && EditContext != _currentEditContext) + { + DetachValidationStateChangedListener(); + EditContext.OnValidationStateChanged += OnValidationStateChanged; + _currentEditContext = EditContext; + } + } + + private void DetachValidationStateChangedListener() + { + if (_currentEditContext != null) + _currentEditContext.OnValidationStateChanged -= OnValidationStateChanged; + } + + #endregion + + + protected override Task OnInitializedAsync() + { + RegisterAsFormComponent(); + return base.OnInitializedAsync(); + } + + protected virtual void RegisterAsFormComponent() + { + if (SubscribeToParentForm) + { + Form?.Add(this); + } + } + + /// + /// Called to dispose this instance. + /// + /// if called within . + protected virtual void Dispose(bool disposing) + { + } + + void IDisposable.Dispose() + { + try + { + Form?.Remove(this); + } + catch { /* ignore */ } + DetachValidationStateChangedListener(); + Dispose(disposing: true); + } +} diff --git a/Components/Form/IForm.cs b/Components/Form/IForm.cs new file mode 100644 index 0000000..3e0361b --- /dev/null +++ b/Components/Form/IForm.cs @@ -0,0 +1,12 @@ +namespace Connected.Components; + +public interface IForm +{ + public bool IsValid { get; } + public string[] Errors { get; } + public object? Model { get; set; } + public void FieldChanged(IFormComponent formControl, object newValue); + internal void Add(IFormComponent formControl); + internal void Remove(IFormComponent formControl); + internal void Update(IFormComponent formControl); +} diff --git a/Components/Form/IFormComponent.cs b/Components/Form/IFormComponent.cs new file mode 100644 index 0000000..4f85fb4 --- /dev/null +++ b/Components/Form/IFormComponent.cs @@ -0,0 +1,15 @@ +namespace Connected.Components; + +public interface IFormComponent +{ + public bool Required { get; set; } + public bool Error { get; set; } + public bool HasErrors { get; } + public bool Touched { get; } + public object Validation { get; set; } + public bool IsForNull { get; } + public List ValidationErrors { get; set; } + public Task Validate(); + public void Reset(); + public void ResetValidation(); +} diff --git a/Components/Grid/Grid.razor b/Components/Grid/Grid.razor new file mode 100644 index 0000000..d58da76 --- /dev/null +++ b/Components/Grid/Grid.razor @@ -0,0 +1,34 @@ +@namespace Connected.Components +@using Connected.Annotations; +@using Connected.Utilities +@using Connected.Extensions +@inherits UIComponent + + +
    + @ChildContent +
    +
    + +@code { + + protected string Classname => + new CssBuilder("grid") + .AddClass($"grid-spacing-xs-{Spacing.ToString()}") + .AddClass($"justify-{Justify.ToDescriptionString()}") + .AddClass(Class) + .Build(); + + [Parameter] + [Category(CategoryTypes.Grid.Behavior)] + public int Spacing { set; get; } = 3; + + [Parameter] + [Category(CategoryTypes.Grid.Behavior)] + public Justify Justify { get; set; } = Justify.FlexStart; + + [Parameter] + [Category(CategoryTypes.Grid.Behavior)] + public RenderFragment ChildContent { get; set; } + +} \ No newline at end of file diff --git a/Components/Grid/Item.razor b/Components/Grid/Item.razor new file mode 100644 index 0000000..c9d2e79 --- /dev/null +++ b/Components/Grid/Item.razor @@ -0,0 +1,48 @@ +@namespace Connected.Components +@using Connected.Annotations; +@using Connected.Utilities +@using Connected.Extensions +@inherits UIComponent + +
    + @ChildContent +
    + +@code { + protected string Classname => + new CssBuilder("grid-item") + .AddClass($"grid-item-xs-{xs.ToString()}", xs != 0) + .AddClass($"grid-item-sm-{sm.ToString()}", sm != 0) + .AddClass($"grid-item-md-{md.ToString()}", md != 0) + .AddClass($"grid-item-lg-{lg.ToString()}", lg != 0) + .AddClass($"grid-item-xl-{xl.ToString()}", xl != 0) + .AddClass($"grid-item-xxl-{xxl.ToString()}", xxl != 0) + .AddClass(Class) + .Build(); + + [CascadingParameter] + private Grid Parent { get; set; } + + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int xs { get; set; } + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int sm { get; set; } + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int md { get; set; } + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int lg { get; set; } + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int xl { get; set; } + [Parameter] [Category(CategoryTypes.Item.Behavior)] public int xxl { get; set; } + + // ToDo false,auto,true on all sizes. + + [Parameter] + [Category(CategoryTypes.Item.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected override void OnInitialized() + { + // NOTE: we can't throw here, the component must be able to live alone for the docs API to infer default parameters + //if (Parent == null) + // throw new ArgumentNullException(nameof(Parent), "Item must exist within a Grid"); + base.OnInitialized(); + } + +} + diff --git a/Components/Hidden/Hidden.razor b/Components/Hidden/Hidden.razor new file mode 100644 index 0000000..80bfa01 --- /dev/null +++ b/Components/Hidden/Hidden.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (!_isHidden) +{ + @ChildContent +} \ No newline at end of file diff --git a/Components/Hidden/Hidden.razor.cs b/Components/Hidden/Hidden.razor.cs new file mode 100644 index 0000000..c90da6f --- /dev/null +++ b/Components/Hidden/Hidden.razor.cs @@ -0,0 +1,118 @@ +using Connected.Annotations; +using Connected.Services; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + + +public partial class Hidden : UIComponent, IAsyncDisposable +{ + private Breakpoint _currentBreakpoint = Breakpoint.None; + private bool _serviceIsReady = false; + private Guid _breakpointServiceSubscriptionId; + + [Inject] public IBreakpointService BreakpointService { get; set; } + + [CascadingParameter] public Breakpoint CurrentBreakpointFromProvider { get; set; } = Breakpoint.None; + + /// + /// The screen size(s) depending on which the ChildContent should not be rendered (or should be, if Invert is true) + /// + [Parameter] + [Category(CategoryTypes.Hidden.Behavior)] + public Breakpoint Breakpoint { get; set; } + + /// + /// Inverts the Breakpoint, so that the ChildContent is only rendered when the breakpoint matches the screen size. + /// + [Parameter] + [Category(CategoryTypes.Hidden.Behavior)] + public bool Invert { get; set; } + + private bool _isHidden = true; + + /// + /// True if the component is not visible (two-way bindable) + /// + [Parameter] + [Category(CategoryTypes.Hidden.Behavior)] + public bool IsHidden + { + get => _isHidden; + set + { + if (_isHidden != value) + { + _isHidden = value; + IsHiddenChanged.InvokeAsync(_isHidden); + + } + } + } + + /// + /// Fires when the breakpoint changes visibility of the component + /// + [Parameter] public EventCallback IsHiddenChanged { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Hidden.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected void Update(Breakpoint currentBreakpoint) + { + if (CurrentBreakpointFromProvider != Breakpoint.None) + { + currentBreakpoint = CurrentBreakpointFromProvider; + } + else if (_serviceIsReady == false) { return; } + + if (currentBreakpoint == Breakpoint.None) { return; } + + _currentBreakpoint = currentBreakpoint; + + var hidden = BreakpointService.IsMediaSize(Breakpoint, currentBreakpoint); + if (Invert == true) + { + hidden = !hidden; + } + + IsHidden = hidden; + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + Update(_currentBreakpoint); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + if (firstRender == true) + { + if (CurrentBreakpointFromProvider == Breakpoint.None) + { + var attachResult = await BreakpointService.Subscribe((x) => + { + Update(x); + InvokeAsync(StateHasChanged); + }); + + _serviceIsReady = true; + _breakpointServiceSubscriptionId = attachResult.SubscriptionId; + Update(attachResult.Breakpoint); + StateHasChanged(); + } + else + { + _serviceIsReady = true; + } + } + } + + public async ValueTask DisposeAsync() => await BreakpointService.Unsubscribe(_breakpointServiceSubscriptionId); +} diff --git a/Components/Highlighter/Highlighter.razor b/Components/Highlighter/Highlighter.razor new file mode 100644 index 0000000..e1bde96 --- /dev/null +++ b/Components/Highlighter/Highlighter.razor @@ -0,0 +1,22 @@ +@namespace Connected.Components +@inherits UIComponent + +@using System.Text.RegularExpressions +@using static Connected.Components.Splitter + +@foreach (var fragment in _fragments.Span) +{ + if (!string.IsNullOrWhiteSpace(_regex) + && Regex.IsMatch(fragment, + _regex, + CaseSensitive + ? RegexOptions.None + : RegexOptions.IgnoreCase)) + { + @fragment + } + else + { + @fragment + } +} \ No newline at end of file diff --git a/Components/Highlighter/Highlighter.razor.cs b/Components/Highlighter/Highlighter.razor.cs new file mode 100644 index 0000000..f3ca201 --- /dev/null +++ b/Components/Highlighter/Highlighter.razor.cs @@ -0,0 +1,59 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using static Connected.Components.Splitter; + +namespace Connected.Components; + +public partial class Highlighter : UIComponent +{ + private Memory _fragments; + private string _regex; + + /// + /// The whole text in which a fragment will be highlighted + /// + [Parameter] + [Category(CategoryTypes.Highlighter.Behavior)] + public string Text { get; set; } + + /// + /// The fragment of text to be highlighted + /// + [Parameter] + [Category(CategoryTypes.Highlighter.Behavior)] + public string HighlightedText { get; set; } + + /// + /// The fragments of text to be highlighted + /// + [Parameter] + [Category(CategoryTypes.Highlighter.Behavior)] + public IEnumerable HighlightedTexts { get; set; } + + /// + /// Whether or not the highlighted text is case sensitive + /// + [Parameter] + [Category(CategoryTypes.Highlighter.Behavior)] + public bool CaseSensitive { get; set; } + + /// + /// If true, highlights the text until the next regex boundary + /// + [Parameter] + [Category(CategoryTypes.Highlighter.Behavior)] + public bool UntilNextBoundary { get; set; } + + //TODO + //Accept regex highlightings + // [Parameter] public bool IsRegex { get; set; } + + protected override void OnParametersSet() + { + _fragments = GetFragments(Text, HighlightedText, HighlightedTexts, out _regex, CaseSensitive, UntilNextBoundary); + } +} diff --git a/Components/Highlighter/Splitter.cs b/Components/Highlighter/Splitter.cs new file mode 100644 index 0000000..6724453 --- /dev/null +++ b/Components/Highlighter/Splitter.cs @@ -0,0 +1,114 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace Connected.Components; + +public static class Splitter +{ + private const string NextBoundary = ".*?\\b"; + + private static StringBuilder s_stringBuilderCached; + + /// + /// Splits the text into fragments, according to the + /// text to be highlighted + /// + /// The whole text + /// The text to be highlighted + /// The texts to be highlighted + /// Regex expression that was used to split fragments. + /// Whether it's case sensitive or not + /// If true, splits until the next regex boundary + /// + public static Memory GetFragments(string text, + string highlightedText, + IEnumerable highlightedTexts, + out string regex, + bool caseSensitive = false, + bool untilNextBoundary = false) + { + if (string.IsNullOrEmpty(text)) + { + regex = ""; + return Memory.Empty; + } + + var builder = Interlocked.Exchange(ref s_stringBuilderCached, null) ?? new(); + //the first brace in the pattern is to keep the patten when splitting, + //the `(?:` in the pattern is to accept multiple highlightedTexts but not capture them. + builder.Append("((?:"); + + //this becomes true if `AppendPattern` was called at least once. + bool hasAtLeastOnePattern = false; + if (!string.IsNullOrEmpty(highlightedText)) + { + AppendPattern(highlightedText); + } + + if (highlightedTexts is not null) + { + foreach (var substring in highlightedTexts) + { + if (string.IsNullOrEmpty(substring)) + continue; + + //split pattern if we already added an string to search. + if (hasAtLeastOnePattern) + { + builder.Append(")|(?:"); + } + + AppendPattern(substring); + } + } + + if (hasAtLeastOnePattern) + { + //close the last pattern group and the capture group. + builder.Append("))"); + } + else + { + builder.Clear(); + s_stringBuilderCached = builder; + + //all patterns were empty or null. + regex = ""; + return new string[] { text }; + } + + regex = builder.ToString(); + builder.Clear(); + s_stringBuilderCached = builder; + + var splits = Regex + .Split(text, + regex, + caseSensitive + ? RegexOptions.None + : RegexOptions.IgnoreCase); + var length = 0; + for (var i = 0; i < splits.Length; i++) + { + var s = splits[i]; + if (!string.IsNullOrEmpty(s)) + { + splits[length++] = s; + } + } + Array.Clear(splits, length, splits.Length - length); + return splits.AsMemory(0, length); + + void AppendPattern(string value) + { + hasAtLeastOnePattern = true; + //escapes the text for regex + value = Regex.Escape(value); + builder.Append(value); + if (untilNextBoundary) + { + builder.Append(NextBoundary); + } + } + } +} diff --git a/Components/Icon/Icon.razor b/Components/Icon/Icon.razor new file mode 100644 index 0000000..33e8a90 --- /dev/null +++ b/Components/Icon/Icon.razor @@ -0,0 +1,18 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (!string.IsNullOrEmpty(Glyph) && Glyph.Trim().StartsWith(("<"))) +{ + +} +else +{ + +} diff --git a/Components/Icon/Icon.razor.cs b/Components/Icon/Icon.razor.cs new file mode 100644 index 0000000..08ebc5c --- /dev/null +++ b/Components/Icon/Icon.razor.cs @@ -0,0 +1,60 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Icon : UIComponent +{ + protected string Classname => + new CssBuilder("mud-icon-root") + .AddClass($"mud-icon-default", Color == ThemeColor.Default) + .AddClass($"mud-svg-icon", !string.IsNullOrEmpty(Glyph) && Glyph.Trim().StartsWith(("<"))) + .AddClass($"mud-{Color.ToDescriptionString()}-text", Color != ThemeColor.Default && Color != ThemeColor.Inherit) + .AddClass($"mud-icon-size-{Size.ToDescriptionString()}") + .AddClass(Class) + .Build(); + + /// + /// Icon to be used can either be svg paths for font icons. + /// + [Parameter] + [Category(CategoryTypes.Icon.Behavior)] + public string Glyph { get; set; } + + /// + /// Title of the icon used for accessibility. + /// + [Parameter] + [Category(CategoryTypes.Icon.Behavior)] + public string Title { get; set; } + + /// + /// The Size of the icon. + /// + [Parameter] + [Category(CategoryTypes.Icon.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Icon.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Inherit; + + /// + /// The viewbox size of an svg element. + /// + [Parameter] + [Category(CategoryTypes.Icon.Behavior)] + public string ViewBox { get; set; } = "0 0 24 24"; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Icon.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Image/Image.razor b/Components/Image/Image.razor new file mode 100644 index 0000000..7caa643 --- /dev/null +++ b/Components/Image/Image.razor @@ -0,0 +1,4 @@ +@namespace Connected.Components +@inherits UIComponent + +@Alt \ No newline at end of file diff --git a/Components/Image/Image.razor.cs b/Components/Image/Image.razor.cs new file mode 100644 index 0000000..8acde53 --- /dev/null +++ b/Components/Image/Image.razor.cs @@ -0,0 +1,78 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Image : UIComponent +{ + protected string Classname => + new CssBuilder("mud-image") + .AddClass("fluid", Fluid) + .AddClass($"object-{ObjectFit.ToDescriptionString()}") + .AddClass($"object-{ObjectPosition.ToDescriptionString()}") + .AddClass($"mud-elevation-{Elevation}", Elevation > 0) + .AddClass(Class) + .Build(); + + /// + /// Applies the fluid class so the image scales with the parent width. + /// + [Parameter] + [Category(CategoryTypes.Image.Behavior)] + public bool Fluid { get; set; } + + /// + /// Specifies the path to the image. + /// + [Parameter] + [Category(CategoryTypes.Image.Behavior)] + public string Src { get; set; } + + /// + /// Specifies an alternate text for the image. + /// + [Parameter] + [Category(CategoryTypes.Image.Behavior)] + public string Alt { get; set; } + + /// + /// Specifies the height of the image in px. + /// + [Parameter] + [Category(CategoryTypes.Image.Appearance)] + public int? Height { get; set; } + + /// + /// Specifies the width of the image in px. + /// + [Parameter] + [Category(CategoryTypes.Image.Appearance)] + public int? Width { get; set; } + + /// + /// The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Image.Appearance)] + public int Elevation { set; get; } + + /// + /// Controls how the image should be resized. + /// + [Parameter] + [Category(CategoryTypes.Image.Appearance)] + public ObjectFit ObjectFit { set; get; } = ObjectFit.Fill; + + /// + /// Controls how the image should positioned within its container. + /// + [Parameter] + [Category(CategoryTypes.Image.Appearance)] + public ObjectPosition ObjectPosition { set; get; } = ObjectPosition.Center; +} diff --git a/Components/Input/DebouncedInput.cs b/Components/Input/DebouncedInput.cs new file mode 100644 index 0000000..10babcf --- /dev/null +++ b/Components/Input/DebouncedInput.cs @@ -0,0 +1,121 @@ +using System.Timers; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public abstract class DebouncedInput : InputBase +{ + private System.Timers.Timer _timer; + private double _debounceInterval; + + /// + /// Interval to be awaited in milliseconds before changing the Text value + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public double DebounceInterval + { + get => _debounceInterval; + set + { + if (NumericConverter.AreEqual(_debounceInterval, value)) + return; + _debounceInterval = value; + if (_debounceInterval == 0) + { + // not debounced, dispose timer if any + ClearTimer(suppressTick: false); + return; + } + SetTimer(); + } + } + + /// + /// callback to be called when the debounce interval has elapsed + /// receives the Text as a parameter + /// + [Parameter] public EventCallback OnDebounceIntervalElapsed { get; set; } + + protected Task OnChange() + { + if (DebounceInterval > 0 && _timer != null) + { + _timer.Stop(); + return base.UpdateValuePropertyAsync(false); + } + + return Task.CompletedTask; + } + + protected override Task UpdateValuePropertyAsync(bool updateText) + { + // This method is called when Value property needs to be refreshed from the current Text property, so typically because Text property has changed. + // We want to debounce only text-input, not a value being set, so the debouncing is only done when updateText==false (because that indicates the + // change came from a Text setter) + if (updateText) + { + // we have a change coming not from the Text setter, no debouncing is needed + return base.UpdateValuePropertyAsync(updateText); + } + // if debounce interval is 0 we update immediately + if (DebounceInterval <= 0 || _timer == null) + return base.UpdateValuePropertyAsync(updateText); + // If a debounce interval is defined, we want to delay the update of Value property. + _timer.Stop(); + // restart the timer while user is typing + _timer.Start(); + return Task.CompletedTask; + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + // if input is to be debounced, makes sense to bind the change of the text to oninput + // so we set Immediate to true + if (DebounceInterval > 0) + Immediate = true; + } + + private void SetTimer() + { + if (_timer == null) + { + _timer = new System.Timers.Timer(); + _timer.Elapsed += OnTimerTick; + _timer.AutoReset = false; + } + _timer.Interval = DebounceInterval; + } + + private void OnTimerTick(object sender, ElapsedEventArgs e) + { + InvokeAsync(OnTimerTickGuiThread).AndForget(); + } + + private async Task OnTimerTickGuiThread() + { + await base.UpdateValuePropertyAsync(false); + await OnDebounceIntervalElapsed.InvokeAsync(Text); + } + + private void ClearTimer(bool suppressTick = false) + { + if (_timer == null) + return; + var wasEnabled = _timer.Enabled; + _timer.Stop(); + _timer.Elapsed -= OnTimerTick; + _timer.Dispose(); + _timer = null; + if (wasEnabled && !suppressTick) + OnTimerTickGuiThread().AndForget(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + ClearTimer(suppressTick: true); + } +} diff --git a/Components/Input/Input.razor b/Components/Input/Input.razor new file mode 100644 index 0000000..4a39db0 --- /dev/null +++ b/Components/Input/Input.razor @@ -0,0 +1,145 @@ +@namespace Connected.Components +@typeparam T +@inherits InputBase + +
    + @if (Adornment == Adornment.Start) + { + + } + + @if (Lines > 1) + { + + @*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@ + @*note: the value="@_internalText" is absolutely essential here. the inner html @Text is needed by tests checking it*@ + } + else + { + + @*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@ + + @if (Disabled) { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown. + In Disabled state the tabindex attribute must NOT be set at all or else it will get focus on click + *@ +
    + @ChildContent +
    + } + else + { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown.*@ +
    + @ChildContent +
    + } + } + + @if (_showClearable && !Disabled) + { + + } + + @if (Adornment == Adornment.End) + { + + } + + @if (Variant == Variant.Outlined) + { +
    + } + + @if (!HideSpinButtons) + { +
    + + +
    + } +
    \ No newline at end of file diff --git a/Components/Input/Input.razor.cs b/Components/Input/Input.razor.cs new file mode 100644 index 0000000..6e666b1 --- /dev/null +++ b/Components/Input/Input.razor.cs @@ -0,0 +1,222 @@ +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Input : InputBase +{ + protected string Classname => InputCssHelper.GetClassname(this, + () => HasNativeHtmlPlaceholder() || !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || !string.IsNullOrWhiteSpace(Placeholder)); + + protected string InputClassname => InputCssHelper.GetInputClassname(this); + + protected string AdornmentClassname => InputCssHelper.GetAdornmentClassname(this); + + protected string ClearButtonClassname => + new CssBuilder() + .AddClass("me-n1", Adornment == Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-end", Adornment == Adornment.End && HideSpinButtons == true) + .AddClass("me-6", Adornment != Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-margin-end", Adornment != Adornment.End && HideSpinButtons == true) + .Build(); + + /// + /// Type of the input element. It should be a valid HTML5 input type. + /// + [Parameter] public InputType InputType { get; set; } = InputType.Text; + + internal override InputType GetInputType() => InputType; + + protected string InputTypeString => InputType.ToDescriptionString(); + + protected Task OnInput(ChangeEventArgs args) + { + if (!Immediate) + return Task.CompletedTask; + _isFocused = true; + return SetTextAsync(args?.Value as string); + } + + protected async Task OnChange(ChangeEventArgs args) + { + _internalText = args?.Value as string; + await OnInternalInputChanged.InvokeAsync(args); + if (!Immediate) + { + await SetTextAsync(args?.Value as string); + } + } + + /// + /// Paste hook for descendants. + /// +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + + protected virtual async Task OnPaste(ClipboardEventArgs args) +#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously + { + // do nothing + return; + } + + /// + /// ChildContent of the MudInput will only be displayed if InputType.Hidden and if its not null. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + public ElementReference ElementReference { get; private set; } + private ElementReference _elementReference1; + + public override async ValueTask FocusAsync() + { + try + { + if (InputType == InputType.Hidden && ChildContent != null) + await _elementReference1.FocusAsync(); + else + await ElementReference.FocusAsync(); + } + catch (Exception e) + { + Console.WriteLine("Input.FocusAsync: " + e.Message); + } + } + + public override ValueTask BlurAsync() + { + return ElementReference.BlurAsync(); + } + + public override ValueTask SelectAsync() + { + return ElementReference.SelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return ElementReference.SelectRangeAsync(pos1, pos2); + } + + /// + /// Invokes the callback when the Up arrow button is clicked when the input is set to . + /// Note: use the optimized control if you need to deal with numbers. + /// + [Parameter] public EventCallback OnIncrement { get; set; } + + /// + /// Invokes the callback when the Down arrow button is clicked when the input is set to . + /// Note: use the optimized control if you need to deal with numbers. + /// + [Parameter] public EventCallback OnDecrement { get; set; } + + /// + /// Hides the spin buttons for + /// + [Parameter] public bool HideSpinButtons { get; set; } = true; + + /// + /// Show clear button. + /// + [Parameter] public bool Clearable { get; set; } = false; + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] public EventCallback OnClearButtonClick { get; set; } + + /// + /// Mouse wheel event for input. + /// + [Parameter] public EventCallback OnMouseWheel { get; set; } + + /// + /// Custom clear icon. + /// + [Parameter] public string ClearIcon { get; set; } = Icons.Material.Filled.Clear; + + /// + /// Custom numeric up icon. + /// + [Parameter] public string NumericUpIcon { get; set; } = Icons.Material.Filled.KeyboardArrowUp; + + /// + /// Custom numeric down icon. + /// + [Parameter] public string NumericDownIcon { get; set; } = Icons.Material.Filled.KeyboardArrowDown; + + private Size GetButtonSize() => Margin == Margin.Dense ? Size.Small : Size.Medium; + + private bool _showClearable; + + private void UpdateClearable(object value) + { + var showClearable = Clearable && ((value is string stringValue && !string.IsNullOrWhiteSpace(stringValue)) || (value is not string && value is not null)); + if (_showClearable != showClearable) + _showClearable = showClearable; + } + + protected override async Task UpdateTextPropertyAsync(bool updateValue) + { + await base.UpdateTextPropertyAsync(updateValue); + if (Clearable) + UpdateClearable(Text); + } + + protected override async Task UpdateValuePropertyAsync(bool updateText) + { + await base.UpdateValuePropertyAsync(updateText); + if (Clearable) + UpdateClearable(Value); + } + + protected virtual async Task ClearButtonClickHandlerAsync(MouseEventArgs e) + { + await SetTextAsync(string.Empty, updateValue: true); + await ElementReference.FocusAsync(); + await OnClearButtonClick.InvokeAsync(e); + } + + private string _internalText; + + public override async Task SetParametersAsync(ParameterView parameters) + { + await base.SetParametersAsync(parameters); + //if (!_isFocused || _forceTextUpdate) + // _internalText = Text; + if (RuntimeLocation.IsServerSide && TextUpdateSuppression) + { + // Text update suppression, only in BSS (not in WASM). + // This is a fix for #1012 + if (!_isFocused || _forceTextUpdate) + _internalText = Text; + } + else + { + // in WASM (or in BSS with TextUpdateSuppression==false) we always update + _internalText = Text; + } + } + + /// + /// Sets the input text from outside programmatically + /// + /// + /// + public Task SetText(string text) + { + _internalText = text; + return SetTextAsync(text); + } + + + // Certain HTML5 inputs (dates and color) have a native placeholder + private bool HasNativeHtmlPlaceholder() + { + return GetInputType() is InputType.Color or InputType.Date or InputType.DateTimeLocal or InputType.Month + or InputType.Time or InputType.Week; + } +} + +public class InputString : Input { } diff --git a/Components/Input/InputAdornment.razor b/Components/Input/InputAdornment.razor new file mode 100644 index 0000000..2b49c5f --- /dev/null +++ b/Components/Input/InputAdornment.razor @@ -0,0 +1,34 @@ +@namespace Connected.Components + + + +
    + @if (!string.IsNullOrWhiteSpace(Text)) + { + @Text + } + else if (!string.IsNullOrWhiteSpace(Icon)) + { + @if (AdornmentClick.HasDelegate) + { + + } + else + { + + } + } +
    + + +@code { + [Parameter] public string Class { get; set; } + [Parameter] public string Text { get; set; } + [Parameter] public string Icon { get; set; } + [Parameter] public Edge Edge { get; set; } + [Parameter] public Size Size { get; set; } = Size.Medium; + [Parameter] public ThemeColor Color { get; set; } = ThemeColor.Default; + [Parameter] public string AriaLabel { get; set; } + + [Parameter] public EventCallback AdornmentClick { get; set; } +} diff --git a/Components/Input/InputBase.cs b/Components/Input/InputBase.cs new file mode 100644 index 0000000..1e587ec --- /dev/null +++ b/Components/Input/InputBase.cs @@ -0,0 +1,488 @@ +using System.Globalization; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public abstract class InputBase : FormComponent +{ + private bool _isDirty; + + protected InputBase() : base(new DefaultConverter()) { } + + /// + /// If true, the input element will be disabled. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, the input will be read-only. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool ReadOnly { get; set; } + + /// + /// If true, the input will take up the full width of its container. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool FullWidth { get; set; } + + /// + /// If true, the input will update the Value immediately on typing. + /// If false, the Value is updated only on Enter. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Immediate { get; set; } + + /// + /// If true, the input will not have an underline. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool DisableUnderLine { get; set; } + + /// + /// The HelperText will be displayed below the text field. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string HelperText { get; set; } + + /// + /// If true, the helper text will only be visible on focus. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool HelperTextOnFocus { get; set; } + + /// + /// Icon that will be used if Adornment is set to Start or End. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string AdornmentIcon { get; set; } + + /// + /// Text that will be used if Adornment is set to Start or End, the Text overrides Icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string AdornmentText { get; set; } + + /// + /// The Adornment if used. By default, it is set to None. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public Adornment Adornment { get; set; } = Adornment.None; + + /// + /// The validation is only triggered if the user has changed the input value at least once. By default, it is false + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool OnlyValidateIfDirty { get; set; } = false; + + /// + /// The color of the adornment if used. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor AdornmentColor { get; set; } = ThemeColor.Default; + + /// + /// The aria-label of the adornment. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string AdornmentAriaLabel { get; set; } = string.Empty; + + /// + /// The Icon Size. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + /// + /// Button click event if set and Adornment used. + /// + [Parameter] public EventCallback OnAdornmentClick { get; set; } + + /// + /// Variant to use. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// Will adjust vertical spacing. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Margin Margin { get; set; } = Margin.None; + + /// + /// The short hint displayed in the input before the user enters a value. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Placeholder { get; set; } + + /// + /// If set, will display the counter, value 0 will display current count but no stop count. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public int? Counter { get; set; } + + /// + /// Maximum number of characters that the input will accept + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public int MaxLength { get; set; } = 524288; + + /// + /// If string has value the label text will be displayed in the input, and scaled down at the top if the input has value. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Label { get; set; } + + /// + /// If true the input will focus automatically. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool AutoFocus { get; set; } + + /// + /// A multiline input (textarea) will be shown, if set to more than one line. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public int Lines { get; set; } = 1; + + /// + /// The text to be displayed. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public string Text { get; set; } + + /// + /// When TextUpdateSuppression is true (which is default) the text can not be updated by bindings while the component is focused in BSS (not WASM). + /// This solves issue #1012: Textfield swallowing chars when typing rapidly + /// If you need to update the input's text while it is focused you can set this parameter to false. + /// Note: on WASM text update suppression is not active, so this parameter has no effect. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool TextUpdateSuppression { get; set; } = true; + + /// + /// Hints at the type of data that might be entered by the user while editing the input + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public virtual InputMode InputMode { get; set; } = InputMode.text; + + /// + /// The pattern attribute, when specified, is a regular expression which the input's value must match in order for the value to pass constraint validation. It must be a valid JavaScript regular expression + /// Not Supported in multline input + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public virtual string Pattern { get; set; } + + /// + /// Derived classes need to override this if they can be something other than text + /// + internal virtual InputType GetInputType() { return InputType.Text; } + + protected virtual async Task SetTextAsync(string text, bool updateValue = true) + { + if (Text != text) + { + Text = text; + if (!string.IsNullOrWhiteSpace(Text)) + Touched = true; + if (updateValue) + await UpdateValuePropertyAsync(false); + await TextChanged.InvokeAsync(Text); + } + } + + /// + /// Text change hook for descendants. Called when Text needs to be refreshed from current Value property. + /// + protected virtual Task UpdateTextPropertyAsync(bool updateValue) + { + return SetTextAsync(Converter.Set(Value), updateValue); + } + + /// + /// Focuses the element + /// + /// The ValueTask + public virtual ValueTask FocusAsync() { return new ValueTask(); } + + public virtual ValueTask BlurAsync() { return new ValueTask(); } + + public virtual ValueTask SelectAsync() { return new ValueTask(); } + + public virtual ValueTask SelectRangeAsync(int pos1, int pos2) { return new ValueTask(); } + + /// + /// Fired when the text value changes. + /// + [Parameter] public EventCallback TextChanged { get; set; } + + /// + /// Fired when the element loses focus. + /// + [Parameter] public EventCallback OnBlur { get; set; } + + /// + /// Fired when the element changes internally its text value. + /// + [Parameter] + public EventCallback OnInternalInputChanged { get; set; } + + protected bool _isFocused; + + protected internal virtual void OnBlurred(FocusEventArgs obj) + { + _isFocused = false; + + if (!OnlyValidateIfDirty || _isDirty) + { + Touched = true; + BeginValidateAfter(OnBlur.InvokeAsync(obj)); + } + } + + /// + /// Fired on the KeyDown event. + /// + [Parameter] public EventCallback OnKeyDown { get; set; } + + protected virtual void InvokeKeyDown(KeyboardEventArgs obj) + { + _isFocused = true; + OnKeyDown.InvokeAsync(obj).AndForget(); + } + + /// + /// Prevent the default action for the KeyDown event. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool KeyDownPreventDefault { get; set; } + + + /// + /// Fired on the KeyPress event. + /// + [Parameter] public EventCallback OnKeyPress { get; set; } + + protected virtual void InvokeKeyPress(KeyboardEventArgs obj) + { + OnKeyPress.InvokeAsync(obj).AndForget(); + } + + /// + /// Prevent the default action for the KeyPress event. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool KeyPressPreventDefault { get; set; } + + /// + /// Fired on the KeyUp event. + /// + [Parameter] public EventCallback OnKeyUp { get; set; } + + protected virtual void InvokeKeyUp(KeyboardEventArgs obj) + { + _isFocused = true; + OnKeyUp.InvokeAsync(obj).AndForget(); + } + + /// + /// Prevent the default action for the KeyUp event. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool KeyUpPreventDefault { get; set; } + + /// + /// Fired when the Value property changes. + /// + [Parameter] + public EventCallback ValueChanged { get; set; } + + /// + /// The value of this input element. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public T Value + { + get => _value; + set => _value = value; + } + + protected virtual async Task SetValueAsync(T value, bool updateText = true) + { + if (!EqualityComparer.Default.Equals(Value, value)) + { + _isDirty = true; + Value = value; + if (updateText) + await UpdateTextPropertyAsync(false); + await ValueChanged.InvokeAsync(Value); + BeginValidate(); + FieldChanged(Value); + } + } + + /// + /// Value change hook for descendants. Called when Value needs to be refreshed from current Text property. + /// + protected virtual Task UpdateValuePropertyAsync(bool updateText) + { + return SetValueAsync(Converter.Get(Text), updateText); + } + + protected override bool SetConverter(Converter value) + { + var changed = base.SetConverter(value); + if (changed) + UpdateTextPropertyAsync(false).AndForget(); // refresh only Text property from current Value + + return changed; + } + + protected override bool SetCulture(CultureInfo value) + { + var changed = base.SetCulture(value); + if (changed) + UpdateTextPropertyAsync(false).AndForget(); // refresh only Text property from current Value + + return changed; + } + + /// + /// Conversion format parameter for ToString(), can be used for formatting primitive types, DateTimes and TimeSpans + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Format + { + get => ((Converter)Converter).Format; + set => SetFormat(value); + } + + protected virtual bool SetFormat(string value) + { + var changed = Format != value; + if (changed) + { + ((Converter)Converter).Format = value; + UpdateTextPropertyAsync(false).AndForget(); // refresh only Text property from current Value + } + return changed; + } + + protected override Task ValidateValue() + { + if (SubscribeToParentForm) + return base.ValidateValue(); + + return Task.CompletedTask; + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + // Because the way the Value setter is built, it won't cause an update if the incoming Value is + // equal to the initial value. This is why we force an update to the Text property here. + if (typeof(T) != typeof(string)) + await UpdateTextPropertyAsync(false); + + if (Label == null && For != null) + Label = For.GetLabelString(); + } + + public virtual void ForceRender(bool forceTextUpdate) + { + _forceTextUpdate = true; + UpdateTextPropertyAsync(false).AndForget(); + StateHasChanged(); + } + + protected bool _forceTextUpdate; + + public override async Task SetParametersAsync(ParameterView parameters) + { + await base.SetParametersAsync(parameters); + + var hasText = parameters.Contains(nameof(Text)); + var hasValue = parameters.Contains(nameof(Value)); + + // Refresh Value from Text + if (hasText && !hasValue) + await UpdateValuePropertyAsync(false); + + // Refresh Text from Value + if (hasValue && !hasText) + { + var updateText = true; + if (_isFocused && !_forceTextUpdate) + { + // Text update suppression, only in BSS (not in WASM). + // This is a fix for #1012 + if (RuntimeLocation.IsServerSide && TextUpdateSuppression) + updateText = false; + } + if (updateText) + { + _forceTextUpdate = false; + await UpdateTextPropertyAsync(false); + } + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + //Only focus automatically after the first render cycle! + if (firstRender && AutoFocus) + { + await FocusAsync(); + } + } + + protected override void OnParametersSet() + { + if (SubscribeToParentForm) + base.OnParametersSet(); + } + + protected override void ResetValue() + { + SetTextAsync(null, updateValue: true).AndForget(); + _isDirty = false; + base.ResetValue(); + } +} diff --git a/Components/Input/InputCssHelper.cs b/Components/Input/InputCssHelper.cs new file mode 100644 index 0000000..6ea89cc --- /dev/null +++ b/Components/Input/InputCssHelper.cs @@ -0,0 +1,37 @@ +using Connected.Extensions; +using Connected.Utilities; + +namespace Connected.Components; + +internal static class InputCssHelper +{ + public static string GetClassname(InputBase baseInput, Func shrinkWhen) => + new CssBuilder("mud-input") + .AddClass($"mud-input-{baseInput.Variant.ToDescriptionString()}") + .AddClass($"mud-input-adorned-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-input-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None) + .AddClass("mud-input-underline", when: () => baseInput.DisableUnderLine == false && baseInput.Variant != Variant.Outlined) + .AddClass("mud-shrink", when: shrinkWhen) + .AddClass("mud-disabled", baseInput.Disabled) + .AddClass("mud-input-error", baseInput.HasErrors) + .AddClass("mud-ltr", baseInput.GetInputType() == InputType.Email || baseInput.GetInputType() == InputType.Telephone) + .AddClass(baseInput.Class) + .Build(); + + public static string GetInputClassname(InputBase baseInput) => + new CssBuilder("mud-input-slot") + .AddClass("mud-input-root") + .AddClass($"mud-input-root-{baseInput.Variant.ToDescriptionString()}") + .AddClass($"mud-input-root-adorned-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-input-root-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None) + .AddClass(baseInput.Class) + .Build(); + + public static string GetAdornmentClassname(InputBase baseInput) => + new CssBuilder("mud-input-adornment") + .AddClass($"mud-input-adornment-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-text", !string.IsNullOrEmpty(baseInput.AdornmentText)) + .AddClass($"mud-input-root-filled-shrink", baseInput.Variant == Variant.Filled) + .AddClass(baseInput.Class) + .Build(); +} diff --git a/Components/Input/InputLabel.razor b/Components/Input/InputLabel.razor new file mode 100644 index 0000000..679b0c9 --- /dev/null +++ b/Components/Input/InputLabel.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + + diff --git a/Components/Input/InputLabel.razor.cs b/Components/Input/InputLabel.razor.cs new file mode 100644 index 0000000..3127f3b --- /dev/null +++ b/Components/Input/InputLabel.razor.cs @@ -0,0 +1,48 @@ +using Connected.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class InputLabel : UIComponent +{ + protected string Classname => + new Utilities.CssBuilder() + .AddClass("mud-input-label") + .AddClass("mud-input-label-animated") + .AddClass($"mud-input-label-{Variant.ToDescriptionString()}") + .AddClass($"mud-input-label-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .AddClass($"mud-disabled", Disabled) + .AddClass("mud-input-error", Error) + .AddClass(Class) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + /// + /// If true, the input element will be disabled. + /// + [Parameter] public bool Disabled { get; set; } + + /// + /// If true, the label will be displayed in an error state. + /// + [Parameter] public bool Error { get; set; } + + /// + /// Variant to use. + /// + [Parameter] public Variant Variant { get; set; } = Variant.Text; + + /// + /// Will adjust vertical spacing. + /// + [Parameter] public Margin Margin { get; set; } = Margin.None; + + /// + /// Will set the for attribute for WCAG accessiblility + /// + [Parameter] public string ForId { get; set; } = string.Empty; +} diff --git a/Components/Input/Range.cs b/Components/Input/Range.cs new file mode 100644 index 0000000..8de9ac7 --- /dev/null +++ b/Components/Input/Range.cs @@ -0,0 +1,29 @@ +namespace Connected.Components; + +public class Range +{ + public T Start { get; set; } + + public T End { get; set; } + + public Range() + { + + } + + public Range(T start, T end) + { + Start = start; + End = end; + } + + public override bool Equals(object obj) + { + return obj is Range r && null != r.Start && r.Start.Equals(Start) && null != r.End && r.End.Equals(End); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } +} diff --git a/Components/Input/RangeInput.razor b/Components/Input/RangeInput.razor new file mode 100644 index 0000000..c6c19a7 --- /dev/null +++ b/Components/Input/RangeInput.razor @@ -0,0 +1,33 @@ +@namespace Connected.Components +@typeparam T +@inherits InputBase> + +
    + @if (Adornment == Adornment.Start) + { + + } + + @if (InputType == InputType.Hidden && ChildContent != null) + { +
    + @ChildContent +
    + } + + + + + + @if (Adornment == Adornment.End) + { + + } + + @if (Variant == Variant.Outlined) + { +
    + } +
    \ No newline at end of file diff --git a/Components/Input/RangeInput.razor.cs b/Components/Input/RangeInput.razor.cs new file mode 100644 index 0000000..f29abb8 --- /dev/null +++ b/Components/Input/RangeInput.razor.cs @@ -0,0 +1,131 @@ +using Connected.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class RangeInput : InputBase> +{ + private string _textStart, _textEnd; + + public RangeInput() + { + Value = new Range(); + Converter = new RangeConverter(); + } + + protected string Classname => InputCssHelper.GetClassname(this, + () => !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || !string.IsNullOrWhiteSpace(PlaceholderStart) || !string.IsNullOrWhiteSpace(PlaceholderEnd)); + + /// + /// Type of the input element. It should be a valid HTML5 input type. + /// + [Parameter] public InputType InputType { get; set; } = InputType.Text; + + internal override InputType GetInputType() => InputType; + + protected string InputClassname => InputCssHelper.GetInputClassname(this); + + protected string AdornmentClassname => InputCssHelper.GetAdornmentClassname(this); + + /// + /// The short hint displayed in the start input before the user enters a value. + /// + [Parameter] public string PlaceholderStart { get; set; } + + /// + /// The short hint displayed in the end input before the user enters a value. + /// + [Parameter] public string PlaceholderEnd { get; set; } + + protected string InputTypeString => InputType.ToDescriptionString(); + + /// + /// ChildContent of the MudInput will only be displayed if InputType.Hidden and if its not null. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + private ElementReference _elementReferenceStart, _elementReferenceEnd; + + /// + /// Custom separator icon, leave null for default. + /// + [Parameter] public string SeparatorIcon { get; set; } = Icons.Material.Filled.ArrowRightAlt; + + /// + /// Focuses the start input of MudRangeInput + /// + /// + public ValueTask FocusStartAsync() => _elementReferenceStart.FocusAsync(); + + /// + /// Selects the start text of MudRangeInput + /// + /// + public ValueTask SelectStartAsync() => _elementReferenceStart.SelectAsync(); + + /// + /// Selects the specified range of the start text + /// + /// Start position of the selection + /// End position of the selection + /// + public ValueTask SelectRangeStartAsync(int pos1, int pos2) => _elementReferenceStart.SelectRangeAsync(pos1, pos2); + + /// + /// Focuses the end input of MudRangeInput + /// + /// + public ValueTask FocusEndAsync() => _elementReferenceEnd.FocusAsync(); + + /// + /// Selects the end text of MudRangeInput + /// + /// + public ValueTask SelectEndAsync() => _elementReferenceEnd.SelectAsync(); + + /// + /// Selects the specified range of the end text + /// + /// Start position of the selection + /// End position of the selection + /// + public ValueTask SelectRangeEndAsync(int pos1, int pos2) => _elementReferenceEnd.SelectRangeAsync(pos1, pos2); + + public string TextStart + { + get => _textStart; + set + { + if (_textStart == value) + return; + _textStart = value; + SetTextAsync(RangeConverter.Join(_textStart, _textEnd)).AndForget(); + } + } + + public string TextEnd + { + get => _textEnd; + set + { + if (_textEnd == value) + return; + _textEnd = value; + SetTextAsync(RangeConverter.Join(_textStart, _textEnd)).AndForget(); + } + } + + protected override async Task UpdateTextPropertyAsync(bool updateValue) + { + await base.UpdateTextPropertyAsync(updateValue); + + RangeConverter.Split(Text, out _textStart, out _textEnd); + } + + protected override async Task UpdateValuePropertyAsync(bool updateText) + { + await base.UpdateValuePropertyAsync(updateText); + + RangeConverter.Split(Text, out _textStart, out _textEnd); + } +} diff --git a/Components/InputControl/InputControl.razor b/Components/InputControl/InputControl.razor new file mode 100644 index 0000000..1cd8bd5 --- /dev/null +++ b/Components/InputControl/InputControl.razor @@ -0,0 +1,43 @@ +@namespace Connected.Components +@inherits UIComponent + +
    +
    + @InputContent + @if (!String.IsNullOrEmpty(Label)) + { + + @Label + + } +
    + @if (Error || !String.IsNullOrEmpty(HelperText) || !String.IsNullOrEmpty(CounterText)) + { +
    +

    +

    + @if (Error) + { +
    + @ErrorText +
    + } + else if (!String.IsNullOrEmpty(HelperText)) + { +
    + @HelperText +
    + } + @if (!String.IsNullOrEmpty(CounterText)) + { +
    + @CounterText +
    + } +
    +

    +
    + } + @ChildContent +
    \ No newline at end of file diff --git a/Components/InputControl/InputControl.razor.cs b/Components/InputControl/InputControl.razor.cs new file mode 100644 index 0000000..38524cb --- /dev/null +++ b/Components/InputControl/InputControl.razor.cs @@ -0,0 +1,103 @@ +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class InputControl : UIComponent +{ + protected string Classname => + new CssBuilder("mud-input-control") + .AddClass("mud-input-required", when: () => Required) + .AddClass($"mud-input-control-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .AddClass("mud-input-control-full-width", FullWidth) + .AddClass("mud-input-error", Error) + .AddClass(Class) + .Build(); + + protected string HelperContainer => + new CssBuilder("mud-input-control-helper-container") + .AddClass($"px-1", Variant == Variant.Filled) + .AddClass($"px-2", Variant == Variant.Outlined) + .Build(); + + protected string HelperClass => + new CssBuilder("mud-input-helper-text") + .AddClass("mud-input-helper-onfocus", HelperTextOnFocus) + .AddClass("mud-input-error", Error) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + /// + /// Should be the Input + /// + [Parameter] public RenderFragment InputContent { get; set; } + + /// + /// Will adjust vertical spacing. + /// + [Parameter] public Margin Margin { get; set; } = Margin.None; + + /// + /// If true, will apply mud-input-required class to the output div + /// + [Parameter] public bool Required { get; set; } + + /// + /// If true, the label will be displayed in an error state. + /// + [Parameter] public bool Error { get; set; } + + /// + /// The ErrorText that will be displayed if Error true + /// + [Parameter] public string ErrorText { get; set; } + /// + /// The ErrorId that will be used by aria-describedby if Error true + /// + [Parameter] public string ErrorId { get; set; } + + /// + /// The HelperText will be displayed below the text field. + /// + [Parameter] public string HelperText { get; set; } + + /// + /// If true, the helper text will only be visible on focus. + /// + [Parameter] public bool HelperTextOnFocus { get; set; } + + /// + /// The current character counter, displayed below the text field. + /// + [Parameter] public string CounterText { get; set; } + + /// + /// If true, the input will take up the full width of its container. + /// + [Parameter] public bool FullWidth { get; set; } + + /// + /// If string has value the label text will be displayed in the input, and scaled down at the top if the input has value. + /// + [Parameter] public string Label { get; set; } + + /// + /// Variant can be Text, Filled or Outlined. + /// + [Parameter] public Variant Variant { get; set; } = Variant.Text; + + /// + /// If true, the input element will be disabled. + /// + [Parameter] public bool Disabled { get; set; } + + /// + /// If string has value the label "for" attribute will be added. + /// + [Parameter] public string ForId { get; set; } = string.Empty; +} diff --git a/Components/ItemsControlBase.cs b/Components/ItemsControlBase.cs new file mode 100644 index 0000000..ed54857 --- /dev/null +++ b/Components/ItemsControlBase.cs @@ -0,0 +1,114 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public abstract class ItemsControlBase : UIComponent + where TChildComponent : UIComponent + +{ + /// + /// Collection of T + /// + [Parameter] + [Category(CategoryTypes.General.Data)] + public RenderFragment ChildContent { get; set; } + + /// + /// Items - will be ignored when ItemsSource is not null + /// + public List Items { get; } = new List(); + + private int _selectedIndexField = -1; + /// + /// Selected Item's index + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public int SelectedIndex + { + get => _selectedIndexField; + set + { + if (SelectedIndex == value) + return; + + LastContainer = _selectedIndexField >= 0 ? SelectedContainer : null; + _selectedIndexField = value; + SelectionChanged(); + StateHasChanged(); + SelectedIndexChanged.InvokeAsync(value); + } + } + + [Parameter] + public EventCallback SelectedIndexChanged { get; set; } + + /// + /// Gets the Selected TChildComponent + /// + public TChildComponent LastContainer { get; private set; } = null; + + /// + /// Gets the Selected TChildComponent + /// + public TChildComponent SelectedContainer + { + get => SelectedIndex >= 0 && Items.Count > SelectedIndex ? Items[SelectedIndex] : null; + } + + protected override Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + if (Items.Count > 0 && SelectedIndex < 0) + MoveTo(0); + + } + return base.OnAfterRenderAsync(firstRender); + } + + internal bool _moveNext = true; + + /// + /// Move to Previous Item + /// + public void Previous() + { + _moveNext = false; + + if (SelectedIndex > 0) + SelectedIndex--; + else + SelectedIndex = Items.Count - 1; + } + + /// + /// Move to Next Item + /// + public void Next() + { + _moveNext = true; + + if (SelectedIndex < (Items.Count - 1)) + SelectedIndex++; + else + SelectedIndex = 0; + } + + /// + /// Move to Item at desired index + /// + public void MoveTo(int index) + { + if (SelectedIndex != index) + { + _moveNext = index >= SelectedIndex; + SelectedIndex = index; + } + } + + protected virtual void SelectionChanged() { } + + public virtual void AddItem(TChildComponent item) { } +} diff --git a/Components/Layout/Layout.razor b/Components/Layout/Layout.razor new file mode 100644 index 0000000..9017f0e --- /dev/null +++ b/Components/Layout/Layout.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits DrawerContainer + +
    + + @ChildContent + +
    diff --git a/Components/Layout/Layout.razor.cs b/Components/Layout/Layout.razor.cs new file mode 100644 index 0000000..aba7569 --- /dev/null +++ b/Components/Layout/Layout.razor.cs @@ -0,0 +1,16 @@ +using Connected.Utilities; + +namespace Connected.Components; + +public partial class Layout : DrawerContainer +{ + protected override string Classname => + new CssBuilder("mud-layout") + .AddClass(base.Classname) + .Build(); + + public Layout() + { + Fixed = true; + } +} diff --git a/Components/Link/Link.razor b/Components/Link/Link.razor new file mode 100644 index 0000000..f6f883f --- /dev/null +++ b/Components/Link/Link.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + \ No newline at end of file diff --git a/Components/Link/Link.razor.cs b/Components/Link/Link.razor.cs new file mode 100644 index 0000000..2b3929c --- /dev/null +++ b/Components/Link/Link.razor.cs @@ -0,0 +1,91 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Link : UIComponent +{ + protected string Classname => + new CssBuilder("mud-typography mud-link") + .AddClass($"mud-{Color.ToDescriptionString()}-text") + .AddClass($"mud-link-underline-{Underline.ToDescriptionString()}") + .AddClass($"mud-typography-{Typo.ToDescriptionString()}") + // When Href is empty, link's hover cursor is text "I beam" even when OnClick has a delegate. + // To change this for more expected look change hover cursor to a pointer: + .AddClass("cursor-pointer", Href == default && OnClick.HasDelegate && !Disabled) + .AddClass($"mud-link-disabled", Disabled) + .AddClass(Class) + .Build(); + + private Dictionary Attributes + { + get => Disabled ? UserAttributes : new Dictionary(UserAttributes) + { + { "href", Href }, + { "target", Target } + }; + } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Link.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + /// + /// Typography variant to use. + /// + [Parameter] + [Category(CategoryTypes.Link.Appearance)] + public Typo Typo { get; set; } = Typo.body1; + + /// + /// Controls when the link should have an underline. + /// + [Parameter] + [Category(CategoryTypes.Link.Appearance)] + public Underline Underline { get; set; } = Underline.Hover; + + /// + /// The URL, which is the actual link. + /// + [Parameter] + [Category(CategoryTypes.Link.Behavior)] + public string Href { get; set; } + + /// + /// The target attribute specifies where to open the link, if Link is specified. Possible values: _blank | _self | _parent | _top | framename + /// + [Parameter] + [Category(CategoryTypes.Link.Behavior)] + public string Target { get; set; } + + /// + /// Link click event. + /// + [Parameter] public EventCallback OnClick { get; set; } + + protected async Task OnClickHandler(MouseEventArgs ev) + { + if (Disabled) return; + await OnClick.InvokeAsync(ev); + } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Link.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If true, the navlink will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Link.Behavior)] + public bool Disabled { get; set; } +} diff --git a/Components/List/List.razor b/Components/List/List.razor new file mode 100644 index 0000000..7747798 --- /dev/null +++ b/Components/List/List.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + @ChildContent + +
    diff --git a/Components/List/List.razor.cs b/Components/List/List.razor.cs new file mode 100644 index 0000000..2b2c0e0 --- /dev/null +++ b/Components/List/List.razor.cs @@ -0,0 +1,194 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class List : UIComponent, IDisposable +{ + protected string Classname => + new CssBuilder("mud-list") + .AddClass("mud-list-padding", !DisablePadding) + .AddClass(Class) + .Build(); + + [CascadingParameter] protected List ParentList { get; set; } + + /// + /// The color of the selected List Item. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Set true to make the list items clickable. This is also the precondition for list selection to work. + /// + [Parameter] + [Category(CategoryTypes.List.Selecting)] + public bool Clickable { get; set; } + + /// + /// If true, vertical padding will be removed from the list. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisablePadding { get; set; } + + /// + /// If true, compact vertical padding will be applied to all list items. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool Dense { get; set; } + + /// + /// If true, the left and right padding is removed on all list items. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisableGutters { get; set; } + + /// + /// If true, will disable the list item if it has onclick. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public bool Disabled { get; set; } + + /// + /// The current selected list item. + /// Note: make the list Clickable for item selection to work. + /// + [Parameter] + [Category(CategoryTypes.List.Selecting)] + public ListItem SelectedItem + { + get => _selectedItem; + set + { + if (_selectedItem == value) + return; + SetSelectedValue(_selectedItem?.Value, force: true); + } + } + + /// + /// Called whenever the selection changed + /// + [Parameter] public EventCallback SelectedItemChanged { get; set; } + + /// + /// The current selected value. + /// Note: make the list Clickable for item selection to work. + /// + [Parameter] + [Category(CategoryTypes.List.Selecting)] + public object SelectedValue + { + get => _selectedValue; + set + { + SetSelectedValue(value, force: true); + } + } + + /// + /// Called whenever the selection changed + /// + [Parameter] public EventCallback SelectedValueChanged { get; set; } + + protected override void OnInitialized() + { + if (ParentList != null) + { + ParentList.Register(this); + CanSelect = ParentList.CanSelect; + } + else + { + CanSelect = SelectedItemChanged.HasDelegate || SelectedValueChanged.HasDelegate || SelectedValue != null; + } + } + + internal event Action ParametersChanged; + + protected override void OnParametersSet() + { + base.OnParametersSet(); + ParametersChanged?.Invoke(); + } + + private HashSet _items = new(); + private HashSet _childLists = new(); + private ListItem _selectedItem; + private object _selectedValue; + + internal void Register(ListItem item) + { + _items.Add(item); + if (CanSelect && SelectedValue != null && object.Equals(item.Value, SelectedValue)) + { + item.SetSelected(true); + _selectedItem = item; + SelectedItemChanged.InvokeAsync(item); + } + } + + internal void Unregister(ListItem item) + { + _items.Remove(item); + } + + internal void Register(List child) + { + _childLists.Add(child); + } + + internal void Unregister(List child) + { + _childLists.Remove(child); + } + + internal void SetSelectedValue(object value, bool force = false) + { + if ((!CanSelect || !Clickable) && !force) + return; + if (object.Equals(_selectedValue, value)) + return; + _selectedValue = value; + SelectedValueChanged.InvokeAsync(value).AndForget(); + _selectedItem = null; // <-- for now, we'll see which item matches the value below + foreach (var listItem in _items.ToArray()) + { + var isSelected = value != null && object.Equals(value, listItem.Value); + listItem.SetSelected(isSelected); + if (isSelected) + _selectedItem = listItem; + } + foreach (var childList in _childLists.ToArray()) + { + childList.SetSelectedValue(value); + if (childList.SelectedItem != null) + _selectedItem = childList.SelectedItem; + } + SelectedItemChanged.InvokeAsync(_selectedItem).AndForget(); + ParentList?.SetSelectedValue(value); + } + + internal bool CanSelect { get; private set; } + + public void Dispose() + { + ParametersChanged = null; + ParentList?.Unregister(this); + } + +} diff --git a/Components/List/ListItem.razor b/Components/List/ListItem.razor new file mode 100644 index 0000000..b5f3b42 --- /dev/null +++ b/Components/List/ListItem.razor @@ -0,0 +1,43 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @if (!string.IsNullOrWhiteSpace(Avatar)) + { +
    + + + +
    + } + else if (!string.IsNullOrWhiteSpace(Icon)) + { +
    + +
    + } +
    + + @if (ChildContent != null) + { + @ChildContent + } + else + { + @Text + } + +
    + @if (NestedList != null) + { + + } +
    +@if (NestedList != null) +{ + + + @NestedList + + +} \ No newline at end of file diff --git a/Components/List/ListItem.razor.cs b/Components/List/ListItem.razor.cs new file mode 100644 index 0000000..0b69080 --- /dev/null +++ b/Components/List/ListItem.razor.cs @@ -0,0 +1,304 @@ +using System.Windows.Input; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class ListItem : UIComponent, IDisposable +{ + protected string Classname => + new CssBuilder("mud-list-item") + .AddClass("mud-list-item-dense", (Dense ?? List?.Dense) ?? false) + .AddClass("mud-list-item-gutters", !DisableGutters && !(List?.DisableGutters == true)) + .AddClass("mud-list-item-clickable", List?.Clickable) + .AddClass("mud-ripple", List?.Clickable == true && !DisableRipple && !Disabled) + .AddClass($"mud-selected-item mud-{List?.Color.ToDescriptionString()}-text mud-{List?.Color.ToDescriptionString()}-hover", _selected && !Disabled) + .AddClass("mud-list-item-disabled", Disabled) + .AddClass(Class) + .Build(); + + [Inject] protected NavigationManager UriHelper { get; set; } + + [CascadingParameter] protected List List { get; set; } + + private bool _onClickHandlerPreventDefault = false; + + /// + /// The text to display + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public string Text { get; set; } + + [Parameter] + [Category(CategoryTypes.List.Selecting)] + public object Value { get; set; } + + /// + /// Avatar to use if set. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public string Avatar { get; set; } + + /// + /// Link to a URL when clicked. + /// + [Parameter] + [Category(CategoryTypes.List.ClickAction)] + public string Href { get; set; } + + /// + /// If true, force browser to redirect outside component router-space. + /// + [Parameter] + [Category(CategoryTypes.List.ClickAction)] + public bool ForceLoad { get; set; } + + /// + /// Avatar CSS Class to apply if Avatar is set. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public string AvatarClass { get; set; } + + private bool _disabled; + /// + /// If true, will disable the list item if it has onclick. + /// The value can be overridden by the parent list. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public bool Disabled + { + get => _disabled || (List?.Disabled ?? false); + set => _disabled = value; + } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// Icon to use if set. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public string Icon { get; set; } + + /// + /// The color of the icon. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// Sets the Icon Size. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + /// + /// The color of the adornment if used. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.List.Expanding)] + public ThemeColor AdornmentColor { get; set; } = ThemeColor.Default; + + /// + /// Custom expand less icon. + /// + [Parameter] + [Category(CategoryTypes.List.Expanding)] + public string ExpandLessIcon { get; set; } = Icons.Material.Filled.ExpandLess; + + /// + /// Custom expand more icon. + /// + [Parameter] + [Category(CategoryTypes.List.Expanding)] + public string ExpandMoreIcon { get; set; } = Icons.Material.Filled.ExpandMore; + + /// + /// If true, the List Subheader will be indented. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool Inset { get; set; } + + /// + /// If true, compact vertical padding will be used. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool? Dense { get; set; } + + /// + /// If true, the left and right padding is removed. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisableGutters { get; set; } + + /// + /// Expand or collapse nested list. Two-way bindable. Note: if you directly set this to + /// true or false (instead of using two-way binding) it will force the nested list's expansion state. + /// + [Parameter] + [Category(CategoryTypes.List.Expanding)] + public bool Expanded + { + get => _expanded; + set + { + if (_expanded == value) + return; + _expanded = value; + _ = ExpandedChanged.InvokeAsync(value); + } + } + + private bool _expanded; + + [Parameter] + public EventCallback ExpandedChanged { get; set; } + + /// + /// If true, expands the nested list on first display + /// + [Parameter] + [Category(CategoryTypes.List.Expanding)] + public bool InitiallyExpanded { get; set; } + + /// + /// Command parameter. + /// + [Parameter] + [Category(CategoryTypes.List.ClickAction)] + public object CommandParameter { get; set; } + + /// + /// Command executed when the user clicks on an element. + /// + [Parameter] + [Category(CategoryTypes.List.ClickAction)] + public ICommand Command { get; set; } + + /// + /// Display content of this list item. If set, this overrides Text + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public RenderFragment ChildContent { get; set; } + + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public bool OnClickHandlerPreventDefault + { + get => _onClickHandlerPreventDefault; + set => _onClickHandlerPreventDefault = value; + } + + /// + /// Add child list items here to create a nested list. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public RenderFragment NestedList { get; set; } + + /// + /// List click event. + /// + [Parameter] + public EventCallback OnClick { get; set; } + + protected void OnClickHandler(MouseEventArgs ev) + { + if (Disabled) + return; + if (!_onClickHandlerPreventDefault) + { + if (NestedList != null) + { + Expanded = !Expanded; + } + else if (Href != null) + { + List?.SetSelectedValue(this.Value); + OnClick.InvokeAsync(ev); + UriHelper.NavigateTo(Href, ForceLoad); + } + else + { + List?.SetSelectedValue(this.Value); + OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + } + else + { + OnClick.InvokeAsync(ev); + } + } + + protected override void OnInitialized() + { + _expanded = InitiallyExpanded; + if (List != null) + { + List.Register(this); + OnListParametersChanged(); + List.ParametersChanged += OnListParametersChanged; + } + } + + private Typo _textTypo; + private void OnListParametersChanged() + { + if ((Dense ?? List?.Dense) ?? false) + { + _textTypo = Typo.body2; + } + else if (!((Dense ?? List?.Dense) ?? false)) + { + _textTypo = Typo.body1; + } + StateHasChanged(); + } + + private bool _selected; + + internal void SetSelected(bool selected) + { + if (Disabled) + return; + if (_selected == selected) + return; + _selected = selected; + StateHasChanged(); + } + + public void Dispose() + { + try + { + if (List == null) + return; + List.ParametersChanged -= OnListParametersChanged; + List.Unregister(this); + } + catch (Exception) { /*ignore*/ } + } + +} diff --git a/Components/List/ListSubheader.razor b/Components/List/ListSubheader.razor new file mode 100644 index 0000000..da208cd --- /dev/null +++ b/Components/List/ListSubheader.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @ChildContent +
    diff --git a/Components/List/ListSubheader.razor.cs b/Components/List/ListSubheader.razor.cs new file mode 100644 index 0000000..b98a76e --- /dev/null +++ b/Components/List/ListSubheader.razor.cs @@ -0,0 +1,27 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ListSubheader : UIComponent +{ + protected string Classname => + new CssBuilder("mud-list-subheader") + .AddClass("mud-list-subheader-gutters", !DisableGutters) + .AddClass("mud-list-subheader-inset", Inset) + .AddClass(Class) + .Build(); + + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public RenderFragment ChildContent { get; set; } + + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisableGutters { get; set; } + + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool Inset { get; set; } +} diff --git a/Components/Main/MainContent.razor b/Components/Main/MainContent.razor new file mode 100644 index 0000000..9630e91 --- /dev/null +++ b/Components/Main/MainContent.razor @@ -0,0 +1,20 @@ +@namespace Connected.Components +@using Connected.Annotations; +@using Connected.Utilities; +@inherits UIComponent + +
    + @ChildContent +
    + +@code { + + protected string Classname => + new CssBuilder("mud-main-content") + .AddClass(Class) + .Build(); + + [Parameter] + [Category(CategoryTypes.MainContent.Behavior)] + public RenderFragment ChildContent { get; set; } +} \ No newline at end of file diff --git a/Components/Mask/Mask.razor b/Components/Mask/Mask.razor new file mode 100644 index 0000000..aa9f911 --- /dev/null +++ b/Components/Mask/Mask.razor @@ -0,0 +1,80 @@ +@namespace Connected.Components +@using Connected.Extensions; +@inherits InputBase + +
    + @if (Adornment == Adornment.Start) + { + + } + + + + @if (Disabled) + { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown. + In Disabled state the tabindex attribute must NOT be set at all or else it will get focus on click + *@ +
    + @ChildContent +
    + } + else + { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown.*@ +
    + @ChildContent +
    + } + + + @if (_showClearable && !Disabled) + { + + } + + @if (Adornment == Adornment.End) + { + + } + + @if (Variant == Variant.Outlined) + { +
    + } + +
    \ No newline at end of file diff --git a/Components/Mask/Mask.razor.cs b/Components/Mask/Mask.razor.cs new file mode 100644 index 0000000..7c7ae7a --- /dev/null +++ b/Components/Mask/Mask.razor.cs @@ -0,0 +1,438 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.RegularExpressions; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Mask : InputBase, IDisposable +{ + public Mask() + { + TextUpdateSuppression = false; + } + + protected string Classname => + new CssBuilder("mud-input") + .AddClass($"mud-input-{Variant.ToDescriptionString()}") + .AddClass($"mud-input-adorned-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-input-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .AddClass("mud-input-underline", when: () => DisableUnderLine == false && Variant != Variant.Outlined) + .AddClass("mud-shrink", + when: () => !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || + !string.IsNullOrWhiteSpace(Placeholder)) + .AddClass("mud-disabled", Disabled) + .AddClass("mud-input-error", HasErrors) + .AddClass("mud-ltr", GetInputType() == InputType.Email || GetInputType() == InputType.Telephone) + .AddClass(Class) + .Build(); + + protected string InputClassname => + new CssBuilder("mud-input-slot") + .AddClass("mud-input-root") + .AddClass($"mud-input-root-{Variant.ToDescriptionString()}") + .AddClass($"mud-input-root-adorned-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-input-root-margin-{Margin.ToDescriptionString()}", when: () => Margin != Margin.None) + .AddClass(Class) + .Build(); + + protected string AdornmentClassname => + new CssBuilder("mud-input-adornment") + .AddClass($"mud-input-adornment-{Adornment.ToDescriptionString()}", Adornment != Adornment.None) + .AddClass($"mud-text", !string.IsNullOrEmpty(AdornmentText)) + .AddClass($"mud-input-root-filled-shrink", Variant == Variant.Filled) + .AddClass(Class) + .Build(); + + protected string ClearButtonClassname => + new CssBuilder() + // .AddClass("me-n1", Adornment == Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-end", Adornment == Adornment.End) + // .AddClass("me-6", Adornment != Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-margin-end", Adornment != Adornment.End) + .Build(); + + + private ElementReference _elementReference; + private ElementReference _elementReference1; + private IJsEvent _jsEvent; + private IKeyInterceptor _keyInterceptor; + + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + [Inject] private IJsEventFactory _jsEventFactory { get; set; } + [Inject] private IJsApiService _jsApiService { get; set; } + + private string _elementId = "mask_" + Guid.NewGuid().ToString().Substring(0, 8); + + private IMask _mask = new PatternMask("** **-** **"); + + /// + /// ChildContent will only be displayed if InputType.Hidden and if its not null. Required for Select + /// + [Parameter] + [Category(CategoryTypes.General.Appearance)] + public RenderFragment ChildContent { get; set; } + + /// + /// Provide a masking object. Built-in masks are PatternMask, MultiMask, RegexMask and BlockMask + /// + [Parameter] + [Category(CategoryTypes.General.Data)] + public IMask MaskKind + { + get => _mask; + set => SetMask(value); + } + + /// + /// Type of the input element. It should be a valid HTML5 input type. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public InputType InputType { get; set; } = InputType.Text; + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool Clearable { get; set; } = false; + + private bool _showClearable; + + private void UpdateClearable(object value) + { + var showClearable = Clearable && !string.IsNullOrWhiteSpace(Text); + if (_showClearable != showClearable) + _showClearable = showClearable; + } + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public EventCallback OnClearButtonClick { get; set; } + + /// + /// Custom clear icon. + /// + [Parameter] + [Category(CategoryTypes.General.Appearance)] + public string ClearIcon { get; set; } = Icons.Material.Filled.Clear; + + protected override async Task OnInitializedAsync() + { + if (Text != MaskKind.Text) + await SetTextAsync(MaskKind.Text, updateValue: false); + await base.OnInitializedAsync(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _jsEvent = _jsEventFactory.Create(); + + await _jsEvent.Connect(_elementId, + new JsEventOptions + { + //EnableLogging = true, + TargetClass = "mud-input-slot", + TagName = "INPUT" + }); + _jsEvent.CaretPositionChanged += OnCaretPositionChanged; + _jsEvent.Paste += OnPaste; + _jsEvent.Select += OnSelect; + + _keyInterceptor = _keyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-input-slot", + Keys = + { + new KeyOptions + { + Key = " ", PreventDown = "key+none" + }, //prevent scrolling page, toggle open/close + new KeyOptions { Key = "ArrowUp", PreventDown = "key+none" }, // prevent scrolling page + new KeyOptions { Key = "ArrowDown", PreventDown = "key+none" }, // prevent scrolling page + new KeyOptions { Key = "PageUp", PreventDown = "key+none" }, // prevent scrolling page + new KeyOptions { Key = "PageDown", PreventDown = "key+none" }, // prevent scrolling page + new KeyOptions { Key = @"/^.$/", PreventDown = "key+none|key+shift" }, + new KeyOptions { Key = "/./", SubscribeDown = true }, + new KeyOptions { Key = "Backspace", PreventDown = "key+none" }, + new KeyOptions { Key = "Delete", PreventDown = "key+none" }, + }, + }); + _keyInterceptor.KeyDown += HandleKeyDownInternally; + } + if (_isFocused && MaskKind.Selection == null) + SetCaretPosition(MaskKind.CaretPos, _selection, render: false); + await base.OnAfterRenderAsync(firstRender); + } + + private async void HandleKeyDownInternally(KeyboardEventArgs args) + { + await HandleKeyDown(args); + } + + protected internal async Task HandleKeyDown(KeyboardEventArgs e) + { + try + { + if ((e.CtrlKey && e.Key != "Backspace") || e.AltKey || ReadOnly) + return; + switch (e.Key) + { + case "Backspace": + if (e.CtrlKey) + { + MaskKind.Clear(); + await Update(); + return; + } + MaskKind.Backspace(); + await Update(); + return; + case "Delete": + MaskKind.Delete(); + await Update(); + return; + } + + if (Regex.IsMatch(e.Key, @"^.$")) + { + MaskKind.Insert(e.Key); + await Update(); + } + } + finally + { + // call user callback + await OnKeyDown.InvokeAsync(e); + } + } + + private bool _updating; + + private async Task Update() + { + var caret = MaskKind.CaretPos; + var selection = MaskKind.Selection; + var text = MaskKind.Text; + var cleanText = MaskKind.GetCleanText(); + _updating = true; + try + { + await base.SetTextAsync(text, updateValue: false); + if (Clearable) + UpdateClearable(Text); + var v = Converter.Get(cleanText); + Value = v; + await ValueChanged.InvokeAsync(v); + SetCaretPosition(caret, selection); + } + finally + { + _updating = false; + } + } + + internal async void HandleClearButton(MouseEventArgs e) + { + MaskKind.Clear(); + await Update(); + await _elementReference.FocusAsync(); + await OnClearButtonClick.InvokeAsync(e); + } + + protected override async Task UpdateTextPropertyAsync(bool updateValue) + { + // allow this only via changes from the outside + if (_updating) + return; + var text = Converter.Set(Value); + var cleanText = MaskKind.GetCleanText(); + if (cleanText == text || string.IsNullOrEmpty(cleanText) && string.IsNullOrEmpty(text)) + return; + var maskText = MaskKind.Text; + MaskKind.SetText(text); + if (maskText == MaskKind.Text) + return; // no change, stop update loop + await Update(); + } + + protected override async Task UpdateValuePropertyAsync(bool updateText) + { + // allow this only via changes from the outside + if (_updating) + return; + var text = Text; + if (MaskKind.Text == text) + return; + var maskText = MaskKind.Text; + MaskKind.SetText(text); + if (maskText == MaskKind.Text) + return; // no change, stop update loop + await Update(); + } + + internal override InputType GetInputType() => InputType; + + private string GetCounterText() => Counter == null + ? string.Empty + : (Counter == 0 + ? (string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + : ((string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + $" / {Counter}")); + + /// + /// Clear the text field. + /// + /// + public Task Clear() + { + MaskKind.Clear(); + return Update(); + } + + public override ValueTask FocusAsync() + { + return _elementReference.FocusAsync(); + } + + public override ValueTask SelectAsync() + { + return _elementReference.SelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return _elementReference.SelectRangeAsync(pos1, pos2); + } + + internal void OnCopy() + { + var text = Text; + if (MaskKind.Selection != null) + { + (_, text, _) = BaseMask.SplitSelection(text, MaskKind.Selection.Value); + } + _jsApiService.CopyToClipboardAsync(text); + } + + internal async void OnPaste(string text) + { + if (text == null || ReadOnly) + return; + MaskKind.Insert(text); + await Update(); + } + + public void OnSelect(int start, int end) + { + MaskKind.Selection = _selection = (start, end); + } + + internal void OnFocused(FocusEventArgs obj) + { + _isFocused = true; + } + + protected internal override void OnBlurred(FocusEventArgs obj) + { + base.OnBlurred(obj); + _isFocused = false; + } + + private int _caret; + private (int, int)? _selection; + + private void SetCaretPosition(int caret, (int, int)? selection = null, bool render = true) + { + if (!_isFocused) + return; + _caret = caret; + if (caret == 0) + _caret = 0; + _selection = selection; + if (selection == null) + { + _elementReference.SelectRangeAsync(caret, caret).AndForget(); + } + else + { + var sel = selection.Value; + _elementReference.SelectRangeAsync(sel.Item1, sel.Item2).AndForget(); + } + } + + // from JS event + internal void OnCaretPositionChanged(int pos) + { + if (MaskKind.Selection != null) + { + // do not clear selection if pos change is at selection border + var sel = MaskKind.Selection.Value; + if (pos == sel.Item1 || pos == sel.Item2) + return; + } + + if (pos == MaskKind.CaretPos) + return; + MaskKind.Selection = null; + MaskKind.CaretPos = pos; + } + + private void SetMask(IMask other) + { + if (_mask == null || other == null || _mask?.GetType() != other?.GetType()) + { + _mask = other; + if (_mask == null) + _mask = new PatternMask("null ********"); // warn the user that the mask parameter is missing + return; + } + + // set new mask properties without loosing state + _mask.UpdateFrom(other); + } + + private async void OnCut(ClipboardEventArgs obj) + { + if (ReadOnly) + return; + + if (_selection != null) + MaskKind.Delete(); + await Update(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + _jsEvent?.Dispose(); + + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDownInternally; + _keyInterceptor.Dispose(); + } + + _keyInterceptor?.Dispose(); + } + } +} diff --git a/Components/Menu/IActivatable.cs b/Components/Menu/IActivatable.cs new file mode 100644 index 0000000..cd7253d --- /dev/null +++ b/Components/Menu/IActivatable.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public interface IActivatable +{ + void Activate(object activator, MouseEventArgs args); +} diff --git a/Components/Menu/Menu.razor b/Components/Menu/Menu.razor new file mode 100644 index 0000000..ec84cfc --- /dev/null +++ b/Components/Menu/Menu.razor @@ -0,0 +1,49 @@ +@namespace Connected.Components +@inherits UIComponent + + +
    + @if (ActivatorContent != null) + { + +
    + @ActivatorContent +
    +
    + } + else if (String.IsNullOrEmpty(Icon)) + { + + } + else + { + + } + @* The portal has to include the cascading values inside, because it's not able to teletransport the cascade *@ + + + + @ChildContent + + + + +
    diff --git a/Components/Menu/Menu.razor.cs b/Components/Menu/Menu.razor.cs new file mode 100644 index 0000000..3d3c2db --- /dev/null +++ b/Components/Menu/Menu.razor.cs @@ -0,0 +1,335 @@ +using System.Diagnostics.CodeAnalysis; +using System.Windows.Input; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Menu : UIComponent, IActivatable +{ + protected string Classname => + new CssBuilder("mud-menu") + .AddClass(Class) + .Build(); + + protected string ActivatorClassname => + new CssBuilder("mud-menu-activator") + .AddClass("mud-disabled", Disabled) + .Build(); + + private bool _isOpen; + private bool _isMouseOver = false; + + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public string Label { get; set; } + + /// + /// User class names for the list, separated by space + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public string ListClass { get; set; } + + /// + /// User class names for the popover, separated by space + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public string PopoverClass { get; set; } + + /// + /// Icon to use if set will turn the button into a MudIconButton. + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public string Icon { get; set; } + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// Icon placed before the text if set. + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public string StartIcon { get; set; } + + /// + /// Icon placed after the text if set. + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public string EndIcon { get; set; } + + /// + /// The color of the button. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The button Size of the component. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// The button variant to use. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + + /// + /// If true, compact vertical padding will be applied to all menu items. + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public bool Dense { get; set; } + + /// + /// If true, the list menu will be same width as the parent. + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public bool FullWidth { get; set; } + + /// + /// Sets the maxheight the menu can have when open. + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public int? MaxHeight { get; set; } + + /// + /// If true, instead of positioning the menu at the left upper corner, position at the exact cursor location. + /// This makes sense for larger activators + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupBehavior)] + public bool PositionAtCursor { get; set; } + + /// + /// If true, instead of positioning the menu at the left upper corner, position at the exact cursor location. + /// This makes sense for larger activators + /// + [Obsolete("Use PositionAtCursor instead.", true)] + [Parameter] + public bool PositionAtCurser + { + get => PositionAtCursor; + set => PositionAtCursor = value; + } + + /// + /// Place a MudButton, a MudIconButton or any other component capable of acting as an activator. This will + /// override the standard button and all parameters which concern it. + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public RenderFragment ActivatorContent { get; set; } + + /// + /// Specify the activation event when ActivatorContent is set + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public MouseEvent ActivationEvent { get; set; } = MouseEvent.LeftClick; + + /// + /// Set the anchor origin point to determen where the popover will open from. + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public Origin AnchorOrigin { get; set; } = Origin.TopLeft; + + /// + /// Sets the transform origin point for the popover. + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public Origin TransformOrigin { get; set; } = Origin.TopLeft; + + /// + /// Sets the direction the select menu will start from relative to its parent. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public Direction Direction { get; set; } = Direction.Bottom; + + /// + /// If true, the select menu will open either before or after the input depending on the direction. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetY { get; set; } + + /// + /// If true, the select menu will open either above or bellow the input depending on the direction. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetX { get; set; } + + /// + /// Set to true if you want to prevent page from scrolling when the menu is open + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupAppearance)] + public bool LockScroll { get; set; } + + /// + /// If true, menu will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Menu.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// If true, no drop-shadow will be used. + /// + [Parameter] + [Category(CategoryTypes.Menu.Appearance)] + public bool DisableElevation { get; set; } + + #region Obsolete members from previous MudButtonBase inherited structure + + [ExcludeFromCodeCoverage] + [Obsolete("Linking is not supported. MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public string Link { get; set; } + + [ExcludeFromCodeCoverage] + [Obsolete("Linking is not supported. MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public string Target { get; set; } + + [ExcludeFromCodeCoverage] + [Obsolete("MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public string HtmlTag { get; set; } = "button"; + + [ExcludeFromCodeCoverage] + [Obsolete("MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public ButtonType ButtonType { get; set; } + + [ExcludeFromCodeCoverage] + [Obsolete("MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public ICommand Command { get; set; } + + [ExcludeFromCodeCoverage] + [Obsolete("MudMenu is not a MudBaseButton anymore.", true)] + [Parameter] public object CommandParameter { get; set; } + + #endregion + + /// + /// Add menu items here + /// + [Parameter] + [Category(CategoryTypes.Menu.PopupBehavior)] + public RenderFragment ChildContent { get; set; } + + public string PopoverStyle { get; set; } + + public void CloseMenu() + { + _isOpen = false; + _isMouseOver = false; + PopoverStyle = null; + StateHasChanged(); + } + + public void OpenMenu(EventArgs args) + { + if (Disabled) + return; + if (PositionAtCursor) SetPopoverStyle((MouseEventArgs)args); + _isOpen = true; + StateHasChanged(); + } + + // Sets the popover style ONLY when there is an activator + private void SetPopoverStyle(MouseEventArgs args) + { + AnchorOrigin = Origin.TopLeft; + PopoverStyle = $"margin-top: {args?.OffsetY.ToPx()}; margin-left: {args?.OffsetX.ToPx()};"; + } + + public void ToggleMenu(MouseEventArgs args) + { + if (Disabled) + return; + if (ActivationEvent == MouseEvent.LeftClick && args.Button != 0 && !_isOpen) + return; + if (ActivationEvent == MouseEvent.RightClick && args.Button != 2 && !_isOpen) + return; + if (_isOpen) + CloseMenu(); + else + OpenMenu(args); + } + + public void ToggleMenuTouch(TouchEventArgs args) + { + if (Disabled) + { + return; + } + + if (_isOpen) + { + CloseMenu(); + } + else + { + OpenMenu(args); + } + } + + /// + /// Implementation of IActivatable.Activate, toggles the menu. + /// + /// + /// + public void Activate(object activator, MouseEventArgs args) + { + ToggleMenu(args); + } + + public void MouseEnter(MouseEventArgs args) + { + _isMouseOver = true; + + if (ActivationEvent == MouseEvent.MouseOver) + { + OpenMenu(args); + } + } + + public async void MouseLeave() + { + _isMouseOver = false; + + await Task.Delay(100); + + if (ActivationEvent == MouseEvent.MouseOver && _isMouseOver == false) + { + CloseMenu(); + } + } +} diff --git a/Components/Menu/MenuItem.razor b/Components/Menu/MenuItem.razor new file mode 100644 index 0000000..3f31277 --- /dev/null +++ b/Components/Menu/MenuItem.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + + + diff --git a/Components/Menu/MenuItem.razor.cs b/Components/Menu/MenuItem.razor.cs new file mode 100644 index 0000000..a3cc95e --- /dev/null +++ b/Components/Menu/MenuItem.razor.cs @@ -0,0 +1,105 @@ +using System.Windows.Input; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class MenuItem : UIComponent +{ + [CascadingParameter] public Menu Menu { get; set; } + + [Parameter][Category(CategoryTypes.Menu.Behavior)] public RenderFragment ChildContent { get; set; } + [Parameter][Category(CategoryTypes.Menu.Behavior)] public bool Disabled { get; set; } + + [Inject] public NavigationManager UriHelper { get; set; } + [Inject] public IJsApiService JsApiService { get; set; } + + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where (Obsolete replaced by Href) + /// + [Obsolete("Use Href Instead.", false)] + [Parameter] + [Category(CategoryTypes.Menu.ClickAction)] + public string Link { get => Href; set => Href = value; } + + /// + /// If set to a URL, clicking the button will open the referenced document. Use Target to specify where + /// + [Parameter] + [Category(CategoryTypes.Menu.ClickAction)] + public string Href { get; set; } + + /// + /// Icon to be used for this menu entry + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public string Icon { get; set; } + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + /// + /// The Icon Size. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + [Parameter][Category(CategoryTypes.Menu.ClickAction)] public string Target { get; set; } + [Parameter][Category(CategoryTypes.Menu.ClickAction)] public bool ForceLoad { get; set; } + [Parameter][Category(CategoryTypes.Menu.ClickAction)] public ICommand Command { get; set; } + [Parameter][Category(CategoryTypes.Menu.ClickAction)] public object CommandParameter { get; set; } + + [Parameter] public EventCallback OnClick { get; set; } + [Parameter] public EventCallback OnTouch { get; set; } + + protected async Task OnClickHandler(MouseEventArgs ev) + { + if (Disabled) + return; + Menu.CloseMenu(); + + if (Href != null) + { + if (string.IsNullOrWhiteSpace(Target)) + UriHelper.NavigateTo(Href, ForceLoad); + else + await JsApiService.Open(Href, Target); + } + else + { + await OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + } + + protected internal async Task OnTouchHandler(TouchEventArgs ev) + { + if (Disabled) + return; + Menu.CloseMenu(); + + if (Href != null) + { + if (string.IsNullOrWhiteSpace(Target)) + UriHelper.NavigateTo(Href, ForceLoad); + else + await JsApiService.Open(Href, Target); + } + else + { + await OnTouch.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + } +} diff --git a/Components/MessageBox/MessageBox.razor b/Components/MessageBox/MessageBox.razor new file mode 100644 index 0000000..a1d76a2 --- /dev/null +++ b/Components/MessageBox/MessageBox.razor @@ -0,0 +1,62 @@ +@namespace Connected.Components +@inherits UIComponent + + + + @if (TitleContent == null) + { + @Title } + else + { + @TitleContent + } + + + @if(MessageContent!=null) + { + @MessageContent + } + else + { + @MarkupMessage + @Message + } + + +
    + + @if (CancelButton != null) + { + + @CancelButton + + } + else if (!string.IsNullOrWhiteSpace(CancelText)) + { + + } + @if (NoButton != null) + { + + @NoButton + + } + else if (!string.IsNullOrWhiteSpace(NoText)) + { + @NoText + } + @if (YesButton != null) + { + + @YesButton + + } + else if (!string.IsNullOrWhiteSpace(YesText)) + { + + } + +
    + +
    +
    diff --git a/Components/MessageBox/MessageBox.razor.cs b/Components/MessageBox/MessageBox.razor.cs new file mode 100644 index 0000000..03eaa11 --- /dev/null +++ b/Components/MessageBox/MessageBox.razor.cs @@ -0,0 +1,211 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class MessageBox : UIComponent +{ + [Inject] private IDialogService DialogService { get; set; } + + [CascadingParameter] private DialogInstance DialogInstance { get; set; } + + /// + /// The message box title. If null or empty, title will be hidden + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public string Title { get; set; } + + /// + /// Define the message box title as a renderfragment (overrides Title) + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public RenderFragment TitleContent { get; set; } + + /// + /// The message box message as string. + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public string Message { get; set; } + + /// + /// The message box message as markup string. + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public MarkupString MarkupMessage { get; set; } + + /// + /// Define the message box body as a renderfragment (overrides Message) + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public RenderFragment MessageContent { get; set; } + + + /// + /// Text of the cancel button. Leave null to hide the button. + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public string CancelText { get; set; } + + /// + /// Define the cancel button as a render fragment (overrides CancelText). + /// Must be a MudButton + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public RenderFragment CancelButton { get; set; } + + /// + /// Text of the no button. Leave null to hide the button. + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public string NoText { get; set; } + + /// + /// Define the no button as a render fragment (overrides CancelText). + /// Must be a MudButton + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public RenderFragment NoButton { get; set; } + + /// + /// Text of the yes/OK button. Leave null to hide the button. + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public string YesText { get; set; } = "OK"; + + /// + /// Define the cancel button as a render fragment (overrides CancelText). + /// Must be a MudButton + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public RenderFragment YesButton { get; set; } + + /// + /// Fired when the yes button is clicked + /// + [Parameter] + public EventCallback OnYes { get; set; } + + /// + /// Fired when the no button is clicked + /// + [Parameter] + public EventCallback OnNo { get; set; } + + /// + /// Fired when the cancel button is clicked or the msg box was closed via the X + /// + [Parameter] + public EventCallback OnCancel { get; set; } + + /// + /// Bind this two-way to show and close an inlined message box. Has no effect on opened msg boxes + /// + [Parameter] + [Category(CategoryTypes.MessageBox.Behavior)] + public bool IsVisible + { + get => _isVisible; + set + { + if (_isVisible == value) + return; + _isVisible = value; + if (IsInline) + { + if (_isVisible) + _ = Show(); + else + Close(); + } + + IsVisibleChanged.InvokeAsync(value); + } + } + + private bool _isVisible; + private bool IsInline => DialogInstance == null; + + private IDialogReference _reference; + + /// + /// Raised when the inline dialog's display status changes. + /// + [Parameter] + public EventCallback IsVisibleChanged { get; set; } + + public async Task Show(DialogOptions options = null) + { + if (DialogService == null) + return null; + var parameters = new DialogParameters() + { + [nameof(Title)] = Title, + [nameof(TitleContent)] = TitleContent, + [nameof(Message)] = Message, + [nameof(MarkupMessage)] = MarkupMessage, + [nameof(MessageContent)] = MessageContent, + [nameof(CancelText)] = CancelText, + [nameof(CancelButton)] = CancelButton, + [nameof(NoText)] = NoText, + [nameof(NoButton)] = NoButton, + [nameof(YesText)] = YesText, + [nameof(YesButton)] = YesButton, + }; + _reference = await DialogService.ShowAsync(parameters: parameters, options: options, title: Title); + var result = await _reference.Result; + if (result.Cancelled || result.Data is not bool data) + return null; + return data; + } + + public void Close() + { + _reference?.Close(); + } + + private ActivatableCallback _yesCallback, _cancelCallback, _noCallback; + + protected override void OnInitialized() + { + base.OnInitialized(); + if (YesButton != null) + _yesCallback = new ActivatableCallback() { ActivateCallback = OnYesActivated }; + if (NoButton != null) + _noCallback = new ActivatableCallback() { ActivateCallback = OnNoActivated }; + if (CancelButton != null) + _cancelCallback = new ActivatableCallback() { ActivateCallback = OnCancelActivated }; + } + + private void OnYesActivated(object arg1, MouseEventArgs arg2) => OnYesClicked(); + + private void OnNoActivated(object arg1, MouseEventArgs arg2) => OnNoClicked(); + + private void OnCancelActivated(object arg1, MouseEventArgs arg2) => OnCancelClicked(); + + private void OnYesClicked() => DialogInstance.Close(DialogResult.Ok(true)); + + private void OnNoClicked() => DialogInstance.Close(DialogResult.Ok(false)); + + private void OnCancelClicked() => DialogInstance.Close(DialogResult.Cancel()); + + private void HandleKeyDown(KeyboardEventArgs args) + { + if (args.Key == "Escape") + { + OnCancelClicked(); + } + } + +} diff --git a/Components/NavMenu/INavigationEventReceiver.cs b/Components/NavMenu/INavigationEventReceiver.cs new file mode 100644 index 0000000..e30c6b7 --- /dev/null +++ b/Components/NavMenu/INavigationEventReceiver.cs @@ -0,0 +1,6 @@ +namespace Connected.Components; + +public interface INavigationEventReceiver +{ + Task OnNavigation(); +} diff --git a/Components/NavMenu/NavGroup.razor b/Components/NavMenu/NavGroup.razor new file mode 100644 index 0000000..be24063 --- /dev/null +++ b/Components/NavMenu/NavGroup.razor @@ -0,0 +1,23 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + + + @ChildContent + + +
    \ No newline at end of file diff --git a/Components/NavMenu/NavGroup.razor.cs b/Components/NavMenu/NavGroup.razor.cs new file mode 100644 index 0000000..0fbbfbf --- /dev/null +++ b/Components/NavMenu/NavGroup.razor.cs @@ -0,0 +1,116 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class NavGroup : UIComponent +{ + protected string Classname => + new CssBuilder("mud-nav-group") + .AddClass(Class) + .AddClass($"mud-nav-group-disabled", Disabled) + .Build(); + + protected string ButtonClassname => + new CssBuilder("mud-nav-link") + .AddClass($"mud-ripple", !DisableRipple) + .AddClass("mud-expanded", Expanded) + .Build(); + + protected string IconClassname => + new CssBuilder("mud-nav-link-icon") + .AddClass($"mud-nav-link-icon-default", IconColor == ThemeColor.Default) + .Build(); + + protected string ExpandIconClassname => + new CssBuilder("mud-nav-link-expand-icon") + .AddClass($"mud-transform", Expanded && !Disabled) + .AddClass($"mud-transform-disabled", Expanded && Disabled) + .Build(); + + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public string Title { get; set; } + + /// + /// Icon to use if set. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public string Icon { get; set; } + + /// + /// The color of the icon. It supports the theme colors, default value uses the themes drawer icon color. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Default; + + /// + /// If true, the button will be disabled. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public bool DisableRipple { get; set; } + + private bool _expanded; + /// + /// If true, expands the nav group, otherwise collapse it. + /// Two-way bindable + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public bool Expanded + { + get => _expanded; + set + { + if (_expanded == value) + return; + + _expanded = value; + ExpandedChanged.InvokeAsync(_expanded); + } + } + + [Parameter] public EventCallback ExpandedChanged { get; set; } + + /// + /// If true, hides expand-icon at the end of the NavGroup. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public bool HideExpandIcon { get; set; } + + /// + /// Explicitly sets the height for the Collapse element to override the css default. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public int? MaxHeight { get; set; } + + /// + /// If set, overrides the default expand icon. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public string ExpandIcon { get; set; } = @Icons.Filled.ArrowDropDown; + + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected void ExpandedToggle() + { + _expanded = !Expanded; + ExpandedChanged.InvokeAsync(_expanded); + } +} diff --git a/Components/NavMenu/NavLink.razor b/Components/NavMenu/NavLink.razor new file mode 100644 index 0000000..4d87f2e --- /dev/null +++ b/Components/NavMenu/NavLink.razor @@ -0,0 +1,36 @@ +@namespace Connected.Components +@inherits SelectItemBase +@using Microsoft.AspNetCore.Components.Routing + +
    + @if (!OnClick.HasDelegate && Command == null) + { + + @if (!string.IsNullOrEmpty(Icon)) + { + + } + + + } + else + { +
    + @if (!string.IsNullOrEmpty(Icon)) + { + + } + +
    + } +
    \ No newline at end of file diff --git a/Components/NavMenu/NavLink.razor.cs b/Components/NavMenu/NavLink.razor.cs new file mode 100644 index 0000000..70d620d --- /dev/null +++ b/Components/NavMenu/NavLink.razor.cs @@ -0,0 +1,75 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; + +namespace Connected.Components; + +public partial class NavLink : SelectItemBase +{ + protected string Classname => + new CssBuilder("mud-nav-item") + .AddClass($"mud-ripple", !DisableRipple && !Disabled) + .AddClass(Class) + .Build(); + + protected string LinkClassname => + new CssBuilder("mud-nav-link") + .AddClass($"mud-nav-link-disabled", Disabled) + .Build(); + + protected string IconClassname => + new CssBuilder("mud-nav-link-icon") + .AddClass($"mud-nav-link-icon-default", IconColor == ThemeColor.Default) + .Build(); + + protected Dictionary Attributes + { + get => Disabled ? null : new Dictionary() + { + { "href", Href }, + { "target", Target }, + { "rel", !string.IsNullOrWhiteSpace(Target) ? "noopener noreferrer" : string.Empty } + }; + } + + /// + /// Icon to use if set. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public string Icon { get; set; } + + /// + /// The color of the icon. It supports the theme colors, default value uses the themes drawer icon color. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Default; + + [Parameter] + [Category(CategoryTypes.NavMenu.Behavior)] + public NavLinkMatch Match { get; set; } = NavLinkMatch.Prefix; + + [Parameter] + [Category(CategoryTypes.NavMenu.ClickAction)] + public string Target { get; set; } + + /// + /// User class names when active, separated by space. + /// + [Parameter] + [Category(CategoryTypes.ComponentBase.Common)] + public string ActiveClass { get; set; } = "active"; + + [CascadingParameter] INavigationEventReceiver NavigationEventReceiver { get; set; } + + protected Task HandleNavigation() + { + if (!Disabled && NavigationEventReceiver != null) + { + return NavigationEventReceiver.OnNavigation(); + } + return Task.CompletedTask; + } +} diff --git a/Components/NavMenu/NavMenu.razor b/Components/NavMenu/NavMenu.razor new file mode 100644 index 0000000..da208cd --- /dev/null +++ b/Components/NavMenu/NavMenu.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @ChildContent +
    diff --git a/Components/NavMenu/NavMenu.razor.cs b/Components/NavMenu/NavMenu.razor.cs new file mode 100644 index 0000000..fb4be2c --- /dev/null +++ b/Components/NavMenu/NavMenu.razor.cs @@ -0,0 +1,58 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class NavMenu : UIComponent +{ + protected string Classname => + new CssBuilder("mud-navmenu") + .AddClass($"mud-navmenu-{Color.ToDescriptionString()}") + .AddClass($"mud-navmenu-margin-{Margin.ToDescriptionString()}") + .AddClass("mud-navmenu-dense", Dense) + .AddClass("mud-navmenu-rounded", Rounded) + .AddClass($"mud-navmenu-bordered mud-border-{Color.ToDescriptionString()}", Bordered) + .AddClass(Class) + .Build(); + + [Category(CategoryTypes.NavMenu.Behavior)] + [Parameter] public RenderFragment ChildContent { get; set; } + + /// + /// The color of the active NavLink. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// If true, adds a border of the active NavLink, does nothing if variant outlined is used. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public bool Bordered { get; set; } + + /// + /// If true, default theme border-radius will be used on all navlinks. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public bool Rounded { get; set; } + + /// + /// Adjust the vertical spacing between navlinks. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public Margin Margin { get; set; } = Margin.None; + + /// + /// If true, compact vertical padding will be applied to all navmenu items. + /// + [Parameter] + [Category(CategoryTypes.NavMenu.Appearance)] + public bool Dense { get; set; } + +} diff --git a/Components/NumericField/NumericField.razor b/Components/NumericField/NumericField.razor new file mode 100644 index 0000000..f3e8d7d --- /dev/null +++ b/Components/NumericField/NumericField.razor @@ -0,0 +1,63 @@ +@namespace Connected.Components +@typeparam T +@inherits DebouncedInput + +@using System.Globalization; + + + + + + + + + + diff --git a/Components/NumericField/NumericField.razor.cs b/Components/NumericField/NumericField.razor.cs new file mode 100644 index 0000000..ae9a3e6 --- /dev/null +++ b/Components/NumericField/NumericField.razor.cs @@ -0,0 +1,438 @@ +// Copyright (c) MudBlazor 2022 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using Connected.Annotations; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class NumericField : DebouncedInput +{ + private IKeyInterceptor _keyInterceptor; + private Comparer _comparer = new(CultureInfo.InvariantCulture); + + public NumericField() : base() + { + Validation = new Func>(ValidateInput); + #region parameters default depending on T + + //sbyte + if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) + { + _minDefault = (T)(object)sbyte.MinValue; + _maxDefault = (T)(object)sbyte.MaxValue; + _stepDefault = (T)(object)(sbyte)1; + } + // byte + else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) + { + _minDefault = (T)(object)byte.MinValue; + _maxDefault = (T)(object)byte.MaxValue; + _stepDefault = (T)(object)(byte)1; + } + // short + else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) + { + _minDefault = (T)(object)short.MinValue; + _maxDefault = (T)(object)short.MaxValue; + _stepDefault = (T)(object)(short)1; + } + // ushort + else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) + { + _minDefault = (T)(object)ushort.MinValue; + _maxDefault = (T)(object)ushort.MaxValue; + _stepDefault = (T)(object)(ushort)1; + } + // int + else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) + { + _minDefault = (T)(object)int.MinValue; + _maxDefault = (T)(object)int.MaxValue; + _stepDefault = (T)(object)1; + } + // uint + else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) + { + _minDefault = (T)(object)uint.MinValue; + _maxDefault = (T)(object)uint.MaxValue; + _stepDefault = (T)(object)1u; + } + // long + else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) + { + _minDefault = (T)(object)long.MinValue; + _maxDefault = (T)(object)long.MaxValue; + _stepDefault = (T)(object)1L; + } + // ulong + else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) + { + _minDefault = (T)(object)ulong.MinValue; + _maxDefault = (T)(object)ulong.MaxValue; + _stepDefault = (T)(object)1ul; + } + // float + else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) + { + _minDefault = (T)(object)float.MinValue; + _maxDefault = (T)(object)float.MaxValue; + _stepDefault = (T)(object)1.0f; + } + // double + else if (typeof(T) == typeof(double) || typeof(T) == typeof(double?)) + { + _minDefault = (T)(object)double.MinValue; + _maxDefault = (T)(object)double.MaxValue; + _stepDefault = (T)(object)1.0; + } + // decimal + else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) + { + _minDefault = (T)(object)decimal.MinValue; + _maxDefault = (T)(object)decimal.MaxValue; + _stepDefault = (T)(object)1M; + } + + #endregion parameters default depending on T + } + + protected string Classname => + new CssBuilder("mud-input-input-control mud-input-number-control " + + (HideSpinButtons ? "mud-input-nospin" : "mud-input-showspin")) + .AddClass(Class) + .Build(); + + + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + private string _elementId = "numericField_" + Guid.NewGuid().ToString().Substring(0, 8); + + private Input _elementReference; + + [ExcludeFromCodeCoverage] + public override ValueTask FocusAsync() + { + return _elementReference.FocusAsync(); + } + + [ExcludeFromCodeCoverage] + public override ValueTask BlurAsync() + { + return _elementReference.BlurAsync(); + } + + [ExcludeFromCodeCoverage] + public override ValueTask SelectAsync() + { + return _elementReference.SelectAsync(); + } + + [ExcludeFromCodeCoverage] + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return _elementReference.SelectRangeAsync(pos1, pos2); + } + + protected override Task SetValueAsync(T value, bool updateText = true) + { + bool valueChanged; + (value, valueChanged) = ConstrainBoundaries(value); + return base.SetValueAsync(value, valueChanged || updateText); + } + + protected internal override async void OnBlurred(FocusEventArgs obj) + { + base.OnBlurred(obj); + await UpdateValuePropertyAsync(true); //Required to set the value after a blur before the debounce period has elapsed + await UpdateTextPropertyAsync(false); //Required to update the string formatting after a blur before the debouce period has elapsed + } + + protected async Task ValidateInput(T value) + { + bool valueChanged; + (value, valueChanged) = ConstrainBoundaries(value); + if (valueChanged) + await SetValueAsync(value, true); + return true; //Don't show errors + } + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Clearable { get; set; } = false; + + /// + /// Decrements or increments depending on factor + /// + /// Multiplication factor (1 or -1) will be applied to the step + private async Task Change(double factor = 1) + { + try + { + var nextValue = GetNextValue(factor); + + // validate that the data type is a value type before we compare them + if (typeof(T).IsValueType) + { + if (factor > 0 && _comparer.Compare(nextValue, Value) < 0) + nextValue = Max; + else if (factor < 0 && (_comparer.Compare(nextValue, Value) > 0 || nextValue is null)) + nextValue = Min; + } + + await SetValueAsync(ConstrainBoundaries(nextValue).value); + _elementReference.SetText(Text).AndForget(); + } + catch (OverflowException) + { + // if next value overflows the primitive type, lets set it to Min or Max depending if factor is positive or negative + await SetValueAsync(factor > 0 ? Max : Min, true); + } + } + + private T GetNextValue(double factor) + { + if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) + return (T)(object)Convert.ToDecimal(FromDecimal(Value) + FromDecimal(Step) * (decimal)factor); + if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) + return (T)(object)Convert.ToInt64(FromInt64(Value) + FromInt64(Step) * factor); + if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) + return (T)(object)Convert.ToUInt64(FromUInt64(Value) + FromUInt64(Step) * factor); + return Num.To(Num.From(Value) + Num.From(Step) * factor); + } + + /// + /// Adds a Step to the Value + /// + public Task Increment() => Change(factor: 1); + + /// + /// Substracts a Step from the Value + /// + public Task Decrement() => Change(factor: -1); + + /// + /// Checks if the value respects the boundaries set for this instance. + /// + /// Value to check. + /// Returns a valid value and if it has been changed. + protected (T value, bool changed) ConstrainBoundaries(T value) + { + if (value == null) + return (default(T), false); + + // validate that the data type is a value type before we compare them + if (typeof(T).IsValueType) + { + // check if value is bigger than defined MAX, if so take the defined MAX value instead + if (_comparer.Compare(value, Max) > 0) + return (Max, true); + + // check if value is lower than defined MIN, if so take the defined MIN value instead + if (_comparer.Compare(value, Min) < 0) + return (Min, true); + }; + + return (value, false); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _keyInterceptor = _keyInterceptorFactory.Create(); + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-input-slot", + Keys = { + new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead increment + new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead decrement + new KeyOptions { Key="Dead", PreventDown = "key+any" }, // prevent dead keys like ^ ` ´ etc + new KeyOptions { Key="/^(?!"+(Pattern ?? "[0-9]").TrimEnd('*')+").$/", PreventDown = "key+none|key+shift|key+alt" }, // prevent input of all other characters except allowed, like [0-9.,-+] + }, + }); + } + await base.OnAfterRenderAsync(firstRender); + } + + protected async Task HandleKeydown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + switch (obj.Key) + { + case "ArrowUp": + await Increment(); + break; + case "ArrowDown": + await Decrement(); + break; + } + OnKeyDown.InvokeAsync(obj).AndForget(); + } + + protected Task HandleKeyUp(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return Task.CompletedTask; + OnKeyUp.InvokeAsync(obj).AndForget(); + return Task.CompletedTask; + } + + protected async Task OnMouseWheel(WheelEventArgs obj) + { + if (!obj.ShiftKey || Disabled || ReadOnly) + return; + if (obj.DeltaY < 0) + { + if (InvertMouseWheel == false) + await Increment(); + else + await Decrement(); + } + else if (obj.DeltaY > 0) + { + if (InvertMouseWheel == false) + await Decrement(); + else + await Increment(); + } + } + + private bool _minHasValue = false; + + /// + /// Reverts mouse wheel up and down events, if true. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool InvertMouseWheel { get; set; } = false; + + private T _minDefault; + + private T _min; + + /// + /// The minimum value for the input. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public T Min + { + get => _minHasValue ? _min : _minDefault; + set + { + _minHasValue = value != null; + _min = value; + } + } + + private bool _maxHasValue = false; + private T _maxDefault; + private T _max; + + /// + /// The maximum value for the input. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Validation)] + public T Max + { + get => _maxHasValue ? _max : _maxDefault; + set + { + _maxHasValue = value != null; + _max = value; + } + } + + private bool _stepHasValue = false; + private T _stepDefault; + private T _step; + + /// + /// The increment added/subtracted by the spin buttons. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public T Step + { + get => _stepHasValue ? _step : _stepDefault; + set + { + _stepHasValue = value != null; + _step = value; + } + } + + /// + /// Hides the spin buttons, the user can still change value with keyboard arrows and manual update. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool HideSpinButtons { get; set; } + + /// + /// Hints at the type of data that might be entered by the user while editing the input. + /// Defaults to numeric + /// + [Parameter] + public override InputMode InputMode { get; set; } = InputMode.numeric; + + /// + /// The pattern attribute, when specified, is a regular expression which the input's value must match in order for the value to pass constraint validation. It must be a valid JavaScript regular expression + /// Defaults to [0-9,.\-] + /// To get a numerical keyboard on safari, use the pattern. The default pattern should achieve numerical keyboard. + /// + /// Note: this pattern is also used to prevent all input except numbers and allowed characters. So for instance to allow only numbers, no signs and no commas you might change it to to [0-9.] + /// + [Parameter] + public override string Pattern { get; set; } = @"[0-9,.\-]"; + + private string GetCounterText() => Counter == null ? string.Empty : (Counter == 0 ? (string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") : ((string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + $" / {Counter}")); + + private Task OnInputValueChanged(string text) + { + return SetTextAsync(text); + } + + //avoids the format to use scientific notation for large or small number in floating points types, while covering all options + //https://stackoverflow.com/questions/1546113/double-to-string-conversion-without-scientific-notation + private const string TagFormat = "0.###################################################################################################################################################################################################################################################################################################################################################"; + + private string FormatParam(T value) + { + if (value is IFormattable f) + return f.ToString(TagFormat, CultureInfo.InvariantCulture.NumberFormat); + else + return null; + } + + private decimal FromDecimal(T v) + => Convert.ToDecimal((decimal?)(object)v); + private long FromInt64(T v) + => Convert.ToInt64((long?)(object)v); + private ulong FromUInt64(T v) + => Convert.ToUInt64((ulong?)(object)v); + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + _keyInterceptor?.Dispose(); + } + } +} diff --git a/Components/Overlay/Overlay.razor b/Components/Overlay/Overlay.razor new file mode 100644 index 0000000..83756d7 --- /dev/null +++ b/Components/Overlay/Overlay.razor @@ -0,0 +1,18 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (Visible) +{ +
    + @if(LightBackground || DarkBackground) + { +
    + } + @if(ChildContent != null) + { +
    + @ChildContent +
    + } +
    +} diff --git a/Components/Overlay/Overlay.razor.cs b/Components/Overlay/Overlay.razor.cs new file mode 100644 index 0000000..ea38af9 --- /dev/null +++ b/Components/Overlay/Overlay.razor.cs @@ -0,0 +1,173 @@ +using System.Windows.Input; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Overlay : UIComponent, IDisposable +{ + private bool _visible; + + protected string Classname => + new CssBuilder("mud-overlay") + .AddClass("mud-overlay-absolute", Absolute) + .AddClass(Class) + .Build(); + + protected string ScrimClassname => + new CssBuilder("mud-overlay-scrim") + .AddClass("mud-overlay-dark", DarkBackground) + .AddClass("mud-overlay-light", LightBackground) + .Build(); + + protected string Styles => + new StyleBuilder() + .AddStyle("z-index", $"{ZIndex}", ZIndex != 5) + .AddStyle(Style) + .Build(); + + [Inject] public IScrollManager ScrollManager { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Fires when Visible changes + /// + [Parameter] + public EventCallback VisibleChanged { get; set; } + + /// + /// If true overlay will be visible. Two-way bindable. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public bool Visible + { + get => _visible; + set + { + if (_visible == value) + return; + _visible = value; + VisibleChanged.InvokeAsync(_visible); + } + } + + /// + /// If true overlay will set Visible false on click. + /// + [Parameter] + [Category(CategoryTypes.Overlay.ClickAction)] + public bool AutoClose { get; set; } + + /// + /// If true (default), the Document.body element will not be able to scroll + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public bool LockScroll { get; set; } = true; + + /// + /// The css class that will be added to body if lockscroll is used. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public string LockScrollClass { get; set; } = "scroll-locked"; + + /// + /// If true applys the themes dark overlay color. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public bool DarkBackground { get; set; } + + /// + /// If true applys the themes light overlay color. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public bool LightBackground { get; set; } + + /// + /// Icon class names, separated by space + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public bool Absolute { get; set; } + + /// + /// Sets the z-index of the overlay. + /// + [Parameter] + [Category(CategoryTypes.Overlay.Behavior)] + public int ZIndex { get; set; } = 5; + + /// + /// Command parameter. + /// + [Parameter] + [Category(CategoryTypes.Overlay.ClickAction)] + public object CommandParameter { get; set; } + + /// + /// Command executed when the user clicks on an element. + /// + [Parameter] + [Category(CategoryTypes.Overlay.ClickAction)] + public ICommand Command { get; set; } + + /// + /// Fired when the overlay is clicked + /// + [Parameter] + public EventCallback OnClick { get; set; } + protected internal void OnClickHandler(MouseEventArgs ev) + { + if (AutoClose) + Visible = false; + OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + + //if not visible or CSS `position:absolute`, don't lock scroll + protected override void OnAfterRender(bool firstTime) + { + if (!LockScroll || Absolute) + return; + + if (Visible) + BlockScroll(); + else + UnblockScroll(); + + } + + //locks the scroll attaching a CSS class to the specified element, in this case the body + void BlockScroll() + { + ScrollManager.LockScrollAsync("body", LockScrollClass); + } + + //removes the CSS class that prevented scrolling + void UnblockScroll() + { + ScrollManager.UnlockScrollAsync("body", LockScrollClass); + } + + //When disposing the overlay, remove the class that prevented scrolling + public void Dispose() + { + UnblockScroll(); + } + +} diff --git a/Components/PageContentNavigation/PageContentNavigation.razor b/Components/PageContentNavigation/PageContentNavigation.razor new file mode 100644 index 0000000..669e1ee --- /dev/null +++ b/Components/PageContentNavigation/PageContentNavigation.razor @@ -0,0 +1,20 @@ +@namespace Connected.Components +@inherits UIComponent +@using Microsoft.AspNetCore.Components.Routing + +
    + @if (_sections.Any() && _sections.Count() > 1) + { + + @Headline + + + @foreach (var docSection in _sections.OrderBy(x => x.LevelSortingValue)) + { + + @docSection.Title + + } + + } +
    \ No newline at end of file diff --git a/Components/PageContentNavigation/PageContentNavigation.razor.cs b/Components/PageContentNavigation/PageContentNavigation.razor.cs new file mode 100644 index 0000000..0ab4141 --- /dev/null +++ b/Components/PageContentNavigation/PageContentNavigation.razor.cs @@ -0,0 +1,172 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class PageContentNavigation : IAsyncDisposable +{ + private List _sections = new(); + private IScrollSpy _scrollSpy; + + [Inject] IScrollSpyFactory ScrollSpyFactory { get; set; } + + /// + /// The displayed section within the MudPageContentNavigation + /// + public IEnumerable Sections => _sections.AsEnumerable(); + + /// + /// The currently active session. null if there is no section selected + /// + public PageContentSection ActiveSection => _sections.FirstOrDefault(x => x.IsActive == true); + + /// + /// The text displayed about the section links. Defaults to "Conents" + /// + [Parameter] public string Headline { get; set; } = "Contents"; + + /// + /// The css selector used to identifify the HTML elements that should be observed for viewport changes + /// + [Parameter] public string SectionClassSelector { get; set; } = string.Empty; + + /// + /// If there are mutliple levels, this can specified to make a mapping between a level class likw "second-level" and the level in the hierarchy + /// + [Parameter] public IDictionary HierarchyMapper { get; set; } = new Dictionary(); + + /// + /// If there are multiple levels, this property controls they visibility of them. + /// + [Parameter] public ContentNavigationExpandBehaviour ExpandBehaviour { get; set; } = ContentNavigationExpandBehaviour.Always; + + /// + /// If this option is true the first added section will become active when there is no other indication of an active session. Default value is false + /// + [Parameter] public bool ActivateFirstSectionAsDefault { get; set; } = false; + + private Task OnNavLinkClick(string id) + { + SelectActiveSection(id); + return _scrollSpy.ScrollToSection(id); + } + + private void ScrollSpy_ScrollSectionSectionCentered(object sender, ScrollSectionCenteredEventArgs e) => + SelectActiveSection(e.Id); + + private void SelectActiveSection(string id) + { + if (string.IsNullOrEmpty(id)) + { + return; + } + + var activelink = _sections.FirstOrDefault(x => x.Id == id); + if (activelink == null) + { + return; + } + + _sections.ToList().ForEach(item => item.Deactive()); + activelink.Activate(); + + StateHasChanged(); + } + + private string GetNavLinkClass(PageContentSection section) => new CssBuilder("page-content-navigation-navlink") + .AddClass("active", section.IsActive) + .AddClass($"navigation-level-{section.Level}") + .Build(); + + private string GetPanelClass() => new CssBuilder("page-content-navigation").AddClass(Class).Build(); + + /// + /// Scrolls to a section based on the fragment of the uri. If there is no fragment, no scroll will occured + /// + /// The uri containing the fragment to scroll + /// A task that completes when the viewport has scrolled + public Task ScrollToSection(Uri uri) => _scrollSpy.ScrollToSection(uri); + + /// + /// Add a section to the content navigation + /// + /// name of the section will be displayed in the navigation + /// id of the section. It will be appending to the current url, if the section becomes active + /// If true, StateHasChanged is called, forcing a rerender of the component + public void AddSection(string sectionName, string sectionId, bool forceUpdate) => AddSection(new(sectionName, sectionId), forceUpdate); + + private Dictionary _parentMapper = new(); + + /// + /// Add a section to the content navigation + /// + /// The section that needs to be added + /// If true, StateHasChanged is called, forcing a rerender of the component + public void AddSection(PageContentSection section, bool forceUpdate) + { + _sections.Add(section); + + int diffRootLevel = 1_000_000; + int counter = 0; + foreach (var item in _sections.Where(x => x.Parent == null)) + { + item.SetLevelStructure(counter, diffRootLevel); + counter += diffRootLevel; + } + + if (section.Id == _scrollSpy.CenteredSection) + { + section.Activate(); + } + else if (_sections.Count == 1 && ActivateFirstSectionAsDefault == true) + { + section.Activate(); + _scrollSpy.SetSectionAsActive(section.Id).AndForget(); + } + + if (forceUpdate == true) + { + StateHasChanged(); + } + } + + + /// + /// Rerender the component + /// + public void Update() => StateHasChanged(); + + protected override void OnInitialized() + { + _scrollSpy = ScrollSpyFactory.Create(); + } + + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + + _scrollSpy.ScrollSectionSectionCentered += ScrollSpy_ScrollSectionSectionCentered; + + if (string.IsNullOrEmpty(SectionClassSelector) == false) + { + await _scrollSpy.StartSpying(SectionClassSelector); + } + + SelectActiveSection(_scrollSpy.CenteredSection); + } + } + + public ValueTask DisposeAsync() + { + if (_scrollSpy == null) { return ValueTask.CompletedTask; } + + _scrollSpy.ScrollSectionSectionCentered -= ScrollSpy_ScrollSectionSectionCentered; + return _scrollSpy.DisposeAsync(); + } +} diff --git a/Components/PageContentNavigation/PageContentSection.cs b/Components/PageContentNavigation/PageContentSection.cs new file mode 100644 index 0000000..72e6b36 --- /dev/null +++ b/Components/PageContentNavigation/PageContentSection.cs @@ -0,0 +1,75 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +/// +/// A section (nav link) inside the MudPageContentNavigation +/// +public class PageContentSection +{ + private List _children = new(); + public int LevelSortingValue { get; private set; } = 0; + public PageContentSection Parent { get; private set; } = null; + + /// + /// create a new instance with a title and id and level set to zero + /// + /// name of the section will be displayed in the navigation + /// id of the section. It will be appending to the current url, if the section becomes active + public PageContentSection(string title, string id) : this(title, id, 0, null) + { + } + + /// + /// create a new instance with a title and id and level + /// + /// name of the section will be displayed in the navigation + /// id of the section. It will be appending to the current url, if the section becomes active + /// The level within the hierachy + /// The parent of the section. null if there is no parent or no hierachy + public PageContentSection(string title, string id, int level, PageContentSection parent) + { + Title = title; + Id = id; + Level = level; + Parent = parent; + if (Parent != null) + { + Parent._children.Add(this); + } + } + + public int Level { get; set; } + + /// + /// The Title of the section. This will be displayed in the navigation + /// + public string Title { get; set; } + + /// + /// Id of the section. It will be appending to the current url, if the section becomes active + /// + public string Id { get; set; } + + /// + /// Indicating if the section is currently in the middle of the viewport + /// + public bool IsActive { get; private set; } + + protected internal void Activate() => IsActive = true; + protected internal void Deactive() => IsActive = false; + + internal void SetLevelStructure(int counter, int diff) + { + LevelSortingValue = counter; + int levelDiff = diff / 10; + int value = counter + levelDiff; + foreach (var item in _children) + { + item.SetLevelStructure(value, levelDiff); + value += levelDiff; + } + } +} diff --git a/Components/Pagination/Pagination.razor b/Components/Pagination/Pagination.razor new file mode 100644 index 0000000..3f5aa3b --- /dev/null +++ b/Components/Pagination/Pagination.razor @@ -0,0 +1,51 @@ +@namespace Connected.Components + +@inherits UIComponent + + + @if (ShowFirstButton) + { +
  • + +
  • + } + @if (ShowPreviousButton) + { +
  • + +
  • + } + @foreach (var state in GeneratePagination()) + { + var currentPage = state; + if (currentPage == -1) + { +
  • + ... +
  • + } + else if (currentPage == Selected) + { +
  • + +
  • + } + else { +
  • + +
  • + } + } + @if (ShowNextButton) + { +
  • + +
  • + } + @if (ShowLastButton) + { +
  • + +
  • + } +
    \ No newline at end of file diff --git a/Components/Pagination/Pagination.razor.cs b/Components/Pagination/Pagination.razor.cs new file mode 100644 index 0000000..0a89279 --- /dev/null +++ b/Components/Pagination/Pagination.razor.cs @@ -0,0 +1,324 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Pagination : UIComponent +{ + #region Css Classes + + private string Classname => + new CssBuilder("mud-pagination") + .AddClass($"mud-pagination-{Variant.ToDescriptionString()}") + .AddClass($"mud-pagination-{Size.ToDescriptionString()}") + .AddClass("mud-pagination-disable-elevation", DisableElevation) + .AddClass("mud-pagination-rtl", RightToLeft) + .AddClass(Class) + .Build(); + + private string ItemClassname => + new CssBuilder("mud-pagination-item") + .AddClass("mud-pagination-item-rectangular", Rectangular) + .Build(); + + private string SelectedItemClassname => + new CssBuilder(ItemClassname) + .AddClass("mud-pagination-item-selected") + .Build(); + + #endregion + + #region Parameter + + private int _count = 1; + + /// + /// The number of pages. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public int Count + { + get => _count; + set + { + _count = Math.Max(1, value); + Selected = Math.Min(Selected, _count); + } + } + + private int _boundaryCount = 2; + + /// + /// The number of items at the start and end of the pagination. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public int BoundaryCount + { + get => _boundaryCount; + set + { + _boundaryCount = Math.Max(1, value); + } + } + + private int _middleCount = 3; + + /// + /// The number of items in the middle of the pagination. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public int MiddleCount + { + get => _middleCount; + set + { + _middleCount = Math.Max(1, value); + } + } + + private bool _selectedFirstSet; + private int _selected = 1; + + /// + /// The selected page number. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public int Selected + { + get => _selected; + set + { + if (_selected == value) + return; + + //this is required because _selected will stay 1 when Count is not yet set + if (!_selectedFirstSet) + { + _selected = value; + _selectedFirstSet = true; + } + else + _selected = Math.Max(1, Math.Min(value, Count)); + + SelectedChanged.InvokeAsync(_selected); + } + } + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + /// + /// If true, the pagination buttons are displayed rectangular. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public bool Rectangular { get; set; } + + /// + /// The size of the component.. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// If true, no drop-shadow will be used. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public bool DisableElevation { get; set; } + + /// + /// If true, the pagination will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, the navigate-to-first-page button is shown. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public bool ShowFirstButton { get; set; } + + /// + /// If true, the navigate-to-last-page button is shown. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public bool ShowLastButton { get; set; } + + /// + /// If true, the navigate-to-previous-page button is shown. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public bool ShowPreviousButton { get; set; } = true; + + /// + /// If true, the navigate-to-next-page button is shown. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Behavior)] + public bool ShowNextButton { get; set; } = true; + + /// + /// Invokes the callback when a control button is clicked. + /// + [Parameter] + public EventCallback ControlButtonClicked { get; set; } + + /// + /// Invokes the callback when selected page changes. + /// + [Parameter] + public EventCallback SelectedChanged { get; set; } + + /// + /// Custom first icon. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public string FirstIcon { get; set; } = Icons.Material.Filled.FirstPage; + + /// + /// Custom before icon. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public string BeforeIcon { get; set; } = Icons.Material.Filled.NavigateBefore; + + /// + /// Custom next icon. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public string NextIcon { get; set; } = Icons.Material.Filled.NavigateNext; + + /// + /// Custom last icon. + /// + [Parameter] + [Category(CategoryTypes.Pagination.Appearance)] + public string LastIcon { get; set; } = Icons.Material.Filled.LastPage; + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + #endregion + + #region Methods + + /*generates an array representing the pagination numbers, e.g. for Count==11, MiddleCount==3, BoundaryCount==1, + Selected==6 the output will be the int array [1, 2, -1, 5, 6, 7, -1, 10, 11] + -1 is displayed as "..." in the ui*/ + private IEnumerable GeneratePagination() + { + //return array {1, ..., Count} if Count is small + if (Count <= 4 || Count <= 2 * BoundaryCount + MiddleCount + 2) + return Enumerable.Range(1, Count).ToArray(); + + var length = 2 * BoundaryCount + MiddleCount + 2; + var pages = new int[length]; + + //set start boundary items, e.g. if BoundaryCount == 3 => [1, 2, 3, ...] + for (var i = 0; i < BoundaryCount; i++) + { + pages[i] = i + 1; + } + + //set end boundary items, e.g. if BoundaryCount == 3 and Count == 11 => [..., 9, 10, 11] + for (var i = 0; i < BoundaryCount; i++) + { + pages[length - i - 1] = Count - i; + } + + //calculate start value for middle items + var startValue = 0; + if (Selected <= BoundaryCount + MiddleCount / 2 + 1) + startValue = BoundaryCount + 2; + else if (Selected >= Count - BoundaryCount - MiddleCount / 2) + startValue = Count - BoundaryCount - MiddleCount; + else + startValue = Selected - MiddleCount / 2; + + //set middle items, e.g. if MiddleCount == 3 and Selected == 5 and Count == 11 => [..., 4, 5, 6, ...] + for (var i = 0; i < MiddleCount; i++) + { + pages[BoundaryCount + 1 + i] = startValue + i; + } + + //set start delimiter "..." when selected page is far enough to the end, dots are represented as -1 + pages[BoundaryCount] = (BoundaryCount + MiddleCount / 2 + 1 < Selected) ? -1 : BoundaryCount + 1; + + //set end delimiter "..." when selected page is far enough to the start, dots are represented as -1 + pages[length - BoundaryCount - 1] = (Count - BoundaryCount - MiddleCount / 2 > Selected) ? -1 : Count - BoundaryCount; + + //remove ellipsis if difference is small enough, e.g convert [..., 5 , -1 , 7, ...] to [..., 5, 6, 7, ...] + for (var i = 0; i < length - 2; i++) + { + if (pages[i] + 2 == pages[i + 2]) + pages[i + 1] = pages[i] + 1; + } + + return pages; + } + + //triggered when the user clicks on a control button, e.g. the navigate-to-next-page-button + private void OnClickControlButton(Page page) + { + ControlButtonClicked.InvokeAsync(page); + NavigateTo(page); + } + + //Last line cannot be tested because Page enum has 4 items + /// + /// Navigates to the specified page. + /// + /// The target page. page=Page.Next navigates to the next page. + [ExcludeFromCodeCoverage] + public void NavigateTo(Page page) + { + Selected = page switch + { + Page.First => 1, + Page.Last => Math.Max(1, Count), + Page.Next => Math.Min(Selected + 1, Count), + Page.Previous => Math.Max(1, Selected - 1), + _ => Selected + }; + } + + /// + /// Navigates to the specified page. + /// + /// The target page. pageIndex=2 navigates to the 3. page. + public void NavigateTo(int pageIndex) + { + Selected = pageIndex + 1; + } + + #endregion +} diff --git a/Components/Paper/Paper.razor b/Components/Paper/Paper.razor new file mode 100644 index 0000000..24b4757 --- /dev/null +++ b/Components/Paper/Paper.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent; + +
    + @ChildContent +
    \ No newline at end of file diff --git a/Components/Paper/Paper.razor.cs b/Components/Paper/Paper.razor.cs new file mode 100644 index 0000000..89b67a6 --- /dev/null +++ b/Components/Paper/Paper.razor.cs @@ -0,0 +1,101 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Connected.Utilities; + +namespace Connected.Components; + +public partial class Paper : UIComponent +{ + protected string Classname => + new CssBuilder("mud-paper") + .AddClass($"mud-paper-outlined", Outlined) + .AddClass($"mud-paper-square", Square) + .AddClass($"mud-elevation-{Elevation.ToString()}", !Outlined) + .AddClass(Class) + .Build(); + + protected string Stylename => + new StyleBuilder() + .AddStyle("height", $"{Height}", !String.IsNullOrEmpty(Height)) + .AddStyle("width", $"{Width}", !String.IsNullOrEmpty(Width)) + .AddStyle("max-height", $"{MaxHeight}", !String.IsNullOrEmpty(MaxHeight)) + .AddStyle("max-width", $"{MaxWidth}", !String.IsNullOrEmpty(MaxWidth)) + .AddStyle("min-height", $"{MinHeight}", !String.IsNullOrEmpty(MinHeight)) + .AddStyle("min-width", $"{MinWidth}", !String.IsNullOrEmpty(MinWidth)) + .AddStyle(Style) + .Build(); + + /// + /// The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public bool Square { get; set; } + + /// + /// If true, card will be outlined. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public bool Outlined { get; set; } + + /// + /// Height of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string Height { get; set; } + + /// + /// Width of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string Width { get; set; } + + /// + /// Max-Height of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string MaxHeight { get; set; } + + /// + /// Max-Width of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string MaxWidth { get; set; } + + /// + /// Min-Height of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string MinHeight { get; set; } + + /// + /// Min-Width of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Appearance)] + public string MinWidth { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Paper.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Picker/Picker.razor b/Components/Picker/Picker.razor new file mode 100644 index 0000000..3cf72b8 --- /dev/null +++ b/Components/Picker/Picker.razor @@ -0,0 +1,117 @@ +@namespace Connected.Components +@inherits FormComponent +@typeparam T + + +@code +{ + + protected virtual RenderFragment InputContent => + // note: Mask needs to remain before Text! + @; + + protected virtual RenderFragment PickerContent => null; + + protected virtual RenderFragment Render => + @ +
    + @if (PickerVariant != PickerVariant.Static) + { + + @if(InputContent != null) { + @InputContent + } + + } + @if (IsOpen && PickerVariant == PickerVariant.Inline) + { + +
    + +
    + @if(PickerContent != null){ + @PickerContent + } +
    + @if (PickerActions != null) + { +
    + @PickerActions(this) +
    + } +
    +
    +
    + } + else if (PickerVariant == PickerVariant.Static) + { + +
    + @if(PickerContent != null){ + @PickerContent + } +
    + @if (PickerActions != null) + { +
    + @PickerActions(this) +
    + } +
    + } + else if(IsOpen && PickerVariant == PickerVariant.Dialog) + { + + +
    + @if(PickerContent != null){ + @PickerContent + } +
    + @if (PickerActions != null) + { +
    + @PickerActions(this) +
    + } +
    +
    + } +
    + @if (PickerVariant == PickerVariant.Inline) + { + + } +
    ; +} + + diff --git a/Components/Picker/Picker.razor.cs b/Components/Picker/Picker.razor.cs new file mode 100644 index 0000000..8b9eebe --- /dev/null +++ b/Components/Picker/Picker.razor.cs @@ -0,0 +1,557 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Picker : FormComponent +{ + protected IKeyInterceptor _keyInterceptor; + + public Picker() : base(new Converter()) { } + protected Picker(Converter converter) : base(converter) { } + + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + private string _elementId = "picker" + Guid.NewGuid().ToString().Substring(0, 8); + + [Inject] private IBrowserWindowSizeProvider WindowSizeListener { get; set; } + + protected string PickerClass => + new CssBuilder("mud-picker") + .AddClass($"mud-picker-inline", PickerVariant != PickerVariant.Static) + .AddClass($"mud-picker-static", PickerVariant == PickerVariant.Static) + .AddClass($"mud-rounded", PickerVariant == PickerVariant.Static && !_pickerSquare) + .AddClass($"mud-elevation-{_pickerElevation}", PickerVariant == PickerVariant.Static) + .AddClass($"mud-picker-input-button", !Editable && PickerVariant != PickerVariant.Static) + .AddClass($"mud-picker-input-text", Editable && PickerVariant != PickerVariant.Static) + .AddClass($"mud-disabled", Disabled && PickerVariant != PickerVariant.Static) + .AddClass(Class) + .Build(); + + protected string PickerPaperClass => + new CssBuilder("mud-picker") + .AddClass("mud-picker-paper") + .AddClass("mud-picker-view", PickerVariant == PickerVariant.Inline) + .AddClass("mud-picker-open", IsOpen && PickerVariant == PickerVariant.Inline) + .AddClass("mud-picker-popover-paper", PickerVariant == PickerVariant.Inline) + .AddClass("mud-dialog", PickerVariant == PickerVariant.Dialog) + .Build(); + + protected string PickerInlineClass => + new CssBuilder("mud-picker-inline-paper") + .Build(); + + protected string PickerContainerClass => + new CssBuilder("mud-picker-container") + .AddClass("mud-paper-square", _pickerSquare) + .AddClass("mud-picker-container-landscape", + Orientation == Orientation.Landscape && PickerVariant == PickerVariant.Static) + .Build(); + + protected string PickerInputClass => + new CssBuilder("mud-input-input-control").AddClass(Class) + .Build(); + + protected string ActionClass => new CssBuilder("mud-picker-actions") + .AddClass(ClassActions) + .Build(); + + /// + /// Sets the icon of the input text field + /// + [ExcludeFromCodeCoverage] + [Parameter] + [Obsolete("Use AdornmentIcon instead.", true)] + public string InputIcon + { + get { return AdornmentIcon; } + set { AdornmentIcon = value; } + } + + /// + /// The color of the adornment if used. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor AdornmentColor { get; set; } = ThemeColor.Default; + + /// + /// Sets the icon of the input text field + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string AdornmentIcon { get; set; } = Icons.Material.Filled.Event; + + /// + /// Sets the aria-label of the input text field icon + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string AdornmentAriaLabel { get; set; } = string.Empty; + + /// + /// The short hint displayed in the input before the user enters a value. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Placeholder { get; set; } + + /// + /// Fired when the dropdown / dialog opens + /// + [Parameter] + public EventCallback PickerOpened { get; set; } + + /// + /// Fired when the dropdown / dialog closes + /// + [Parameter] + public EventCallback PickerClosed { get; set; } + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow set to 8 by default in inline mode and 0 in static mode. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public int Elevation { set; get; } = 8; + + /// + /// If true, border-radius is set to 0 this is set to true automatically in static mode but can be overridden with Rounded bool. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public bool Square { get; set; } + + /// + /// If true, no date or time can be defined. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool ReadOnly { get; set; } + + /// + /// If true, border-radius is set to theme default when in Static Mode. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public bool Rounded { get; set; } + + /// + /// If string has value, HelperText will be applied. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string HelperText { get; set; } + + /// + /// If true, the helper text will only be visible on focus. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool HelperTextOnFocus { get; set; } + + /// + /// If string has value the label text will be displayed in the input, and scaled down at the top if the input has value. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Label { get; set; } + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Clearable { get; set; } = false; + + /// + /// If true, the picker will be disabled. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, the picker will be editable. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Editable { get; set; } = false; + + /// + /// Hide toolbar and show only date/time views. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public bool DisableToolbar { get; set; } + + /// + /// User class names for picker's ToolBar, separated by space + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string ToolBarClass { get; set; } + + /// + /// Picker container option + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public PickerVariant PickerVariant { get; set; } = PickerVariant.Inline; + + /// + /// Variant of the text input + /// + [ExcludeFromCodeCoverage] + [Parameter] + [Obsolete("Use Variant instead.", true)] + public Variant InputVariant + { + get { return Variant; } + set { Variant = value; } + } + + /// + /// Variant of the text input + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// Sets if the icon will be att start or end, set to false to disable. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public Adornment Adornment { get; set; } = Adornment.End; + + /// + /// What orientation to render in when in PickerVariant Static Mode. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public Orientation Orientation { get; set; } = Orientation.Portrait; + + /// + /// Sets the Icon Size. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Size IconSize { get; set; } = Size.Medium; + + /// + /// The color of the toolbar, selected and active. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + /// + /// Changes the cursor appearance. + /// + [Obsolete("This is enabled now by default when you use Editable=true. You can remove the parameter.", false)] + [Parameter] + public bool AllowKeyboardInput { get; set; } + + /// + /// Fired when the text changes. + /// + [Parameter] + public EventCallback TextChanged { get; set; } + + /// + /// The currently selected string value (two-way bindable) + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public string Text + { + get => _text; + set => SetTextAsync(value, true).AndForget(); + } + + private string _text; + + /// + /// CSS class that will be applied to the action buttons container + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerAppearance)] + public string ClassActions { get; set; } + + /// + /// Define the action buttons here + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public RenderFragment> PickerActions { get; set; } + + /// + /// Will adjust vertical spacing. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Margin Margin { get; set; } = Margin.None; + + /// + /// A mask for structured input of the date (requires Editable to be true). + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public IMask Mask + { + get => _mask; + set => _mask = value; + } + + /// + /// Gets or sets the origin of the popover's anchor. Defaults to + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public Origin AnchorOrigin { get; set; } = Origin.TopLeft; + + /// + /// Gets or sets the origin of the popover's transform. Defaults to + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public Origin TransformOrigin { get; set; } = Origin.TopLeft; + + protected IMask _mask = null; + + protected async Task SetTextAsync(string value, bool callback) + { + if (_text != value) + { + _text = value; + if (callback) + await StringValueChanged(_text); + await TextChanged.InvokeAsync(_text); + } + } + + /// + /// Value change hook for descendants. + /// + protected virtual Task StringValueChanged(string value) + { + return Task.CompletedTask; + } + + protected bool IsOpen { get; set; } + + public void ToggleOpen() + { + if (IsOpen) + Close(); + else + Open(); + } + + public void Close(bool submit = true) + { + IsOpen = false; + + if (submit) + { + Submit(); + } + + OnClosed(); + StateHasChanged(); + } + + public void Open() + { + IsOpen = true; + StateHasChanged(); + OnOpened(); + } + + private void CloseOverlay() => Close(PickerActions == null); + + protected internal virtual void Submit() { } + + public virtual void Clear(bool close = true) + { + if (close && PickerVariant != PickerVariant.Static) + { + Close(false); + } + } + + protected override void ResetValue() + { + _inputReference?.Reset(); + base.ResetValue(); + } + + protected internal TextField _inputReference; + + public virtual ValueTask FocusAsync() => _inputReference?.FocusAsync() ?? ValueTask.CompletedTask; + + public virtual ValueTask BlurAsync() => _inputReference?.BlurAsync() ?? ValueTask.CompletedTask; + + public virtual ValueTask SelectAsync() => _inputReference?.SelectAsync() ?? ValueTask.CompletedTask; + + public virtual ValueTask SelectRangeAsync(int pos1, int pos2) => + _inputReference?.SelectRangeAsync(pos1, pos2) ?? ValueTask.CompletedTask; + + private bool _pickerSquare; + private int _pickerElevation; + private ElementReference _pickerInlineRef; + + protected override void OnInitialized() + { + if (PickerVariant == PickerVariant.Static) + { + IsOpen = true; + if (Elevation == 8) + { + _pickerElevation = 0; + } + else + { + _pickerElevation = Elevation; + } + + if (!Rounded) + { + _pickerSquare = true; + } + } + else + { + _pickerSquare = Square; + _pickerElevation = Elevation; + } + + if (Label == null && For != null) + Label = For.GetLabelString(); + } + + private async Task EnsureKeyInterceptor() + { + if (_keyInterceptor == null) + { + _keyInterceptor = _keyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-input-slot", + Keys = + { + new KeyOptions { Key = " ", PreventDown = "key+none" }, + new KeyOptions { Key = "ArrowUp", PreventDown = "key+none" }, + new KeyOptions { Key = "ArrowDown", PreventDown = "key+none" }, + new KeyOptions { Key = "Enter", PreventDown = "key+none" }, + new KeyOptions { Key = "NumpadEnter", PreventDown = "key+none" }, + new KeyOptions { Key = "/./", SubscribeDown = true, SubscribeUp = true }, // for our users + }, + }); + _keyInterceptor.KeyDown += HandleKeyDown; + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender == true) + { + await EnsureKeyInterceptor(); + } + + await base.OnAfterRenderAsync(firstRender); + } + + protected internal void ToggleState() + { + if (Disabled) + return; + if (IsOpen) + { + IsOpen = false; + OnClosed(); + } + else + { + IsOpen = true; + OnOpened(); + FocusAsync(); + } + } + + protected virtual async void OnOpened() + { + OnPickerOpened(); + + if (PickerVariant == PickerVariant.Inline) + { + await _pickerInlineRef.ChangeCssAsync(PickerInlineClass); + } + + await EnsureKeyInterceptor(); + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "key+none" }); + } + + protected virtual async void OnClosed() + { + OnPickerClosed(); + + await EnsureKeyInterceptor(); + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "none" }); + } + + protected virtual void OnPickerOpened() + { + PickerOpened.InvokeAsync(this); + } + + protected virtual void OnPickerClosed() + { + PickerClosed.InvokeAsync(this); + } + + protected internal virtual void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + switch (obj.Key) + { + case "Backspace": + if (obj.CtrlKey == true && obj.ShiftKey == true) + { + Clear(); + _value = default(T); + Reset(); + } + + break; + case "Escape": + case "Tab": + Close(false); + break; + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.Dispose(); + } + + } + } + +} diff --git a/Components/Picker/PickerContent.razor b/Components/Picker/PickerContent.razor new file mode 100644 index 0000000..d7eaebe --- /dev/null +++ b/Components/Picker/PickerContent.razor @@ -0,0 +1,16 @@ +@namespace Connected.Components +@using Connected.Utilities; + +
    + @ChildContent +
    + +@code { + protected string Classnames => + new CssBuilder("mud-picker-content") + .AddClass(Class) + .Build(); + + [Parameter] public string Class { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Picker/PickerToolbar.razor b/Components/Picker/PickerToolbar.razor new file mode 100644 index 0000000..c920dce --- /dev/null +++ b/Components/Picker/PickerToolbar.razor @@ -0,0 +1,27 @@ +@namespace Connected.Components +@using Connected.Extensions; +@using Connected.Utilities; + +@if (!DisableToolbar) +{ + + @ChildContent + +} + + +@code { + protected string Classnames => + new CssBuilder("mud-picker-toolbar") + .AddClass($"mud-theme-{Color.ToDescriptionString()}") + .AddClass("mud-picker-toolbar-landscape", Orientation == Orientation.Landscape) + .AddClass(Class) + .Build(); + + [Parameter] public string Class { get; set; } + [Parameter] public string Style { get; set; } + [Parameter] public bool DisableToolbar { get; set; } + [Parameter] public Orientation Orientation { get; set; } + [Parameter] public ThemeColor Color { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Popover/Popover.razor b/Components/Popover/Popover.razor new file mode 100644 index 0000000..77da8a9 --- /dev/null +++ b/Components/Popover/Popover.razor @@ -0,0 +1,5 @@ +@namespace Connected.Components +@inherits UIComponent + +
    +
    diff --git a/Components/Popover/Popover.razor.cs b/Components/Popover/Popover.razor.cs new file mode 100644 index 0000000..2177c2d --- /dev/null +++ b/Components/Popover/Popover.razor.cs @@ -0,0 +1,207 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected.Components; + +public partial class Popover : UIComponent, IAsyncDisposable +{ + [Inject] public IPopoverService Service { get; set; } + + protected string PopoverClass => + new CssBuilder("mud-popover") + .AddClass($"mud-popover-fixed", Fixed) + .AddClass($"mud-popover-open", Open) + .AddClass($"mud-popover-{TransformOrigin.ToDescriptionString()}") + .AddClass($"mud-popover-anchor-{AnchorOrigin.ToDescriptionString()}") + .AddClass($"mud-popover-overflow-{OverflowBehavior.ToDescriptionString()}") + .AddClass($"mud-popover-relative-width", RelativeWidth) + .AddClass($"mud-paper", Paper) + .AddClass($"mud-paper-square", Paper && Square) + .AddClass($"mud-elevation-{Elevation}", Paper) + .AddClass($"overflow-y-auto", MaxHeight != null) + .AddClass(Class) + .Build(); + + protected string PopoverStyles => + new StyleBuilder() + .AddStyle("transition-duration", $"{Duration}ms") + .AddStyle("transition-delay", $"{Delay}ms") + .AddStyle("max-height", MaxHeight.ToPx(), MaxHeight != null) + .AddStyle(Style) + .Build(); + + internal Direction ConvertDirection(Direction direction) + { + return direction switch + { + Direction.Start => RightToLeft ? Direction.Right : Direction.Left, + Direction.End => RightToLeft ? Direction.Left : Direction.Right, + _ => direction + }; + } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// Sets the maxheight the popover can have when open. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public int? MaxHeight { get; set; } = null; + + /// + /// If true, will apply default MudPaper classes. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public bool Paper { get; set; } = true; + + /// + /// The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public int Elevation { set; get; } = 8; + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public bool Square { get; set; } + + /// + /// If true, the popover is visible. + /// + [Parameter] + [Category(CategoryTypes.Popover.Behavior)] + public bool Open { get; set; } + + /// + /// If true the popover will be fixed position instead of absolute. + /// + [Parameter] + [Category(CategoryTypes.Popover.Behavior)] + public bool Fixed { get; set; } + + /// + /// Sets the length of time that the opening transition takes to complete. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public double Duration { get; set; } = 251; + + /// + /// Sets the amount of time in milliseconds to wait from opening the popover before beginning to perform the transition. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public double Delay { get; set; } = 0; + + /// + /// Sets the direction the popover will start from relative to its parent. + /// + /// + [Obsolete("Use AnchorOrigin and TransformOrigin instead.", true)] + [Parameter] public Direction Direction { get; set; } = Direction.Bottom; + + /// + /// Set the anchor point on the element of the popover. + /// The anchor point will determinate where the popover will be placed. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public Origin AnchorOrigin { get; set; } = Origin.TopLeft; + + /// + /// Sets the intersection point if the anchor element. At this point the popover will lay above the popover. + /// This property in conjunction with AnchorPlacement determinate where the popover will be placed. + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public Origin TransformOrigin { get; set; } = Origin.TopLeft; + + /// + /// Set the overflow behavior of a popover and controls how the element should react if there is not enough space for the element to be visible + /// Defaults to none, which doens't apply any overflow logic + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public OverflowBehavior OverflowBehavior { get; set; } = OverflowBehavior.FlipOnOpen; + + /// + /// If true, the select menu will open either above or bellow the input depending on the direction. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin and TransformOrigin instead.", true)] + [Parameter] public bool OffsetX { get; set; } + + /// + /// If true, the select menu will open either before or after the input depending on the direction. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin and TransformOrigin instead.", true)] + [Parameter] public bool OffsetY { get; set; } + + /// + /// If true, the popover will have the same width at its parent element, default to false + /// + [Parameter] + [Category(CategoryTypes.Popover.Appearance)] + public bool RelativeWidth { get; set; } = false; + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Popover.Behavior)] + public RenderFragment ChildContent { get; set; } + + private PopoverHandler _handler; + + protected override void OnInitialized() + { + _handler = Service.Register(ChildContent ?? new RenderFragment((x) => { })); + _handler.SetComponentBaseParameters(this, PopoverClass, PopoverStyles, Open); + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + + // henon: this change by PR #3776 caused problems on BSS (#4303) + //// Only update the fragment if the popover is currently shown or will show + //// This prevents unnecessary renders and popover handle locking + //if (!_handler.ShowContent && !Open) + // return; + + _handler.UpdateFragment(ChildContent, this, PopoverClass, PopoverStyles, Open); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender == true) + { + await _handler.Initialize(); + await Service.InitializeIfNeeded(); + } + + await base.OnAfterRenderAsync(firstRender); + } + + [ExcludeFromCodeCoverage] + public async ValueTask DisposeAsync() + { + try + { + await Service.Unregister(_handler); + } + catch (JSDisconnectedException) { } + catch (TaskCanceledException) { } + } +} diff --git a/Components/Popover/PopoverOptions.cs b/Components/Popover/PopoverOptions.cs new file mode 100644 index 0000000..7dc362d --- /dev/null +++ b/Components/Popover/PopoverOptions.cs @@ -0,0 +1,12 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class PopoverOptions +{ + public string ContainerClass { get; set; } = "mudblazor-main-content"; + public int FlipMargin { get; set; } = 0; + public bool ThrowOnDuplicateProvider { get; set; } = true; +} diff --git a/Components/Popover/PopoverProvider.razor b/Components/Popover/PopoverProvider.razor new file mode 100644 index 0000000..8b2f5d2 --- /dev/null +++ b/Components/Popover/PopoverProvider.razor @@ -0,0 +1,18 @@ +@namespace Connected.Components + +@if (IsEnabled) +{ +
    + @foreach (var handler in Service.Handlers) + { + +
    + @if (handler.ShowContent == true) + { + @handler.Fragment + } +
    +
    + } +
    +} diff --git a/Components/Popover/PopoverProvider.razor.cs b/Components/Popover/PopoverProvider.razor.cs new file mode 100644 index 0000000..98bba17 --- /dev/null +++ b/Components/Popover/PopoverProvider.razor.cs @@ -0,0 +1,74 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class PopoverProvider : IDisposable +{ + private bool _isConnectedToService = false; + + [Inject] public IPopoverService Service { get; set; } + + /// + /// In some scenarios we need more than one ThemeProvider but we must not have more than one + /// PopoverProvider. Set a cascading value with UsePopoverProvider=false to prevent it. + /// + [CascadingParameter(Name = "UsePopoverProvider")] + public bool IsEnabled { get; set; } = true; + + + public void Dispose() + { + Service.FragmentsChanged -= Service_FragmentsChanged; + } + + protected override void OnInitialized() + { + if (IsEnabled == false) + { + return; + } + + Service.FragmentsChanged += Service_FragmentsChanged; + _isConnectedToService = true; + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + + if (IsEnabled == false && _isConnectedToService == true) + { + Service.FragmentsChanged -= Service_FragmentsChanged; + _isConnectedToService = false; + } + else if (IsEnabled == true && _isConnectedToService == false) + { + Service.FragmentsChanged -= Service_FragmentsChanged; // make sure to avoid multiple registration + Service.FragmentsChanged += Service_FragmentsChanged; + _isConnectedToService = true; + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender && IsEnabled && Service.ThrowOnDuplicateProvider) + { + await Service.InitializeIfNeeded(); + if (await Service.CountProviders() > 1) + { + throw new InvalidOperationException("Duplicate MudPopoverProvider detected. Please ensure there is only one provider, or disable this warning with PopoverOptions.ThrowOnDuplicateProvider."); + } + } + await base.OnAfterRenderAsync(firstRender); + } + + private void Service_FragmentsChanged(object sender, EventArgs e) + { + InvokeAsync(StateHasChanged); + } + +} diff --git a/Components/Popover/PopoverService.cs b/Components/Popover/PopoverService.cs new file mode 100644 index 0000000..b1fe11f --- /dev/null +++ b/Components/Popover/PopoverService.cs @@ -0,0 +1,195 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Components; + +public interface IPopoverService +{ + PopoverHandler Register(RenderFragment fragment); + Task Unregister(PopoverHandler hanlder); + ValueTask CountProviders(); + bool ThrowOnDuplicateProvider { get; } + IEnumerable Handlers { get; } + Task InitializeIfNeeded(); + event EventHandler FragmentsChanged; +} + +public class PopoverHandler +{ + private readonly SemaphoreSlim _semaphore = new(1, 1); + private readonly IJSRuntime _runtime; + private readonly Action _updater; + private bool _detached; + + public Guid Id { get; } + public RenderFragment Fragment { get; private set; } + public bool IsConnected { get; private set; } + public string Class { get; private set; } + public string Style { get; private set; } + public object Tag { get; private set; } + public bool ShowContent { get; private set; } + public DateTime? ActivationDate { get; private set; } + public Dictionary UserAttributes { get; set; } = new Dictionary(); + public Render ElementReference { get; set; } + + public PopoverHandler(RenderFragment fragment, IJSRuntime jsInterop, Action updater) + { + Fragment = fragment ?? throw new ArgumentNullException(nameof(fragment)); + _runtime = jsInterop ?? throw new ArgumentNullException(nameof(jsInterop)); + _updater = updater ?? throw new ArgumentNullException(nameof(updater)); + Id = Guid.NewGuid(); + } + + public void SetComponentBaseParameters(UIComponent componentBase, string @class, string style, bool showContent) + { + Class = @class; + Style = style; + Tag = componentBase.Tag; + UserAttributes = componentBase.UserAttributes; + ShowContent = showContent; + if (showContent == true) + { + ActivationDate = DateTime.Now; + } + else + { + ActivationDate = null; + } + } + + public void UpdateFragment(RenderFragment fragment, + UIComponent componentBase, string @class, string style, bool showContent) + { + Fragment = fragment; + SetComponentBaseParameters(componentBase, @class, @style, showContent); + // this basically calls StateHasChanged on the Popover + ElementReference?.ForceRender(); + _updater?.Invoke(); // <-- this doesn't do anything anymore except making unit tests happy + } + + public async Task Initialize() + { + await _semaphore.WaitAsync(); + try + { + if (_detached) + { + // If _detached is True, it means Detach() was invoked before Initialize() has had + // a chance to run. In this case, we just want to return and not do anything else + // otherwise we will end up with a memory leak. + return; + } + + IsConnected = await _runtime.InvokeVoidAsyncWithErrorHandling("mudPopover.connect", Id); ; + } + finally + { + _semaphore.Release(); + } + } + + public async Task Detach() + { + await _semaphore.WaitAsync(); + try + { + _detached = true; + + if (IsConnected) + { + await _runtime.InvokeVoidAsyncWithErrorHandling("mudPopover.disconnect", Id); + } + } + finally + { + IsConnected = false; + _semaphore.Release(); + } + } + +} + +public class PopoverService : IPopoverService, IAsyncDisposable +{ + private Dictionary _handlers = new(); + private bool _isInitialized = false; + private readonly IJSRuntime _jsRuntime; + private readonly PopoverOptions _options; + private SemaphoreSlim _semaphoreSlim = new(1, 1); + + public event EventHandler FragmentsChanged; + + public bool ThrowOnDuplicateProvider => _options.ThrowOnDuplicateProvider; + public IEnumerable Handlers => _handlers.Values.AsEnumerable(); + + public PopoverService(IJSRuntime jsInterop, IOptions options = null) + { + this._options = options?.Value ?? new PopoverOptions(); + _jsRuntime = jsInterop ?? throw new ArgumentNullException(nameof(jsInterop)); + } + + public async Task InitializeIfNeeded() + { + if (_isInitialized == true) { return; } + + try + { + await _semaphoreSlim.WaitAsync(); + if (_isInitialized == true) { return; } + + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudPopover.initialize", _options.ContainerClass, _options.FlipMargin); + _isInitialized = true; + } + finally + { + _semaphoreSlim.Release(); + } + } + + public PopoverHandler Register(RenderFragment fragment) + { + var handler = new PopoverHandler(fragment, _jsRuntime, () => { /*not doing anything on purpose for now*/ }); + _handlers.Add(handler.Id, handler); + + FragmentsChanged?.Invoke(this, EventArgs.Empty); + + return handler; + } + + public async Task Unregister(PopoverHandler handler) + { + if (handler == null) { return false; } + if (_handlers.Remove(handler.Id) == false) { return false; } + + await handler.Detach(); + + FragmentsChanged?.Invoke(this, EventArgs.Empty); + + return true; + } + + public async ValueTask CountProviders() + { + if (!_isInitialized) { return -1; } + + var (success, value) = await _jsRuntime.InvokeAsyncWithErrorHandling("mudpopoverHelper.countProviders"); + if (success) + return value; + return 0; + } + + //TO DO add js test + [ExcludeFromCodeCoverage] + public async ValueTask DisposeAsync() + { + if (_isInitialized == false) { return; } + + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudPopover.dispose"); + } +} diff --git a/Components/Progress/ProgressCircular.razor b/Components/Progress/ProgressCircular.razor new file mode 100644 index 0000000..935061a --- /dev/null +++ b/Components/Progress/ProgressCircular.razor @@ -0,0 +1,16 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + + @if (Indeterminate) + { + + } + else + { + + } + +
    + diff --git a/Components/Progress/ProgressCircular.razor.cs b/Components/Progress/ProgressCircular.razor.cs new file mode 100644 index 0000000..50031ef --- /dev/null +++ b/Components/Progress/ProgressCircular.razor.cs @@ -0,0 +1,107 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ProgressCircular : UIComponent +{ + private const int _magicNumber = 126; // weird, but required for the SVG to work + + protected string DivClassname => + new CssBuilder("mud-progress-circular") + .AddClass($"mud-{Color.ToDescriptionString()}-text") + .AddClass($"mud-progress-{Size.ToDescriptionString()}") + .AddClass($"mud-progress-indeterminate", Indeterminate) + .AddClass($"mud-progress-static", !Indeterminate) + .AddClass(Class) + .Build(); + + protected string SvgClassname => + new CssBuilder("mud-progress-circular-circle") + .AddClass($"mud-progress-indeterminate", Indeterminate) + .AddClass($"mud-progress-static", !Indeterminate) + .Build(); + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.ProgressCircular.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The size of the component. + /// + [Parameter] + [Category(CategoryTypes.ProgressCircular.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// Constantly animates, does not follow any value. + /// + [Parameter] + [Category(CategoryTypes.ProgressCircular.Behavior)] + public bool Indeterminate { get; set; } + + [Parameter] + [Category(CategoryTypes.ProgressCircular.Behavior)] + public double Min { get; set; } = 0.0; + + [Parameter] + [Category(CategoryTypes.ProgressCircular.Behavior)] + public double Max { get; set; } = 100.0; + + private int _svgValue; + private double _value; + + [Parameter] + [Category(CategoryTypes.ProgressCircular.Behavior)] + public double Value + { + get => _value; + set + { + if (_value != value) + { + _value = value; + _svgValue = ToSvgValue(_value); + StateHasChanged(); + } + } + } + + private int ToSvgValue(double in_value) + { + var value = Math.Min(Math.Max(Min, in_value), Max); + // calculate fraction, which is a value between 0 and 1 + var fraction = (value - Min) / (Max - Min); + // now project into the range of the SVG value (126 .. 0) + return (int)Math.Round(_magicNumber - _magicNumber * fraction); + } + + [Parameter] + [Category(CategoryTypes.ProgressCircular.Appearance)] + public int StrokeWidth { get; set; } = 3; + + protected override void OnInitialized() + { + base.OnInitialized(); + _svgValue = ToSvgValue(_value); + } + + #region --> Obsolete Forwarders for Backwards-Compatiblilty + + [ExcludeFromCodeCoverage] + [Obsolete("Use Min instead.", true)] + [Parameter] public double Minimum { get => Min; set => Min = value; } + + [ExcludeFromCodeCoverage] + [Obsolete("Use Max instead.", true)] + [Parameter] public double Maximum { get => Max; set => Max = value; } + + #endregion + +} diff --git a/Components/Progress/ProgressLinear.razor b/Components/Progress/ProgressLinear.razor new file mode 100644 index 0000000..169e3d5 --- /dev/null +++ b/Components/Progress/ProgressLinear.razor @@ -0,0 +1,29 @@ +@namespace Connected.Components +@using Connected.Extensions; +@inherits UIComponent + +
    +
    + @if (Indeterminate) + { +
    +
    + } + else if (Buffer) + { +
    +
    +
    + } + else + { +
    + } +
    + @if(ChildContent != null) + { +
    + @ChildContent +
    + } +
    diff --git a/Components/Progress/ProgressLinear.razor.cs b/Components/Progress/ProgressLinear.razor.cs new file mode 100644 index 0000000..5d9b3ee --- /dev/null +++ b/Components/Progress/ProgressLinear.razor.cs @@ -0,0 +1,185 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ProgressLinear : UIComponent +{ + protected string DivClassname => + new CssBuilder("mud-progress-linear") + .AddClass("mud-progress-linear-rounded", Rounded) + .AddClass($"mud-progress-linear-striped", Striped) + .AddClass($"mud-progress-indeterminate", Indeterminate) + .AddClass($"mud-progress-linear-buffer", Buffer && !Indeterminate) + .AddClass($"mud-progress-linear-{Size.ToDescriptionString()}") + .AddClass($"mud-progress-linear-color-{Color.ToDescriptionString()}") + .AddClass("horizontal", !Vertical) + .AddClass("vertical", Vertical) + .AddClass("mud-flip-x-rtl") + .AddClass(Class) + .Build(); + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Appearance)] + public Size Size { get; set; } = Size.Small; + + /// + /// Constantly animates, does not follow any value. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public bool Indeterminate { get; set; } = false; + + /// + /// If true, the buffer value will be used. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public bool Buffer { get; set; } = false; + + /// + /// If true, border-radius is set to the themes default value. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Appearance)] + public bool Rounded { get; set; } = false; + + /// + /// Adds stripes to the filled part of the linear progress. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Appearance)] + public bool Striped { get; set; } = false; + + /// + /// If true, the progress bar will be displayed vertically. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Appearance)] + public bool Vertical { get; set; } = false; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// The minimum allowed value of the linear progress. Should not be equal to max. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public double Min + { + get => _min; + set + { + _min = value; + UpdatePercentages(); + } + } + + /// + /// The maximum allowed value of the linear progress. Should not be equal to min. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public double Max + { + get => _max; + set + { + _max = value; + UpdatePercentages(); + } + } + + private double _min = 0.0; + private double _max = 100.0; + + private double _value; + private double _bufferValue; + + /// + /// The maximum allowed value of the linear progress. Should not be equal to min. + /// + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public double Value + { + get => _value; + set + { + _value = value; + UpdatePercentages(); + } + } + + [Parameter] + [Category(CategoryTypes.ProgressLinear.Behavior)] + public double BufferValue + { + get => _bufferValue; + set + { + _bufferValue = value; + UpdatePercentages(); + } + } + + protected double ValuePercent { get; set; } + protected double BufferPercent { get; set; } + + protected void UpdatePercentages() + { + ValuePercent = GetValuePercent(); + BufferPercent = GetBufferPercent(); + StateHasChanged(); + } + + private double GetPercentage(double input) + { + var total = Math.Abs(_max - _min); + if (NumericConverter.AreEqual(0, total)) + { // numeric instability! + return 0.0; + } + var value = Math.Max(0, Math.Min(total, input - _min)); + return value / total * 100.0; + } + + public double GetValuePercent() => GetPercentage(_value); + public double GetBufferPercent() => GetPercentage(_bufferValue); + + private string GetStyleBarTransform(double input) => + Vertical == true ? $"transform: translateY({(int)Math.Round(100 - input)}%);" : $"transform: translateX(-{(int)Math.Round(100 - input)}%);"; + + public string GetStyledBar1Transform() => GetStyleBarTransform(ValuePercent); + public string GetStyledBar2Transform() => GetStyleBarTransform(BufferPercent); + + #region --> Obsolete Forwarders for Backwards-Compatiblilty + + [Obsolete("Use Min instead.", true)] + [ExcludeFromCodeCoverage] + [Parameter] public double Minimum { get => Min; set => Min = value; } + + [Obsolete("Use Max instead.", true)] + [ExcludeFromCodeCoverage] + [Parameter] public double Maximum { get => Max; set => Max = value; } + + #endregion +} diff --git a/Components/RTLProvider/RTLProvider.razor b/Components/RTLProvider/RTLProvider.razor new file mode 100644 index 0000000..6dc9dce --- /dev/null +++ b/Components/RTLProvider/RTLProvider.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits UIComponent + + + + @ChildContent + + \ No newline at end of file diff --git a/Components/RTLProvider/RTLProvider.razor.cs b/Components/RTLProvider/RTLProvider.razor.cs new file mode 100644 index 0000000..b5e92a2 --- /dev/null +++ b/Components/RTLProvider/RTLProvider.razor.cs @@ -0,0 +1,41 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class RTLProvider : UIComponent +{ + protected string Classname => + new CssBuilder("mud-rtl-provider") + .AddClass("mud-application-layout-rtl", RightToLeft) + .AddClass(Class) + .Build(); + + private bool _rtl; + /// + /// If true, changes the layout to RightToLeft. + /// + [Parameter] + [Category(CategoryTypes.RTLProvider.Behavior)] + public bool RightToLeft + { + get => _rtl; + set + { + _rtl = value; + UserAttributes["dir"] = RightToLeft ? "rtl" : "ltr"; + } + } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.RTLProvider.Behavior)] + public RenderFragment ChildContent { get; set; } +} diff --git a/Components/Radio/IRadioGroup.cs b/Components/Radio/IRadioGroup.cs new file mode 100644 index 0000000..38a91ef --- /dev/null +++ b/Components/Radio/IRadioGroup.cs @@ -0,0 +1,7 @@ +namespace Connected.Components; + +internal interface IRadioGroup +{ + //This interface need to throw exception properly. + void CheckGenericTypeMatch(object select_item); +} diff --git a/Components/Radio/Radio.razor b/Components/Radio/Radio.razor new file mode 100644 index 0000000..2d59ad0 --- /dev/null +++ b/Components/Radio/Radio.razor @@ -0,0 +1,23 @@ +@namespace Connected.Components +@typeparam T +@inherits UIComponent + + diff --git a/Components/Radio/Radio.razor.cs b/Components/Radio/Radio.razor.cs new file mode 100644 index 0000000..2c0082d --- /dev/null +++ b/Components/Radio/Radio.razor.cs @@ -0,0 +1,226 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Radio : UIComponent, IDisposable +{ + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + protected string Classname => + new CssBuilder("mud-radio") + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-radio-content-placement-{ConvertPlacement(Placement).ToDescriptionString()}") + .AddClass(Class) + .Build(); + + protected string ButtonClassname => + new CssBuilder("mud-button-root mud-icon-button") + .AddClass($"mud-ripple mud-ripple-radio", !DisableRipple && !Disabled) + .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", UnCheckedColor == null || (UnCheckedColor != null && Checked == true)) + .AddClass($"mud-{UnCheckedColor?.ToDescriptionString()}-text hover:mud-{UnCheckedColor?.ToDescriptionString()}-hover", UnCheckedColor != null && Checked == false) + .AddClass($"mud-radio-dense", Dense) + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-checked", Checked) + .AddClass("mud-error-text", RadioGroup?.HasErrors) + .Build(); + + protected string RadioIconsClassNames => + new CssBuilder("mud-radio-icons") + .AddClass($"mud-checked", Checked) + .Build(); + + protected string IconClassName => + new CssBuilder("mud-icon-root mud-svg-icon") + .AddClass($"mud-icon-size-{Size.ToDescriptionString()}") + .Build(); + + protected string CheckedIconClassName => + new CssBuilder("mud-icon-root mud-svg-icon mud-radio-icon-checked") + .AddClass($"mud-icon-size-{Size.ToDescriptionString()}") + .Build(); + + protected string ChildSpanClassName => + new CssBuilder("mud-radio-content mud-typography mud-typography-body1") + .AddClass("mud-error-text", RadioGroup.HasErrors) + .Build(); + + private IRadioGroup _parent; + + /// + /// The parent Radio Group + /// + [CascadingParameter] + internal IRadioGroup ParentGroup + { + get => _parent; + set + { + _parent = value; + if (_parent == null) + return; + _parent.CheckGenericTypeMatch(this); + //MudRadioGroup?.Add(this); + } + } + + internal RadioGroup RadioGroup => (RadioGroup)ParentGroup; + + private Placement ConvertPlacement(Placement placement) + { + return placement switch + { + Placement.Left => RightToLeft ? Placement.End : Placement.Start, + Placement.Right => RightToLeft ? Placement.Start : Placement.End, + _ => placement + }; + } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The base color of the component in its none active/unchecked state. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public ThemeColor? UnCheckedColor { get; set; } = null; + + /// + /// The position of the child content. + /// + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public Placement Placement { get; set; } = Placement.End; + + /// + /// The value to associate to the button. + /// + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public T Option { get; set; } + + /// + /// If true, compact padding will be applied. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public bool Dense { get; set; } + + /// + /// The Size of the component. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public Size Size { get; set; } = Size.Medium; + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// If true, the button will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public bool Disabled { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public RenderFragment ChildContent { get; set; } + + internal bool Checked { get; private set; } + + internal void SetChecked(bool value) + { + if (Checked != value) + { + Checked = value; + StateHasChanged(); + } + } + + public void Select() + { + RadioGroup?.SetSelectedRadioAsync(this).AndForget(); + } + + internal Task OnClick() + { + if (RadioGroup != null) + return RadioGroup.SetSelectedRadioAsync(this); + + return Task.CompletedTask; + } + + protected internal void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled) + return; + switch (obj.Key) + { + case "Enter": + case "NumpadEnter": + case " ": + Select(); + break; + case "Backspace": + RadioGroup.Reset(); + break; + } + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + if (RadioGroup != null) + await RadioGroup.RegisterRadioAsync(this); + } + + public void Dispose() + { + RadioGroup?.UnregisterRadio(this); + _keyInterceptor?.Dispose(); + } + + private IKeyInterceptor _keyInterceptor; + [Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; } + + private string _elementId = "radio" + Guid.NewGuid().ToString().Substring(0, 8); + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _keyInterceptor = _keyInterceptorFactory.Create(); + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-button-root", + Keys = { + new KeyOptions { Key=" ", PreventDown = "key+none", PreventUp = "key+none" }, // prevent scrolling page + new KeyOptions { Key="Enter", PreventDown = "key+none" }, + new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, + new KeyOptions { Key="Backspace", PreventDown = "key+none" }, + }, + }); + } + await base.OnAfterRenderAsync(firstRender); + } + +} diff --git a/Components/Radio/RadioGroup.razor b/Components/Radio/RadioGroup.razor new file mode 100644 index 0000000..e11ef39 --- /dev/null +++ b/Components/Radio/RadioGroup.razor @@ -0,0 +1,13 @@ +@namespace Connected.Components +@typeparam T +@inherits FormComponent + + + + +
    + @ChildContent +
    +
    +
    +
    \ No newline at end of file diff --git a/Components/Radio/RadioGroup.razor.cs b/Components/Radio/RadioGroup.razor.cs new file mode 100644 index 0000000..f3988ab --- /dev/null +++ b/Components/Radio/RadioGroup.razor.cs @@ -0,0 +1,142 @@ +using Connected.Annotations; +using Connected.Utilities; +using Connected.Utilities.Exceptions; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class RadioGroup : FormComponent, IRadioGroup +{ + public RadioGroup() : base(new Converter()) { } + + private Radio _selectedRadio; + + private HashSet> _radios = new(); + + protected string Classname => + new CssBuilder("mud-input-control-boolean-input") + .AddClass(Class) + .Build(); + + private string GetInputClass() => + new CssBuilder("mud-radio-group") + .AddClass(InputClass) + .Build(); + + /// + /// User class names for the input, separated by space + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public string InputClass { get; set; } + + /// + /// User style definitions for the input + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public string InputStyle { get; set; } + + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public RenderFragment ChildContent { get; set; } + + [Parameter] + [Category(CategoryTypes.Radio.Behavior)] + public string Name { get; set; } = Guid.NewGuid().ToString(); + + public void CheckGenericTypeMatch(object select_item) + { + var itemT = select_item.GetType().GenericTypeArguments[0]; + if (itemT != typeof(T)) + throw new GenericTypeMismatchException("MudRadioGroup", "MudRadio", typeof(T), itemT); + } + + [Parameter] + [Category(CategoryTypes.Radio.Data)] + public T SelectedOption + { + get => _value; + set => SetSelectedOptionAsync(value, true).AndForget(); + } + + protected async Task SetSelectedOptionAsync(T option, bool updateRadio) + { + if (!OptionEquals(_value, option)) + { + _value = option; + + if (updateRadio) + await SetSelectedRadioAsync(_radios.FirstOrDefault(r => OptionEquals(r.Option, _value)), false); + + await SelectedOptionChanged.InvokeAsync(_value); + + BeginValidate(); + FieldChanged(_value); + } + } + + [Parameter] + public EventCallback SelectedOptionChanged { get; set; } + + internal Task SetSelectedRadioAsync(Radio radio) + { + Touched = true; + return SetSelectedRadioAsync(radio, true); + } + + protected async Task SetSelectedRadioAsync(Radio radio, bool updateOption) + { + if (_selectedRadio != radio) + { + _selectedRadio = radio; + + foreach (var item in _radios.ToArray()) + item.SetChecked(item == _selectedRadio); + + if (updateOption) + await SetSelectedOptionAsync(GetOptionOrDefault(_selectedRadio), false); + } + } + + internal Task RegisterRadioAsync(Radio radio) + { + _radios.Add(radio); + + if (_selectedRadio == null) + { + if (OptionEquals(radio.Option, _value)) + return SetSelectedRadioAsync(radio, false); + } + return Task.CompletedTask; + } + + internal void UnregisterRadio(Radio radio) + { + _radios.Remove(radio); + + if (_selectedRadio == radio) + _selectedRadio = null; + } + + protected override void ResetValue() + { + if (_selectedRadio != null) + { + _selectedRadio.SetChecked(false); + _selectedRadio = null; + } + + base.ResetValue(); + } + + private static T GetOptionOrDefault(Radio radio) + { + return radio != null ? radio.Option : default; + } + + private static bool OptionEquals(T option1, T option2) + { + return EqualityComparer.Default.Equals(option1, option2); + } +} diff --git a/Components/Rating/Rating.razor b/Components/Rating/Rating.razor new file mode 100644 index 0000000..912a4b9 --- /dev/null +++ b/Components/Rating/Rating.razor @@ -0,0 +1,14 @@ +@namespace Connected.Components +@inherits UIComponent + + + + + @for (int i = 1; i <= MaxValue; i++) + { + + } + + \ No newline at end of file diff --git a/Components/Rating/Rating.razor.cs b/Components/Rating/Rating.razor.cs new file mode 100644 index 0000000..6864cba --- /dev/null +++ b/Components/Rating/Rating.razor.cs @@ -0,0 +1,195 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Rating : UIComponent +{ + /// + /// Space separated class names + /// + protected string ClassName => + new CssBuilder("") + .AddClass($"mud-rating-root") + .AddClass(Class) + .Build(); + + /// + /// User class names for RatingItems, separated by space + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public string RatingItemsClass { get; set; } + + /// + /// User styles for RatingItems. + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public string RatingItemsStyle { get; set; } + + /// + /// Input name. If not initialized, name will be random guid. + /// + [Parameter] + [Category(CategoryTypes.Rating.Behavior)] + public string Name { get; set; } = Guid.NewGuid().ToString(); + + /// + /// Max value and how many elements to click will be generated. Default: 5 + /// + [Parameter] + [Category(CategoryTypes.Rating.Behavior)] + public int MaxValue { get; set; } = 5; + + /// + /// Selected or hovered icon. Default @Icons.Material.Star + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public string FullIcon { get; set; } = Icons.Material.Filled.Star; + + /// + /// Non selected item icon. Default @Icons.Material.StarBorder + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public string EmptyIcon { get; set; } = Icons.Material.Filled.StarBorder; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + /// + /// The Size of the icons. + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public Size Size { get; set; } = Size.Medium; + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Rating.Appearance)] + public bool DisableRipple { get; set; } + /// + /// If true, the controls will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Rating.Behavior)] + public bool Disabled { get; set; } + /// + /// If true, the ratings will show without interactions. + /// + [Parameter] + [Category(CategoryTypes.Rating.Behavior)] + public bool ReadOnly { get; set; } + + /// + /// Fires when SelectedValue changes. + /// + [Parameter] public EventCallback SelectedValueChanged { get; set; } + + /// + /// Selected value. This property is two-way bindable. + /// + [Parameter] + [Category(CategoryTypes.Rating.Data)] + public int SelectedValue + { + get => _selectedValue; + set + { + if (_selectedValue == value) + return; + + _selectedValue = value; + + SelectedValueChanged.InvokeAsync(_selectedValue); + } + } + + private int _selectedValue = 0; + + /// + /// Fires when hovered value change. Value will be null if no rating item is hovered. + /// + [Parameter] public EventCallback HoveredValueChanged { get; set; } + + internal int? HoveredValue + { + get => _hoveredValue; + set + { + if (_hoveredValue == value) + return; + + _hoveredValue = value; + HoveredValueChanged.InvokeAsync(value); + } + } + + private int? _hoveredValue = null; + + internal bool IsRatingHover => HoveredValue.HasValue; + + private void HandleItemClicked(int itemValue) + { + SelectedValue = itemValue; + + if (itemValue == 0) + { + HoveredValue = null; + } + } + + internal void HandleItemHovered(int? itemValue) => HoveredValue = itemValue; + + private void IncreaseValue(int val) + { + if ((SelectedValue == MaxValue && val > 0) || (SelectedValue == 0 && val < 0)) + { + + } + else + { + SelectedValue += val; + } + } + + protected internal void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + { + return; + } + + switch (obj.Key) + { + case "ArrowRight": + if (obj.ShiftKey == true) + { + IncreaseValue(MaxValue - SelectedValue); + } + else + { + IncreaseValue(1); + } + break; + case "ArrowLeft": + if (obj.ShiftKey == true) + { + IncreaseValue(-SelectedValue); + } + else + { + IncreaseValue(-1); + } + break; + } + } +} diff --git a/Components/Rating/RatingItem.razor b/Components/Rating/RatingItem.razor new file mode 100644 index 0000000..bd78f31 --- /dev/null +++ b/Components/Rating/RatingItem.razor @@ -0,0 +1,16 @@ +@namespace Connected.Components +@inherits UIComponent + +@if (ReadOnly) +{ + + + +} +else +{ + + + + +} diff --git a/Components/Rating/RatingItem.razor.cs b/Components/Rating/RatingItem.razor.cs new file mode 100644 index 0000000..7a761f1 --- /dev/null +++ b/Components/Rating/RatingItem.razor.cs @@ -0,0 +1,141 @@ +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class RatingItem : UIComponent +{ + /// + /// Space separated class names + /// + protected string ClassName => + new CssBuilder("") + .AddClass($"mud-rating-item") + .AddClass($"mud-ripple mud-ripple-icon", !DisableRipple) + .AddClass($"yellow-text.text-darken-3", Color == ThemeColor.Default) + .AddClass($"mud-{Color.ToDescriptionString()}-text", Color != ThemeColor.Default) + .AddClass($"mud-rating-item-active", IsActive) + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-readonly", ReadOnly) + .AddClass(Class) + .Build(); + + [CascadingParameter] + private Rating Rating { get; set; } + + /// + /// This rating item value; + /// + [Parameter] + public int ItemValue { get; set; } + + internal string ItemIcon { get; set; } + + internal bool IsActive { get; set; } + + private bool IsChecked => ItemValue == Rating?.SelectedValue; + + /// + /// The Size of the icon. + /// + [Parameter] public Size Size { get; set; } = Size.Medium; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// If true, disables ripple effect. + /// + [Parameter] public bool DisableRipple { get; set; } + + /// + /// If true, the controls will be disabled. + /// + [Parameter] public bool Disabled { get; set; } + + /// + /// If true, the item will be readonly. + /// + [Parameter] public bool ReadOnly { get; set; } + + /// + /// Fires when element clicked. + /// + [Parameter] public EventCallback ItemClicked { get; set; } + + /// + /// Fires when element hovered. + /// + [Parameter] public EventCallback ItemHovered { get; set; } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + ItemIcon = SelectIcon(); + } + + internal string SelectIcon() + { + if (Rating == null) + return null; + if (Rating.HoveredValue.HasValue && Rating.HoveredValue.Value >= ItemValue) + { + // full icon when @RatingItem hovered + return Rating.FullIcon; + } + else if (Rating.SelectedValue >= ItemValue) + { + if (Rating.HoveredValue.HasValue && Rating.HoveredValue.Value < ItemValue) + { + // empty icon when equal or higher RatingItem value clicked, but less value hovered + return Rating.EmptyIcon; + } + else + { + // full icon when equal or higher RatingItem value clicked + return Rating.FullIcon; + } + } + else + { + // empty icon when this or higher RatingItem is not clicked and not hovered + return Rating.EmptyIcon; + } + } + + // rating item lose hover + internal Task HandleMouseOut(MouseEventArgs e) + { + if (Disabled || Rating == null) + return Task.CompletedTask; + + IsActive = false; + return ItemHovered.InvokeAsync(null); + } + + internal void HandleMouseOver(MouseEventArgs e) + { + if (Disabled) return; + + IsActive = true; + ItemHovered.InvokeAsync(ItemValue); + } + + private void HandleClick(MouseEventArgs e) + { + if (Disabled) return; + IsActive = false; + if (Rating?.SelectedValue == ItemValue) + { + ItemClicked.InvokeAsync(0); + } + else + { + ItemClicked.InvokeAsync(ItemValue); + } + } +} diff --git a/Components/Render/Render.razor b/Components/Render/Render.razor new file mode 100644 index 0000000..66c5943 --- /dev/null +++ b/Components/Render/Render.razor @@ -0,0 +1,25 @@ +@namespace Connected.Components + +@* MudRender is a container component that only renders its content, so it really doesn't do anything other than giving you the ability to force a re-render of its content + This is especially useful if you don't want to render the whole tree for some reason. All you need to force a renderupdate of its content is to call ForceRender() on an + ElementReference to Render +*@ + +@ChildContent + +@code { + + /// + /// The content to render + /// + [Parameter] + public RenderFragment ChildContent { get; set; } + + /// + /// Re-render the content + /// + public void ForceRender() + { + StateHasChanged(); + } +} diff --git a/Components/ScrollToTop/ScrollToTop.razor b/Components/ScrollToTop/ScrollToTop.razor new file mode 100644 index 0000000..bcad72e --- /dev/null +++ b/Components/ScrollToTop/ScrollToTop.razor @@ -0,0 +1,10 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + + \ No newline at end of file diff --git a/Components/ScrollToTop/ScrollToTop.razor.cs b/Components/ScrollToTop/ScrollToTop.razor.cs new file mode 100644 index 0000000..4d70c43 --- /dev/null +++ b/Components/ScrollToTop/ScrollToTop.razor.cs @@ -0,0 +1,136 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class ScrollToTop : IDisposable +{ + private IScrollListener _scrollListener; + + protected string Classname => + new CssBuilder("mud-scroll-to-top") + .AddClass("visible", Visible && string.IsNullOrWhiteSpace(VisibleCssClass)) + .AddClass("hidden", !Visible && string.IsNullOrWhiteSpace(HiddenCssClass)) + .AddClass(VisibleCssClass, Visible && !string.IsNullOrWhiteSpace(VisibleCssClass)) + .AddClass(HiddenCssClass, !Visible && !string.IsNullOrWhiteSpace(HiddenCssClass)) + .AddClass(Class) + .Build(); + + [Inject] IScrollListenerFactory ScrollListenerFactory { get; set; } + + [Inject] IScrollManager ScrollManager { get; set; } + + [Parameter] + [Category(CategoryTypes.ScrollToTop.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// The CSS selector to which the scroll event will be attached + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Behavior)] + public string Selector { get; set; } + + /// + /// If set to true, it starts Visible. If sets to false, it will become visible when the TopOffset amount of scrolled pixels is reached + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Behavior)] + public bool Visible { get; set; } + + /// + /// CSS class for the Visible state. Here, apply some transitions and animations that will happen when the component becomes visible + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Appearance)] + public string VisibleCssClass { get; set; } + + /// + /// CSS class for the Hidden state. Here, apply some transitions and animations that will happen when the component becomes invisible + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Appearance)] + public string HiddenCssClass { get; set; } + + /// + /// The distance in pixels scrolled from the top of the selected element from which + /// the component becomes visible + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Behavior)] + public int TopOffset { get; set; } = 300; + + /// + /// Smooth or Auto + /// + [Parameter] + [Category(CategoryTypes.ScrollToTop.Behavior)] + public ScrollBehavior ScrollBehavior { get; set; } = ScrollBehavior.Smooth; + + /// + /// Called when scroll event is fired + /// + [Parameter] public EventCallback OnScroll { get; set; } + + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + + var selector = !string.IsNullOrWhiteSpace(Selector) + ? Selector + : null;// null is defaulted to document element in JS function + + _scrollListener = ScrollListenerFactory.Create(selector); + + //subscribe to event + _scrollListener.OnScroll += ScrollListener_OnScroll; + } + } + + /// + /// event received when scroll in the selected element happens + /// + /// ScrollListener instance + /// Information about the position of the scrolled element + private async void ScrollListener_OnScroll(object sender, ScrollEventArgs e) + { + await OnScroll.InvokeAsync(e); + + var topOffset = e.NodeName == "#document" + ? e.FirstChildBoundingClientRect.Top * -1 + : e.ScrollTop; + + if (topOffset >= TopOffset && Visible != true) + { + Visible = true; + await InvokeAsync(() => StateHasChanged()); + } + + if (topOffset < TopOffset && Visible == true) + { + Visible = false; + await InvokeAsync(() => StateHasChanged()); + } + } + + /// + /// Scrolls to top when clicked + /// + private void OnClick() + { + ScrollManager.ScrollToTopAsync(_scrollListener.Selector, ScrollBehavior); + } + + /// + /// Remove the event + /// + public void Dispose() + { + if (_scrollListener == null) { return; } + + _scrollListener.OnScroll -= ScrollListener_OnScroll; + _scrollListener.Dispose(); + } +} diff --git a/Components/Select/ISelect.cs b/Components/Select/ISelect.cs new file mode 100644 index 0000000..696a097 --- /dev/null +++ b/Components/Select/ISelect.cs @@ -0,0 +1,11 @@ +namespace Connected.Components; + +internal interface ISelect +{ + void CheckGenericTypeMatch(object select_item); + bool MultiSelection { get; set; } +} + +internal interface IShadowSelect +{ +} diff --git a/Components/Select/Select.razor b/Components/Select/Select.razor new file mode 100644 index 0000000..9283aee --- /dev/null +++ b/Components/Select/Select.razor @@ -0,0 +1,49 @@ +@namespace Connected.Components +@typeparam T +@inherits InputBase + + +
    + + + + @if (CanRenderValue) + { + @GetSelectedValuePresenter() + } + + + + + @if (MultiSelection && SelectAll) + { + + + } + @ChildContent + + + + + +
    + @*Shadow select items for IsValueInList and CanRenderValue*@ + + + @ChildContent + + + +
    + + \ No newline at end of file diff --git a/Components/Select/Select.razor.cs b/Components/Select/Select.razor.cs new file mode 100644 index 0000000..2e0260a --- /dev/null +++ b/Components/Select/Select.razor.cs @@ -0,0 +1,1077 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Services; +using Connected.Utilities; +using Connected.Utilities.Exceptions; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Select : InputBase, ISelect, IShadowSelect +{ + private HashSet _selectedValues = new HashSet(); + private IEqualityComparer _comparer; + private bool _dense; + private string multiSelectionText; + private bool? _selectAllChecked; + private IKeyInterceptor _keyInterceptor; + + protected string Classname => + new CssBuilder("mud-select") + .AddClass(Class) + .Build(); + + [Inject] private IKeyInterceptorFactory KeyInterceptorFactory { get; set; } + [Inject] IScrollManager ScrollManager { get; set; } + + private string _elementId = "select_" + Guid.NewGuid().ToString().Substring(0, 8); + + private Task SelectNextItem() => SelectAdjacentItem(+1); + + private Task SelectPreviousItem() => SelectAdjacentItem(-1); + + private async Task SelectAdjacentItem(int direction) + { + if (_items == null || _items.Count == 0) + return; + var index = _items.FindIndex(x => x.ItemId == (string)_activeItemId); + if (direction < 0 && index < 0) + index = 0; + SelectItem item = null; + // the loop allows us to jump over disabled items until we reach the next non-disabled one + for (int i = 0; i < _items.Count; i++) + { + index += direction; + if (index < 0) + index = 0; + if (index >= _items.Count) + index = _items.Count - 1; + if (_items[index].Disabled) + continue; + item = _items[index]; + if (!MultiSelection) + { + _selectedValues.Clear(); + _selectedValues.Add(item.Value); + await SetValueAsync(item.Value, updateText: true); + HilightItem(item); + break; + } + else + { + // in multiselect mode don't select anything, just hilight. + // selecting is done by Enter + HilightItem(item); + break; + } + } + await _elementReference.SetText(Text); + await ScrollToItemAsync(item); + } + private ValueTask ScrollToItemAsync(SelectItem item) + => item != null ? ScrollManager.ScrollToListItemAsync(item.ItemId) : ValueTask.CompletedTask; + private async Task SelectFirstItem(string startChar = null) + { + if (_items == null || _items.Count == 0) + return; + var items = _items.Where(x => !x.Disabled); + var firstItem = items.FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(startChar)) + { + // find first item that starts with the letter + var currentItem = items.FirstOrDefault(x => x.ItemId == (string)_activeItemId); + if (currentItem != null && + Converter.Set(currentItem.Value)?.ToLowerInvariant().StartsWith(startChar) == true) + { + // this will step through all items that start with the same letter if pressed multiple times + items = items.SkipWhile(x => x != currentItem).Skip(1); + } + items = items.Where(x => Converter.Set(x.Value)?.ToLowerInvariant().StartsWith(startChar) == true); + } + var item = items.FirstOrDefault(); + if (item == null) + return; + if (!MultiSelection) + { + _selectedValues.Clear(); + _selectedValues.Add(item.Value); + await SetValueAsync(item.Value, updateText: true); + HilightItem(item); + } + else + { + HilightItem(item); + } + await _elementReference.SetText(Text); + await ScrollToItemAsync(item); + } + + private async Task SelectLastItem() + { + if (_items == null || _items.Count == 0) + return; + var item = _items.LastOrDefault(x => !x.Disabled); + if (item == null) + return; + if (!MultiSelection) + { + _selectedValues.Clear(); + _selectedValues.Add(item.Value); + await SetValueAsync(item.Value, updateText: true); + HilightItem(item); + } + else + { + HilightItem(item); + } + await _elementReference.SetText(Text); + await ScrollToItemAsync(item); + } + + /// + /// Fired when dropdown opens. + /// + [Category(CategoryTypes.FormComponent.Behavior)] + [Parameter] public EventCallback OnOpen { get; set; } + + /// + /// Fired when dropdown closes. + /// + [Category(CategoryTypes.FormComponent.Behavior)] + [Parameter] public EventCallback OnClose { get; set; } + + /// + /// Add the MudSelectItems here + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// User class names for the popover, separated by space + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string PopoverClass { get; set; } + + /// + /// If true, compact vertical padding will be applied to all Select items. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public bool Dense + { + get { return _dense; } + set { _dense = value; } + } + + /// + /// The Open Select Icon + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string OpenIcon { get; set; } = Icons.Material.Filled.ArrowDropDown; + + /// + /// The Close Select Icon + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string CloseIcon { get; set; } = Icons.Material.Filled.ArrowDropUp; + + /// + /// If set to true and the MultiSelection option is set to true, a "select all" checkbox is added at the top of the list of items. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool SelectAll { get; set; } + + /// + /// Define the text of the Select All option. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string SelectAllText { get; set; } = "Select all"; + + /// + /// Fires when SelectedValues changes. + /// + [Parameter] public EventCallback> SelectedValuesChanged { get; set; } + + /// + /// Function to define a customized multiselection text. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public Func, string> MultiSelectionTextFunc { get; set; } + + /// + /// Parameter to define the delimited string separator. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Delimiter { get; set; } = ", "; + + /// + /// Set of selected values. If MultiSelection is false it will only ever contain a single value. This property is two-way bindable. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public IEnumerable SelectedValues + { + get + { + if (_selectedValues == null) + _selectedValues = new HashSet(_comparer); + return _selectedValues; + } + set + { + var set = value ?? new HashSet(_comparer); + if (SelectedValues.Count() == set.Count() && _selectedValues.All(x => set.Contains(x))) + return; + _selectedValues = new HashSet(set, _comparer); + SelectionChangedFromOutside?.Invoke(_selectedValues); + if (!MultiSelection) + SetValueAsync(_selectedValues.FirstOrDefault()).AndForget(); + else + { + //Warning. Here the Converter was not set yet + if (MultiSelectionTextFunc != null) + { + SetCustomizedTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), + selectedConvertedValues: SelectedValues.Select(x => Converter.Set(x)).ToList(), + multiSelectionTextFunc: MultiSelectionTextFunc).AndForget(); + } + else + { + SetTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), updateValue: false).AndForget(); + } + } + SelectedValuesChanged.InvokeAsync(new HashSet(SelectedValues, _comparer)); + if (MultiSelection && typeof(T) == typeof(string)) + SetValueAsync((T)(object)Text, updateText: false).AndForget(); + } + } + + /// + /// The Comparer to use for comparing selected values internally. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public IEqualityComparer Comparer + { + get => _comparer; + set + { + _comparer = value; + // Apply comparer and refresh selected values + _selectedValues = new HashSet(_selectedValues, _comparer); + SelectedValues = _selectedValues; + } + } + + private Func _toStringFunc = x => x?.ToString(); + + private Input _elementReference; + + /// + /// Defines how values are displayed in the drop-down list + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public Func ToStringFunc + { + get => _toStringFunc; + set + { + if (_toStringFunc == value) + return; + _toStringFunc = value; + Converter = new Converter + { + SetFunc = _toStringFunc ?? (x => x?.ToString()), + //GetFunc = LookupValue, + }; + } + } + + public Select() + { + Adornment = Adornment.End; + IconSize = Size.Medium; + } + + protected override void OnAfterRender(bool firstRender) + { + base.OnAfterRender(firstRender); + if (firstRender && Value != null) + { + // we need to render the initial Value which is not possible without the items + // which supply the RenderFragment. So in this case, a second render is necessary + StateHasChanged(); + } + UpdateSelectAllChecked(); + lock (this) + { + if (_renderComplete != null) + { + _renderComplete.TrySetResult(); + _renderComplete = null; + } + } + } + + + private Task WaitForRender() + { + Task t = null; + lock (this) + { + if (_renderComplete != null) + return _renderComplete.Task; + _renderComplete = new TaskCompletionSource(); + t = _renderComplete.Task; + } + StateHasChanged(); + return t; + } + + private TaskCompletionSource _renderComplete; + + /// + /// Returns whether or not the Value can be found in items. If not, the Select will display it as a string. + /// + protected bool CanRenderValue + { + get + { + if (Value == null) + return false; + if (!_shadowLookup.TryGetValue(Value, out var item)) + return false; + return (item.ChildContent != null); + } + } + + protected bool IsValueInList + { + get + { + if (Value == null) + return false; + return _shadowLookup.TryGetValue(Value, out var _); + } + } + + protected RenderFragment GetSelectedValuePresenter() + { + if (Value == null) + return null; + if (!_shadowLookup.TryGetValue(Value, out var item)) + return null; //<-- for now. we'll add a custom template to present values (set from outside) which are not on the list? + return item.ChildContent; + } + + protected override Task UpdateValuePropertyAsync(bool updateText) + { + // For MultiSelection of non-string T's we don't update the Value!!! + if (typeof(T) == typeof(string) || !MultiSelection) + base.UpdateValuePropertyAsync(updateText); + return Task.CompletedTask; + } + + protected override Task UpdateTextPropertyAsync(bool updateValue) + { + // when multiselection is true, we return + // a comma separated list of selected values + if (MultiSelectionTextFunc != null) + { + return MultiSelection + ? SetCustomizedTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), + selectedConvertedValues: SelectedValues.Select(x => Converter.Set(x)).ToList(), + multiSelectionTextFunc: MultiSelectionTextFunc) + : base.UpdateTextPropertyAsync(updateValue); + } + else + { + return MultiSelection + ? SetTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x)))) + : base.UpdateTextPropertyAsync(updateValue); + } + } + + internal event Action> SelectionChangedFromOutside; + + private bool _multiSelection; + /// + /// If true, multiple values can be selected via checkboxes which are automatically shown in the dropdown + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool MultiSelection + { + get => _multiSelection; + set + { + if (value != _multiSelection) + { + _multiSelection = value; + UpdateTextPropertyAsync(false).AndForget(); + } + } + } + + /// + /// The collection of items within this select + /// + public IReadOnlyList> Items => _items; + + protected internal List> _items = new(); + protected Dictionary> _valueLookup = new(); + protected Dictionary> _shadowLookup = new(); + + // note: this must be object to satisfy MudList + private object _activeItemId = null; + + internal bool Add(SelectItem item) + { + if (item == null) + return false; + bool? result = null; + if (!_items.Select(x => x.Value).Contains(item.Value)) + { + _items.Add(item); + + if (item.Value != null) + { + _valueLookup[item.Value] = item; + if (item.Value.Equals(Value) && !MultiSelection) + result = true; + } + } + UpdateSelectAllChecked(); + if (result.HasValue == false) + { + result = item.Value?.Equals(Value); + } + return result == true; + } + + internal void Remove(SelectItem item) + { + _items.Remove(item); + if (item.Value != null) + _valueLookup.Remove(item.Value); + } + + /// + /// Sets the maxheight the Select can have when open. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public int MaxHeight { get; set; } = 300; + + /// + /// Set the anchor origin point to determen where the popover will open from. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public Origin AnchorOrigin { get; set; } = Origin.TopCenter; + + /// + /// Sets the transform origin point for the popover. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public Origin TransformOrigin { get; set; } = Origin.TopCenter; + + /// + /// Sets the direction the Select menu should open. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public Direction Direction { get; set; } = Direction.Bottom; + + /// + /// If true, the Select menu will open either before or after the input (left/right). + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetX { get; set; } + + /// + /// If true, the Select menu will open either before or after the input (top/bottom). + /// + /// [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetY { get; set; } + + /// + /// If true, the Select's input will not show any values that are not defined in the dropdown. + /// This can be useful if Value is bound to a variable which is initialized to a value which is not in the list + /// and you want the Select to show the label / placeholder instead. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Strict { get; set; } + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Clearable { get; set; } = false; + + /// + /// If true, prevent scrolling while dropdown is open. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool LockScroll { get; set; } = false; + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] public EventCallback OnClearButtonClick { get; set; } + + internal bool _isOpen; + + public string _currentIcon { get; set; } + + public async Task SelectOption(int index) + { + if (index < 0 || index >= _items.Count) + { + if (!MultiSelection) + await CloseMenu(); + return; + } + await SelectOption(_items[index].Value); + } + + public async Task SelectOption(object obj) + { + var value = (T)obj; + if (MultiSelection) + { + // multi-selection: menu stays open + if (!_selectedValues.Contains(value)) + _selectedValues.Add(value); + else + _selectedValues.Remove(value); + + if (MultiSelectionTextFunc != null) + { + await SetCustomizedTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), + selectedConvertedValues: SelectedValues.Select(x => Converter.Set(x)).ToList(), + multiSelectionTextFunc: MultiSelectionTextFunc); + } + else + { + await SetTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), updateValue: false); + } + + UpdateSelectAllChecked(); + BeginValidate(); + } + else + { + // single selection + // CloseMenu(true) doesn't close popover in BSS + await CloseMenu(false); + + if (EqualityComparer.Default.Equals(Value, value)) + { + StateHasChanged(); + return; + } + + await SetValueAsync(value); + _elementReference.SetText(Text).AndForget(); + _selectedValues.Clear(); + _selectedValues.Add(value); + } + + HilightItemForValue(value); + await SelectedValuesChanged.InvokeAsync(SelectedValues); + if (MultiSelection && typeof(T) == typeof(string)) + await SetValueAsync((T)(object)Text, updateText: false); + await InvokeAsync(StateHasChanged); + } + + private async void HilightItemForValue(T value) + { + if (value == null) + { + HilightItem(null); + return; + } + await WaitForRender(); + _valueLookup.TryGetValue(value, out var item); + HilightItem(item); + } + + private async void HilightItem(SelectItem item) + { + _activeItemId = item?.ItemId; + // we need to make sure we are just after a render here or else there will be race conditions + await WaitForRender(); + // Note: this is a hack but I found no other way to make the list hilight the currently hilighted item + // without the delay it always shows the previously hilighted item because the popup items don't exist yet + // they are only registered after they are rendered, so we need to render again! + await Task.Delay(1); + StateHasChanged(); + } + + private async Task HilightSelectedValue() + { + await WaitForRender(); + if (MultiSelection) + HilightItem(_items.FirstOrDefault(x => !x.Disabled)); + else + HilightItemForValue(Value); + } + + private void UpdateSelectAllChecked() + { + if (MultiSelection && SelectAll) + { + var oldState = _selectAllChecked; + if (_selectedValues.Count == 0) + { + _selectAllChecked = false; + } + else if (_items.Count == _selectedValues.Count) + { + _selectAllChecked = true; + } + else + { + _selectAllChecked = null; + } + } + } + + public async Task ToggleMenu() + { + if (Disabled || ReadOnly) + return; + if (_isOpen) + await CloseMenu(true); + else + await OpenMenu(); + } + + public async Task OpenMenu() + { + if (Disabled || ReadOnly) + return; + _isOpen = true; + UpdateIcon(); + StateHasChanged(); + await HilightSelectedValue(); + //Scroll the active item on each opening + if (_activeItemId != null) + { + var index = _items.FindIndex(x => x.ItemId == (string)_activeItemId); + if (index > 0) + { + var item = _items[index]; + await ScrollToItemAsync(item); + } + } + //disable escape propagation: if selectmenu is open, only the select popover should close and underlying components should not handle escape key + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "Key+none" }); + + await OnOpen.InvokeAsync(); + } + + public async Task CloseMenu(bool focusAgain = true) + { + _isOpen = false; + UpdateIcon(); + if (focusAgain == true) + { + StateHasChanged(); + await OnBlur.InvokeAsync(new FocusEventArgs()); + _elementReference.FocusAsync().AndForget(TaskOption.Safe); + StateHasChanged(); + } + + //enable escape propagation: the select popover was closed, now underlying components are allowed to handle escape key + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "none" }); + + await OnClose.InvokeAsync(); + } + + private void UpdateIcon() + { + _currentIcon = !string.IsNullOrWhiteSpace(AdornmentIcon) ? AdornmentIcon : _isOpen ? CloseIcon : OpenIcon; + } + + protected override void OnInitialized() + { + base.OnInitialized(); + UpdateIcon(); + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + UpdateIcon(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _keyInterceptor = KeyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-input-control", + Keys = { + new KeyOptions { Key=" ", PreventDown = "key+none" }, //prevent scrolling page, toggle open/close + new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead hilight previous item + new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead hilight next item + new KeyOptions { Key="Home", PreventDown = "key+none" }, + new KeyOptions { Key="End", PreventDown = "key+none" }, + new KeyOptions { Key="Escape" }, + new KeyOptions { Key="Enter", PreventDown = "key+none" }, + new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, + new KeyOptions { Key="a", PreventDown = "key+ctrl" }, // select all items instead of all page text + new KeyOptions { Key="A", PreventDown = "key+ctrl" }, // select all items instead of all page text + new KeyOptions { Key="/./", SubscribeDown = true, SubscribeUp = true }, // for our users + }, + }); + _keyInterceptor.KeyDown += HandleKeyDown; + _keyInterceptor.KeyUp += HandleKeyUp; + } + + await base.OnAfterRenderAsync(firstRender); + } + + public void CheckGenericTypeMatch(object select_item) + { + var itemT = select_item.GetType().GenericTypeArguments[0]; + if (itemT != typeof(T)) + throw new GenericTypeMismatchException("MudSelect", "MudSelectItem", typeof(T), itemT); + } + + public override ValueTask FocusAsync() + { + return _elementReference.FocusAsync(); + } + + public override ValueTask BlurAsync() + { + return _elementReference.BlurAsync(); + } + + public override ValueTask SelectAsync() + { + return _elementReference.SelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return _elementReference.SelectRangeAsync(pos1, pos2); + } + + /// + /// Extra handler for clearing selection. + /// + protected async ValueTask SelectClearButtonClickHandlerAsync(MouseEventArgs e) + { + await SetValueAsync(default, false); + await SetTextAsync(default, false); + _selectedValues.Clear(); + BeginValidate(); + StateHasChanged(); + await SelectedValuesChanged.InvokeAsync(_selectedValues); + await OnClearButtonClick.InvokeAsync(e); + } + + protected async Task SetCustomizedTextAsync(string text, bool updateValue = true, + List selectedConvertedValues = null, + Func, string> multiSelectionTextFunc = null) + { + // The Text property of the control is updated + Text = multiSelectionTextFunc?.Invoke(selectedConvertedValues); + + // The comparison is made on the multiSelectionText variable + if (multiSelectionText != text) + { + multiSelectionText = text; + if (!string.IsNullOrWhiteSpace(multiSelectionText)) + Touched = true; + if (updateValue) + await UpdateValuePropertyAsync(false); + await TextChanged.InvokeAsync(multiSelectionText); + } + } + + /// + /// Custom checked icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string CheckedIcon { get; set; } = Icons.Material.Filled.CheckBox; + + /// + /// Custom unchecked icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string UncheckedIcon { get; set; } = Icons.Material.Filled.CheckBoxOutlineBlank; + + /// + /// Custom indeterminate icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string IndeterminateIcon { get; set; } = Icons.Material.Filled.IndeterminateCheckBox; + + /// + /// The checkbox icon reflects the select all option's state + /// + protected string SelectAllCheckBoxIcon + { + get + { + return _selectAllChecked.HasValue ? _selectAllChecked.Value ? CheckedIcon : UncheckedIcon : IndeterminateIcon; + } + } + + internal async void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + var key = obj.Key.ToLowerInvariant(); + if (_isOpen && key.Length == 1 && key != " " && !(obj.CtrlKey || obj.ShiftKey || obj.AltKey || obj.MetaKey)) + { + await SelectFirstItem(key); + return; + } + switch (obj.Key) + { + case "Tab": + await CloseMenu(false); + break; + case "ArrowUp": + if (obj.AltKey == true) + { + await CloseMenu(); + break; + } + else if (_isOpen == false) + { + await OpenMenu(); + break; + } + else + { + await SelectPreviousItem(); + break; + } + case "ArrowDown": + if (obj.AltKey == true) + { + await OpenMenu(); + break; + } + else if (_isOpen == false) + { + await OpenMenu(); + break; + } + else + { + await SelectNextItem(); + break; + } + case " ": + await ToggleMenu(); + break; + case "Escape": + await CloseMenu(true); + break; + case "Home": + await SelectFirstItem(); + break; + case "End": + await SelectLastItem(); + break; + case "Enter": + case "NumpadEnter": + var index = _items.FindIndex(x => x.ItemId == (string)_activeItemId); + if (!MultiSelection) + { + if (!_isOpen) + { + await OpenMenu(); + return; + } + // this also closes the menu + await SelectOption(index); + break; + } + else + { + if (_isOpen == false) + { + await OpenMenu(); + break; + } + else + { + await SelectOption(index); + await _elementReference.SetText(Text); + break; + } + } + case "a": + case "A": + if (obj.CtrlKey == true) + { + if (MultiSelection) + { + await SelectAllClickAsync(); + //If we didn't add delay, it won't work. + await WaitForRender(); + await Task.Delay(1); + StateHasChanged(); + //It only works when selecting all, not render unselect all. + //UpdateSelectAllChecked(); + } + } + break; + } + OnKeyDown.InvokeAsync(obj).AndForget(); + + } + + internal void HandleKeyUp(KeyboardEventArgs obj) + { + OnKeyUp.InvokeAsync(obj).AndForget(); + } + + [ExcludeFromCodeCoverage] + [Obsolete("Use Clear instead.", true)] + public Task ClearAsync() => Clear(); + + /// + /// Clear the selection + /// + public async Task Clear() + { + await SetValueAsync(default, false); + await SetTextAsync(default, false); + _selectedValues.Clear(); + BeginValidate(); + StateHasChanged(); + await SelectedValuesChanged.InvokeAsync(_selectedValues); + } + + private async Task SelectAllClickAsync() + { + // Manage the fake tri-state of a checkbox + if (!_selectAllChecked.HasValue) + _selectAllChecked = true; + else if (_selectAllChecked.Value) + _selectAllChecked = false; + else + _selectAllChecked = true; + // Define the items selection + if (_selectAllChecked.Value == true) + await SelectAllItems(); + else + await Clear(); + } + + private async Task SelectAllItems() + { + if (!MultiSelection) + return; + var selectedValues = new HashSet(_items.Where(x => !x.Disabled && x.Value != null).Select(x => x.Value), _comparer); + _selectedValues = new HashSet(selectedValues, _comparer); + if (MultiSelectionTextFunc != null) + { + await SetCustomizedTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), + selectedConvertedValues: SelectedValues.Select(x => Converter.Set(x)).ToList(), + multiSelectionTextFunc: MultiSelectionTextFunc); + } + else + { + await SetTextAsync(string.Join(Delimiter, SelectedValues.Select(x => Converter.Set(x))), updateValue: false); + } + UpdateSelectAllChecked(); + _selectedValues = selectedValues; // need to force selected values because Blazor overwrites it under certain circumstances due to changes of Text or Value + BeginValidate(); + await SelectedValuesChanged.InvokeAsync(SelectedValues); + if (MultiSelection && typeof(T) == typeof(string)) + SetValueAsync((T)(object)Text, updateText: false).AndForget(); + } + + public void RegisterShadowItem(SelectItem item) + { + if (item == null || item.Value == null) + return; + _shadowLookup[item.Value] = item; + } + + public void UnregisterShadowItem(SelectItem item) + { + if (item == null || item.Value == null) + return; + _shadowLookup.Remove(item.Value); + } + + internal void OnLostFocus(FocusEventArgs obj) + { + if (_isOpen) + { + // when the menu is open we immediately get back the focus if we lose it (i.e. because of checkboxes in multi-select) + // otherwise we can't receive key strokes any longer + _elementReference.FocusAsync().AndForget(TaskOption.Safe); + } + base.OnBlur.InvokeAsync(obj); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.KeyUp -= HandleKeyUp; + + _keyInterceptor.Dispose(); + } + } + } + + /// + /// Fixes issue #4328 + /// Returns true when MultiSelection is true and it has selected values(Since Value property is not used when MultiSelection=true + /// + /// + /// True when component has a value + protected override bool HasValue(T value) + { + if (MultiSelection) + return SelectedValues?.Count() > 0; + else + return base.HasValue(value); + } +} diff --git a/Components/Select/SelectItem.razor b/Components/Select/SelectItem.razor new file mode 100644 index 0000000..b2e774b --- /dev/null +++ b/Components/Select/SelectItem.razor @@ -0,0 +1,19 @@ +@namespace Connected.Components +@typeparam T +@inherits SelectItemBase + +@if (HideContent == false) +{ + + @if (ChildContent != null) + { + @ChildContent + } + else + { + @DisplayString + } + +} + + diff --git a/Components/Select/SelectItem.razor.cs b/Components/Select/SelectItem.razor.cs new file mode 100644 index 0000000..f259c81 --- /dev/null +++ b/Components/Select/SelectItem.razor.cs @@ -0,0 +1,154 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +/// +/// Represents an option of a select or multi-select. To be used inside MudSelect. +/// +public partial class SelectItem : SelectItemBase, IDisposable +{ + private String GetCssClasses() => new CssBuilder() + .AddClass(Class) + .Build(); + + private ISelect _parent; + internal string ItemId { get; } = "_" + Guid.NewGuid().ToString().Substring(0, 8); + + /// + /// The parent select component + /// + [CascadingParameter] + internal ISelect IMudSelect + { + get => _parent; + set + { + _parent = value; + if (_parent == null) + return; + _parent.CheckGenericTypeMatch(this); + if (Select == null) + return; + bool isSelected = Select.Add(this); + if (_parent.MultiSelection) + { + Select.SelectionChangedFromOutside += OnUpdateSelectionStateFromOutside; + InvokeAsync(() => OnUpdateSelectionStateFromOutside(Select.SelectedValues)); + } + else + { + IsSelected = isSelected; + } + } + } + + private IShadowSelect _shadowParent; + private bool _isSelected; + + [CascadingParameter] + internal IShadowSelect ParentShadow + { + get => _shadowParent; + set + { + _shadowParent = value; + ((Select)_shadowParent)?.RegisterShadowItem(this); + } + } + + /// + /// Select items with HideContent==true are only there to register their RenderFragment with the select but + /// wont render and have no other purpose! + /// + [CascadingParameter(Name = "HideContent")] + internal bool HideContent { get; set; } + + internal Select Select => (Select)IMudSelect; + + private void OnUpdateSelectionStateFromOutside(IEnumerable selection) + { + if (selection == null) + return; + var old_is_selected = IsSelected; + IsSelected = selection.Contains(Value); + if (old_is_selected != IsSelected) + InvokeAsync(StateHasChanged); + } + + /// + /// A user-defined option that can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public T Value { get; set; } + + /// + /// Mirrors the MultiSelection status of the parent select + /// + protected bool MultiSelection + { + get + { + if (Select == null) + return false; + return Select.MultiSelection; + } + } + + /// + /// Selected state of the option. Only works if the parent is a mulit-select + /// + internal bool IsSelected + { + get => _isSelected; + set + { + _isSelected = value; + } + } + + /// + /// The checkbox icon reflects the multi-select option's state + /// + protected string CheckBoxIcon + { + get + { + if (!MultiSelection) + return null; + return IsSelected ? Icons.Material.Filled.CheckBox : Icons.Material.Filled.CheckBoxOutlineBlank; + } + } + + protected string DisplayString + { + get + { + var converter = Select?.Converter; + if (converter == null) + return $"{Value}"; + return converter.Set(Value); + } + } + + private void OnClicked() + { + if (MultiSelection) + IsSelected = !IsSelected; + + Select?.SelectOption(Value); + InvokeAsync(StateHasChanged); + } + + public void Dispose() + { + try + { + Select?.Remove(this); + ((Select)_shadowParent)?.UnregisterShadowItem(this); + } + catch (Exception) { } + } +} diff --git a/Components/SelectItemBase.cs b/Components/SelectItemBase.cs new file mode 100644 index 0000000..8e07bbd --- /dev/null +++ b/Components/SelectItemBase.cs @@ -0,0 +1,81 @@ +using System.Windows.Input; +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public abstract class SelectItemBase : UIComponent +{ + /// + /// If true, the input element will be disabled. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public bool Disabled { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.General.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// Link to a URL when clicked. + /// + [Parameter] + [Category(CategoryTypes.General.ClickAction)] + public string Href { get; set; } + + /// + /// If true, force browser to redirect outside component router-space. + /// + [Parameter] + [Category(CategoryTypes.General.ClickAction)] + public bool ForceLoad { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Command parameter. + /// + [Parameter] + [Category(CategoryTypes.General.ClickAction)] + public object CommandParameter { get; set; } + + /// + /// Command executed when the user clicks on an element. + /// + [Parameter] + [Category(CategoryTypes.General.ClickAction)] + public ICommand Command { get; set; } + + [Inject] private NavigationManager UriHelper { get; set; } + + [Parameter] + public EventCallback OnClick { get; set; } + + protected async Task OnClickHandler(MouseEventArgs ev) + { + if (Disabled) + return; + if (Href != null) + { + UriHelper.NavigateTo(Href, ForceLoad); + } + else + { + await OnClick.InvokeAsync(ev); + if (Command?.CanExecute(CommandParameter) ?? false) + { + Command.Execute(CommandParameter); + } + } + } +} diff --git a/Components/Skeleton/Skeleton.razor b/Components/Skeleton/Skeleton.razor new file mode 100644 index 0000000..6579454 --- /dev/null +++ b/Components/Skeleton/Skeleton.razor @@ -0,0 +1,5 @@ +@namespace Connected.Components +@inherits UIComponent; + + + diff --git a/Components/Skeleton/Skeleton.razor.cs b/Components/Skeleton/Skeleton.razor.cs new file mode 100644 index 0000000..c51de6f --- /dev/null +++ b/Components/Skeleton/Skeleton.razor.cs @@ -0,0 +1,63 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Skeleton : UIComponent +{ + protected string Classname => + new CssBuilder("mud-skeleton") + .AddClass($"mud-skeleton-{SkeletonType.ToDescriptionString()}") + .AddClass($"mud-skeleton-{Animation.ToDescriptionString()}") + .AddClass(Class) + .Build(); + + /// + /// With defined in string, needs px or % or equal prefix. + /// + [Parameter] + [Category(CategoryTypes.Skeleton.Appearance)] + public string Width { set; get; } + + /// + /// Height defined in string, needs px or % or equal prefix. + /// + [Parameter] + [Category(CategoryTypes.Skeleton.Appearance)] + public string Height { set; get; } + + /// + /// Shape of the skeleton that will be rendered. + /// + [Parameter] + [Category(CategoryTypes.Skeleton.Appearance)] + public SkeletonType SkeletonType { set; get; } = SkeletonType.Text; + + /// + /// Animation style, if false it will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Skeleton.Appearance)] + public Animation Animation { set; get; } = Animation.Pulse; + + private string _width; + private string _height; + private string _styleString; + + protected override void OnInitialized() + { + if (!string.IsNullOrEmpty(Width)) + { + _width = $"width:{Width};"; + } + + if (!string.IsNullOrEmpty(Height)) + { + _height = $"height:{Height};"; + } + + _styleString = $"{_width}{_height}{Style}"; + } +} diff --git a/Components/Slider/Slider.razor b/Components/Slider/Slider.razor new file mode 100644 index 0000000..8d7ac24 --- /dev/null +++ b/Components/Slider/Slider.razor @@ -0,0 +1,51 @@ +@namespace Connected.Components +@using System.Globalization +@inherits UIComponent +@typeparam T + +@{ + var width = CalculatePosition().ToString(CultureInfo.InvariantCulture); +} + +
    + @if (ChildContent != null) + { + @ChildContent + } +
    + @if (Variant == Variant.Filled) + { +
    +
    +
    + } + @if (TickMarks == true) + { +
    +
    + @for (int i = 0; i < _tickMarkCount; i++) + { + int current = i; + +
    + + @if (TickMarkLabels != null && current < TickMarkLabels.Length) + { + @TickMarkLabels[current] + } +
    + } +
    +
    + } + + @if (ValueLabel) + { +
    + @Value.ToString() +
    + } +
    + +
    \ No newline at end of file diff --git a/Components/Slider/Slider.razor.cs b/Components/Slider/Slider.razor.cs new file mode 100644 index 0000000..22fbfbf --- /dev/null +++ b/Components/Slider/Slider.razor.cs @@ -0,0 +1,188 @@ +using System.Globalization; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Slider : UIComponent +{ + protected string Classname => + new CssBuilder("mud-slider") + .AddClass($"mud-slider-{Size.ToDescriptionString()}") + .AddClass($"mud-slider-{Color.ToDescriptionString()}") + .AddClass("mud-slider-vertical", Vertical) + .AddClass(Class) + .Build(); + + protected string _value; + protected string _min = "0"; + protected string _max = "100"; + protected string _step = "1"; + + /// + /// The minimum allowed value of the slider. Should not be equal to max. + /// + [Parameter] + [Category(CategoryTypes.Slider.Validation)] + public T Min + { + get => Converter.Get(_min); + set => _min = Converter.Set(value); + } + + /// + /// The maximum allowed value of the slider. Should not be equal to min. + /// + /// + [Parameter] + [Category(CategoryTypes.Slider.Validation)] + public T Max + { + get => Converter.Get(_max); + set => _max = Converter.Set(value); + } + + /// + /// How many steps the slider should take on each move. + /// + /// + [Parameter] + [Category(CategoryTypes.Slider.Validation)] + public T Step + { + get => Converter.Get(_step); + set => _step = Converter.Set(value); + } + + /// + /// If true, the slider will be disabled. + /// + /// + [Parameter] + [Category(CategoryTypes.Slider.Behavior)] + public bool Disabled { get; set; } = false; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Slider.Behavior)] + public RenderFragment ChildContent { get; set; } + + [Parameter] + [Category(CategoryTypes.Slider.Behavior)] + public Converter Converter { get; set; } = new DefaultConverter() { Culture = CultureInfo.InvariantCulture }; + + [Parameter] public EventCallback ValueChanged { get; set; } + + [Parameter] + [Category(CategoryTypes.Slider.Data)] + public T Value + { + get => Converter.Get(_value); + set + { + var d = Converter.Set(value); + if (_value == d) + return; + _value = d; + ValueChanged.InvokeAsync(value); + } + } + + /// + /// The color of the component. It supports the Primary, Secondary and Tertiary theme colors. + /// + [Parameter] + [Category(CategoryTypes.Slider.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + protected string Text + { + get => _value; + set + { + if (_value == value) + return; + _value = value; + ValueChanged.InvokeAsync(Value); + } + } + + /// + /// If true, the dragging the slider will update the Value immediately. + /// If false, the Value is updated only on releasing the handle. + /// + [Parameter] + [Category(CategoryTypes.Slider.Behavior)] + public bool Immediate { get; set; } = true; + + /// + /// If true, displays the slider vertical. + /// + [Parameter] + [Category(CategoryTypes.Slider.Appearance)] + public bool Vertical { get; set; } = false; + + /// + /// If true, displays tick marks on the track. + /// + [Parameter] + [Category(CategoryTypes.Slider.Appearance)] + public bool TickMarks { get; set; } = false; + + /// + /// Labels for tick marks, will attempt to map the labels to each step in index order. + /// + [Parameter] + [Category(CategoryTypes.Slider.Appearance)] + public string[] TickMarkLabels { get; set; } + + /// + /// Labels for tick marks, will attempt to map the labels to each step in index order. + /// + [Parameter] + [Category(CategoryTypes.Slider.Appearance)] + public Size Size { get; set; } = Size.Small; + + /// + /// The variant to use. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public Variant Variant { get; set; } = Variant.Text; + + /// + /// Displays the value over the slider thumb. + /// + [Parameter] + [Category(CategoryTypes.Button.Appearance)] + public bool ValueLabel { get; set; } + + private int _tickMarkCount = 0; + protected override void OnParametersSet() + { + if (TickMarks) + { + var min = Convert.ToDouble(Min); + var max = Convert.ToDouble(Max); + var step = Convert.ToDouble(Step); + + _tickMarkCount = 1 + (int)((max - min) / step); + } + } + + private double CalculatePosition() + { + var min = Convert.ToDouble(Min); + var max = Convert.ToDouble(Max); + var value = Convert.ToDouble(Value); + var result = 100.0 * (value - min) / (max - min); + + result = Math.Min(Math.Max(0, result), 100); + + return Math.Round(result, 2); + } +} diff --git a/Components/Snackbar/CommonSnackbarOptions.cs b/Components/Snackbar/CommonSnackbarOptions.cs new file mode 100644 index 0000000..94a285a --- /dev/null +++ b/Components/Snackbar/CommonSnackbarOptions.cs @@ -0,0 +1,37 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +namespace Connected.Components; + +public abstract class CommonSnackbarOptions +{ + public int MaximumOpacity { get; set; } = 95; + + public int ShowTransitionDuration { get; set; } = 1000; + + public int VisibleStateDuration { get; set; } = 5000; + + public int HideTransitionDuration { get; set; } = 2000; + + public bool ShowCloseIcon { get; set; } = true; + + public bool RequireInteraction { get; set; } = false; + + public bool BackgroundBlurred { get; set; } = false; + + public Variant SnackbarVariant { get; set; } = Variant.Filled; + + protected CommonSnackbarOptions() { } + + protected CommonSnackbarOptions(CommonSnackbarOptions options) + { + MaximumOpacity = options.MaximumOpacity; + ShowTransitionDuration = options.ShowTransitionDuration; + VisibleStateDuration = options.VisibleStateDuration; + HideTransitionDuration = options.HideTransitionDuration; + ShowCloseIcon = options.ShowCloseIcon; + RequireInteraction = options.RequireInteraction; + BackgroundBlurred = options.BackgroundBlurred; + SnackbarVariant = options.SnackbarVariant; + } +} diff --git a/Components/Snackbar/Defaults.cs b/Components/Snackbar/Defaults.cs new file mode 100644 index 0000000..019dd41 --- /dev/null +++ b/Components/Snackbar/Defaults.cs @@ -0,0 +1,25 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +namespace Connected.Components; + +public static class Defaults +{ + public static class Classes + { + public static class Position + { + public const string TopLeft = "mud-snackbar-location-top-left"; + public const string TopCenter = "mud-snackbar-location-top-center"; + public const string TopRight = "mud-snackbar-location-top-right"; + public const string TopStart = "mud-snackbar-location-top-start"; + public const string TopEnd = "mud-snackbar-location-top-end"; + + public const string BottomLeft = "mud-snackbar-location-bottom-left"; + public const string BottomCenter = "mud-snackbar-location-bottom-center"; + public const string BottomRight = "mud-snackbar-location-bottom-right"; + public const string BottomStart = "mud-snackbar-location-bottom-start"; + public const string BottomEnd = "mud-snackbar-location-bottom-end"; + } + } +} diff --git a/Components/Snackbar/ISnackbar.cs b/Components/Snackbar/ISnackbar.cs new file mode 100644 index 0000000..628d656 --- /dev/null +++ b/Components/Snackbar/ISnackbar.cs @@ -0,0 +1,23 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public interface ISnackbar : IDisposable +{ + IEnumerable ShownSnackbars { get; } + + SnackbarConfiguration Configuration { get; } + + event Action OnSnackbarsUpdated; + + Snackbar Add(string message, Severity severity = Severity.Normal, Action configure = null, string key = ""); + Snackbar Add(RenderFragment message, Severity severity = Severity.Normal, Action configure = null, string key = ""); + Snackbar Add(Dictionary componentParameters = null, Severity severity = Severity.Normal, Action configure = null, string key = "") where T : IComponent; + + void Clear(); + + void Remove(Snackbar snackbar); +} diff --git a/Components/Snackbar/InternalComponents/SnackbarMessageRenderFragment.razor b/Components/Snackbar/InternalComponents/SnackbarMessageRenderFragment.razor new file mode 100644 index 0000000..5096504 --- /dev/null +++ b/Components/Snackbar/InternalComponents/SnackbarMessageRenderFragment.razor @@ -0,0 +1,9 @@ +@namespace Connected.Components + +@Message + +@code { + + [Parameter] + public RenderFragment Message { get; set; } +} diff --git a/Components/Snackbar/InternalComponents/SnackbarMessageText.razor b/Components/Snackbar/InternalComponents/SnackbarMessageText.razor new file mode 100644 index 0000000..22ce073 --- /dev/null +++ b/Components/Snackbar/InternalComponents/SnackbarMessageText.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components + +@Message + +@code { + [Parameter] + public MarkupString Message { get; set; } +} diff --git a/Components/Snackbar/SnackBarMessageState.cs b/Components/Snackbar/SnackBarMessageState.cs new file mode 100644 index 0000000..28700df --- /dev/null +++ b/Components/Snackbar/SnackBarMessageState.cs @@ -0,0 +1,102 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +using System.Diagnostics; +using static System.String; + +namespace Connected.Components; + +internal class SnackBarMessageState +{ + private string AnimationId { get; } + public bool UserHasInteracted { get; set; } + public SnackbarOptions Options { get; } + public SnackbarState SnackbarState { get; set; } + public Stopwatch Stopwatch { get; } = new Stopwatch(); + + public SnackBarMessageState(SnackbarOptions options) + { + Options = options; + AnimationId = $"snackbar-{Guid.NewGuid()}"; + SnackbarState = SnackbarState.Init; + } + private string Opacity => ((decimal)Options.MaximumOpacity / 100).ToPercentage(); + + public bool ShowActionButton => !IsNullOrWhiteSpace(Options.Action); + public bool ShowCloseIcon => Options.ShowCloseIcon; + + public bool HideIcon => Options.HideIcon; + public string Icon => Options.Icon; + public ThemeColor IconColor => Options.IconColor; + public Size IconSize => Options.IconSize; + + public string ProgressBarStyle + { + get + { + var duration = RemainingTransitionMilliseconds(Options.VisibleStateDuration); + return $"width:100;animation:{AnimationId} {duration}ms;"; + } + } + + public string AnimationStyle + { + get + { + const string Template = "opacity: {0}; animation: {1}ms linear {2};"; + + switch (SnackbarState) + { + case SnackbarState.Showing: + var showingDuration = RemainingTransitionMilliseconds(Options.ShowTransitionDuration); + return Format(Template, Opacity, showingDuration, AnimationId); + + case SnackbarState.Hiding: + var hidingDuration = RemainingTransitionMilliseconds(Options.HideTransitionDuration); + return Format(Template, 0, hidingDuration, AnimationId); + + case SnackbarState.Visible: + return $"opacity: {Opacity};"; + + default: + return Empty; + } + } + } + + public string SnackbarClass + { + get + { + var result = $"mud-snackbar {Options.SnackbarTypeClass}"; + + if (Options.Onclick != null && !ShowActionButton) + result += " force-cursor"; + + return result; + } + } + + public string TransitionClass + { + get + { + var template = "@keyframes " + AnimationId + " {{from{{ {0}: {1}; }} to{{ {0}: {2}; }}}}"; + + return SnackbarState switch + { + SnackbarState.Showing => Format(template, "opacity", "0%", Opacity), + SnackbarState.Hiding => Format(template, "opacity", Opacity, "0%"), + SnackbarState.Visible => Format(template, "width", "100%", "0%"), + _ => Empty, + }; + } + } + + private int RemainingTransitionMilliseconds(int transitionDuration) + { + var duration = transitionDuration - (int)Stopwatch.ElapsedMilliseconds; + + return duration >= 0 ? duration : 0; + } +} diff --git a/Components/Snackbar/Snackbar.cs b/Components/Snackbar/Snackbar.cs new file mode 100644 index 0000000..5aae8d5 --- /dev/null +++ b/Components/Snackbar/Snackbar.cs @@ -0,0 +1,111 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +namespace Connected.Components; + +public class Snackbar : IDisposable +{ + private Timer Timer { get; set; } + internal SnackBarMessageState State { get; } + public string Message => SnackbarMessage.Text; + internal SnackbarMessage SnackbarMessage { get; } + public event Action OnClose; + public event Action OnUpdate; + public Severity Severity => State.Options.Severity; + + internal Snackbar(SnackbarMessage message, SnackbarOptions options) + { + SnackbarMessage = message; + State = new SnackBarMessageState(options); + Timer = new Timer(TimerElapsed, null, Timeout.Infinite, Timeout.Infinite); + } + + internal void Init() => TransitionTo(SnackbarState.Showing); + + internal void Clicked(bool fromCloseIcon) + { + if (!fromCloseIcon) + { + // Do not start the hiding transition if no click action + if (State.Options.Onclick == null) + return; + + // Click action is executed only if it's not from the close icon + State.Options.Onclick.Invoke(this); + } + + State.UserHasInteracted = true; + TransitionTo(SnackbarState.Hiding); + } + + private void TransitionTo(SnackbarState state) + { + StopTimer(); + State.SnackbarState = state; + var options = State.Options; + + if (state.IsShowing()) + { + if (options.ShowTransitionDuration <= 0) TransitionTo(SnackbarState.Visible); + else StartTimer(options.ShowTransitionDuration); + } + else if (state.IsVisible() && !options.RequireInteraction) + { + if (options.VisibleStateDuration <= 0) TransitionTo(SnackbarState.Hiding); + else StartTimer(options.VisibleStateDuration); + } + else if (state.IsHiding()) + { + if (options.HideTransitionDuration <= 0) OnClose?.Invoke(this); + else StartTimer(options.HideTransitionDuration); + } + + OnUpdate?.Invoke(); + } + + private void TimerElapsed(object state) + { + switch (State.SnackbarState) + { + case SnackbarState.Showing: + TransitionTo(SnackbarState.Visible); + break; + case SnackbarState.Visible: + TransitionTo(SnackbarState.Hiding); + break; + case SnackbarState.Hiding: + OnClose?.Invoke(this); + break; + } + } + + private void StartTimer(int duration) + { + State.Stopwatch.Restart(); + Timer?.Change(duration, Timeout.Infinite); + } + + private void StopTimer() + { + State.Stopwatch.Stop(); + Timer?.Change(Timeout.Infinite, Timeout.Infinite); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposing) return; + StopTimer(); + + var timer = Timer; + Timer = null; + + timer?.Dispose(); + } +} + diff --git a/Components/Snackbar/SnackbarConfiguration.cs b/Components/Snackbar/SnackbarConfiguration.cs new file mode 100644 index 0000000..975d36f --- /dev/null +++ b/Components/Snackbar/SnackbarConfiguration.cs @@ -0,0 +1,74 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +namespace Connected.Components; + + +public class SnackbarConfiguration : CommonSnackbarOptions +{ + private bool _newestOnTop; + private bool _preventDuplicates; + private int _maxDisplayedSnackbars; + private string _positionClass; + private bool _clearAfterNavigation; + + internal event Action OnUpdate; + + public bool NewestOnTop + { + get => _newestOnTop; + set + { + _newestOnTop = value; + OnUpdate?.Invoke(); + } + } + + public bool PreventDuplicates + { + get => _preventDuplicates; + set + { + _preventDuplicates = value; + OnUpdate?.Invoke(); + } + } + + public int MaxDisplayedSnackbars + { + get => _maxDisplayedSnackbars; + set + { + _maxDisplayedSnackbars = value; + OnUpdate?.Invoke(); + } + } + + public string PositionClass + { + get => _positionClass; + set + { + _positionClass = value; + OnUpdate?.Invoke(); + } + } + + public bool ClearAfterNavigation + { + get => _clearAfterNavigation; + set + { + _clearAfterNavigation = value; + OnUpdate?.Invoke(); + } + } + + public SnackbarConfiguration() + { + PositionClass = Defaults.Classes.Position.TopRight; + NewestOnTop = false; + PreventDuplicates = true; + MaxDisplayedSnackbars = 5; + } +} diff --git a/Components/Snackbar/SnackbarDuplicatesBehavior.cs b/Components/Snackbar/SnackbarDuplicatesBehavior.cs new file mode 100644 index 0000000..705313d --- /dev/null +++ b/Components/Snackbar/SnackbarDuplicatesBehavior.cs @@ -0,0 +1,12 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public enum SnackbarDuplicatesBehavior +{ + Allow, + Prevent, + GlobalDefault, +} diff --git a/Components/Snackbar/SnackbarElement.razor b/Components/Snackbar/SnackbarElement.razor new file mode 100644 index 0000000..cfb2cc4 --- /dev/null +++ b/Components/Snackbar/SnackbarElement.razor @@ -0,0 +1,35 @@ +@namespace Connected.Components +@inherits UIComponent + +@Css +
    + @if (!HideIcon) + { +
    + +
    + } + +
    + @if (Message?.ComponentType != null) + { + + } +
    + + @if (ShowCloseIcon || ShowActionButton) + { +
    + + @if (ShowActionButton) + { + + } + + @if (ShowCloseIcon) + { + + } +
    + } +
    diff --git a/Components/Snackbar/SnackbarElement.razor.cs b/Components/Snackbar/SnackbarElement.razor.cs new file mode 100644 index 0000000..218e4e9 --- /dev/null +++ b/Components/Snackbar/SnackbarElement.razor.cs @@ -0,0 +1,78 @@ +// Copyright (c) Alessandro Ghidini. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Changes and improvements Copyright (c) The MudBlazor Team + +using Microsoft.AspNetCore.Components; +using static System.String; + +namespace Connected.Components; + +public partial class SnackbarElement : UIComponent, IDisposable +{ + [Parameter] + public Snackbar Snackbar { get; set; } + + /// + /// Custom close icon. + /// + [Parameter] public string CloseIcon { get; set; } = Icons.Material.Filled.Close; + + // appearance + private string Action => Snackbar?.State.Options.Action; + private ThemeColor ActionColor => Snackbar?.State.Options.ActionColor ?? ThemeColor.Default; + private Variant ActionVariant => Snackbar?.State.Options.ActionVariant ?? Snackbar?.State.Options.SnackbarVariant ?? Variant.Text; + private string AnimationStyle => Snackbar?.State.AnimationStyle + Style; + private string SnackbarClass => Snackbar?.State.SnackbarClass; + private RenderFragment Css; + private bool ShowActionButton => Snackbar?.State.ShowActionButton == true; + private bool ShowCloseIcon => Snackbar?.State.ShowCloseIcon == true; + + // icon + private bool HideIcon => Snackbar?.State.HideIcon == true; + private string Icon => Snackbar?.State.Icon; + private ThemeColor IconColor => Snackbar?.State.Options.IconColor ?? ThemeColor.Inherit; + private Size IconSize => Snackbar?.State.Options.IconSize ?? Size.Medium; + + // behavior + private void ActionClicked() => Snackbar?.Clicked(false); + private void CloseIconClicked() => Snackbar?.Clicked(true); + private SnackbarMessage Message => Snackbar?.SnackbarMessage; + + private void SnackbarClicked() + { + if (!ShowActionButton) + Snackbar?.Clicked(false); + } + + private void SnackbarUpdated() + { + InvokeAsync(StateHasChanged); + } + + protected override void OnInitialized() + { + if (Snackbar != null) + { + Snackbar.OnUpdate += SnackbarUpdated; + Snackbar.Init(); + + Css = builder => + { + var transitionClass = Snackbar.State.TransitionClass; + + if (!IsNullOrWhiteSpace(transitionClass)) + { + builder.OpenElement(1, "style"); + builder.AddContent(2, transitionClass); + builder.CloseElement(); + } + }; + } + } + + public void Dispose() + { + if (Snackbar != null) + Snackbar.OnUpdate -= SnackbarUpdated; + } +} diff --git a/Components/Snackbar/SnackbarMessage.cs b/Components/Snackbar/SnackbarMessage.cs new file mode 100644 index 0000000..ad54d3a --- /dev/null +++ b/Components/Snackbar/SnackbarMessage.cs @@ -0,0 +1,25 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; + +namespace Connected.Components; + +internal class SnackbarMessage +{ + internal Type ComponentType { get; } + internal Dictionary ComponentParameters { get; } + internal string Key { get; } + + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(SnackbarMessageRenderFragment))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(SnackbarMessageText))] + internal SnackbarMessage(Type componentType, Dictionary componentParameters = null, string key = "") + { + ComponentType = componentType; + ComponentParameters = componentParameters; + Key = key; + } + + public string Text { get; set; } +} diff --git a/Components/Snackbar/SnackbarOptions.cs b/Components/Snackbar/SnackbarOptions.cs new file mode 100644 index 0000000..399ecdf --- /dev/null +++ b/Components/Snackbar/SnackbarOptions.cs @@ -0,0 +1,82 @@ +//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +using Connected.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public class SnackbarOptions : CommonSnackbarOptions +{ + public Func Onclick { get; set; } + + public string Action { get; set; } + + public Variant? ActionVariant { get; set; } + + public ThemeColor ActionColor { get; set; } = ThemeColor.Default; + + public Severity Severity { get; } + + public string SnackbarTypeClass { get; set; } + + public bool CloseAfterNavigation { get; set; } + + public bool HideIcon { get; set; } + + public string Icon { get; set; } + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + public Size IconSize { get; set; } = Size.Medium; + + public SnackbarDuplicatesBehavior DuplicatesBehavior { get; set; } = SnackbarDuplicatesBehavior.GlobalDefault; + + /// + /// Custom normal icon. + /// + [Parameter] public string NormalIcon { get; set; } = Icons.Material.Outlined.EventNote; + + /// + /// Custom info icon. + /// + [Parameter] public string InfoIcon { get; set; } = Icons.Material.Outlined.Info; + + /// + /// Custom success icon. + /// + [Parameter] public string SuccessIcon { get; set; } = Icons.Custom.Uncategorized.AlertSuccess; + + /// + /// Custom warning icon. + /// + [Parameter] public string WarningIcon { get; set; } = Icons.Material.Outlined.ReportProblem; + + /// + /// Custom error icon. + /// + [Parameter] public string ErrorIcon { get; set; } = Icons.Material.Filled.ErrorOutline; + + public SnackbarOptions(Severity severity, CommonSnackbarOptions options) : base(options) + { + Severity = severity; + + SnackbarTypeClass = $"mud-alert-{SnackbarVariant.ToDescriptionString()}-{severity.ToDescriptionString()}"; + + if (SnackbarVariant != Variant.Filled) + { + SnackbarTypeClass += BackgroundBlurred ? " mud-snackbar-blurred" : " mud-snackbar-surface"; + } + + if (string.IsNullOrEmpty(Icon)) + { + Icon = Severity switch + { + Severity.Normal => NormalIcon, + Severity.Info => InfoIcon, + Severity.Success => SuccessIcon, + Severity.Warning => WarningIcon, + Severity.Error => ErrorIcon, + _ => throw new ArgumentOutOfRangeException(nameof(Severity)), + }; + } + } +} diff --git a/Components/Snackbar/SnackbarProvider.razor b/Components/Snackbar/SnackbarProvider.razor new file mode 100644 index 0000000..1d8e552 --- /dev/null +++ b/Components/Snackbar/SnackbarProvider.razor @@ -0,0 +1,17 @@ +@* + Copyright (c) Alessandro Ghidini. All rights reserved. + Changes and improvements Copyright (c) The MudBlazor Team. +*@ + +@namespace Connected.Components +@inherits UIComponent + +
    + @if (Snackbar != null) + { + @foreach (var snackbar in Snackbar) + { + + } + } +
    diff --git a/Components/Snackbar/SnackbarProvider.razor.cs b/Components/Snackbar/SnackbarProvider.razor.cs new file mode 100644 index 0000000..411a24a --- /dev/null +++ b/Components/Snackbar/SnackbarProvider.razor.cs @@ -0,0 +1,53 @@ +// Copyright (c) Alessandro Ghidini. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Changes and improvements Copyright (c) The MudBlazor Team + +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class SnackbarProvider : UIComponent, IDisposable +{ + [Inject] private ISnackbar Snackbars { get; set; } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + protected IEnumerable Snackbar => Snackbars.Configuration.NewestOnTop + ? Snackbars.ShownSnackbars.Reverse() + : Snackbars.ShownSnackbars; + + protected string Classname => + new CssBuilder(Class) + .AddClass(GetPositionClass()) + .Build(); + + private string GetPositionClass() + { + var positionClass = Snackbars.Configuration.PositionClass; + return positionClass switch + { + Defaults.Classes.Position.BottomStart => RightToLeft ? Defaults.Classes.Position.BottomRight : Defaults.Classes.Position.BottomLeft, + Defaults.Classes.Position.BottomEnd => RightToLeft ? Defaults.Classes.Position.BottomLeft : Defaults.Classes.Position.BottomRight, + Defaults.Classes.Position.TopStart => RightToLeft ? Defaults.Classes.Position.TopRight : Defaults.Classes.Position.TopLeft, + Defaults.Classes.Position.TopEnd => RightToLeft ? Defaults.Classes.Position.TopLeft : Defaults.Classes.Position.TopRight, + _ => positionClass + }; + } + + protected override void OnInitialized() + { + base.OnInitialized(); + Snackbars.OnSnackbarsUpdated += OnSnackbarsUpdated; + } + + private void OnSnackbarsUpdated() + { + InvokeAsync(StateHasChanged); + } + + public void Dispose() + { + Snackbars.OnSnackbarsUpdated -= OnSnackbarsUpdated; + } +} diff --git a/Components/Snackbar/SnackbarService.cs b/Components/Snackbar/SnackbarService.cs new file mode 100644 index 0000000..5460866 --- /dev/null +++ b/Components/Snackbar/SnackbarService.cs @@ -0,0 +1,227 @@ +//Copyright (c) 2019 Alessandro Ghidini.All rights reserved. +//Copyright (c) 2020 Jonny Larson and Meinrad Recheis + +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; + +namespace Connected.Components; + +/// +public class SnackbarService : ISnackbar, IDisposable +{ + public SnackbarConfiguration Configuration { get; } + public event Action OnSnackbarsUpdated; + + private NavigationManager _navigationManager; + private ReaderWriterLockSlim SnackBarLock { get; } + private IList SnackBarList { get; } + + public SnackbarService(NavigationManager navigationManager, SnackbarConfiguration configuration = null) + { + _navigationManager = navigationManager; + configuration ??= new SnackbarConfiguration(); + + Configuration = configuration; + Configuration.OnUpdate += ConfigurationUpdated; + navigationManager.LocationChanged += NavigationManager_LocationChanged; + + SnackBarLock = new ReaderWriterLockSlim(); + SnackBarList = new List(); + } + + public IEnumerable ShownSnackbars + { + get + { + SnackBarLock.EnterReadLock(); + try + { + return SnackBarList.Take(Configuration.MaxDisplayedSnackbars); + } + finally + { + SnackBarLock.ExitReadLock(); + } + } + } + + private Snackbar Add(SnackbarMessage message, Severity severity = Severity.Normal, Action configure = null) + { + var options = new SnackbarOptions(severity, Configuration); + configure?.Invoke(options); + + var snackbar = new Snackbar(message, options); + + SnackBarLock.EnterWriteLock(); + try + { + if (ResolvePreventDuplicates(options) && SnackbarAlreadyPresent(snackbar)) return null; + snackbar.OnClose += Remove; + SnackBarList.Add(snackbar); + } + finally + { + SnackBarLock.ExitWriteLock(); + } + + OnSnackbarsUpdated?.Invoke(); + + return snackbar; + } + + /// + /// Displays a snackbar containing a custom component specified by T. + /// + /// The type of the custom component that specifies the content of the snackbar. + /// Any additional parameters needed by the custom component to display the message. + /// The severity of the snackbar. Dictates the color and default icon of the notification. + /// Additional configuration for the snackbar. + /// If a key is provided, this message will not be shown while any other message with the same key is being shown. + /// The snackbar created by the parameters. + public Snackbar Add(Dictionary componentParameters = null, Severity severity = Severity.Normal, Action configure = null, string key = "") where T : IComponent + { + var type = typeof(T); + var message = new SnackbarMessage(type, componentParameters, key); + + return Add(message, severity, configure); + } + + /// + /// Displays a snackbar containing the RenderFragment. + /// + /// The RenderFragment which specifies the content of the snackbar. + /// The severity of the snackbar. Dictates the color and default icon of the notification. + /// Additional configuration for the snackbar. + /// If a key is provided, this message will not be shown while any other message with the same key is being shown. + /// The snackbar created by the parameters. + public Snackbar Add(RenderFragment message, Severity severity = Severity.Normal, Action configure = null, string key = "") + { + if (message == null) return null; + + var componentParams = new Dictionary() + { + { "Message", message as object } + }; + + return Add + ( + new SnackbarMessage(typeof(SnackbarMessageRenderFragment), componentParams, key), + severity, + configure + ); + } + + /// + /// Displays a snackbar containing the text. + /// + /// The string which specifies the content of the snackbar. + /// The severity of the snackbar. Dictates the color and default icon of the notification. + /// Additional configuration for the snackbar. + /// If no key is passed, defaults to the content of the message. This message will not be shown while any other message with the same key is being shown. + /// The snackbar created by the parameters. + public Snackbar Add(string message, Severity severity = Severity.Normal, Action configure = null, string key = "") + { + if (message.IsEmpty()) return null; + message = message.Trimmed(); + + var componentParams = new Dictionary() { { "Message", new MarkupString(message) } }; + + return Add + ( + new SnackbarMessage(typeof(SnackbarMessageText), componentParams, string.IsNullOrEmpty(key) ? message : key) { Text = message }, + severity, + configure + ); + } + + [Obsolete("Use Add instead.", true)] + [ExcludeFromCodeCoverage] + public Snackbar AddNew(Severity severity, string message, Action configure) + { + return Add(message, severity, configure); + } + + public void Clear() + { + SnackBarLock.EnterWriteLock(); + try + { + RemoveAllSnackbars(SnackBarList); + } + finally + { + SnackBarLock.ExitWriteLock(); + } + + OnSnackbarsUpdated?.Invoke(); + } + + public void Remove(Snackbar snackbar) + { + snackbar.OnClose -= Remove; + snackbar.Dispose(); + + SnackBarLock.EnterWriteLock(); + try + { + var index = SnackBarList.IndexOf(snackbar); + if (index < 0) return; + SnackBarList.RemoveAt(index); + } + finally + { + SnackBarLock.ExitWriteLock(); + } + + OnSnackbarsUpdated?.Invoke(); + } + + private bool ResolvePreventDuplicates(SnackbarOptions options) + { + return options.DuplicatesBehavior == SnackbarDuplicatesBehavior.Prevent + || (options.DuplicatesBehavior == SnackbarDuplicatesBehavior.GlobalDefault && Configuration.PreventDuplicates); + } + + private bool SnackbarAlreadyPresent(Snackbar newSnackbar) + { + return !string.IsNullOrEmpty(newSnackbar.SnackbarMessage.Key) && SnackBarList.Any(snackbar => newSnackbar.SnackbarMessage.Key == snackbar.SnackbarMessage.Key); + } + + private void ConfigurationUpdated() + { + OnSnackbarsUpdated?.Invoke(); + } + + private void NavigationManager_LocationChanged(object sender, LocationChangedEventArgs e) + { + if (Configuration.ClearAfterNavigation) + { + Clear(); + } + else + { + ShownSnackbars.Where(s => s.State.Options.CloseAfterNavigation).ToList().ForEach(s => Remove(s)); + } + } + + public void Dispose() + { + Configuration.OnUpdate -= ConfigurationUpdated; + _navigationManager.LocationChanged -= NavigationManager_LocationChanged; + RemoveAllSnackbars(SnackBarList); + } + + private void RemoveAllSnackbars(IEnumerable snackbars) + { + if (SnackBarList.Count == 0) return; + + foreach (var snackbar in snackbars) + { + snackbar.OnClose -= Remove; + snackbar.Dispose(); + } + + SnackBarList.Clear(); + } +} diff --git a/Components/Snackbar/SnackbarState.cs b/Components/Snackbar/SnackbarState.cs new file mode 100644 index 0000000..69c817e --- /dev/null +++ b/Components/Snackbar/SnackbarState.cs @@ -0,0 +1,19 @@ +// Copyright (c) A//Copyright(c) Alessandro Ghidini.All rights reserved. +//Changes and improvements Copyright (c) The MudBlazor Team. + +namespace Connected.Components; + +internal enum SnackbarState +{ + Init, + Showing, + Hiding, + Visible +} + +internal static class SnackbarStateExtensions +{ + public static bool IsShowing(this SnackbarState state) => state == SnackbarState.Showing; + public static bool IsVisible(this SnackbarState state) => state == SnackbarState.Visible; + public static bool IsHiding(this SnackbarState state) => state == SnackbarState.Hiding; +} diff --git a/Components/Spacer/Spacer.razor b/Components/Spacer/Spacer.razor new file mode 100644 index 0000000..ebddb0a --- /dev/null +++ b/Components/Spacer/Spacer.razor @@ -0,0 +1,3 @@ +@namespace Connected.Components + +
    \ No newline at end of file diff --git a/Components/Sparkline/SparkLine.razor b/Components/Sparkline/SparkLine.razor new file mode 100644 index 0000000..b125988 --- /dev/null +++ b/Components/Sparkline/SparkLine.razor @@ -0,0 +1,20 @@ +@namespace Connected.Components +@using Connected.Utilities +@inherits UIComponent; + + + + + + + + + + + +@code { + + [Parameter] public int StrokeWidth { get; set; } = 2; + + public string StaticSparkLine { get; set; } = "M1 74L15.688473556373268 63.92508726536008S22.285714285714285 59.4 27.861539803229217 53.66326139708028L37.99560305391364 43.23673860291972S43.57142857142857 37.5 48.28394541736507 31.035312461010605L60.14462601120636 14.76468753898939S64.85714285714286 8.299999999999997 69.56965970307935 14.764687538989392L81.43034029692065 31.035312461010605S86.14285714285714 37.5 90.17298445189184 30.58927833920561L103.39844411953672 7.910721660794391S107.42857142857142 1 110.50476151148447 8.384920756093958L125.63809563137266 44.71507924390605S128.71428571428572 52.1 135.31152644362675 47.574912734639916L143.40275927065898 42.025087265360085S150 37.5 154.0301273090347 44.410721660794394L167.25558697667958 67.0892783392056S171.28571428571428 74 179.28571428571428 74L184.57142857142856 74S192.57142857142856 74 200.1387735214474 71.40475619499354L206.28979790712398 69.29524380500646S213.85714285714283 66.7 216.9333329400559 59.31507924390604L232.06666705994408 22.98492075609396S235.14285714285714 15.600000000000001 238.63960783972632 22.79532727288654L252.93182073170226 52.20467272711346S256.42857142857144 59.4 259.5047615114845 52.01507924390604L274.63809563137266 15.684920756093957S277.7142857142857 8.299999999999997 280.17997601927675 15.910543431311153L299 74"; +} diff --git a/Components/Stack/Stack.razor b/Components/Stack/Stack.razor new file mode 100644 index 0000000..bbe100c --- /dev/null +++ b/Components/Stack/Stack.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent; + +
    + @ChildContent +
    \ No newline at end of file diff --git a/Components/Stack/Stack.razor.cs b/Components/Stack/Stack.razor.cs new file mode 100644 index 0000000..c76a188 --- /dev/null +++ b/Components/Stack/Stack.razor.cs @@ -0,0 +1,65 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Stack : UIComponent +{ + protected string Classname => + new CssBuilder("d-flex") + .AddClass($"flex-{(Row ? "row" : "column")}{(Reverse ? "-reverse" : string.Empty)}") + .AddClass($"justify-{Justify?.ToDescriptionString()}", Justify != null) + .AddClass($"align-{AlignItems?.ToDescriptionString()}", AlignItems != null) + .AddClass($"gap-{Spacing}") + .AddClass(Class) + .Build(); + + /// + /// If true, items will be placed horizontally in a row instead of vertically. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public bool Row { get; set; } + + /// + /// Reverses the order of its items. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public bool Reverse { get; set; } + + /// + /// Defines the spacing between its items. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public int Spacing { get; set; } = 3; + + /// + /// Defines the spacing between its items. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public Justify? Justify { get; set; } + + /// + /// Defines the spacing between its items. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public AlignItems? AlignItems { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Stack.Behavior)] + public RenderFragment ChildContent { get; set; } +} + diff --git a/Components/SwipeArea/SwipeArea.razor b/Components/SwipeArea/SwipeArea.razor new file mode 100644 index 0000000..59a5bf2 --- /dev/null +++ b/Components/SwipeArea/SwipeArea.razor @@ -0,0 +1,9 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @ChildContent +
    \ No newline at end of file diff --git a/Components/SwipeArea/SwipeArea.razor.cs b/Components/SwipeArea/SwipeArea.razor.cs new file mode 100644 index 0000000..d921352 --- /dev/null +++ b/Components/SwipeArea/SwipeArea.razor.cs @@ -0,0 +1,132 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class SwipeArea : UIComponent +{ + internal double? _xDown, _yDown; + private double? _swipeDelta; + internal ElementReference _componentRef; + private static readonly string[] _preventDefaultEventNames = { "touchstart", "touchend", "touchcancel" }; + internal int[] _listenerIds; + + [Parameter] + [Category(CategoryTypes.SwipeArea.Behavior)] + public RenderFragment ChildContent { get; set; } + + [Parameter] + [Category(CategoryTypes.SwipeArea.Behavior)] + public Action OnSwipe { get; set; } + + /// + /// Swipe threshold in pixels. If SwipeDelta is below Sensitivity then OnSwipe is not called. + /// + [Parameter] + [Category(CategoryTypes.SwipeArea.Behavior)] + public int Sensitivity { get; set; } = 100; + + /// + /// Prevents default behavior of the browser when swiping. + /// Usable espacially when swiping up/down - this will prevent the whole page from scrolling up/down. + /// + [Parameter] + [Category(CategoryTypes.SwipeArea.Behavior)] + public bool PreventDefault { get; set; } + + private bool _preventDefaultChanged; + + public override async Task SetParametersAsync(ParameterView parameters) + { + var preventDefault = parameters.GetValueOrDefault(nameof(PreventDefault)); + if (preventDefault != PreventDefault) + { + _preventDefaultChanged = true; + } + + await base.SetParametersAsync(parameters); + } + + private async Task SetPreventDefaultInternal(bool value) + { + if (value) + { + _listenerIds = await _componentRef.AddDefaultPreventingHandlers(_preventDefaultEventNames); + } + else + { + if (_listenerIds != null) + { + await _componentRef.RemoveDefaultPreventingHandlers(_preventDefaultEventNames, _listenerIds); + _listenerIds = null; + } + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (_preventDefaultChanged) + { + _preventDefaultChanged = false; + await SetPreventDefaultInternal(PreventDefault); + } + } + + private void OnTouchStart(TouchEventArgs arg) + { + _xDown = arg.Touches[0].ClientX; + _yDown = arg.Touches[0].ClientY; + } + + internal void OnTouchEnd(TouchEventArgs arg) + { + if (_xDown == null || _yDown == null) + return; + + var xDiff = _xDown.Value - arg.ChangedTouches[0].ClientX; + var yDiff = _yDown.Value - arg.ChangedTouches[0].ClientY; + + if (Math.Abs(xDiff) < Sensitivity && Math.Abs(yDiff) < Sensitivity) + { + _xDown = _yDown = null; + return; + } + + if (Math.Abs(xDiff) > Math.Abs(yDiff)) + { + if (xDiff > 0) + { + InvokeAsync(() => OnSwipe(SwipeDirection.RightToLeft)); + } + else + { + InvokeAsync(() => OnSwipe(SwipeDirection.LeftToRight)); + } + _swipeDelta = xDiff; + } + else + { + if (yDiff > 0) + { + InvokeAsync(() => OnSwipe(SwipeDirection.BottomToTop)); + } + else + { + InvokeAsync(() => OnSwipe(SwipeDirection.TopToBottom)); + } + _swipeDelta = yDiff; + } + _xDown = _yDown = null; + } + + /// + /// The last successful swipe difference in pixels since the last OnSwipe invocation + /// + public double? GetSwipeDelta() => _swipeDelta; + + internal void OnTouchCancel(TouchEventArgs arg) + { + _xDown = _yDown = null; + } +} diff --git a/Components/Switch/Switch.razor b/Components/Switch/Switch.razor new file mode 100644 index 0000000..529204f --- /dev/null +++ b/Components/Switch/Switch.razor @@ -0,0 +1,39 @@ +@namespace Connected.Components +@using Connected.Annotations; +@inherits BooleanInput +@typeparam T + + + +@code +{ + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public RenderFragment ChildContent { get; set; } +} + diff --git a/Components/Switch/Switch.razor.cs b/Components/Switch/Switch.razor.cs new file mode 100644 index 0000000..f916808 --- /dev/null +++ b/Components/Switch/Switch.razor.cs @@ -0,0 +1,168 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Switch : BooleanInput +{ + protected string Classname => + new CssBuilder("mud-switch") + .AddClass($"mud-disabled", Disabled) + .AddClass($"mud-readonly", ReadOnly) + .AddClass(LabelPosition == LabelPosition.End ? "mud-ltr" : "mud-rtl", true) + .AddClass(Class) + .Build(); + + protected string SwitchClassname => + new CssBuilder("mud-button-root mud-icon-button mud-switch-base") + .AddClass($"mud-ripple mud-ripple-switch", !DisableRipple && !ReadOnly && !Disabled) + .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", BoolValue == true) + .AddClass($"mud-{UnCheckedColor.ToDescriptionString()}-text hover:mud-{UnCheckedColor.ToDescriptionString()}-hover", BoolValue == false) + .AddClass($"mud-switch-disabled", Disabled) + .AddClass($"mud-readonly", ReadOnly) + .AddClass($"mud-checked", BoolValue) + .Build(); + + protected string TrackClassname => + new CssBuilder("mud-switch-track") + .AddClass($"mud-{Color.ToDescriptionString()}", BoolValue == true) + .AddClass($"mud-{UnCheckedColor.ToDescriptionString()}", BoolValue == false) + .Build(); + + //Excluded because not used + [ExcludeFromCodeCoverage] + protected string SpanClassname => + new CssBuilder("mud-switch-span mud-flip-x-rtl") + .Build(); + + private IKeyInterceptor _keyInterceptor; + [Inject] private IKeyInterceptorFactory KeyInterceptorFactory { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The base color of the component in its none active/unchecked state. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Radio.Appearance)] + public ThemeColor UnCheckedColor { get; set; } = ThemeColor.Default; + + /// + /// The text/label will be displayed next to the switch if set. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Label { get; set; } + + /// + /// The position of the text/label. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public LabelPosition LabelPosition { get; set; } = LabelPosition.End; + + /// + /// Shows an icon on Switch's thumb. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string ThumbIcon { get; set; } + + /// + /// The color of the thumb icon. Supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ThemeColor ThumbIconColor { get; set; } = ThemeColor.Default; + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public bool DisableRipple { get; set; } + + protected internal void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + switch (obj.Key) + { + case "ArrowLeft": + case "Delete": + SetBoolValueAsync(false); + break; + case "ArrowRight": + case "Enter": + case "NumpadEnter": + SetBoolValueAsync(true); + break; + case " ": + if (BoolValue == true) + { + SetBoolValueAsync(false); + } + else + { + SetBoolValueAsync(true); + } + break; + } + } + + private string _elementId = "switch_" + Guid.NewGuid().ToString().Substring(0, 8); + + protected override void OnInitialized() + { + base.OnInitialized(); + + if (Label == null && For != null) + Label = For.GetLabelString(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _keyInterceptor = KeyInterceptorFactory.Create(); + + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-switch-base", + Keys = { + new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead increment + new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead decrement + new KeyOptions { Key=" ", PreventDown = "key+none", PreventUp = "key+none" }, + }, + }); + + _keyInterceptor.KeyDown += HandleKeyDown; + } + await base.OnAfterRenderAsync(firstRender); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.Dispose(); + } + } + } +} diff --git a/Components/Table/AvatarColumn.razor b/Components/Table/AvatarColumn.razor new file mode 100644 index 0000000..08d7060 --- /dev/null +++ b/Components/Table/AvatarColumn.razor @@ -0,0 +1,24 @@ +@typeparam T +@namespace Connected.Components +@inherits ColumnBase +@if (Visible) +{ + @if (Mode == Rendermode.Header) + { + @HeaderText + } + else if (Mode is Rendermode.Item or Rendermode.Edit) + { + @Value.ToString() + } + else if (Mode == Rendermode.Footer) + { + + } +} + +@code { + + [Parameter] + public T Value { get; set; } +} diff --git a/Components/Table/EditButtonContext.cs b/Components/Table/EditButtonContext.cs new file mode 100644 index 0000000..9c03c02 --- /dev/null +++ b/Components/Table/EditButtonContext.cs @@ -0,0 +1,17 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class EditButtonContext +{ + public Action ButtonAction { get; } + public bool ButtonDisabled { get; } + + public EditButtonContext(Action buttonAction, bool buttonDisabled) + { + ButtonAction = buttonAction; + ButtonDisabled = buttonDisabled; + } +} diff --git a/Components/Table/SortableColumn.razor b/Components/Table/SortableColumn.razor new file mode 100644 index 0000000..31cb0f0 --- /dev/null +++ b/Components/Table/SortableColumn.razor @@ -0,0 +1,45 @@ +@namespace Connected.Components +@typeparam T +@typeparam ModelType +@inherits ColumnBase +@if (Visible) +{ + if (Mode == Rendermode.Header) + { + if (SortLabel != null) + { + @HeaderText + } + else if (SortBy != null) + { + @HeaderText + } + else + { + @HeaderText + } + } + else if (Mode == Rendermode.Item || (ReadOnly && Mode == Rendermode.Edit)) + { + @GetFormattedString(Value) + } + else if (Mode == Rendermode.Edit) + { + + } + else if (Mode == Rendermode.Footer) + { + @if (_footerValueAvailable) + { + + @GetFormattedString(FooterValue) + + } + else + { + + @FooterText + + } + } +} \ No newline at end of file diff --git a/Components/Table/SortableColumn.razor.cs b/Components/Table/SortableColumn.razor.cs new file mode 100644 index 0000000..e9ddbfc --- /dev/null +++ b/Components/Table/SortableColumn.razor.cs @@ -0,0 +1,70 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +/// +/// Binds an object's property to a column by its property name +/// +public partial class SortableColumn : ColumnBase +{ + T InternalValue + { + get => Value; + set + { + if (!EqualityComparer.Default.Equals(value, Value)) + { + Value = value; + ValueChanged.InvokeAsync(value); + } + } + } + + /// + /// Specifies the name of the object's property bound to the column + /// + [Parameter] public T Value { get; set; } + [Parameter] public EventCallback ValueChanged { get; set; } + + /// + /// Specifies the name of the object's property bound to the footer + /// + [Parameter] + public T FooterValue + { + get { return _footerValue; } + set { _footerValue = value; _footerValueAvailable = true; } + } + private T _footerValue; + private bool _footerValueAvailable = false; + + /// + /// Used if no FooterValue is available + /// + [Parameter] public string FooterText { get; set; } + + /// + /// Specifies which string format should be used. + /// + [Parameter] public string DataFormatString { get; set; } + + /// + /// Specifies if the column should be readonly even if the DataTable is in editmode. + /// + [Parameter] public bool ReadOnly { get; set; } + [Parameter] public string SortLabel { get; set; } + + [Parameter] public Func SortBy { get; set; } = default; + + private string GetFormattedString(T item) + { + if (DataFormatString != null) + { + return string.Format(DataFormatString, item); + } + else + { + return item?.ToString(); + } + } +} diff --git a/Components/Table/TFootRow.razor b/Components/Table/TFootRow.razor new file mode 100644 index 0000000..d602a82 --- /dev/null +++ b/Components/Table/TFootRow.razor @@ -0,0 +1,30 @@ +@namespace Connected.Components +@implements IDisposable +@inherits UIComponent + + + @if (Context.DisplayApplyButtonAtStart(IgnoreEditable) || Context.DisplayEditbuttonAtStart(IgnoreEditable)) + { + + } + @if (IsExpandable || ((Context?.Table.MultiSelection ?? false) && !IgnoreCheckbox)) + { + + @if (IsExpandable) + { +
    + } + @if (IsCheckable) + { + + } + + } + @ChildContent + @if (Context.DisplayApplyButtonAtEnd(IgnoreEditable) || Context.DisplayEditbuttonAtEnd(IgnoreEditable)) + { + + } + + + diff --git a/Components/Table/TFootRow.razor.cs b/Components/Table/TFootRow.razor.cs new file mode 100644 index 0000000..81b042e --- /dev/null +++ b/Components/Table/TFootRow.razor.cs @@ -0,0 +1,75 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class TFootRow : UIComponent +{ + protected string Classname => new CssBuilder("mud-table-row") + .AddClass(Class).Build(); + + [CascadingParameter] public TableContext Context { get; set; } + + [Parameter] public RenderFragment ChildContent { get; set; } + + /// + /// Add a multi-select checkbox that will select/unselect every item in the table + /// + [Parameter] public bool IsCheckable { get; set; } + + /// + /// Specify behavior in case the table is multi-select mode. If set to true, it won't render an additional empty column. + /// + [Parameter] public bool IgnoreCheckbox { get; set; } + + /// + /// Specify behavior in case the table is editable. If set to true, it won't render an additional empty column. + /// + [Parameter] public bool IgnoreEditable { get; set; } + + [Parameter] public bool IsExpandable { get; set; } + + /// + /// On click event + /// + [Parameter] public EventCallback OnRowClick { get; set; } + + private bool _checked; + public bool IsChecked + { + get => _checked; + set + { + if (value != _checked) + { + _checked = value; + if (IsCheckable) + Context.Table.OnHeaderCheckboxClicked(value); + } + } + } + + protected override Task OnInitializedAsync() + { + Context?.FooterRows.Add(this); + return base.OnInitializedAsync(); + } + + public void Dispose() + { + Context?.FooterRows.Remove(this); + } + + public void SetChecked(bool b, bool notify) + { + if (notify) + IsChecked = b; + else + { + _checked = b; + if (IsCheckable) + InvokeAsync(StateHasChanged); + } + } +} diff --git a/Components/Table/THeadRow.razor b/Components/Table/THeadRow.razor new file mode 100644 index 0000000..e8bf144 --- /dev/null +++ b/Components/Table/THeadRow.razor @@ -0,0 +1,32 @@ +@namespace Connected.Components +@implements IDisposable +@inherits UIComponent + + + + @if (Context.DisplayApplyButtonAtStart(IgnoreEditable) || Context.DisplayEditbuttonAtStart(IgnoreEditable)) + { + + } + + @if (IsExpandable || ((Context?.Table.MultiSelection ?? false) && !IgnoreCheckbox)) + { + + @if (IsExpandable) + { +
    + } + @if (IsCheckable) + { + + } + + } + @ChildContent + @if (Context.DisplayApplyButtonAtEnd(IgnoreEditable) || Context.DisplayEditbuttonAtEnd(IgnoreEditable)) + { + + } + + + diff --git a/Components/Table/THeadRow.razor.cs b/Components/Table/THeadRow.razor.cs new file mode 100644 index 0000000..61f6dd5 --- /dev/null +++ b/Components/Table/THeadRow.razor.cs @@ -0,0 +1,75 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class THeadRow : UIComponent +{ + protected string Classname => new CssBuilder("mud-table-row") + .AddClass(Class).Build(); + + [CascadingParameter] public TableContext Context { get; set; } + + [Parameter] public RenderFragment ChildContent { get; set; } + + /// + /// Add a multi-select checkbox that will select/unselect every item in the table + /// + [Parameter] public bool IsCheckable { get; set; } + + /// + /// Specify behavior in case the table is multi-select mode. If set to true, it won't render an additional empty column. + /// + [Parameter] public bool IgnoreCheckbox { get; set; } + + /// + /// Specify behavior in case the table is editable. If set to true, it won't render an additional empty column. + /// + [Parameter] public bool IgnoreEditable { get; set; } + + [Parameter] public bool IsExpandable { get; set; } + + /// + /// On click event + /// + [Parameter] public EventCallback OnRowClick { get; set; } + + private bool _checked; + public bool IsChecked + { + get => _checked; + set + { + if (value != _checked) + { + _checked = value; + if (IsCheckable) + Context.Table.OnHeaderCheckboxClicked(value); + } + } + } + + protected override Task OnInitializedAsync() + { + Context?.HeaderRows.Add(this); + return base.OnInitializedAsync(); + } + + public void Dispose() + { + Context?.HeaderRows.Remove(this); + } + + public void SetChecked(bool b, bool notify) + { + if (notify) + IsChecked = b; + else + { + _checked = b; + if (IsCheckable) + InvokeAsync(StateHasChanged); + } + } +} diff --git a/Components/Table/Table.razor b/Components/Table/Table.razor new file mode 100644 index 0000000..88e6949 --- /dev/null +++ b/Components/Table/Table.razor @@ -0,0 +1,246 @@ +@namespace Connected.Components +@using Connected.Utilities; +@inherits TableBase +@typeparam T +
    +@if (Items != null || ServerData != null) +{ + + @if (ToolBarContent != null) + { + + @ToolBarContent + + } + @if (Context.SortLabels.Any()) + { +
    + + + +
    + } +
    + + @if (ColGroup != null) + { + + @ColGroup + + } + @if (HeaderContent != null || Columns != null) + { + + @if (CustomHeader) + { + @HeaderContent + } + else + { + + @if (HeaderContent != null) + { + @HeaderContent + } + + @if (Columns != null) + { + + @Columns(Def) + + } + + } + + } + + @if (Loading) + { + + + + } + @if(GroupBy != null) + { + @foreach (var group in GroupItemsPage) + { + + } + } + else + { + @if (CurrentPageItems != null && CurrentPageItems.Count() > 0) + { + var rowIndex = 0; + + @{ var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, rowIndex)).Build(); } + @{ var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, rowIndex)).Build(); } + + + @if ((!ReadOnly) && IsEditable && object.Equals(_editingItem, item)) + { + + @if(RowEditingTemplate != null) + { + @RowEditingTemplate(item) + } + @if (Columns != null) + { + + @Columns(item) + + } + + } + else + { + if (RowTemplate != null) + { + @RowTemplate(item) + } + @if (Columns != null) + { + + @Columns(item) + + } + } + + @if (ChildRowContent != null) + { + @ChildRowContent(item) + } + @{ rowIndex++; } + + } + } + @if(!(CurrentPageItems != null && CurrentPageItems.Count() > 0) + && (Loading ? LoadingContent != null : NoRecordsContent != null) + ) + { + + + + } + + @if (FooterContent != null || Columns != null) + { + + @if (CustomFooter) + { + @FooterContent + } + else + { + + @if (@FooterContent != null) + { + @FooterContent + } + @if (Columns != null) + { + + @Columns(Def) + + } + + } + + } +
    + +
    +
    + @if(Loading) + { + @LoadingContent + } + else + { + @NoRecordsContent + } +
    +
    +
    + @if (PagerContent != null) + { +
    + @PagerContent +
    + } +
    +} +
    +@code +{ + // moved to code to avoid repeatedly code on markup block + internal RenderFragment RenderRows(IEnumerable source, string customClass = null, bool isExpandable = false) + { + var rowIndex = 0; + + RenderFragment rootNode = + @ + + + ; + + RenderFragment child() => item => + @ + @{ + var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, rowIndex)).AddClass(customClass, ! string.IsNullOrEmpty("mud-table-row-group-indented-1")).Build(); + var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, rowIndex)).Build(); + } + + + @if ((!ReadOnly) && IsEditable && object.Equals(_editingItem, item)) + { + + @if(RowEditingTemplate != null) + { + @RowEditingTemplate(item) + } + @if (Columns != null) + { + + @Columns(item) + + } + + } + else + { + if (RowTemplate != null) + { + @RowTemplate(item) + } + @if (Columns != null) + { + + @Columns(item) + + } + } + + @if (ChildRowContent != null) + { + @ChildRowContent(item) + } + @{rowIndex++;} + + ; + + + return rootNode; + } +} \ No newline at end of file diff --git a/Components/Table/Table.razor.cs b/Components/Table/Table.razor.cs new file mode 100644 index 0000000..d09ab9b --- /dev/null +++ b/Components/Table/Table.razor.cs @@ -0,0 +1,577 @@ +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Connected.Annotations; +using Connected.Extensions; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +// note: the MudTable code is split. Everything depending on the type parameter T of MudTable is here in MudTable + +public partial class Table<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : TableBase +{ + /// + /// Defines how a table row looks like. Use MudTd to define the table cells and their content. + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public RenderFragment RowTemplate { get; set; } + + /// + /// Row Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public RenderFragment ChildRowContent { get; set; } + + /// + /// Defines how a table row looks like in edit mode (for selected row). Use MudTd to define the table cells and their content. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public RenderFragment RowEditingTemplate { get; set; } + + #region Code for column based approach + /// + /// Defines how a table column looks like. Columns components should inherit from MudBaseColumn + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public RenderFragment Columns { get; set; } + /// + /// Comma separated list of columns to show if there is no templates defined + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public string QuickColumns { get; set; } + + // Workaround because "where T : new()" didn't work with Blazor components + // T must have a default constructor, otherwise we cannot show headers when Items collection + // is empty + protected T Def + { + get + { + T t1 = default; + if (t1 == null) + { + return Activator.CreateInstance(); + } + else + { + return default; + } + } + } + /// + /// Creates a default Column renderfragment if there is no templates defined + /// + protected override void OnInitialized() + { + if (Columns == null && RowTemplate == null && RowEditingTemplate == null) + { + string[] quickcolumnslist = null; + if (!QuickColumns.IsEmpty()) + { + quickcolumnslist = QuickColumns.Split(","); + } + // Create template from T + Columns = context => builder => + { + var myType = context.GetType(); + IList propertylist = new List(myType.GetProperties().Where(p => p.PropertyType.IsPublic)); + + if (quickcolumnslist == null) + { + foreach (var propinfo in propertylist) + { + BuildMudColumnTemplateItem(context, builder, propinfo); + } + } + else + { + foreach (var colname in quickcolumnslist) + { + var propinfo = propertylist.SingleOrDefault(pl => pl.Name == colname); + if (propinfo != null) + { + BuildMudColumnTemplateItem(context, builder, propinfo); + } + } + } + + }; + } + } + + private static void BuildMudColumnTemplateItem(T context, RenderTreeBuilder builder, PropertyInfo propinfo) + { + if (propinfo.PropertyType.IsPrimitive || propinfo.PropertyType == typeof(string)) + { + builder.OpenComponent>(0); + builder.AddAttribute(1, "Value", propinfo.GetValue(context)?.ToString()); + builder.AddAttribute(2, "HeaderText", propinfo.Name); + builder.CloseComponent(); + } + } + #endregion + /// + /// Defines the table body content when there are no matching records found + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public RenderFragment NoRecordsContent { get; set; } + + /// + /// Defines the table body content the table has no rows and is loading + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public RenderFragment LoadingContent { get; set; } + + /// + /// Defines if the table has a horizontal scrollbar. + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public bool HorizontalScrollbar { get; set; } + + internal string GetHorizontalScrollbarStyle() => HorizontalScrollbar ? ";display: block; overflow-x: auto;" : string.Empty; + + /// + /// The data to display in the table. MudTable will render one row per item + /// + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public IEnumerable Items + { + get => _items; + set + { + if (_items == value) + return; + _items = value; + if (Context?.PagerStateHasChanged != null) + InvokeAsync(Context.PagerStateHasChanged); + } + } + + /// + /// A function that returns whether or not an item should be displayed in the table. You can use this to implement your own search function. + /// + [Parameter] + [Category(CategoryTypes.Table.Filtering)] + public Func Filter { get; set; } = null; + + /// + /// Button click event. + /// + [Parameter] public EventCallback> OnRowClick { get; set; } + + internal override void FireRowClickEvent(MouseEventArgs args, Tr row, object o) + { + var item = default(T); + try + { + item = (T)o; + } + catch (Exception) { /*ignore*/} + OnRowClick.InvokeAsync(new TableRowClickEventArgs() + { + MouseEventArgs = args, + Row = row, + Item = item, + }); + } + + /// + /// Returns the class that will get joined with RowClass. Takes the current item and row index. + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public Func RowClassFunc { get; set; } + + /// + /// Returns the style that will get joined with RowStyle. Takes the current item and row index. + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public Func RowStyleFunc { get; set; } + + /// + /// Returns the item which was last clicked on in single selection mode (that is, if MultiSelection is false) + /// + [Parameter] + [Category(CategoryTypes.Table.Selecting)] + public T SelectedItem + { + get => _selectedItem; + set + { + if (_comparer != null && _comparer.Equals(SelectedItem, value)) + return; + else if (EqualityComparer.Default.Equals(SelectedItem, value)) + return; + _selectedItem = value; + SelectedItemChanged.InvokeAsync(value); + } + } + private T _selectedItem; + + /// + /// Callback is called when a row has been clicked and returns the selected item. + /// + [Parameter] public EventCallback SelectedItemChanged { get; set; } + + /// + /// If MultiSelection is true, this returns the currently selected items. You can bind this property and the initial content of the HashSet you bind it to will cause these rows to be selected initially. + /// + [Parameter] + [Category(CategoryTypes.Table.Selecting)] + public HashSet SelectedItems + { + get + { + if (!MultiSelection) + if (_selectedItem is null) + return new HashSet(Array.Empty(), _comparer); + else + return new HashSet(new T[] { _selectedItem }, _comparer); + else + return Context.Selection; + } + set + { + if (value == Context.Selection) + return; + if (value == null) + { + if (Context.Selection.Count == 0) + return; + Context.Selection = new HashSet(_comparer); + } + else + Context.Selection = value; + SelectedItemsChanged.InvokeAsync(Context.Selection); + InvokeAsync(StateHasChanged); + } + } + + /// + /// The Comparer to use for comparing selected items internally. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public IEqualityComparer Comparer + { + get => _comparer; + set + { + if (value == _comparer) return; + _comparer = value; + // Apply comparer and (selected values are refreshed in the Context.Comparer setter) + Context.Comparer = _comparer; + } + } + + private IEqualityComparer _comparer; + + /// + /// Callback is called whenever items are selected or deselected in multi selection mode. + /// + [Parameter] public EventCallback> SelectedItemsChanged { get; set; } + + private TableGroupDefinition _groupBy; + /// + /// Defines data grouping parameters. It can has N hierarchical levels + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public TableGroupDefinition GroupBy + { + get => _groupBy; + set + { + _groupBy = value; + if (_groupBy != null) + _groupBy.Context = Context; + } + } + + /// + /// Defines how a table grouping row header looks like. It works only when GroupBy is not null. Use MudTd to define the table cells and their content. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public RenderFragment> GroupHeaderTemplate { get; set; } + + /// + /// Defines custom CSS classes for using on Group Header's MudTr. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public string GroupHeaderClass { get; set; } + + /// + /// Defines custom styles for using on Group Header's MudTr. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public string GroupHeaderStyle { get; set; } + + /// + /// Defines custom CSS classes for using on Group Footer's MudTr. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public string GroupFooterClass { get; set; } + + /// + /// Defines custom styles for using on Group Footer's MudTr. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public string GroupFooterStyle { get; set; } + + /// + /// Defines how a table grouping row footer looks like. It works only when GroupBy is not null. Use MudTd to define the table cells and their content. + /// + [Parameter] + [Category(CategoryTypes.Table.Grouping)] + public RenderFragment> GroupFooterTemplate { get; set; } + + private IEnumerable _preEditSort { get; set; } = null; + private bool _hasPreEditSort => _preEditSort != null; + + public IEnumerable FilteredItems + { + get + { + if (IsEditing && _hasPreEditSort) + return _preEditSort; + if (ServerData != null) + { + _preEditSort = _server_data.Items.ToList(); + return _preEditSort; + } + + if (Filter == null) + { + _preEditSort = Context.Sort(Items).ToList(); + return _preEditSort; + } + _preEditSort = Context.Sort(Items.Where(Filter)).ToList(); + return _preEditSort; + } + } + + protected IEnumerable CurrentPageItems + { + get + { + if (@PagerContent == null) + return FilteredItems; // we have no pagination + if (ServerData == null) + { + var filteredItemCount = GetFilteredItemsCount(); + int lastPageNo; + if (filteredItemCount == 0) + lastPageNo = 0; + else + lastPageNo = (filteredItemCount / RowsPerPage) - (filteredItemCount % RowsPerPage == 0 ? 1 : 0); + CurrentPage = lastPageNo < CurrentPage ? lastPageNo : CurrentPage; + } + + return GetItemsOfPage(CurrentPage, RowsPerPage); + } + } + + protected IEnumerable GetItemsOfPage(int n, int pageSize) + { + if (n < 0 || pageSize <= 0) + return Array.Empty(); + + if (ServerData != null) + return _server_data.Items; + + return FilteredItems.Skip(n * pageSize).Take(pageSize); + } + + protected override int NumPages + { + get + { + if (ServerData != null) + return (int)Math.Ceiling(_server_data.TotalItems / (double)RowsPerPage); + + return (int)Math.Ceiling(FilteredItems.Count() / (double)RowsPerPage); + } + } + + public override int GetFilteredItemsCount() + { + if (ServerData != null) + return _server_data.TotalItems; + return FilteredItems.Count(); + } + + public override void SetSelectedItem(object item) + { + SelectedItem = item.As(); + } + + public override void SetEditingItem(object item) + { + if (!ReferenceEquals(_editingItem, item)) + _editingItem = item; + } + + public override bool ContainsItem(object item) + { + var t = item.As(); + if (t is null) + return false; + return FilteredItems?.Contains(t) ?? false; + } + + public override void UpdateSelection() => SelectedItemsChanged.InvokeAsync(SelectedItems); + + public override TableContext TableContext + { + get + { + Context.Table = this; + Context.TableStateHasChanged = this.StateHasChanged; + return Context; + } + } + + // TableContext provides shared functionality between all table sub-components + public TableContext Context { get; } = new TableContext(); + + private void OnRowCheckboxChanged(bool value, T item) + { + if (value) + Context.Selection.Add(item); + else + Context.Selection.Remove(item); + SelectedItemsChanged.InvokeAsync(SelectedItems); + } + + internal override void OnHeaderCheckboxClicked(bool value) + { + if (!value) + Context.Selection.Clear(); + else + { + foreach (var item in FilteredItems) + Context.Selection.Add(item); + } + Context.UpdateRowCheckBoxes(false); + SelectedItemsChanged.InvokeAsync(SelectedItems); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await InvokeServerLoadFunc(); + + TableContext.UpdateRowCheckBoxes(); + await base.OnAfterRenderAsync(firstRender); + } + + /// + /// Supply an async function which (re)loads filtered, paginated and sorted data from server. + /// Table will await this func and update based on the returned TableData. + /// Used only with ServerData + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public Func>> ServerData { get; set; } + + internal override bool HasServerData => ServerData != null; + + + TableData _server_data = new() { TotalItems = 0, Items = Array.Empty() }; + private IEnumerable _items; + + internal override async Task InvokeServerLoadFunc() + { + if (ServerData == null) + return; + + Loading = true; + var label = Context.CurrentSortLabel; + + var state = new TableState + { + Page = CurrentPage, + PageSize = RowsPerPage, + SortDirection = Context.SortDirection, + SortLabel = label?.SortLabel + }; + + _server_data = await ServerData(state); + + if (CurrentPage * RowsPerPage > _server_data.TotalItems) + CurrentPage = 0; + + Loading = false; + StateHasChanged(); + Context?.PagerStateHasChanged?.Invoke(); + } + + protected override void OnAfterRender(bool firstRender) + { + base.OnAfterRender(firstRender); + if (!firstRender) + Context?.PagerStateHasChanged?.Invoke(); + } + + /// + /// Call this to reload the server-filtered, -sorted and -paginated items + /// + public Task ReloadServerData() + { + return InvokeServerLoadFunc(); + } + + internal override bool IsEditable { get => (RowEditingTemplate != null) || (Columns != null); } + + //GROUPING: + private IEnumerable> GroupItemsPage + { + get + { + return GetItemsOfGroup(GroupBy, CurrentPageItems); + } + } + + internal IEnumerable> GetItemsOfGroup(TableGroupDefinition parent, IEnumerable sourceList) + { + if (parent == null || sourceList == null) + return new List>(); + + return sourceList.GroupBy(parent.Selector).ToList(); + } + + internal void OnGroupHeaderCheckboxClicked(bool value, IEnumerable items) + { + if (value) + { + foreach (var item in items) + Context.Selection.Add(item); + } + else + { + foreach (var item in items) + Context.Selection.Remove(item); + } + + Context.UpdateRowCheckBoxes(false); + SelectedItemsChanged.InvokeAsync(SelectedItems); + } +} diff --git a/Components/Table/TableBase.cs b/Components/Table/TableBase.cs new file mode 100644 index 0000000..5f3c413 --- /dev/null +++ b/Components/Table/TableBase.cs @@ -0,0 +1,538 @@ +using System.Diagnostics.CodeAnalysis; +using System.Windows.Input; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +// note: the MudTable code is split. Everything that has nothing to do with the type parameter of MudTable is here in MudTableBase + +public abstract class TableBase : UIComponent +{ + internal object _editingItem = null; + internal bool IsEditing => _editingItem != null; + + private int _currentPage = 0; + private int? _rowsPerPage; + private bool _isFirstRendered = false; + + protected string Classname => + new CssBuilder("mud-table") + .AddClass("mud-xs-table", Breakpoint == Breakpoint.Xs) + .AddClass("mud-sm-table", Breakpoint == Breakpoint.Sm) + .AddClass("mud-md-table", Breakpoint == Breakpoint.Md) + .AddClass("mud-lg-table", Breakpoint is Breakpoint.Lg or Breakpoint.Always) + .AddClass("mud-xl-table", Breakpoint is Breakpoint.Xl or Breakpoint.Always) + .AddClass("mud-xxl-table", Breakpoint is Breakpoint.Xxl or Breakpoint.Always) + .AddClass("mud-table-dense", Dense) + .AddClass("mud-table-hover", Hover) + .AddClass("mud-table-bordered", Bordered) + .AddClass("mud-table-striped", Striped) + .AddClass("mud-table-outlined", Outlined) + .AddClass("mud-table-square", Square) + .AddClass("mud-table-sticky-header", FixedHeader) + .AddClass("mud-table-sticky-footer", FixedFooter) + .AddClass($"mud-elevation-{Elevation}", !Outlined) + .AddClass(Class) + .Build(); + + protected string HeadClassname => new CssBuilder("mud-table-head") + .AddClass(HeaderClass).Build(); + protected string FootClassname => new CssBuilder("mud-table-foot") + .AddClass(FooterClass).Build(); + + /// + /// When editing a row and this is true, the editing row must be saved/cancelled before a new row will be selected. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public bool IsEditRowSwitchingBlocked { get; set; } = false; + + /// + /// The higher the number, the heavier the drop-shadow. 0 for no shadow. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// Set true to disable rounded corners + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Square { get; set; } + + /// + /// If true, table will be outlined. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Outlined { get; set; } + + /// + /// If true, table's cells will have left/right borders. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Bordered { get; set; } + + /// + /// Set true for rows with a narrow height + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Dense { get; set; } + + /// + /// Set true to see rows hover on mouse-over. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Hover { get; set; } + + /// + /// If true, striped table rows will be used. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public bool Striped { get; set; } + + /// + /// At what breakpoint the table should switch to mobile layout. Takes None, Xs, Sm, Md, Lg and Xl the default behavior is breaking on Xs. + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public Breakpoint Breakpoint { get; set; } = Breakpoint.Xs; + + /// + /// When true, the header will stay in place when the table is scrolled. Note: set Height to make the table scrollable. + /// + [Parameter] + [Category(CategoryTypes.Table.Header)] + public bool FixedHeader { get; set; } + + /// + /// When true, the footer will be visible is not scrolled to the bottom. Note: set Height to make the table scrollable. + /// + [Parameter] + [Category(CategoryTypes.Table.Footer)] + public bool FixedFooter { get; set; } + + /// + /// Setting a height will allow to scroll the table. If not set, it will try to grow in height. You can set this to any CSS value that the + /// attribute 'height' accepts, i.e. 500px. + /// + [Parameter] + [Category(CategoryTypes.Table.Appearance)] + public string Height { get; set; } + + /// + /// If table is in smalldevice mode and uses any kind of sorting the text applied here will be the sort selects label. + /// + [Parameter] + [Category(CategoryTypes.Table.Sorting)] + public string SortLabel { get; set; } + + /// + /// If true allows table to be in an unsorted state through column clicks (i.e. first click sorts "Ascending", second "Descending", third "None"). + /// If false only "Ascending" and "Descending" states are allowed (i.e. there always should be a column to sort). + /// + [Parameter] + [Category(CategoryTypes.Table.Sorting)] + public bool AllowUnsorted { get; set; } = true; + + /// + /// If the table has more items than this number, it will break the rows into pages of said size. + /// Note: requires a MudTablePager in PagerContent. + /// + [Parameter] + [Category(CategoryTypes.Table.Pagination)] + public int RowsPerPage + { + get => _rowsPerPage ?? 10; + set + { + if (_rowsPerPage is null || _rowsPerPage != value) + SetRowsPerPage(value); + } + } + + /// + /// Rows Per Page two-way bindable parameter + /// + [Parameter] public EventCallback RowsPerPageChanged { get; set; } + + /// + /// The page index of the currently displayed page (Zero based). Usually called by MudTablePager. + /// Note: requires a MudTablePager in PagerContent. + /// + [Parameter] + [Category(CategoryTypes.Table.Pagination)] + public int CurrentPage + { + get => _currentPage; + set + { + if (_currentPage == value) + return; + _currentPage = value; + InvokeAsync(StateHasChanged); + if (_isFirstRendered) + InvokeServerLoadFunc(); + } + } + + /// + /// Set to true to enable selection of multiple rows with check boxes. + /// + [Parameter] + [Category(CategoryTypes.Table.Selecting)] + public bool MultiSelection { get; set; } + + /// + /// Optional. Add any kind of toolbar to this render fragment. + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public RenderFragment ToolBarContent { get; set; } + + /// + /// Show a loading animation, if true. + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public bool Loading { get; set; } + + /// + /// The color of the loading progress if used. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public ThemeColor LoadingProgressColor { get; set; } = ThemeColor.Info; + + /// + /// Add MudTh cells here to define the table header. If is set, add one or more MudTHeadRow instead. + /// + [Parameter] + [Category(CategoryTypes.Table.Header)] + public RenderFragment HeaderContent { get; set; } + + /// + /// Specify if the header has multiple rows. In that case, you need to provide the MudTHeadRow tags. + /// + [Parameter] + [Category(CategoryTypes.Table.Header)] + public bool CustomHeader { get; set; } + + /// + /// Add a class to the thead tag + /// + [Parameter] + [Category(CategoryTypes.Table.Header)] + public string HeaderClass { get; set; } + + /// + /// Add MudTd cells here to define the table footer. If is set, add one or more MudTFootRow instead. + /// + [Parameter] + [Category(CategoryTypes.Table.Footer)] + public RenderFragment FooterContent { get; set; } + + /// + /// Specify if the footer has multiple rows. In that case, you need to provide the MudTFootRow tags. + /// + [Parameter] + [Category(CategoryTypes.Table.Footer)] + public bool CustomFooter { get; set; } + + /// + /// Add a class to the tfoot tag + /// + [Parameter] + [Category(CategoryTypes.Table.Footer)] + public string FooterClass { get; set; } + + /// + /// Specifies a group of one or more columns in a table for formatting. + /// Ex: + /// table + /// colgroup + /// col span="2" style="background-color:red" + /// col style="background-color:yellow" + /// colgroup + /// header + /// body + /// table + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public RenderFragment ColGroup { get; set; } + + //[Parameter] public RenderFragment RowTemplate { get; set; } <-- see MudTable.razor + + /// + /// Add MudTablePager here to enable breaking the rows in to multiple pages. + /// + [Parameter] + [Category(CategoryTypes.Table.Pagination)] + public RenderFragment PagerContent { get; set; } + + + /// + /// Locks Inline Edit mode, if true. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public bool ReadOnly { get; set; } = false; + + /// + /// Button commit edit click event. + /// + [Parameter] public EventCallback OnCommitEditClick { get; set; } + + /// + /// Button cancel edit click event. + /// + [Parameter] public EventCallback OnCancelEditClick { get; set; } + + /// + /// Event is called before the item is modified in inline editing. + /// + [Parameter] public EventCallback OnPreviewEditClick { get; set; } + + /// + /// Command executed when the user clicks on the CommitEdit Button. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public ICommand CommitEditCommand { get; set; } + + /// + /// Command parameter for the CommitEdit Button. By default, will be the row level item model, if you won't set anything else. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public object CommitEditCommandParameter { get; set; } + + /// + /// Tooltip for the CommitEdit Button. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public string CommitEditTooltip { get; set; } + + /// + /// Tooltip for the CancelEdit Button. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public string CancelEditTooltip { get; set; } + + /// + /// Sets the Icon of the CommitEdit Button. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public string CommitEditIcon { get; set; } = Icons.Material.Filled.Done; + + /// + /// Sets the Icon of the CancelEdit Button. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public string CancelEditIcon { get; set; } = Icons.Material.Filled.Cancel; + + /// + /// Define if Cancel button is present or not for inline editing. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public bool CanCancelEdit { get; set; } + + /// + /// Set the positon of the CommitEdit and CancelEdit button, if IsEditable is true. Defaults to the end of the row + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public TableApplyButtonPosition ApplyButtonPosition { get; set; } = TableApplyButtonPosition.End; + + /// + /// Set the positon of the StartEdit button, if IsEditable is true. Defaults to the end of the row + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public TableEditButtonPosition EditButtonPosition { get; set; } = TableEditButtonPosition.End; + + /// + /// Defines how a table row edit will be triggered + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public TableEditTrigger EditTrigger { get; set; } = TableEditTrigger.RowClick; + + /// + /// Defines the edit button that will be rendered when EditTrigger.EditButton + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public RenderFragment EditButtonContent { get; set; } + + /// + /// The method is called before the item is modified in inline editing. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public Action RowEditPreview { get; set; } + + /// + /// The method is called when the edition of the item has been committed in inline editing. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public Action RowEditCommit { get; set; } + + /// + /// The method is called when the edition of the item has been canceled in inline editing. + /// + [Parameter] + [Category(CategoryTypes.Table.Editing)] + public Action RowEditCancel { get; set; } + + /// + /// Number of items. Used only with ServerData="true" + /// + [Parameter] + [Category(CategoryTypes.Table.Data)] + public int TotalItems { get; set; } + + /// + /// CSS class for the table rows. Note, many CSS settings are overridden by MudTd though + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public string RowClass { get; set; } + + /// + /// CSS styles for the table rows. Note, many CSS settings are overridden by MudTd though + /// + [Parameter] + [Category(CategoryTypes.Table.Rows)] + public string RowStyle { get; set; } + + /// + /// If true, the results are displayed in a Virtualize component, allowing a boost in rendering speed. + /// + [Parameter] + [Category(CategoryTypes.Table.Behavior)] + public bool Virtualize { get; set; } + + #region --> Obsolete Forwarders for Backwards-Compatiblilty + /// + /// Alignment of the table cell text when breakpoint is smaller than + /// + [ExcludeFromCodeCoverage] + [Obsolete("This property is not needed anymore, the cells width/alignment is done automatically.", true)] + [Parameter] public bool RightAlignSmall { get; set; } = true; + #endregion + + public abstract TableContext TableContext { get; } + + protected override Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + _isFirstRendered = true; + + return base.OnAfterRenderAsync(firstRender); + } + + public void NavigateTo(Page page) + { + switch (page) + { + case Page.First: + CurrentPage = 0; + break; + case Page.Last: + CurrentPage = Math.Max(0, NumPages - 1); + break; + case Page.Next: + CurrentPage = Math.Min(NumPages - 1, CurrentPage + 1); + break; + case Page.Previous: + CurrentPage = Math.Max(0, CurrentPage - 1); + break; + } + } + /// + /// Navigate to page with specified index. + /// + /// The index of the page number. + public void NavigateTo(int pageIndex) + { + CurrentPage = Math.Min(Math.Max(0, pageIndex), NumPages - 1); + } + + public void SetRowsPerPage(int size) + { + if (_rowsPerPage == size) + return; + _rowsPerPage = size; + CurrentPage = 0; + StateHasChanged(); + RowsPerPageChanged.InvokeAsync(_rowsPerPage.Value); + if (_isFirstRendered) + InvokeServerLoadFunc(); + } + + protected abstract int NumPages { get; } + + public abstract int GetFilteredItemsCount(); + + public abstract void SetSelectedItem(object item); + + public abstract void SetEditingItem(object item); + + internal async Task OnCommitEditHandler(MouseEventArgs ev, object item) + { + await OnCommitEditClick.InvokeAsync(ev); + if (CommitEditCommand?.CanExecute(CommitEditCommandParameter) ?? false) + { + var parameter = CommitEditCommandParameter; + if (parameter == null) + parameter = item; + CommitEditCommand.Execute(parameter); + } + } + + internal Task OnPreviewEditHandler(object item) + { + return OnPreviewEditClick.InvokeAsync(item); + } + + internal Task OnCancelEditHandler(MouseEventArgs ev) + { + return OnCancelEditClick.InvokeAsync(ev); + } + + protected string TableStyle + => new StyleBuilder() + .AddStyle($"height", Height, !string.IsNullOrWhiteSpace(Height)) + .Build(); + + internal abstract bool HasServerData { get; } + + internal abstract Task InvokeServerLoadFunc(); + + internal abstract void FireRowClickEvent(MouseEventArgs args, Tr tr, object item); + + internal abstract void OnHeaderCheckboxClicked(bool value); + + internal abstract bool IsEditable { get; } + + public abstract bool ContainsItem(object item); + public abstract void UpdateSelection(); + + public IForm Validator { get; set; } = new TableRowValidator(); +} diff --git a/Components/Table/TableButtonPosition.cs b/Components/Table/TableButtonPosition.cs new file mode 100644 index 0000000..366d110 --- /dev/null +++ b/Components/Table/TableButtonPosition.cs @@ -0,0 +1,50 @@ +namespace Connected.Components; + +//public enum TableButtonPosition +//{ +// Start, +// End, +// StartAndEnd, +//} + +public enum TableEditButtonPosition +{ + Start, + End, + StartAndEnd, +} + +public enum TableApplyButtonPosition +{ + Start, + End, + StartAndEnd, +} + +public static class TableButtonPositionExtentions +{ + public static bool IsEditable(this TableContext context, bool ignoreEditable) => + (context?.Table.IsEditable ?? false) && !ignoreEditable; + + public static bool DisplayApplyButtonAtStart(this TableApplyButtonPosition position) => + position is TableApplyButtonPosition.Start or TableApplyButtonPosition.StartAndEnd; + public static bool DisplayEditButtonAtStart(this TableEditButtonPosition position) => + position is TableEditButtonPosition.Start or TableEditButtonPosition.StartAndEnd; + + public static bool DisplayApplyButtonAtStart(this TableContext context, bool ignoreEditable) => + context.IsEditable(ignoreEditable) && context.Table.ApplyButtonPosition.DisplayApplyButtonAtStart(); + + public static bool DisplayApplyButtonAtEnd(this TableApplyButtonPosition position) => + position is TableApplyButtonPosition.End or TableApplyButtonPosition.StartAndEnd; + public static bool DisplayEditButtonAtEnd(this TableEditButtonPosition position) => + position is TableEditButtonPosition.End or TableEditButtonPosition.StartAndEnd; + + public static bool DisplayApplyButtonAtEnd(this TableContext context, bool ignoreEditable) => + context.IsEditable(ignoreEditable) && context.Table.ApplyButtonPosition.DisplayApplyButtonAtEnd(); + + public static bool DisplayEditbuttonAtStart(this TableContext context, bool ignoreEditable) => + context.IsEditable(ignoreEditable) && context.Table.EditButtonPosition.DisplayEditButtonAtStart() && context.Table.EditTrigger == TableEditTrigger.EditButton; + + public static bool DisplayEditbuttonAtEnd(this TableContext context, bool ignoreEditable) => + context.IsEditable(ignoreEditable) && context.Table.EditButtonPosition.DisplayEditButtonAtEnd() && context.Table.EditTrigger == TableEditTrigger.EditButton; +} diff --git a/Components/Table/TableColumn.razor b/Components/Table/TableColumn.razor new file mode 100644 index 0000000..15bf128 --- /dev/null +++ b/Components/Table/TableColumn.razor @@ -0,0 +1,34 @@ +@namespace Connected.Components +@typeparam T +@inherits ColumnBase + +@if (Visible) +{ + @if (Mode == Rendermode.Header) + { + @HeaderText + } + else if (Mode == Rendermode.Item || (ReadOnly && Mode == Rendermode.Edit)) + { + @GetFormattedString(Value) + } + else if (Mode == Rendermode.Edit) + { + + } + else if (Mode == Rendermode.Footer) + { + @if (_footerValueAvailable) + { + + @GetFormattedString(FooterValue) + + } + else + { + + @FooterText + + } + } +} diff --git a/Components/Table/TableColumn.razor.cs b/Components/Table/TableColumn.razor.cs new file mode 100644 index 0000000..20bc3cf --- /dev/null +++ b/Components/Table/TableColumn.razor.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +/// +/// Binds an object's property to a column by its property name +/// +public partial class TableColumn : ColumnBase +{ + T InternalValue + { + get => Value; + set + { + if (!EqualityComparer.Default.Equals(value, Value)) + { + Value = value; + ValueChanged.InvokeAsync(value); + } + } + } + /// + /// Specifies the name of the object's property bound to the column + /// + [Parameter] public T Value { get; set; } + [Parameter] public EventCallback ValueChanged { get; set; } + + [Parameter] + public T FooterValue + { + get { return _footerValue; } + set { _footerValue = value; _footerValueAvailable = true; } + } + private T _footerValue; + private bool _footerValueAvailable = false; + + /// + /// Used if no FooterValue is available + /// + [Parameter] public string FooterText { get; set; } + /// + /// Specifies which string format should be used. + /// + [Parameter] public string DataFormatString { get; set; } + + [Parameter] public bool ReadOnly { get; set; } + + private string GetFormattedString(T item) + { + if (DataFormatString != null) + { + return string.Format(DataFormatString, item); + } + else + { + return item?.ToString(); + } + } +} diff --git a/Components/Table/TableContext.cs b/Components/Table/TableContext.cs new file mode 100644 index 0000000..bf5f135 --- /dev/null +++ b/Components/Table/TableContext.cs @@ -0,0 +1,183 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Extensions; + +namespace Connected.Components; + +public abstract class TableContext +{ + public TableBase Table { get; set; } + public Action TableStateHasChanged { get; set; } + public Action PagerStateHasChanged { get; set; } + public bool HasPager { get; set; } + public abstract void Add(Tr row, object item); + public abstract void Remove(Tr row, object item); + public abstract void UpdateRowCheckBoxes(bool notify = true); + public List HeaderRows { get; set; } = new List(); + public List FooterRows { get; set; } = new List(); + + public abstract void InitializeSorting(); + + public abstract string SortFieldLabel { get; internal set; } + + public abstract SortDirection SortDirection { get; protected set; } + + public abstract void ManagePreviousEditedRow(Tr row); +} + +public class TableContext<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : TableContext +{ + private Tr editedRow; + + public IEqualityComparer Comparer //when the comparer value is setup, update the collections with the new comparer + { + get => _comparer; + set + { + _comparer = value; + Selection = new HashSet(Selection, _comparer); + Rows = new Dictionary(Rows, _comparer); + } + } + private IEqualityComparer _comparer; + + public HashSet Selection { get; set; } = new HashSet(); + public Dictionary Rows { get; set; } = new Dictionary(); + public List> GroupRows { get; set; } = new List>(); + + public List> SortLabels { get; set; } = new List>(); + + public override void UpdateRowCheckBoxes(bool notify = true) + { + if (!Table.MultiSelection) + return; + // update row checkboxes + foreach (var pair in Rows.ToArray()) + { + var row = pair.Value; + var item = pair.Key; + row.SetChecked(Selection.Contains(item), notify: notify); + } + //update group checkboxes + foreach (var row in GroupRows) + { + var rowGroupItems = row.Items.ToList(); + row.SetChecked(Selection.Intersect(rowGroupItems).Count() == rowGroupItems.Count, notify: false); + } + if (HeaderRows.Count > 0 || FooterRows.Count > 0) + { + var itemsCount = Table.GetFilteredItemsCount(); + var b = Selection.Count == itemsCount && itemsCount != 0; + // update header checkbox + foreach (var header in HeaderRows) + header.SetChecked(b, notify: false); + + // update footer checkbox + foreach (var footer in FooterRows) + footer.SetChecked(b, notify: false); + } + } + + public override void ManagePreviousEditedRow(Tr row) + { + if (Table.IsEditable) + { + // Reset edition values of the edited row + // if another row is selected for edition + if (editedRow != null && row != editedRow) + { + editedRow.ManagePreviousEdition(); + } + + // The selected row is the edited row + editedRow = row; + } + } + + public override void Add(Tr row, object item) + { + var t = item.As(); + if (t is null) + return; + Rows[t] = row; + } + + public override void Remove(Tr row, object item) + { + var t = item.As(); + if (t is null) + return; + if (Rows[t] == row) + Rows.Remove(t); + if (!Table.ContainsItem(item)) + { + Selection.Remove(t); + Table.UpdateSelection(); + } + } + + #region --> Sorting + + public override SortDirection SortDirection + { + get; + protected set; + } + + public Func SortBy { get; protected set; } + public TableSortLabel CurrentSortLabel { get; protected set; } + + public async Task SetSortFunc(TableSortLabel label, bool override_direction_none = false) + { + CurrentSortLabel = label; + if (label.SortDirection == SortDirection.None && override_direction_none) + label.SetSortDirection(SortDirection.Ascending); + SortDirection = label.SortDirection; + SortBy = label.SortBy; + UpdateSortLabels(label); + + if (Table.HasServerData) + await Table.InvokeServerLoadFunc(); + + TableStateHasChanged(); + } + + public IEnumerable Sort(IEnumerable items) + { + if (items == null) + return items; + if (SortBy == null || SortDirection == SortDirection.None) + return items; + if (SortDirection == SortDirection.Ascending) + return items.OrderBy(item => SortBy(item)); + else + return items.OrderByDescending(item => SortBy(item)); + } + + public override void InitializeSorting() + { + var initial_sortlabel = SortLabels.FirstOrDefault(x => x.InitialDirection != SortDirection.None); + if (initial_sortlabel == null) + return; + CurrentSortLabel = initial_sortlabel; + UpdateSortLabels(initial_sortlabel); + // this will trigger initial sorting of the table + initial_sortlabel.SetSortDirection(initial_sortlabel.InitialDirection); + SortDirection = initial_sortlabel.SortDirection; + SortBy = initial_sortlabel.SortBy; + TableStateHasChanged(); + } + + private void UpdateSortLabels(TableSortLabel label) + { + foreach (var x in SortLabels) + { + if (x != label) + x.SetSortDirection(SortDirection.None); + } + } + + public override string SortFieldLabel { get; internal set; } + + #endregion + +} diff --git a/Components/Table/TableEditTrigger.cs b/Components/Table/TableEditTrigger.cs new file mode 100644 index 0000000..0883d2c --- /dev/null +++ b/Components/Table/TableEditTrigger.cs @@ -0,0 +1,11 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public enum TableEditTrigger +{ + RowClick, + EditButton +} diff --git a/Components/Table/TableGroupData.cs b/Components/Table/TableGroupData.cs new file mode 100644 index 0000000..7b8a994 --- /dev/null +++ b/Components/Table/TableGroupData.cs @@ -0,0 +1,19 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Components; + +public class TableGroupData +{ + public TableGroupData(string groupName, TKey key, IEnumerable items) + { + GroupName = groupName; + Key = key; + Items = items; + } + + public string GroupName { get; } + public TKey Key { get; } + public IEnumerable Items { get; } +} diff --git a/Components/Table/TableGroupDefinition.cs b/Components/Table/TableGroupDefinition.cs new file mode 100644 index 0000000..eb439c6 --- /dev/null +++ b/Components/Table/TableGroupDefinition.cs @@ -0,0 +1,150 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; + +namespace Connected.Components; + +public class TableGroupDefinition<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> +{ + public TableGroupDefinition() + { + } + + public TableGroupDefinition(Func selector, TableGroupDefinition innerGroup = null) + { + Selector = selector; + InnerGroup = innerGroup; + } + + /// + /// Gets or Sets the Group Name. It's useful for use on Header, for example. + /// + public string GroupName { get; set; } + + /// + /// The selector func to be used on .GroupBy() with LINQ. + /// + public Func Selector { get; set; } + + private TableGroupDefinition _innerGroup; + public TableGroupDefinition InnerGroup + { + get => _innerGroup; + set + { + if (_innerGroup != null) + { + _innerGroup.Parent = null; + _innerGroup.Context = null; + } + + _innerGroup = value; + + if (_innerGroup != null) + { + _innerGroup.Parent = this; + _innerGroup.Indentation = Indentation; + _innerGroup.Context = Context; + } + } + } + + internal TableGroupDefinition Parent { get; private set; } + + private bool _indentation; + /// + /// Gets or Sets if First Column cell must have Indentation. + /// It must be set on First grouping level and works recursively. + /// + public bool Indentation + { + get => _indentation; + set + { + _indentation = value; + if (InnerGroup != null) + InnerGroup.Indentation = value; + } + + } + + private bool _expandable = false; + /// + /// Gets or Sets is group header can Expand and Collapse its children. + /// + public bool Expandable + { + get => _expandable; + set + { + _expandable = value; + if (_expandable == false) + Context?.GroupRows.Where(gr => gr.GroupDefinition == this).ToList().ForEach(gr => gr.IsExpanded = IsInitiallyExpanded); + } + } + + private bool _isInitiallyExpanded = true; + /// + /// Gets or Sets if expandable group header is collapsed or expanded on initialization. + /// + public bool IsInitiallyExpanded + { + get => _isInitiallyExpanded; + set + { + _isInitiallyExpanded = value; + } + + } + + internal bool IsParentExpandable + { + get + { + if (Parent?.Expandable ?? false) + return true; + else + return Parent?.IsParentExpandable ?? false; + } + } + + internal bool IsThisOrParentExpandable + { + get + { + if (Expandable) + return Expandable; + else + return Parent?.IsThisOrParentExpandable ?? false; + } + } + + internal int Level + { + get + { + if (Parent == null) + return 1; + else + return Parent.Level + 1; + } + } + + private TableContext _context; + internal TableContext Context + { + get => _context; + set + { + _context = value; + if (_innerGroup != null) + { + _innerGroup.Context = _context; + } + + } + } + +} diff --git a/Components/Table/TableGroupRow.razor b/Components/Table/TableGroupRow.razor new file mode 100644 index 0000000..eb631ee --- /dev/null +++ b/Components/Table/TableGroupRow.razor @@ -0,0 +1,78 @@ +@namespace Connected.Components +@implements IDisposable +@inherits UIComponent +@typeparam T + +@*HEADER:*@ +@if (HeaderTemplate != null && GroupDefinition != null) +{ + + @if ((GroupDefinition?.IsThisOrParentExpandable ?? false) || (Context?.Table.MultiSelection ?? false)) + { + +
    + @if (GroupDefinition.Expandable) + { + + } + else + { + if (GroupDefinition?.IsParentExpandable ?? false) + { +
    + } + } + @if (IsCheckable) + { + + } +
    + + } + @HeaderTemplate(new TableGroupData(GroupDefinition.GroupName, Items.Key, Items.ToList())) + @if ((Context?.Table.IsEditable ?? false)) + { + + } + +} +else +{ +@("There aren't any group definition to use with this component.") +} + +@if (IsExpanded) +{ + @*CHILDREN:*@ + @if (_innerGroupItems != null && GroupDefinition != null) + { + @foreach (var group in _innerGroupItems) + { + + } + } + else + { + @Table?.RenderRows(Items, (GroupDefinition?.Indentation ?? false) ? $"mud-table-row-group-indented-{GroupDefinition?.Level - 1}" : null, GroupDefinition?.IsThisOrParentExpandable ?? false) + } + + @*FOOTER:*@ + @if (FooterTemplate != null && GroupDefinition != null) + { + + @if ((GroupDefinition?.IsThisOrParentExpandable ?? false) || (Context?.Table.MultiSelection ?? false)) + { + + } + @FooterTemplate(new TableGroupData(GroupDefinition.GroupName, Items.Key, Items.ToList())) + @if ((Context?.Table.IsEditable ?? false)) + { + + } + + + } +} \ No newline at end of file diff --git a/Components/Table/TableGroupRow.razor.cs b/Components/Table/TableGroupRow.razor.cs new file mode 100644 index 0000000..06402d7 --- /dev/null +++ b/Components/Table/TableGroupRow.razor.cs @@ -0,0 +1,139 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class TableGroupRow<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : UIComponent +{ + protected string HeaderClassname => new CssBuilder("mud-table-row") + .AddClass(HeaderClass) + .AddClass($"mud-table-row-group-indented-{GroupDefinition?.Level - 1}", (GroupDefinition?.Indentation ?? false) && GroupDefinition?.Level > 1).Build(); + + protected string FooterClassname => new CssBuilder("mud-table-row") + .AddClass(FooterClass) + .AddClass($"mud-table-row-group-indented-{GroupDefinition?.Level - 1}", (GroupDefinition?.Indentation ?? false) && GroupDefinition?.Level > 1).Build(); + + protected string ActionsStylename => new StyleBuilder() + .AddStyle("padding-left", "34px", GroupDefinition?.IsParentExpandable ?? false).Build(); + + [CascadingParameter] public TableContext Context { get; set; } + + private IEnumerable> _innerGroupItems = null; + + /// + /// The group definition for this grouping level. It's recursive. + /// + [Parameter] public TableGroupDefinition GroupDefinition { get; set; } + + IGrouping _items = null; + /// + /// Inner Items List for the Group + /// + [Parameter] + public IGrouping Items + { + get => _items; + set + { + _items = value; + SyncInnerGroupItems(); + } + } + + /// + /// Defines Group Header Data Template + /// + [Parameter] public RenderFragment> HeaderTemplate { get; set; } + + /// + /// Defines Group Header Data Template + /// + [Parameter] public RenderFragment> FooterTemplate { get; set; } + + /// + /// Add a multi-select checkbox that will select/unselect every item in the table + /// + [Parameter] public bool IsCheckable { get; set; } + + [Parameter] public string HeaderClass { get; set; } + [Parameter] public string FooterClass { get; set; } + + [Parameter] public string HeaderStyle { get; set; } + [Parameter] public string FooterStyle { get; set; } + + /// + /// Custom expand icon. + /// + [Parameter] public string ExpandIcon { get; set; } = Icons.Material.Filled.ExpandMore; + + /// + /// Custom collapse icon. + /// + [Parameter] public string CollapseIcon { get; set; } = Icons.Material.Filled.ChevronRight; + + /// + /// On click event + /// + [Parameter] public EventCallback OnRowClick { get; set; } + + private bool _checked; + public bool IsChecked + { + get => _checked; + set + { + if (value != _checked) + { + _checked = value; + if (IsCheckable) + Table.OnGroupHeaderCheckboxClicked(value, Items.ToList()); + } + } + } + + public bool IsExpanded { get; internal set; } = true; + + protected override Task OnInitializedAsync() + { + if (GroupDefinition != null) + { + IsExpanded = GroupDefinition.IsInitiallyExpanded; + ((TableContext)Context)?.GroupRows.Add(this); + SyncInnerGroupItems(); + } + return base.OnInitializedAsync(); + } + + private void SyncInnerGroupItems() + { + if (GroupDefinition.InnerGroup != null) + { + _innerGroupItems = Table?.GetItemsOfGroup(GroupDefinition.InnerGroup, Items); + } + } + + public void Dispose() + { + ((TableContext)Context)?.GroupRows.Remove(this); + } + + public void SetChecked(bool b, bool notify) + { + if (notify) + IsChecked = b; + else + { + _checked = b; + if (IsCheckable) + InvokeAsync(StateHasChanged); + } + } + + private Table Table + { + get => (Table)((TableContext)Context)?.Table; + } + +} diff --git a/Components/Table/TablePager.razor b/Components/Table/TablePager.razor new file mode 100644 index 0000000..089692d --- /dev/null +++ b/Components/Table/TablePager.razor @@ -0,0 +1,51 @@ +@namespace Connected.Components +@inherits UIComponent + + + @if (HorizontalAlignment == HorizontalAlignment.End || + (HorizontalAlignment == HorizontalAlignment.Right && !RightToLeft) || + (HorizontalAlignment == HorizontalAlignment.Left && RightToLeft) || + HorizontalAlignment == HorizontalAlignment.Center) + { +
    + } + @if (!HideRowsPerPage) + { +
    +
    +
    @RowsPerPageString
    +
    + + + +
    + } + @if (!HidePageNumber) + { +
    +
    @Info
    +
    + } + @if (!HidePagination) + { +
    + + + + +
    + } + @if (HorizontalAlignment == HorizontalAlignment.Start || + (HorizontalAlignment == HorizontalAlignment.Left && !RightToLeft) || + (HorizontalAlignment == HorizontalAlignment.Right && RightToLeft) || + HorizontalAlignment == HorizontalAlignment.Center) + { +
    + } +
    + diff --git a/Components/Table/TablePager.razor.cs b/Components/Table/TablePager.razor.cs new file mode 100644 index 0000000..b033117 --- /dev/null +++ b/Components/Table/TablePager.razor.cs @@ -0,0 +1,128 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class TablePager : UIComponent +{ + protected string Classname => + new CssBuilder("mud-table-pagination-toolbar") + .AddClass("mud-tablepager-left", !RightToLeft) + .AddClass("mud-tablepager-right", RightToLeft) + .AddClass(Class) + .Build(); + + protected string PaginationClassname => + new CssBuilder("mud-table-pagination-display") + .AddClass("mud-tablepager-left", !RightToLeft) + .AddClass("mud-tablepager-right", RightToLeft) + .AddClass(Class) + .Build(); + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + [CascadingParameter] public TableContext Context { get; set; } + + /// + /// Set true to hide the part of the pager which allows to change the page size. + /// + [Parameter] public bool HideRowsPerPage { get; set; } + + /// + /// Set true to hide the part of the pager which allows to change the page size. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use HideRowsPerPage instead.", true)] + [Parameter] public bool DisableRowsPerPage { get => HideRowsPerPage; set => HideRowsPerPage = value; } + + /// + /// Set true to hide the number of pages. + /// + [Parameter] public bool HidePageNumber { get; set; } + + /// + /// Set true to hide the pagination. + /// + [Parameter] public bool HidePagination { get; set; } + + /// + /// Set the horizontal alignment position. + /// + [Parameter] public HorizontalAlignment HorizontalAlignment { get; set; } = HorizontalAlignment.Right; + + /// + /// Define a list of available page size options for the user to choose from + /// + [Parameter] public int[] PageSizeOptions { get; set; } = new int[] { 10, 25, 50, 100 }; + + /// + /// Format string for the display of the current page, which you can localize to your language. Available variables are: + /// {first_item}, {last_item} and {all_items} which will replaced with the indices of the page's first and last item, as well as the total number of items. + /// Default: "{first_item}-{last_item} of {all_items}" which is transformed into "0-25 of 77". + /// + [Parameter] public string InfoFormat { get; set; } = "{first_item}-{last_item} of {all_items}"; + + private string Info + { + get + { + // fetch number of filtered items (once only) + var filteredItemsCount = Table?.GetFilteredItemsCount() ?? 0; + + return Table == null + ? "Table==null" + : InfoFormat + .Replace("{first_item}", $"{(filteredItemsCount == 0 ? 0 : Table?.CurrentPage * Table.RowsPerPage + 1)}") + .Replace("{last_item}", $"{Math.Min((Table.CurrentPage + 1) * Table.RowsPerPage, filteredItemsCount)}") + .Replace("{all_items}", $"{filteredItemsCount}"); + } + } + + /// + /// The localizable "Rows per page:" text. + /// + [Parameter] public string RowsPerPageString { get; set; } = "Rows per page:"; + + /// + /// Custom first icon. + /// + [Parameter] public string FirstIcon { get; set; } = Icons.Material.Filled.FirstPage; + + /// + /// Custom before icon. + /// + [Parameter] public string BeforeIcon { get; set; } = Icons.Material.Filled.NavigateBefore; + + /// + /// Custom next icon. + /// + [Parameter] public string NextIcon { get; set; } = Icons.Material.Filled.NavigateNext; + + /// + /// Custom last icon. + /// + [Parameter] public string LastIcon { get; set; } = Icons.Material.Filled.LastPage; + + private void SetRowsPerPage(string size) + { + Table?.SetRowsPerPage(int.Parse(size)); + } + + private bool BackButtonsDisabled => Table == null ? false : Table.CurrentPage == 0; + + private bool ForwardButtonsDisabled => Table == null ? false : (Table.CurrentPage + 1) * Table.RowsPerPage >= Table.GetFilteredItemsCount(); + + public TableBase Table => Context?.Table; + + protected override void OnInitialized() + { + base.OnInitialized(); + if (Context != null) + { + Context.HasPager = true; + Context.PagerStateHasChanged = StateHasChanged; + } + } + +} diff --git a/Components/Table/TableRowClickEventArgs.cs b/Components/Table/TableRowClickEventArgs.cs new file mode 100644 index 0000000..28426fd --- /dev/null +++ b/Components/Table/TableRowClickEventArgs.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public class TableRowClickEventArgs : EventArgs +{ + public MouseEventArgs MouseEventArgs { get; set; } + public T Item { get; set; } + public Tr Row { get; set; } +} diff --git a/Components/Table/TableRowValidator.cs b/Components/Table/TableRowValidator.cs new file mode 100644 index 0000000..477cf66 --- /dev/null +++ b/Components/Table/TableRowValidator.cs @@ -0,0 +1,59 @@ +namespace Connected.Components; + +public class TableRowValidator : IForm +{ + public bool IsValid + { + get + { + Validate(); + return Errors.Length <= 0; + } + } + + public string[] Errors + { + get => _errors.ToArray(); + } + +#nullable enable + public object? Model { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } +#nullable disable + + protected HashSet _errors = new(); + + void IForm.FieldChanged(IFormComponent formControl, object newValue) + { + //implement in future for table + } + + void IForm.Add(IFormComponent formControl) + { + _formControls.Add(formControl); + } + + void IForm.Remove(IFormComponent formControl) + { + _formControls.Remove(formControl); + } + + void IForm.Update(IFormComponent formControl) + { + //Validate(formControl); + } + + protected HashSet _formControls = new(); + + public void Validate() + { + _errors.Clear(); + foreach (var formControl in _formControls.ToArray()) + { + formControl.Validate(); + foreach (var err in formControl.ValidationErrors) + { + _errors.Add(err); + } + } + } +} diff --git a/Components/Table/TableSortLabel.razor b/Components/Table/TableSortLabel.razor new file mode 100644 index 0000000..4199ba8 --- /dev/null +++ b/Components/Table/TableSortLabel.razor @@ -0,0 +1,26 @@ +@namespace Connected.Components +@typeparam T +@inherits UIComponent +@implements IDisposable + + + @if (!AppendIcon) + { + @ChildContent + } + @if (Enabled) + { + @if (_direction != SortDirection.None) + { + + } + else + { + + } + } + @if (AppendIcon) + { + @ChildContent + } + diff --git a/Components/Table/TableSortLabel.razor.cs b/Components/Table/TableSortLabel.razor.cs new file mode 100644 index 0000000..90851ff --- /dev/null +++ b/Components/Table/TableSortLabel.razor.cs @@ -0,0 +1,124 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + + +namespace Connected.Components; + +public partial class TableSortLabel<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : UIComponent +{ + protected string Classname => new CssBuilder("mud-button-root mud-table-sort-label") + .AddClass(Class).Build(); + + [CascadingParameter] public TableContext TableContext { get; set; } + + public TableBase Table => TableContext?.Table; + public TableContext Context => TableContext as TableContext; + + [Parameter] public RenderFragment ChildContent { get; set; } + + [Parameter] + public SortDirection InitialDirection { get; set; } = SortDirection.None; + + /// + /// Enable the sorting. Set to true by default. + /// + [Parameter] + public bool Enabled { get; set; } = true; + + /// + /// The Icon used to display sortdirection. + /// + [Parameter] public string SortIcon { get; set; } = Icons.Material.Filled.ArrowUpward; + + /// + /// If true the icon will be placed before the label text. + /// + [Parameter] public bool AppendIcon { get; set; } + + private SortDirection _direction = SortDirection.None; + + [Parameter] + public SortDirection SortDirection + { + get => _direction; + set + { + if (_direction == value) + return; + _direction = value; + + SortDirectionChanged.InvokeAsync(_direction); + } + } + + private Task UpdateSortDirectionAsync(SortDirection sortDirection) + { + SortDirection = sortDirection; + return Context?.SetSortFunc(this); + } + + [Parameter] + public EventCallback SortDirectionChanged { get; set; } + + [Parameter] + public Func SortBy { get; set; } = null; + + [Parameter] public string SortLabel { get; set; } + + public Task ToggleSortDirection() + { + if (!Enabled) + return Task.CompletedTask; + + switch (SortDirection) + { + case SortDirection.None: + return UpdateSortDirectionAsync(SortDirection.Ascending); + + case SortDirection.Ascending: + return UpdateSortDirectionAsync(SortDirection.Descending); + + case SortDirection.Descending: + return UpdateSortDirectionAsync(Table.AllowUnsorted ? SortDirection.None : SortDirection.Ascending); + } + + throw new NotImplementedException(); + } + + protected override void OnInitialized() + { + Context?.SortLabels.Add(this); + Context?.InitializeSorting(); + } + + public void Dispose() + { + Context?.SortLabels.Remove(this); + } + + /// + /// Set sort direction but don't update Table sort order. This should only be called by Table + /// + internal void SetSortDirection(SortDirection dir) + { + _direction = dir; + StateHasChanged(); + } + + private string GetSortIconClass() + { + if (_direction == SortDirection.Descending) + { + return $"mud-table-sort-label-icon mud-direction-desc"; + } + else if (_direction == SortDirection.Ascending) + { + return $"mud-table-sort-label-icon mud-direction-asc"; + } + else + { + return $"mud-table-sort-label-icon"; + } + } +} diff --git a/Components/Table/TableState.cs b/Components/Table/TableState.cs new file mode 100644 index 0000000..5005fc3 --- /dev/null +++ b/Components/Table/TableState.cs @@ -0,0 +1,18 @@ +namespace Connected.Components; + +public class TableState +{ + public int Page { get; set; } + + public int PageSize { get; set; } + + public string SortLabel { get; set; } + + public SortDirection SortDirection { get; set; } +} + +public class TableData +{ + public IEnumerable Items { get; set; } + public int TotalItems { get; set; } +} diff --git a/Components/Table/Td.razor b/Components/Table/Td.razor new file mode 100644 index 0000000..6bfc483 --- /dev/null +++ b/Components/Table/Td.razor @@ -0,0 +1,6 @@ +@namespace Connected.Components +@inherits UIComponent + + + @ChildContent + \ No newline at end of file diff --git a/Components/Table/Td.razor.cs b/Components/Table/Td.razor.cs new file mode 100644 index 0000000..23acad6 --- /dev/null +++ b/Components/Table/Td.razor.cs @@ -0,0 +1,23 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Td : UIComponent +{ + + protected string Classname => + new CssBuilder("mud-table-cell") + .AddClass("mud-table-cell-hide", HideSmall) + .AddClass(Class) + .Build(); + + [Parameter] public RenderFragment ChildContent { get; set; } + + [Parameter] public string DataLabel { get; set; } + + /// + /// Hide cell when breakpoint is smaller than the defined value in table. + /// + [Parameter] public bool HideSmall { get; set; } +} diff --git a/Components/Table/TemplateColumn.razor b/Components/Table/TemplateColumn.razor new file mode 100644 index 0000000..260dd50 --- /dev/null +++ b/Components/Table/TemplateColumn.razor @@ -0,0 +1,36 @@ +@namespace Connected.Components +@typeparam T +@inherits ColumnBase +@if (Visible) +{ + @if (Mode == Rendermode.Header && Header!= null) + { + @Header(DataContext) + } + else if (Mode == Rendermode.Item && Row != null) + { + @Row(DataContext) + } + else if (Mode == Rendermode.Edit && Edit != null) + { + @Edit(DataContext) + } + else if (Mode == Rendermode.Footer && Footer != null) + { + @Footer(DataContext) + } + else + { + + } +} +@code { + + [Parameter] public T DataContext { get; set; } + #region Templates + [Parameter] public RenderFragment Header { get; set; } + [Parameter] public RenderFragment Row { get; set; } + [Parameter] public RenderFragment Edit { get; set; } + [Parameter] public RenderFragment Footer { get; set; } + #endregion +} diff --git a/Components/Table/Th.razor b/Components/Table/Th.razor new file mode 100644 index 0000000..9f30966 --- /dev/null +++ b/Components/Table/Th.razor @@ -0,0 +1,7 @@ +@namespace Connected.Components +@inherits UIComponent + + @ChildContent + + + diff --git a/Components/Table/Th.razor.cs b/Components/Table/Th.razor.cs new file mode 100644 index 0000000..cef4cd8 --- /dev/null +++ b/Components/Table/Th.razor.cs @@ -0,0 +1,13 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Th : UIComponent +{ + protected string Classname => new CssBuilder("mud-table-cell") + .AddClass(Class).Build(); + + [Parameter] public RenderFragment ChildContent { get; set; } +} + diff --git a/Components/Table/Tr.razor b/Components/Table/Tr.razor new file mode 100644 index 0000000..c0c6f81 --- /dev/null +++ b/Components/Table/Tr.razor @@ -0,0 +1,82 @@ +@namespace Connected.Components +@implements IDisposable +@inherits UIComponent + + + @if (IsEditable && ((Context?.Table.EditButtonPosition.DisplayEditButtonAtStart() == true && Context?.Table.EditTrigger == TableEditTrigger.EditButton) || Context?.Table.ApplyButtonPosition.DisplayApplyButtonAtStart() == true)) + { + @* Add datalabel as a placeholder to avoid jumps on small viewports *@ + + @if (Context?.Table.EditTrigger == TableEditTrigger.EditButton && !object.ReferenceEquals(Context?.Table._editingItem, Item) && (!Context?.Table.ReadOnly ?? false) && Context?.Table.EditButtonPosition.DisplayEditButtonAtStart() == true) + { + @if (Context?.Table.EditButtonContent != null) + { + @Context?.Table.EditButtonContent(new EditButtonContext(StartEditingItem, Context.EditButtonDisabled(Item))) + } + else + { + + } + } + else if (object.ReferenceEquals(Context?.Table._editingItem, Item) && (!Context?.Table.ReadOnly ?? false) && Context?.Table.ApplyButtonPosition.DisplayApplyButtonAtStart() == true) + { +
    + + + + @if (Context.Table.CanCancelEdit) + { + + + + } +
    + } + + } + @if (IsExpandable || IsCheckable) + { + +
    + @if (IsCheckable) + { + + } +
    +
    + } + @ChildContent + @if (IsEditable && ((Context?.Table.EditButtonPosition.DisplayEditButtonAtEnd() == true && Context?.Table.EditTrigger == TableEditTrigger.EditButton) || Context?.Table.ApplyButtonPosition.DisplayApplyButtonAtEnd() == true)) + { + @* Add datalabel as a placeholder to avoid jumps on small viewports *@ + + @if (Context?.Table.EditTrigger == TableEditTrigger.EditButton && !object.ReferenceEquals(Context?.Table._editingItem, Item) && (!Context?.Table.ReadOnly ?? false) && Context?.Table.EditButtonPosition.DisplayEditButtonAtEnd() == true) + { + @if (Context?.Table.EditButtonContent != null) + { + @Context?.Table.EditButtonContent(new EditButtonContext(StartEditingItem, Context.EditButtonDisabled(Item))) + } + else + { + + } + } + else if (object.ReferenceEquals(Context?.Table._editingItem, Item) && (!Context?.Table.ReadOnly ?? false) && Context?.Table.ApplyButtonPosition.DisplayApplyButtonAtEnd() == true) + { +
    + + + + @if (Context.Table.CanCancelEdit) + { + + + + } +
    + } + + } + + + diff --git a/Components/Table/Tr.razor.cs b/Components/Table/Tr.razor.cs new file mode 100644 index 0000000..5304061 --- /dev/null +++ b/Components/Table/Tr.razor.cs @@ -0,0 +1,191 @@ +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Tr : UIComponent +{ + private bool hasBeenCanceled; + private bool hasBeenCommitted; + private bool hasBeenClickedFirstTime; + + internal object _itemCopy; + + protected string Classname => new CssBuilder("mud-table-row") + .AddClass(Class).Build(); + + protected string ActionsStylename => new StyleBuilder() + .AddStyle("padding-left", "34px", IsExpandable).Build(); + + + [CascadingParameter] public TableContext Context { get; set; } + + [Parameter] public RenderFragment ChildContent { get; set; } + + [Parameter] public object Item { get; set; } + + [Parameter] public bool IsCheckable { get; set; } + + [Parameter] public bool IsEditable { get; set; } + + [Parameter] public bool IsEditing { get; set; } + + [Parameter] public bool IsEditSwitchBlocked { get; set; } + + [Parameter] public bool IsExpandable { get; set; } + + + [Parameter] + public EventCallback IsCheckedChanged { get; set; } + + private bool _checked; + [Parameter] + public bool IsChecked + { + get => _checked; + set + { + if (value != _checked) + { + _checked = value; + IsCheckedChanged.InvokeAsync(value); + } + } + } + + public void OnRowClicked(MouseEventArgs args) + { + StartEditingItem(buttonClicked: false); + + if (Context?.Table.MultiSelection == true && !(Context?.Table.IsEditable == true)) + { + IsChecked = !IsChecked; + } + Context?.Table.FireRowClickEvent(args, this, Item); + } + + private void StartEditingItem() => StartEditingItem(buttonClicked: true); + + private void StartEditingItem(bool buttonClicked) + { + if (Context?.Table.IsEditable == true && Context?.Table.IsEditing == true && Context?.Table.IsEditRowSwitchingBlocked == true) return; + + if ((Context?.Table.EditTrigger == TableEditTrigger.RowClick && buttonClicked) || (Context?.Table.EditTrigger == TableEditTrigger.EditButton && !buttonClicked)) return; + + // Manage any previous edited row + Context.ManagePreviousEditedRow(this); + + if (!(Context?.Table.Validator.IsValid ?? true)) + return; + + if (!buttonClicked) + Context?.Table.SetSelectedItem(Item); + + // Manage edition the first time the row is clicked and if the table is editable + if (!hasBeenClickedFirstTime && IsEditable) + { + // Sets hasBeenClickedFirstTime to true + hasBeenClickedFirstTime = true; + + // Set to false that the item has been committed + // Set to false that the item has been cancelled + hasBeenCanceled = false; + hasBeenCommitted = false; + + // Trigger the preview event + Context?.Table.OnPreviewEditHandler(Item); + + // Trigger the row edit preview event + Context.Table.RowEditPreview?.Invoke(Item); + + Context?.Table.SetEditingItem(Item); + } + } + + protected override Task OnInitializedAsync() + { + Context?.Add(this, Item); + return base.OnInitializedAsync(); + } + + public void Dispose() + { + Context?.Remove(this, Item); + } + + public void SetChecked(bool b, bool notify) + { + if (notify) + IsChecked = b; + else + { + _checked = b; + InvokeAsync(StateHasChanged); + } + } + + private void FinishEdit(MouseEventArgs ev) + { + // Check the validity of the item + if (!Context?.Table.Validator.IsValid ?? true) return; + + // Set the item value to cancel edit mode + Context?.Table.SetEditingItem(null); + + // Trigger the commit event + Context?.Table.OnCommitEditHandler(ev, Item); + + // Trigger the row edit commit event + Context.Table.RowEditCommit?.Invoke(Item); + + // Set to true that the item has been committed + // Set to false that the item has been cancelled + hasBeenCommitted = true; + hasBeenCanceled = false; + + // Set hasBeenClickedFirstTime to false + hasBeenClickedFirstTime = false; + } + + private void CancelEdit(MouseEventArgs ev) + { + // Set the item value to cancel edit mode + Context?.Table.SetEditingItem(null); + + // Trigger the cancel event + Context?.Table.OnCancelEditHandler(ev); + + // Trigger the row edit cancel event + Context?.Table.RowEditCancel?.Invoke(Item); + + // Set to true that the item has been canceled + // Set to false that the items has been committed + hasBeenCanceled = true; + hasBeenCommitted = false; + + // Set hasBeenClickedFirstTime to false + hasBeenClickedFirstTime = false; + } + + public void ManagePreviousEdition() + { + // Reset the item to its original value if no cancellation and no commit has been done + if (!hasBeenCanceled && !hasBeenCommitted) + { + // Set the item value to cancel edit mode + Context?.Table.SetEditingItem(null); + + // Force/indicate a refresh on the component to remove the edition mode for the row + StateHasChanged(); + + // Trigger the row edit cancel event + Context.Table.RowEditCancel?.Invoke(Item); + } + + // Reset the variables + hasBeenCanceled = false; + hasBeenCommitted = false; + hasBeenClickedFirstTime = false; + } +} diff --git a/Components/TableSimple/SimpleTable.razor b/Components/TableSimple/SimpleTable.razor new file mode 100644 index 0000000..5dc37ae --- /dev/null +++ b/Components/TableSimple/SimpleTable.razor @@ -0,0 +1,10 @@ +@namespace Connected.Components +@inherits UIComponent + +
    +
    + + @ChildContent +
    +
    +
    diff --git a/Components/TableSimple/SimpleTable.razor.cs b/Components/TableSimple/SimpleTable.razor.cs new file mode 100644 index 0000000..3ccb045 --- /dev/null +++ b/Components/TableSimple/SimpleTable.razor.cs @@ -0,0 +1,85 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class SimpleTable : UIComponent +{ + protected string Classname => + new CssBuilder("mud-table mud-simple-table") + .AddClass($"mud-table-dense", Dense) + .AddClass($"mud-table-hover", Hover) + .AddClass($"mud-table-bordered", Bordered) + .AddClass($"mud-table-outlined", Outlined) + .AddClass($"mud-table-striped", Striped) + .AddClass($"mud-table-square", Square) + .AddClass($"mud-table-sticky-header", FixedHeader) + .AddClass($"mud-elevation-{Elevation}", !Outlined) + .AddClass(Class) + .Build(); + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public int Elevation { set; get; } = 1; + + /// + /// If true, the table row will shade on hover. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Hover { get; set; } + + /// + /// If true, border-radius is set to 0. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Square { get; set; } + + /// + /// If true, compact padding will be used. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Dense { get; set; } + + /// + /// If true, table will be outlined. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Outlined { get; set; } + + /// + /// If true, table's cells will have left/right borders. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Bordered { get; set; } + + /// + /// If true, striped table rows will be used. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool Striped { get; set; } + + /// + /// When true, the header will stay in place when the table is scrolled. Note: set Height to make the table scrollable. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Appearance)] + public bool FixedHeader { get; set; } + + /// + /// Child content of the component. + /// + [Parameter] + [Category(CategoryTypes.SimpleTable.Behavior)] + public RenderFragment ChildContent { get; set; } + +} diff --git a/Components/Tabs/DynamicTabs.razor b/Components/Tabs/DynamicTabs.razor new file mode 100644 index 0000000..f1aaa84 --- /dev/null +++ b/Components/Tabs/DynamicTabs.razor @@ -0,0 +1,44 @@ +@namespace Connected.Components +@inherits Tabs + +@{ + base.BuildRenderTree(__builder); +} + +@code { + + + protected override void OnInitialized() + { + base.Header = (context) => + @:@{ + if (string.IsNullOrEmpty(AddIconToolTip) == false) + { + + + + } + else + { + + } + } + ; + + base.TabPanelHeader = (context) => + @:@{ + if (string.IsNullOrEmpty(CloseIconToolTip) == false) + { + + + + } + else + { + + } + } + ; + } + +} diff --git a/Components/Tabs/DynamicTabs.razor.cs b/Components/Tabs/DynamicTabs.razor.cs new file mode 100644 index 0000000..399fa25 --- /dev/null +++ b/Components/Tabs/DynamicTabs.razor.cs @@ -0,0 +1,75 @@ +using Connected.Annotations; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class DynamicTabs : Tabs +{ + /// + /// The icon used for the add button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string AddTabIcon { get; set; } = Icons.Material.Filled.Add; + + /// + /// the icon used of the close button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string CloseTabIcon { get; set; } = Icons.Material.Filled.Close; + + /// + /// The callback, when the add button has been clicked + /// + [Parameter] public EventCallback AddTab { get; set; } + + /// + /// The callback, when the a close button has been clicked + /// + [Parameter] public EventCallback CloseTab { get; set; } + + /// + /// Classes that are applied to the icon button of the add button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string AddIconClass { get; set; } = string.Empty; + + /// + /// Styles that are applied to the icon button of the add button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string AddIconStyle { get; set; } = string.Empty; + + /// + /// Classes that are applied to the icon button of the close button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string CloseIconClass { get; set; } = string.Empty; + + /// + /// Styles that are applied to the icon button of the close button + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string CloseIconStyle { get; set; } = string.Empty; + + /// + /// Tooltip that shown when a user hovers of the add button. Empty or null, if no tooltip should be visible + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public string AddIconToolTip { get; set; } = string.Empty; + + /// + /// Tooltip that shown when a user hovers of the close button. Empty or null, if no tooltip should be visible + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public string CloseIconToolTip { get; set; } = string.Empty; + + protected override string InternalClassName { get; } = "mud-dynamic-tabs"; +} diff --git a/Components/Tabs/TabHeaderPosition.cs b/Components/Tabs/TabHeaderPosition.cs new file mode 100644 index 0000000..b41e51a --- /dev/null +++ b/Components/Tabs/TabHeaderPosition.cs @@ -0,0 +1,24 @@ + + +using System.ComponentModel; + +namespace Connected.Components; + +public enum TabHeaderPosition +{ + /// + /// Additional content is placed after the the first tab + /// + [Description("after")] + After, + /// + /// Additional content is placed before the first tab + /// + [Description("before")] + Before, + /// + /// No additional content is rendered + /// + [Description("none")] + None, +} diff --git a/Components/Tabs/TabPanel.razor b/Components/Tabs/TabPanel.razor new file mode 100644 index 0000000..fed0c73 --- /dev/null +++ b/Components/Tabs/TabPanel.razor @@ -0,0 +1,140 @@ +@namespace Connected.Components +@using Connected.Annotations; +@inherits UIComponent +@implements IAsyncDisposable + +@if (Parent?.KeepPanelsAlive == true) +{ +
    + @ChildContent +
    +} +else +{ + @if (Parent?.ActivePanel == this) + { + @ChildContent + } +} + +@code { + + private Boolean _disposed; + + [CascadingParameter] private Tabs Parent { get; set; } + + public ElementReference PanelRef; + + + /// + /// Text will be displayed in the TabPanel as TabTitle. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public string Text { get; set; } + + /// + /// Icon placed before the text if set. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public string Icon { get; set; } + + /// + /// If true, the tabpanel will be disabled. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public bool Disabled { get; set; } + + /// + /// Optional information to be showed into a badge + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public object BadgeData { get; set; } + + /// + /// Optional information to show the badge as a dot. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public bool BadgeDot { get; set; } + + /// + /// The color of the badge. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public ThemeColor BadgeColor { get; set; } = ThemeColor.Primary; + + /// + /// Unique TabPanel ID. Useful for activation when Panels are dynamically generated. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public object ID { get; set; } + + /// + /// Raised when tab is clicked + /// + [Parameter] public EventCallback OnClick { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Tab content of component. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment TabContent { get; set; } + + /// + /// Tab content wrapper of component. It is used to wrap the content of a tab heading in a user supplied div or component. + /// Use @context in the TabWrapperContent to render the tab header within your custom wrapper. + /// This is most useful with tooltips, which must wrap the entire content they refer to. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment TabWrapperContent { get; set; } + + /// + /// TabPanel Tooltip. It will be ignored if TabContent is provided. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public string ToolTip { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + if(firstRender == true && Parent != null) + { + await Parent.SetPanelRef(PanelRef); + } + } + + protected override void OnInitialized() + { + // NOTE: we must not throw here because we need the component to be able to live for the API docs to be able to infer default values + //if (Parent == null) + // throw new ArgumentNullException(nameof(Parent), "TabPanel must exist within a Tabs component"); + base.OnInitialized(); + + Parent?.AddPanel(this); + } + + public async ValueTask DisposeAsync() + { + if(_disposed == true) { return; } + + _disposed = true; + await Parent?.RemovePanel(this); + + } +} diff --git a/Components/Tabs/Tabs.razor b/Components/Tabs/Tabs.razor new file mode 100644 index 0000000..cc21840 --- /dev/null +++ b/Components/Tabs/Tabs.razor @@ -0,0 +1,112 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + +
    +
    + @if (HeaderPosition == TabHeaderPosition.Before && Header != null) + { +
    + @Header(this) +
    + } + @if (_showScrollButtons) + { +
    + +
    + } +
    +
    + @foreach (TabPanel panel in _panels) + { + @if (panel.TabContent == null && panel.TabWrapperContent == null) + { + + @RenderTab(panel) + + } + else + { + if (panel.TabWrapperContent == null) + { +
    + @RenderTab(panel) +
    + } + else + { +
    + @panel.TabWrapperContent(RenderTab(panel)) +
    + } + } + } + @if (!HideSlider) + { +
    + } +
    +
    + @if (_showScrollButtons) + { +
    + +
    + } + @if (HeaderPosition == TabHeaderPosition.After && Header != null) + { +
    + @Header(this) +
    + } +
    +
    + @if (PrePanelContent != null) + { + @PrePanelContent(ActivePanel) + } +
    + @ChildContent +
    +
    +
    + +@code { + RenderFragment RenderTab(TabPanel panel) => @
    ActivatePanel(panel, e, false) )> + @if (TabPanelHeaderPosition == TabHeaderPosition.Before && TabPanelHeader != null) + { +
    + @TabPanelHeader(panel) +
    + } + @if (panel.TabContent != null) + { + @panel.TabContent + } + else if (!String.IsNullOrEmpty(panel.Text) && String.IsNullOrEmpty(panel.Icon)) + { + @((MarkupString)panel.Text) + } + else if (String.IsNullOrEmpty(panel.Text) && !String.IsNullOrEmpty(panel.Icon)) + { + + } + else if (!String.IsNullOrEmpty(panel.Text) && !String.IsNullOrEmpty(panel.Icon)) + { + + @((MarkupString)panel.Text) + } + @if (panel.BadgeData != null || panel.BadgeDot) + { + + } + @if (TabPanelHeaderPosition == TabHeaderPosition.After && TabPanelHeader != null) + { +
    + @TabPanelHeader(panel) +
    + } +
    ; +} \ No newline at end of file diff --git a/Components/Tabs/Tabs.razor.cs b/Components/Tabs/Tabs.razor.cs new file mode 100644 index 0000000..b123f5c --- /dev/null +++ b/Components/Tabs/Tabs.razor.cs @@ -0,0 +1,746 @@ +using System.Globalization; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Interop; +using Connected.Services; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class Tabs : UIComponent, IAsyncDisposable +{ + private bool _isDisposed; + + private int _activePanelIndex = 0; + private int _scrollIndex = 0; + + private bool _isRendered = false; + private bool _prevButtonDisabled; + private bool _nextButtonDisabled; + private bool _showScrollButtons; + private bool _disableSliderAnimation; + private ElementReference _tabsContentSize; + private double _size; + private double _position; + private double _toolbarContentSize; + private double _allTabsSize; + private double _scrollPosition; + + private IResizeObserver _resizeObserver; + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + [Inject] private IResizeObserverFactory _resizeObserverFactory { get; set; } + + /// + /// If true, render all tabs and hide (display:none) every non-active. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public bool KeepPanelsAlive { get; set; } = false; + + /// + /// If true, sets the border-radius to theme default. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool Rounded { get; set; } + + /// + /// If true, sets a border between the content and the toolbar depending on the position. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool Border { get; set; } + + /// + /// If true, toolbar will be outlined. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool Outlined { get; set; } + + /// + /// If true, centers the tabitems. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool Centered { get; set; } + + /// + /// Hides the active tab slider. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool HideSlider { get; set; } + + /// + /// Icon to use for left pagination. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string PrevIcon { get; set; } = Icons.Filled.ChevronLeft; + + /// + /// Icon to use for right pagination. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string NextIcon { get; set; } = Icons.Filled.ChevronRight; + + /// + /// If true, always display the scroll buttons even if the tabs are smaller than the required with, buttons will be disabled if there is nothing to scroll. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool AlwaysShowScrollButtons { get; set; } + + /// + /// Sets the maxheight the component can have. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public int? MaxHeight { get; set; } = null; + + /// + /// Sets the position of the tabs itself. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public Position Position { get; set; } = Position.Top; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// The color of the tab slider. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public ThemeColor SliderColor { get; set; } = ThemeColor.Inherit; + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Inherit; + + /// + /// The color of the next/prev icons. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public ThemeColor ScrollIconColor { get; set; } = ThemeColor.Inherit; + + /// + /// The higher the number, the heavier the drop-shadow, applies around the whole component. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public int Elevation { set; get; } = 0; + + /// + /// If true, will apply elevation, rounded, outlined effects to the whole tab component instead of just toolbar. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool ApplyEffectsToContainer { get; set; } + + /// + /// If true, disables ripple effect. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool DisableRipple { get; set; } + + /// + /// If true, disables slider animation + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public bool DisableSliderAnimation { get => _disableSliderAnimation; set => _disableSliderAnimation = value; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// This fragment is placed between toolbar and panels. + /// It can be used to display additional content like an address line in a browser. + /// The active tab will be the content of this RenderFragement + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment PrePanelContent { get; set; } + + /// + /// Custom class/classes for TabPanel + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string TabPanelClass { get; set; } + + /// + /// Custom class/classes for Selected Content Panel + /// + [Parameter] + [Category(CategoryTypes.Tabs.Appearance)] + public string PanelClass { get; set; } + + public TabPanel ActivePanel { get; private set; } + + /// + /// The current active panel index. Also with Bidirectional Binding + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public int ActivePanelIndex + { + get => _activePanelIndex; + set + { + if (_activePanelIndex != value) + { + _activePanelIndex = value; + if (_isRendered) + ActivePanel = _panels[_activePanelIndex]; + ActivePanelIndexChanged.InvokeAsync(value); + } + } + } + + /// + /// Fired when ActivePanelIndex changes. + /// + [Parameter] + public EventCallback ActivePanelIndexChanged { get; set; } + + /// + /// A readonly list of the current panels. Panels should be added or removed through the RenderTree use this collection to get informations about the current panels + /// + public IReadOnlyList Panels { get; private set; } + + private List _panels; + + /// + /// A render fragment that is added before or after (based on the value of HeaderPosition) the tabs inside the header panel of the tab control + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment Header { get; set; } + + /// + /// Additional content specified by Header is placed either before the tabs, after or not at all + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public TabHeaderPosition HeaderPosition { get; set; } = TabHeaderPosition.After; + + /// + /// A render fragment that is added before or after (based on the value of HeaderPosition) inside each tab panel + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public RenderFragment TabPanelHeader { get; set; } + + /// + /// Additional content specified by Header is placed either before the tabs, after or not at all + /// + [Parameter] + [Category(CategoryTypes.Tabs.Behavior)] + public TabHeaderPosition TabPanelHeaderPosition { get; set; } = TabHeaderPosition.After; + + /// + /// Can be used in derived class to add a class to the main container. If not overwritten return an empty string + /// + protected virtual string InternalClassName { get; } = string.Empty; + + private string _prevIcon; + + private string _nextIcon; + + #region Life cycle management + + public Tabs() + { + _panels = new List(); + Panels = _panels.AsReadOnly(); + } + + protected override void OnInitialized() + { + _resizeObserver = _resizeObserverFactory.Create(); + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + if (_resizeObserver == null) + { + _resizeObserver = _resizeObserverFactory.Create(); + } + + Rerender(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + var items = _panels.Select(x => x.PanelRef).ToList(); + items.Add(_tabsContentSize); + + if (_panels.Count > 0) + ActivePanel = _panels[_activePanelIndex]; + + await _resizeObserver.Observe(items); + + _resizeObserver.OnResized += OnResized; + + Rerender(); + StateHasChanged(); + + _isRendered = true; + } + } + + public async ValueTask DisposeAsync() + { + if (_isDisposed == true) + return; + _isDisposed = true; + _resizeObserver.OnResized -= OnResized; + await _resizeObserver.DisposeAsync(); + } + + #endregion + + #region Children + + internal void AddPanel(TabPanel tabPanel) + { + _panels.Add(tabPanel); + if (_panels.Count == 1) + ActivePanel = tabPanel; + + StateHasChanged(); + } + + internal async Task SetPanelRef(ElementReference reference) + { + if (_isRendered == true && _resizeObserver.IsElementObserved(reference) == false) + { + await _resizeObserver.Observe(reference); + Rerender(); + StateHasChanged(); + } + } + + internal async Task RemovePanel(TabPanel tabPanel) + { + if (_isDisposed) + return; + + var index = _panels.IndexOf(tabPanel); + var newIndex = index; + if (ActivePanelIndex == index && index == _panels.Count - 1) + { + newIndex = index > 0 ? index - 1 : 0; + if (_panels.Count == 1) + { + ActivePanel = null; + } + } + else if (_activePanelIndex > index) + { + _activePanelIndex--; + await ActivePanelIndexChanged.InvokeAsync(_activePanelIndex); + } + + if (index != newIndex) + { + ActivePanelIndex = newIndex; + } + + _panels.Remove(tabPanel); + await _resizeObserver.Unobserve(tabPanel.PanelRef); + Rerender(); + StateHasChanged(); + } + + public void ActivatePanel(TabPanel panel, bool ignoreDisabledState = false) + { + ActivatePanel(panel, null, ignoreDisabledState); + } + + public void ActivatePanel(int index, bool ignoreDisabledState = false) + { + var panel = _panels[index]; + ActivatePanel(panel, null, ignoreDisabledState); + } + + public void ActivatePanel(object id, bool ignoreDisabledState = false) + { + var panel = _panels.Where((p) => Equals(p.ID, id)).FirstOrDefault(); + if (panel != null) + ActivatePanel(panel, null, ignoreDisabledState); + } + + private void ActivatePanel(TabPanel panel, MouseEventArgs ev, bool ignoreDisabledState = false) + { + if (!panel.Disabled || ignoreDisabledState) + { + ActivePanelIndex = _panels.IndexOf(panel); + + if (ev != null) + ActivePanel.OnClick.InvokeAsync(ev); + + CenterScrollPositionAroundSelectedItem(); + SetSliderState(); + SetScrollabilityStates(); + StateHasChanged(); + } + } + + #endregion + + #region Style and classes + protected string TabsClassnames => + new CssBuilder("mud-tabs") + .AddClass($"mud-tabs-rounded", ApplyEffectsToContainer && Rounded) + .AddClass($"mud-paper-outlined", ApplyEffectsToContainer && Outlined) + .AddClass($"mud-elevation-{Elevation}", ApplyEffectsToContainer && Elevation != 0) + .AddClass($"mud-tabs-reverse", Position == Position.Bottom) + .AddClass($"mud-tabs-vertical", IsVerticalTabs()) + .AddClass($"mud-tabs-vertical-reverse", Position == Position.Right && !RightToLeft || (Position == Position.Left) && RightToLeft || Position == Position.End) + .AddClass(InternalClassName) + .AddClass(Class) + .Build(); + + protected string ToolbarClassnames => + new CssBuilder("mud-tabs-toolbar") + .AddClass($"mud-tabs-rounded", !ApplyEffectsToContainer && Rounded) + .AddClass($"mud-tabs-vertical", IsVerticalTabs()) + .AddClass($"mud-tabs-toolbar-{Color.ToDescriptionString()}", Color != ThemeColor.Default) + .AddClass($"mud-tabs-border-{ConvertPosition(Position).ToDescriptionString()}", Border) + .AddClass($"mud-paper-outlined", !ApplyEffectsToContainer && Outlined) + .AddClass($"mud-elevation-{Elevation}", !ApplyEffectsToContainer && Elevation != 0) + .Build(); + + protected string WrapperClassnames => + new CssBuilder("mud-tabs-toolbar-wrapper") + .AddClass($"mud-tabs-centered", Centered) + .AddClass($"mud-tabs-vertical", IsVerticalTabs()) + .Build(); + + protected string WrapperScrollStyle => + new StyleBuilder() + .AddStyle("transform", $"translateX({(-1 * _scrollPosition).ToString(CultureInfo.InvariantCulture)}px)", Position is Position.Top or Position.Bottom) + .AddStyle("transform", $"translateY({(-1 * _scrollPosition).ToString(CultureInfo.InvariantCulture)}px)", IsVerticalTabs()) + .Build(); + + protected string PanelsClassnames => + new CssBuilder("mud-tabs-panels") + .AddClass($"mud-tabs-vertical", IsVerticalTabs()) + .AddClass(PanelClass) + .Build(); + + protected string SliderClass => + new CssBuilder("mud-tab-slider") + .AddClass($"mud-{SliderColor.ToDescriptionString()}", SliderColor != ThemeColor.Inherit) + .AddClass($"mud-tab-slider-horizontal", Position is Position.Top or Position.Bottom) + .AddClass($"mud-tab-slider-vertical", IsVerticalTabs()) + .AddClass($"mud-tab-slider-horizontal-reverse", Position == Position.Bottom) + .AddClass($"mud-tab-slider-vertical-reverse", Position == Position.Right || Position == Position.Start && RightToLeft || Position == Position.End && !RightToLeft) + .Build(); + + protected string MaxHeightStyles => + new StyleBuilder() + .AddStyle("max-height", MaxHeight.ToPx(), MaxHeight != null) + .Build(); + + protected string SliderStyle => RightToLeft ? + new StyleBuilder() + .AddStyle("width", _size.ToPx(), Position is Position.Top or Position.Bottom) + .AddStyle("right", _position.ToPx(), Position is Position.Top or Position.Bottom) + .AddStyle("transition", _disableSliderAnimation ? "none" : "right .3s cubic-bezier(.64,.09,.08,1);", Position is Position.Top or Position.Bottom) + .AddStyle("transition", _disableSliderAnimation ? "none" : "top .3s cubic-bezier(.64,.09,.08,1);", IsVerticalTabs()) + .AddStyle("height", _size.ToPx(), IsVerticalTabs()) + .AddStyle("top", _position.ToPx(), IsVerticalTabs()) + .Build() : new StyleBuilder() + .AddStyle("width", _size.ToPx(), Position is Position.Top or Position.Bottom) + .AddStyle("left", _position.ToPx(), Position is Position.Top or Position.Bottom) + .AddStyle("transition", _disableSliderAnimation ? "none" : "left .3s cubic-bezier(.64,.09,.08,1);", Position is Position.Top or Position.Bottom) + .AddStyle("transition", _disableSliderAnimation ? "none" : "top .3s cubic-bezier(.64,.09,.08,1);", IsVerticalTabs()) + .AddStyle("height", _size.ToPx(), IsVerticalTabs()) + .AddStyle("top", _position.ToPx(), IsVerticalTabs()) + .Build(); + + private bool IsVerticalTabs() + { + return Position is Position.Left or Position.Right or Position.Start or Position.End; + } + + private Position ConvertPosition(Position position) + { + return position switch + { + Position.Start => RightToLeft ? Position.Right : Position.Left, + Position.End => RightToLeft ? Position.Left : Position.Right, + _ => position + }; + } + + string GetTabClass(TabPanel panel) + { + var tabClass = new CssBuilder("mud-tab") + .AddClass($"mud-tab-active", when: () => panel == ActivePanel) + .AddClass($"mud-disabled", panel.Disabled) + .AddClass($"mud-ripple", !DisableRipple) + .AddClass(TabPanelClass) + .AddClass(panel.Class) + .Build(); + + return tabClass; + } + + private Placement GetTooltipPlacement() + { + if (Position == Position.Right) + return Placement.Left; + else if (Position == Position.Left) + return Placement.Right; + else if (Position == Position.Bottom) + return Placement.Top; + else + return Placement.Bottom; + } + + string GetTabStyle(TabPanel panel) + { + var tabStyle = new StyleBuilder() + .AddStyle(panel.Style) + .Build(); + + return tabStyle; + } + + #endregion + + #region Rendering and placement + + private void Rerender() + { + _nextIcon = RightToLeft ? PrevIcon : NextIcon; + _prevIcon = RightToLeft ? NextIcon : PrevIcon; + + GetToolbarContentSize(); + GetAllTabsSize(); + SetScrollButtonVisibility(); + SetSliderState(); + SetScrollabilityStates(); + } + + private async void OnResized(IDictionary changes) + { + Rerender(); + await InvokeAsync(StateHasChanged); + } + + private void SetSliderState() + { + if (ActivePanel == null) { return; } + + _position = GetLengthOfPanelItems(ActivePanel); + _size = GetRelevantSize(ActivePanel.PanelRef); + } + + private void GetToolbarContentSize() => _toolbarContentSize = GetRelevantSize(_tabsContentSize); + + private void GetAllTabsSize() + { + double totalTabsSize = 0; + + foreach (var panel in _panels) + { + totalTabsSize += GetRelevantSize(panel.PanelRef); + } + + _allTabsSize = totalTabsSize; + } + + private double GetRelevantSize(ElementReference reference) => Position switch + { + Position.Top or Position.Bottom => _resizeObserver.GetWidth(reference), + _ => _resizeObserver.GetHeight(reference) + }; + + private double GetLengthOfPanelItems(TabPanel panel, bool inclusive = false) + { + var value = 0.0; + foreach (var item in _panels) + { + if (item == panel) + { + if (inclusive) + { + value += GetRelevantSize(item.PanelRef); + } + + break; + } + + value += GetRelevantSize(item.PanelRef); + } + + return value; + } + + private double GetPanelLength(TabPanel panel) => panel == null ? 0.0 : GetRelevantSize(panel.PanelRef); + + #endregion + + #region scrolling + + private void SetScrollButtonVisibility() + { + _showScrollButtons = AlwaysShowScrollButtons || _allTabsSize > _toolbarContentSize; + } + + private void ScrollPrev() + { + _scrollIndex = Math.Max(_scrollIndex - GetVisiblePanels(), 0); + ScrollToItem(_panels[_scrollIndex]); + SetScrollabilityStates(); + } + + private void ScrollNext() + { + _scrollIndex = Math.Min(_scrollIndex + GetVisiblePanels(), _panels.Count - 1); + ScrollToItem(_panels[_scrollIndex]); + SetScrollabilityStates(); + } + + /// + /// Calculates the amount of panels that are completely visible inside the toolbar content area. Panels that are just partially visible are not considered here! + /// + /// The amount of panels visible inside the toolbar area. CAUTION: Might return 0! + private int GetVisiblePanels() + { + var x = 0D; + var count = 0; + + var toolbarContentSize = GetRelevantSize(_tabsContentSize); + + foreach (var panel in _panels) + { + x += GetRelevantSize(panel.PanelRef); + + if (x < toolbarContentSize) + { + count++; + } + else + { + break; + } + } + + return count; + } + + private void ScrollToItem(TabPanel panel) + { + var position = GetLengthOfPanelItems(panel); + _scrollPosition = RightToLeft ? -position : position; + } + + private bool IsAfterLastPanelIndex(int index) => index >= _panels.Count; + private bool IsBeforeFirstPanelIndex(int index) => index < 0; + + private void CenterScrollPositionAroundSelectedItem() + { + TabPanel panelToStart = ActivePanel; + var length = GetPanelLength(panelToStart); + if (length >= _toolbarContentSize) + { + ScrollToItem(panelToStart); + return; + } + + var indexCorrection = 1; + while (true) + { + var panelAfterIndex = _activePanelIndex + indexCorrection; + if (!IsAfterLastPanelIndex(panelAfterIndex)) + { + length += GetPanelLength(_panels[panelAfterIndex]); + } + + if (length >= _toolbarContentSize) + { + _scrollIndex = _panels.IndexOf(panelToStart); + ScrollToItem(panelToStart); + break; + } + + length = _toolbarContentSize - length; + + var panelBeforeindex = _activePanelIndex - indexCorrection; + if (!IsBeforeFirstPanelIndex(panelBeforeindex)) + { + length -= GetPanelLength(_panels[panelBeforeindex]); + } + else + { + break; + } + + if (length < 0) + { + _scrollIndex = _panels.IndexOf(panelToStart); + ScrollToItem(panelToStart); + break; + } + + length = _toolbarContentSize - length; + panelToStart = _panels[_activePanelIndex - indexCorrection]; + + indexCorrection++; + } + + _scrollIndex = _panels.IndexOf(panelToStart); + ScrollToItem(panelToStart); + + SetScrollabilityStates(); + } + + private void SetScrollabilityStates() + { + var isEnoughSpace = _allTabsSize <= _toolbarContentSize; + + if (isEnoughSpace) + { + _nextButtonDisabled = true; + _prevButtonDisabled = true; + } + else + { + // Disable next button if the last panel is completely visible + _nextButtonDisabled = Math.Abs(_scrollPosition) >= GetLengthOfPanelItems(_panels.Last(), true) - _toolbarContentSize; + _prevButtonDisabled = _scrollIndex == 0; + } + } + + #endregion +} diff --git a/Components/TextField/TextField.razor b/Components/TextField/TextField.razor new file mode 100644 index 0000000..0c5d5bf --- /dev/null +++ b/Components/TextField/TextField.razor @@ -0,0 +1,95 @@ +@namespace Connected.Components +@typeparam T +@inherits DebouncedInput + + + + + + @if (_mask == null) + { + + } + else + { + + } + + + + \ No newline at end of file diff --git a/Components/TextField/TextField.razor.cs b/Components/TextField/TextField.razor.cs new file mode 100644 index 0000000..b5f6dfc --- /dev/null +++ b/Components/TextField/TextField.razor.cs @@ -0,0 +1,155 @@ +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class TextField : DebouncedInput +{ + protected string Classname => + new CssBuilder("mud-input-input-control") + .AddClass(Class) + .Build(); + + public Input InputReference { get; private set; } + private Mask _maskReference; + + /// + /// Type of the input element. It should be a valid HTML5 input type. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public InputType InputType { get; set; } = InputType.Text; + + internal override InputType GetInputType() => InputType; + + private string GetCounterText() => Counter == null ? string.Empty : (Counter == 0 ? (string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") : ((string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + $" / {Counter}")); + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Clearable { get; set; } = false; + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] public EventCallback OnClearButtonClick { get; set; } + + public override ValueTask FocusAsync() + { + if (_mask == null) + return InputReference.FocusAsync(); + else + return _maskReference.FocusAsync(); + } + + public override ValueTask BlurAsync() + { + if (_mask == null) + return InputReference.BlurAsync(); + else + return _maskReference.BlurAsync(); + } + + public override ValueTask SelectAsync() + { + if (_mask == null) + return InputReference.SelectAsync(); + else + return _maskReference.SelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + if (_mask == null) + return InputReference.SelectRangeAsync(pos1, pos2); + else + return _maskReference.SelectRangeAsync(pos1, pos2); + } + + protected override void ResetValue() + { + if (_mask == null) + InputReference.Reset(); + else + _maskReference.Reset(); + base.ResetValue(); + } + + /// + /// Clear the text field, set Value to default(T) and Text to null + /// + /// + public Task Clear() + { + if (_mask == null) + return InputReference.SetText(null); + else + return _maskReference.Clear(); + } + + /// + /// Sets the input text from outside programmatically + /// + /// + /// + public async Task SetText(string text) + { + if (_mask == null) + { + if (InputReference != null) + await InputReference.SetText(text); + return; + } + await _maskReference.Clear(); + _maskReference.OnPaste(text); + } + + + private IMask _mask = null; + + /// + /// Provide a masking object. Built-in masks are PatternMask, MultiMask, RegexMask and BlockMask + /// Note: when Mask is set, TextField will ignore some properties such as Lines, Pattern or HideSpinButtons, OnKeyDown and OnKeyUp, etc. + /// + [Parameter] + [Category(CategoryTypes.General.Data)] + public IMask Mask + { + get => _maskReference?.MaskKind ?? _mask; // this might look strange, but it is absolutely necessary due to how Mask works. + set + { + _mask = value; + } + } + + protected override Task SetValueAsync(T value, bool updateText = true) + { + if (_mask != null) + { + var textValue = Converter.Set(value); + _mask.SetText(textValue); + textValue = Mask.GetCleanText(); + value = Converter.Get(textValue); + } + return base.SetValueAsync(value, updateText); + } + + protected override Task SetTextAsync(string text, bool updateValue = true) + { + if (_mask != null) + { + _mask.SetText(text); + text = _mask.Text; + } + return base.SetTextAsync(text, updateValue); + } + + private async Task OnMaskedValueChanged(string s) + { + await SetTextAsync(s); + } +} \ No newline at end of file diff --git a/Components/ThemeProvider/ThemeProvider.razor b/Components/ThemeProvider/ThemeProvider.razor new file mode 100644 index 0000000..5f4a846 --- /dev/null +++ b/Components/ThemeProvider/ThemeProvider.razor @@ -0,0 +1,21 @@ +@namespace Connected.Components +@inherits ThemeProviderBase + +@if(!DefaultScrollbar) +{ + @((MarkupString)BuildMudBlazorScrollbar()) +} + +@*Needed for charts, maybe put in bool, IncludeCharts="true"??*@ + + +@((MarkupString)BuildTheme()) + + + + + diff --git a/Components/ThemeProvider/ThemeProvider.razor.cs b/Components/ThemeProvider/ThemeProvider.razor.cs new file mode 100644 index 0000000..7c2aace --- /dev/null +++ b/Components/ThemeProvider/ThemeProvider.razor.cs @@ -0,0 +1,410 @@ +using System.Globalization; +using System.Text; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected.Components; + +public class ThemeProviderBase : ComponentBase +{ + /// + /// The theme used by the application. + /// + [Parameter] + public Theme Theme { get; set; } + + /// + /// If true, will not apply MudBlazor styled scrollbar and use browser default. + /// + [Parameter] + public bool DefaultScrollbar { get; set; } + + #region Dark mode handling + + public ThemeProviderBase() + { + _dotNetRef = DotNetObjectReference.Create(this); + } + + private readonly DotNetObjectReference _dotNetRef; + [Inject] private IJSRuntime JsRuntime { get; set; } + + /// + /// Returns the dark mode preference of the user. True if dark mode is preferred. + /// + /// + public async Task GetSystemPreference() + { + return await JsRuntime.InvokeAsync("darkModeChange", _dotNetRef); + } + + internal bool _isDarkMode; + + /// + /// The active palette of the theme. + /// + [Parameter] + public bool IsDarkMode + { + get => _isDarkMode; + set + { + if (_isDarkMode == value) + { + return; + } + + _isDarkMode = value; + IsDarkModeChanged.InvokeAsync(_isDarkMode); + } + } + + /// + /// Invoked when the dark mode changes. + /// + [Parameter] + public EventCallback IsDarkModeChanged + { + get; + set; + } + + #endregion + + protected override void OnInitialized() + { + Theme ??= new Theme(); + } + + protected string BuildTheme() + { + var theme = new StringBuilder(); + theme.AppendLine(""); + return theme.ToString(); + } + + protected string BuildMudBlazorScrollbar() + { + var scrollbar = new StringBuilder(); + scrollbar.AppendLine(""); + return scrollbar.ToString(); + } + + // private const string Breakpoint = "mud-breakpoint"; + private const string Palette = "mud-palette"; + private const string Elevation = "mud-elevation"; + private const string Typography = "mud-typography"; + private const string LayoutProperties = "mud"; + private const string Zindex = "mud-zindex"; + + protected virtual void GenerateTheme(StringBuilder theme) + { + if (Theme == null) + return; + var palette = _isDarkMode == false ? Theme.Palette : Theme.PaletteDark; + + //Palette + theme.AppendLine($"--{Palette}-black: {palette.Black};"); + theme.AppendLine($"--{Palette}-white: {palette.White};"); + + theme.AppendLine($"--{Palette}-primary: {palette.Primary};"); + theme.AppendLine( + $"--{Palette}-primary-rgb: {palette.Primary.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-primary-text: {palette.PrimaryContrastText};"); + theme.AppendLine($"--{Palette}-primary-darken: {palette.PrimaryDarken};"); + theme.AppendLine($"--{Palette}-primary-lighten: {palette.PrimaryLighten};"); + theme.AppendLine( + $"--{Palette}-primary-hover: {palette.Primary.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-secondary: {palette.Secondary};"); + theme.AppendLine( + $"--{Palette}-secondary-rgb: {palette.Secondary.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-secondary-text: {palette.SecondaryContrastText};"); + theme.AppendLine($"--{Palette}-secondary-darken: {palette.SecondaryDarken};"); + theme.AppendLine($"--{Palette}-secondary-lighten: {palette.SecondaryLighten};"); + theme.AppendLine( + $"--{Palette}-secondary-hover: {palette.Secondary.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-tertiary: {palette.Tertiary};"); + theme.AppendLine( + $"--{Palette}-tertiary-rgb: {palette.Tertiary.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-tertiary-text: {palette.TertiaryContrastText};"); + theme.AppendLine($"--{Palette}-tertiary-darken: {palette.TertiaryDarken};"); + theme.AppendLine($"--{Palette}-tertiary-lighten: {palette.TertiaryLighten};"); + theme.AppendLine( + $"--{Palette}-tertiary-hover: {palette.Tertiary.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-info: {palette.Info};"); + theme.AppendLine( + $"--{Palette}-info-rgb: {palette.Info.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-info-text: {palette.InfoContrastText};"); + theme.AppendLine($"--{Palette}-info-darken: {palette.InfoDarken};"); + theme.AppendLine($"--{Palette}-info-lighten: {palette.InfoLighten};"); + theme.AppendLine( + $"--{Palette}-info-hover: {palette.Info.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-success: {palette.Success};"); + theme.AppendLine( + $"--{Palette}-success-rgb: {palette.Success.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-success-text: {palette.SuccessContrastText};"); + theme.AppendLine($"--{Palette}-success-darken: {palette.SuccessDarken};"); + theme.AppendLine($"--{Palette}-success-lighten: {palette.SuccessLighten};"); + theme.AppendLine( + $"--{Palette}-success-hover: {palette.Success.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-warning: {palette.Warning};"); + theme.AppendLine( + $"--{Palette}-warning-rgb: {palette.Warning.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-warning-text: {palette.WarningContrastText};"); + theme.AppendLine($"--{Palette}-warning-darken: {palette.WarningDarken};"); + theme.AppendLine($"--{Palette}-warning-lighten: {palette.WarningLighten};"); + theme.AppendLine( + $"--{Palette}-warning-hover: {palette.Warning.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-error: {palette.Error};"); + theme.AppendLine( + $"--{Palette}-error-rgb: {palette.Error.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-error-text: {palette.ErrorContrastText};"); + theme.AppendLine($"--{Palette}-error-darken: {palette.ErrorDarken};"); + theme.AppendLine($"--{Palette}-error-lighten: {palette.ErrorLighten};"); + theme.AppendLine( + $"--{Palette}-error-hover: {palette.Error.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-dark: {palette.Dark};"); + theme.AppendLine( + $"--{Palette}-dark-rgb: {palette.Dark.ToString(ColorOutputFormats.ColorElements)};"); + theme.AppendLine($"--{Palette}-dark-text: {palette.DarkContrastText};"); + theme.AppendLine($"--{Palette}-dark-darken: {palette.DarkDarken};"); + theme.AppendLine($"--{Palette}-dark-lighten: {palette.DarkLighten};"); + theme.AppendLine( + $"--{Palette}-dark-hover: {palette.Dark.SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + + theme.AppendLine($"--{Palette}-text-primary: {palette.TextPrimary};"); + theme.AppendLine($"--{Palette}-text-secondary: {palette.TextSecondary};"); + theme.AppendLine($"--{Palette}-text-disabled: {palette.TextDisabled};"); + + theme.AppendLine($"--{Palette}-action-default: {palette.ActionDefault};"); + theme.AppendLine( + $"--{Palette}-action-default-hover: {new Color(Colors.Shades.Black).SetAlpha(palette.HoverOpacity).ToString(ColorOutputFormats.RGBA)};"); + theme.AppendLine($"--{Palette}-action-disabled: {palette.ActionDisabled};"); + theme.AppendLine( + $"--{Palette}-action-disabled-background: {palette.ActionDisabledBackground};"); + + theme.AppendLine($"--{Palette}-surface: {palette.Surface};"); + theme.AppendLine($"--{Palette}-background: {palette.Background};"); + theme.AppendLine($"--{Palette}-background-grey: {palette.BackgroundGrey};"); + theme.AppendLine($"--{Palette}-drawer-background: {palette.DrawerBackground};"); + theme.AppendLine($"--{Palette}-drawer-text: {palette.DrawerText};"); + theme.AppendLine($"--{Palette}-drawer-icon: {palette.DrawerIcon};"); + theme.AppendLine($"--{Palette}-appbar-background: {palette.AppbarBackground};"); + theme.AppendLine($"--{Palette}-appbar-text: {palette.AppbarText};"); + + theme.AppendLine($"--{Palette}-lines-default: {palette.LinesDefault};"); + theme.AppendLine($"--{Palette}-lines-inputs: {palette.LinesInputs};"); + + theme.AppendLine($"--{Palette}-table-lines: {palette.TableLines};"); + theme.AppendLine($"--{Palette}-table-striped: {palette.TableStriped};"); + theme.AppendLine($"--{Palette}-table-hover: {palette.TableHover};"); + + theme.AppendLine($"--{Palette}-divider: {palette.Divider};"); + theme.AppendLine($"--{Palette}-divider-light: {palette.DividerLight};"); + + theme.AppendLine($"--{Palette}-grey-default: {palette.GrayDefault};"); + theme.AppendLine($"--{Palette}-grey-light: {palette.GrayLight};"); + theme.AppendLine($"--{Palette}-grey-lighter: {palette.GrayLighter};"); + theme.AppendLine($"--{Palette}-grey-dark: {palette.GrayDark};"); + theme.AppendLine($"--{Palette}-grey-darker: {palette.GrayDarker};"); + + theme.AppendLine($"--{Palette}-overlay-dark: {palette.OverlayDark};"); + theme.AppendLine($"--{Palette}-overlay-light: {palette.OverlayLight};"); + + //Elevations + theme.AppendLine($"--{Elevation}-0: {Theme.Shadows.Elevation.GetValue(0)};"); + theme.AppendLine($"--{Elevation}-1: {Theme.Shadows.Elevation.GetValue(1)};"); + theme.AppendLine($"--{Elevation}-2: {Theme.Shadows.Elevation.GetValue(2)};"); + theme.AppendLine($"--{Elevation}-3: {Theme.Shadows.Elevation.GetValue(3)};"); + theme.AppendLine($"--{Elevation}-4: {Theme.Shadows.Elevation.GetValue(4)};"); + theme.AppendLine($"--{Elevation}-5: {Theme.Shadows.Elevation.GetValue(5)};"); + theme.AppendLine($"--{Elevation}-6: {Theme.Shadows.Elevation.GetValue(6)};"); + theme.AppendLine($"--{Elevation}-7: {Theme.Shadows.Elevation.GetValue(7)};"); + theme.AppendLine($"--{Elevation}-8: {Theme.Shadows.Elevation.GetValue(8)};"); + theme.AppendLine($"--{Elevation}-9: {Theme.Shadows.Elevation.GetValue(9)};"); + theme.AppendLine($"--{Elevation}-10: {Theme.Shadows.Elevation.GetValue(10)};"); + theme.AppendLine($"--{Elevation}-11: {Theme.Shadows.Elevation.GetValue(11)};"); + theme.AppendLine($"--{Elevation}-12: {Theme.Shadows.Elevation.GetValue(12)};"); + theme.AppendLine($"--{Elevation}-13: {Theme.Shadows.Elevation.GetValue(13)};"); + theme.AppendLine($"--{Elevation}-14: {Theme.Shadows.Elevation.GetValue(14)};"); + theme.AppendLine($"--{Elevation}-15: {Theme.Shadows.Elevation.GetValue(15)};"); + theme.AppendLine($"--{Elevation}-16: {Theme.Shadows.Elevation.GetValue(16)};"); + theme.AppendLine($"--{Elevation}-17: {Theme.Shadows.Elevation.GetValue(17)};"); + theme.AppendLine($"--{Elevation}-18: {Theme.Shadows.Elevation.GetValue(18)};"); + theme.AppendLine($"--{Elevation}-19: {Theme.Shadows.Elevation.GetValue(19)};"); + theme.AppendLine($"--{Elevation}-20: {Theme.Shadows.Elevation.GetValue(20)};"); + theme.AppendLine($"--{Elevation}-21: {Theme.Shadows.Elevation.GetValue(21)};"); + theme.AppendLine($"--{Elevation}-22: {Theme.Shadows.Elevation.GetValue(22)};"); + theme.AppendLine($"--{Elevation}-23: {Theme.Shadows.Elevation.GetValue(23)};"); + theme.AppendLine($"--{Elevation}-24: {Theme.Shadows.Elevation.GetValue(24)};"); + theme.AppendLine($"--{Elevation}-25: {Theme.Shadows.Elevation.GetValue(25)};"); + + //Layout Properties + theme.AppendLine( + $"--{LayoutProperties}-default-borderradius: {Theme.LayoutProperties.DefaultBorderRadius};"); + theme.AppendLine($"--{LayoutProperties}-drawer-width-left: {Theme.LayoutProperties.DrawerWidthLeft};"); + theme.AppendLine($"--{LayoutProperties}-drawer-width-right: {Theme.LayoutProperties.DrawerWidthRight};"); + theme.AppendLine( + $"--{LayoutProperties}-drawer-width-mini-left: {Theme.LayoutProperties.DrawerMiniWidthLeft};"); + theme.AppendLine( + $"--{LayoutProperties}-drawer-width-mini-right: {Theme.LayoutProperties.DrawerMiniWidthRight};"); + theme.AppendLine($"--{LayoutProperties}-appbar-height: {Theme.LayoutProperties.AppbarHeight};"); + + //Breakpoint + //theme.AppendLine($"--{Breakpoint}-xs: {Theme.Breakpoints.xs};"); + //theme.AppendLine($"--{Breakpoint}-sm: {Theme.Breakpoints.sm};"); + //theme.AppendLine($"--{Breakpoint}-md: {Theme.Breakpoints.md};"); + //theme.AppendLine($"--{Breakpoint}-lg: {Theme.Breakpoints.lg};"); + //theme.AppendLine($"--{Breakpoint}-xl: {Theme.Breakpoints.xl};"); + //theme.AppendLine($"--{Breakpoint}-xxl: {Theme.Breakpoints.xxl};"); + + //Typography + theme.AppendLine( + $"--{Typography}-default-family: '{string.Join("','", Theme.Typography.Default.FontFamily)}';"); + theme.AppendLine($"--{Typography}-default-size: {Theme.Typography.Default.FontSize};"); + theme.AppendLine($"--{Typography}-default-weight: {Theme.Typography.Default.FontWeight};"); + theme.AppendLine( + $"--{Typography}-default-lineheight: {Theme.Typography.Default.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-default-letterspacing: {Theme.Typography.Default.LetterSpacing};"); + theme.AppendLine($"--{Typography}-default-text-transform: {Theme.Typography.Default.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h1-family: '{string.Join("','", (Theme.Typography.H1.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H1.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h1-size: {Theme.Typography.H1.FontSize};"); + theme.AppendLine($"--{Typography}-h1-weight: {Theme.Typography.H1.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h1-lineheight: {Theme.Typography.H1.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h1-letterspacing: {Theme.Typography.H1.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h1-text-transform: {Theme.Typography.H1.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h2-family: '{string.Join("','", (Theme.Typography.H2.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H2.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h2-size: {Theme.Typography.H2.FontSize};"); + theme.AppendLine($"--{Typography}-h2-weight: {Theme.Typography.H2.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h2-lineheight: {Theme.Typography.H2.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h2-letterspacing: {Theme.Typography.H2.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h2-text-transform: {Theme.Typography.H2.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h3-family: '{string.Join("','", (Theme.Typography.H3.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H3.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h3-size: {Theme.Typography.H3.FontSize};"); + theme.AppendLine($"--{Typography}-h3-weight: {Theme.Typography.H3.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h3-lineheight: {Theme.Typography.H3.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h3-letterspacing: {Theme.Typography.H3.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h3-text-transform: {Theme.Typography.H3.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h4-family: '{string.Join("','", (Theme.Typography.H4.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H4.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h4-size: {Theme.Typography.H4.FontSize};"); + theme.AppendLine($"--{Typography}-h4-weight: {Theme.Typography.H4.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h4-lineheight: {Theme.Typography.H4.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h4-letterspacing: {Theme.Typography.H4.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h4-text-transform: {Theme.Typography.H4.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h5-family: '{string.Join("','", (Theme.Typography.H5.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H5.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h5-size: {Theme.Typography.H5.FontSize};"); + theme.AppendLine($"--{Typography}-h5-weight: {Theme.Typography.H5.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h5-lineheight: {Theme.Typography.H5.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h5-letterspacing: {Theme.Typography.H5.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h5-text-transform: {Theme.Typography.H5.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-h6-family: '{string.Join("','", (Theme.Typography.H6.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.H6.FontFamily))}';"); + theme.AppendLine($"--{Typography}-h6-size: {Theme.Typography.H6.FontSize};"); + theme.AppendLine($"--{Typography}-h6-weight: {Theme.Typography.H6.FontWeight};"); + theme.AppendLine( + $"--{Typography}-h6-lineheight: {Theme.Typography.H6.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-h6-letterspacing: {Theme.Typography.H6.LetterSpacing};"); + theme.AppendLine($"--{Typography}-h6-text-transform: {Theme.Typography.H6.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-subtitle1-family: '{string.Join("','", (Theme.Typography.Subtitle1.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Subtitle1.FontFamily))}';"); + theme.AppendLine($"--{Typography}-subtitle1-size: {Theme.Typography.Subtitle1.FontSize};"); + theme.AppendLine($"--{Typography}-subtitle1-weight: {Theme.Typography.Subtitle1.FontWeight};"); + theme.AppendLine( + $"--{Typography}-subtitle1-lineheight: {Theme.Typography.Subtitle1.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-subtitle1-letterspacing: {Theme.Typography.Subtitle1.LetterSpacing};"); + theme.AppendLine($"--{Typography}-subtitle1-text-transform: {Theme.Typography.Subtitle1.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-subtitle2-family: '{string.Join("','", (Theme.Typography.Subtitle2.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Subtitle2.FontFamily))}';"); + theme.AppendLine($"--{Typography}-subtitle2-size: {Theme.Typography.Subtitle2.FontSize};"); + theme.AppendLine($"--{Typography}-subtitle2-weight: {Theme.Typography.Subtitle2.FontWeight};"); + theme.AppendLine( + $"--{Typography}-subtitle2-lineheight: {Theme.Typography.Subtitle2.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-subtitle2-letterspacing: {Theme.Typography.Subtitle2.LetterSpacing};"); + theme.AppendLine($"--{Typography}-subtitle2-text-transform: {Theme.Typography.Subtitle2.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-body1-family: '{string.Join("','", (Theme.Typography.Body1.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Body1.FontFamily))}';"); + theme.AppendLine($"--{Typography}-body1-size: {Theme.Typography.Body1.FontSize};"); + theme.AppendLine($"--{Typography}-body1-weight: {Theme.Typography.Body1.FontWeight};"); + theme.AppendLine( + $"--{Typography}-body1-lineheight: {Theme.Typography.Body1.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-body1-letterspacing: {Theme.Typography.Body1.LetterSpacing};"); + theme.AppendLine($"--{Typography}-body1-text-transform: {Theme.Typography.Body1.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-body2-family: '{string.Join("','", (Theme.Typography.Body2.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Body2.FontFamily))}';"); + theme.AppendLine($"--{Typography}-body2-size: {Theme.Typography.Body2.FontSize};"); + theme.AppendLine($"--{Typography}-body2-weight: {Theme.Typography.Body2.FontWeight};"); + theme.AppendLine( + $"--{Typography}-body2-lineheight: {Theme.Typography.Body2.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-body2-letterspacing: {Theme.Typography.Body2.LetterSpacing};"); + theme.AppendLine($"--{Typography}-body2-text-transform: {Theme.Typography.Body2.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-button-family: '{string.Join("','", (Theme.Typography.Button.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Button.FontFamily))}';"); + theme.AppendLine($"--{Typography}-button-size: {Theme.Typography.Button.FontSize};"); + theme.AppendLine($"--{Typography}-button-weight: {Theme.Typography.Button.FontWeight};"); + theme.AppendLine( + $"--{Typography}-button-lineheight: {Theme.Typography.Button.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-button-letterspacing: {Theme.Typography.Button.LetterSpacing};"); + theme.AppendLine($"--{Typography}-button-text-transform: {Theme.Typography.Button.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-caption-family: '{string.Join("','", (Theme.Typography.Caption.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Caption.FontFamily))}';"); + theme.AppendLine($"--{Typography}-caption-size: {Theme.Typography.Caption.FontSize};"); + theme.AppendLine($"--{Typography}-caption-weight: {Theme.Typography.Caption.FontWeight};"); + theme.AppendLine( + $"--{Typography}-caption-lineheight: {Theme.Typography.Caption.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-caption-letterspacing: {Theme.Typography.Caption.LetterSpacing};"); + theme.AppendLine($"--{Typography}-caption-text-transform: {Theme.Typography.Caption.TextTransform};"); + + theme.AppendLine( + $"--{Typography}-overline-family: '{string.Join("','", (Theme.Typography.Overline.FontFamily == null ? Theme.Typography.Default.FontFamily : Theme.Typography.Overline.FontFamily))}';"); + theme.AppendLine($"--{Typography}-overline-size: {Theme.Typography.Overline.FontSize};"); + theme.AppendLine($"--{Typography}-overline-weight: {Theme.Typography.Overline.FontWeight};"); + theme.AppendLine( + $"--{Typography}-overline-lineheight: {Theme.Typography.Overline.LineHeight.ToString(CultureInfo.InvariantCulture)};"); + theme.AppendLine($"--{Typography}-overline-letterspacing: {Theme.Typography.Overline.LetterSpacing};"); + theme.AppendLine($"--{Typography}-overline-text-transform: {Theme.Typography.Overline.TextTransform};"); + + + //Z-Index + theme.AppendLine($"--{Zindex}-drawer: {Theme.ZIndex.Drawer};"); + theme.AppendLine($"--{Zindex}-appbar: {Theme.ZIndex.AppBar};"); + theme.AppendLine($"--{Zindex}-dialog: {Theme.ZIndex.Dialog};"); + theme.AppendLine($"--{Zindex}-popover: {Theme.ZIndex.Popover};"); + theme.AppendLine($"--{Zindex}-snackbar: {Theme.ZIndex.Snackbar};"); + theme.AppendLine($"--{Zindex}-tooltip: {Theme.ZIndex.Tooltip};"); + } +} diff --git a/Components/TimePicker/TimePicker.razor b/Components/TimePicker/TimePicker.razor new file mode 100644 index 0000000..2558f1e --- /dev/null +++ b/Components/TimePicker/TimePicker.razor @@ -0,0 +1,101 @@ +@namespace Connected.Components +@inherits Picker + +@Render + +@code{ + + protected override RenderFragment PickerContent=> + @ + +
    + @if (TimeEditMode == TimeEditMode.Normal) + { + + : + + } + else + { + @GetHourString():@GetMinuteString() + } +
    + @if (AmPm) + { +
    + + +
    + } +
    + +
    +
    + +
    +
    +
    +
    ; + +} diff --git a/Components/TimePicker/TimePicker.razor.cs b/Components/TimePicker/TimePicker.razor.cs new file mode 100644 index 0000000..b4d02a6 --- /dev/null +++ b/Components/TimePicker/TimePicker.razor.cs @@ -0,0 +1,678 @@ +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Text.RegularExpressions; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class TimePicker : Picker +{ + private const string format24Hours = "HH:mm"; + private const string format12Hours = "hh:mm tt"; + + public TimePicker() : base(new DefaultConverter()) + { + Converter.GetFunc = OnGet; + Converter.SetFunc = OnSet; + ((DefaultConverter)Converter).Format = format24Hours; + AdornmentIcon = Icons.Material.Filled.AccessTime; + AdornmentAriaLabel = "Open Time Picker"; + } + + private string OnSet(TimeSpan? timespan) + { + if (timespan == null) + return string.Empty; + + var time = DateTime.Today.Add(timespan.Value); + + return time.ToString(((DefaultConverter)Converter).Format, Culture); + } + + private TimeSpan? OnGet(string value) + { + if (string.IsNullOrEmpty(value)) + return null; + + if (DateTime.TryParseExact(value, ((DefaultConverter)Converter).Format, Culture, DateTimeStyles.None, out var time)) + { + return time.TimeOfDay; + } + else + { + var m = Regex.Match(value, "AM|PM", RegexOptions.IgnoreCase); + if (m.Success) + { + return DateTime.ParseExact(value, format12Hours, CultureInfo.InvariantCulture).TimeOfDay; + } + else + { + return DateTime.ParseExact(value, format24Hours, CultureInfo.InvariantCulture).TimeOfDay; + } + } + } + + private bool _amPm = false; + private OpenTo _currentView; + private string _timeFormat = string.Empty; + + internal TimeSpan? TimeIntermediate { get; private set; } + + /// + /// First view to show in the MudDatePicker. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public OpenTo OpenTo { get; set; } = OpenTo.Hours; + + /// + /// Choose the edition mode. By default, you can edit hours and minutes. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public TimeEditMode TimeEditMode { get; set; } = TimeEditMode.Normal; + + /// + /// Sets the amount of time in milliseconds to wait before closing the picker. This helps the user see that the time was selected before the popover disappears. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public int ClosingDelay { get; set; } = 200; + + /// + /// If AutoClose is set to true and PickerActions are defined, the hour and the minutes can be defined without any action. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.PickerBehavior)] + public bool AutoClose { get; set; } + + /// + /// If true, sets 12 hour selection clock. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool AmPm + { + get => _amPm; + set + { + if (value == _amPm) + return; + + _amPm = value; + + if (Converter is DefaultConverter defaultConverter && string.IsNullOrWhiteSpace(_timeFormat)) + { + defaultConverter.Format = AmPm ? format12Hours : format24Hours; + } + + Touched = true; + SetTextAsync(Converter.Set(_value), false).AndForget(); + } + } + + /// + /// String Format for selected time view + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string TimeFormat + { + get => _timeFormat; + set + { + if (_timeFormat == value) + return; + + _timeFormat = value; + if (Converter is DefaultConverter defaultConverter) + defaultConverter.Format = _timeFormat; + + Touched = true; + SetTextAsync(Converter.Set(_value), false).AndForget(); + } + } + + /// + /// The currently selected time (two-way bindable). If null, then nothing was selected. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public TimeSpan? Time + { + get => _value; + set => SetTimeAsync(value, true).AndForget(); + } + + protected async Task SetTimeAsync(TimeSpan? time, bool updateValue) + { + if (_value != time) + { + TimeIntermediate = time; + _value = time; + if (updateValue) + await SetTextAsync(Converter.Set(_value), false); + UpdateTimeSetFromTime(); + await TimeChanged.InvokeAsync(_value); + BeginValidate(); + FieldChanged(_value); + } + } + + /// + /// Fired when the date changes. + /// + [Parameter] public EventCallback TimeChanged { get; set; } + + protected override Task StringValueChanged(string value) + { + Touched = true; + // Update the time property (without updating back the Value property) + return SetTimeAsync(Converter.Get(value), false); + } + + //The last line cannot be tested + [ExcludeFromCodeCoverage] + protected override void OnPickerOpened() + { + base.OnPickerOpened(); + _currentView = TimeEditMode switch + { + TimeEditMode.Normal => OpenTo, + TimeEditMode.OnlyHours => OpenTo.Hours, + TimeEditMode.OnlyMinutes => OpenTo.Minutes, + _ => _currentView + }; + } + + protected internal override void Submit() + { + if (ReadOnly) + return; + Time = TimeIntermediate; + } + + public override async void Clear(bool close = true) + { + TimeIntermediate = null; + await SetTimeAsync(null, true); + + if (AutoClose == true) + { + Close(false); + } + } + + private string GetHourString() + { + if (TimeIntermediate == null) + return "--"; + var h = AmPm ? TimeIntermediate.Value.ToAmPmHour() : TimeIntermediate.Value.Hours; + return Math.Min(23, Math.Max(0, h)).ToString(CultureInfo.InvariantCulture); + } + + private string GetMinuteString() + { + if (TimeIntermediate == null) + return "--"; + return $"{Math.Min(59, Math.Max(0, TimeIntermediate.Value.Minutes)):D2}"; + } + + private void UpdateTime() + { + TimeIntermediate = new TimeSpan(_timeSet.Hour, _timeSet.Minute, 0); + if ((PickerVariant == PickerVariant.Static && PickerActions == null) || (PickerActions != null && AutoClose)) + { + Submit(); + } + } + + private void OnHourClick() + { + _currentView = OpenTo.Hours; + FocusAsync().AndForget(); + } + + private void OnMinutesClick() + { + _currentView = OpenTo.Minutes; + FocusAsync().AndForget(); + } + + private void OnAmClicked() + { + _timeSet.Hour %= 12; // "12:-- am" is "00:--" in 24h + UpdateTime(); + FocusAsync().AndForget(); + } + + private void OnPmClicked() + { + if (_timeSet.Hour <= 12) // "12:-- pm" is "12:--" in 24h + _timeSet.Hour += 12; + _timeSet.Hour %= 24; + UpdateTime(); + FocusAsync().AndForget(); + } + + protected string ToolbarClass => + new CssBuilder("mud-picker-timepicker-toolbar") + .AddClass($"mud-picker-timepicker-toolbar-landscape", Orientation == Orientation.Landscape && PickerVariant == PickerVariant.Static) + .AddClass(Class) + .Build(); + + protected string HoursButtonClass => + new CssBuilder("mud-timepicker-button") + .AddClass($"mud-timepicker-toolbar-text", _currentView == OpenTo.Minutes) + .Build(); + + protected string MinuteButtonClass => + new CssBuilder("mud-timepicker-button") + .AddClass($"mud-timepicker-toolbar-text", _currentView == OpenTo.Hours) + .Build(); + + protected string AmButtonClass => + new CssBuilder("mud-timepicker-button") + .AddClass($"mud-timepicker-toolbar-text", !IsAm) // gray it out + .Build(); + + protected string PmButtonClass => + new CssBuilder("mud-timepicker-button") + .AddClass($"mud-timepicker-toolbar-text", !IsPm) // gray it out + .Build(); + + private string HourDialClass => + new CssBuilder("mud-time-picker-hour") + .AddClass($"mud-time-picker-dial") + .AddClass($"mud-time-picker-dial-out", _currentView != OpenTo.Hours) + .AddClass($"mud-time-picker-dial-hidden", _currentView != OpenTo.Hours) + .Build(); + + private string MinuteDialClass => + new CssBuilder("mud-time-picker-minute") + .AddClass($"mud-time-picker-dial") + .AddClass($"mud-time-picker-dial-out", _currentView != OpenTo.Minutes) + .AddClass($"mud-time-picker-dial-hidden", _currentView != OpenTo.Minutes) + .Build(); + + private bool IsAm => _timeSet.Hour >= 00 && _timeSet.Hour < 12; // am is 00:00 to 11:59 + private bool IsPm => _timeSet.Hour >= 12 && _timeSet.Hour < 24; // pm is 12:00 to 23:59 + + private string GetClockPinColor() + { + return $"mud-picker-time-clock-pin mud-{Color.ToDescriptionString()}"; + } + + private string GetClockPointerColor() + { + if (MouseDown) + return $"mud-picker-time-clock-pointer mud-{Color.ToDescriptionString()}"; + else + return $"mud-picker-time-clock-pointer mud-picker-time-clock-pointer-animation mud-{Color.ToDescriptionString()}"; + } + + private string GetClockPointerThumbColor() + { + var deg = GetDeg(); + if (deg % 30 == 0) + return $"mud-picker-time-clock-pointer-thumb mud-onclock-text mud-onclock-primary mud-{Color.ToDescriptionString()}"; + else + return $"mud-picker-time-clock-pointer-thumb mud-onclock-minute mud-{Color.ToDescriptionString()}-text"; + } + + private string GetNumberColor(int value) + { + if (_currentView == OpenTo.Hours) + { + var h = _timeSet.Hour; + if (AmPm) + { + h = _timeSet.Hour % 12; + if (_timeSet.Hour % 12 == 0) + h = 12; + } + if (h == value) + return $"mud-clock-number mud-theme-{Color.ToDescriptionString()}"; + } + else if (_currentView == OpenTo.Minutes && _timeSet.Minute == value) + { + return $"mud-clock-number mud-theme-{Color.ToDescriptionString()}"; + } + return $"mud-clock-number"; + } + + private double GetDeg() + { + double deg = 0; + if (_currentView == OpenTo.Hours) + deg = (_timeSet.Hour * 30) % 360; + if (_currentView == OpenTo.Minutes) + deg = (_timeSet.Minute * 6) % 360; + return deg; + } + + private string GetTransform(double angle, double radius, double offsetX, double offsetY) + { + angle = angle / 180 * Math.PI; + var x = (Math.Sin(angle) * radius + offsetX).ToString("F3", CultureInfo.InvariantCulture); + var y = ((Math.Cos(angle) + 1) * radius + offsetY).ToString("F3", CultureInfo.InvariantCulture); + return $"transform: translate({x}px, {y}px);"; + } + + private string GetPointerRotation() + { + double deg = 0; + if (_currentView == OpenTo.Hours) + deg = (_timeSet.Hour * 30) % 360; + if (_currentView == OpenTo.Minutes) + deg = (_timeSet.Minute * 6) % 360; + return $"rotateZ({deg}deg);"; + } + + private string GetPointerHeight() + { + var height = 40; + if (_currentView == OpenTo.Minutes) + height = 40; + if (_currentView == OpenTo.Hours) + { + if (!AmPm && _timeSet.Hour > 0 && _timeSet.Hour < 13) + height = 26; + else + height = 40; + } + return $"{height}%;"; + } + + private readonly SetTime _timeSet = new(); + private int _initialHour; + private int _initialMinute; + + protected override void OnInitialized() + { + base.OnInitialized(); + UpdateTimeSetFromTime(); + _currentView = OpenTo; + _initialHour = _timeSet.Hour; + _initialMinute = _timeSet.Minute; + } + + + private void UpdateTimeSetFromTime() + { + if (TimeIntermediate == null) + { + _timeSet.Hour = 0; + _timeSet.Minute = 0; + return; + } + _timeSet.Hour = TimeIntermediate.Value.Hours; + _timeSet.Minute = TimeIntermediate.Value.Minutes; + } + + public bool MouseDown { get; set; } + + /// + /// Sets Mouse Down bool to true if mouse is inside the clock mask. + /// + private void OnMouseDown(MouseEventArgs e) + { + MouseDown = true; + } + + /// + /// Sets Mouse Down bool to false if mouse is inside the clock mask. + /// + private void OnMouseUp(MouseEventArgs e) + { + if (MouseDown && _currentView == OpenTo.Minutes && _timeSet.Minute != _initialMinute || _currentView == OpenTo.Hours && _timeSet.Hour != _initialHour && TimeEditMode == TimeEditMode.OnlyHours) + { + MouseDown = false; + SubmitAndClose(); + } + + MouseDown = false; + + if (_currentView == OpenTo.Hours && _timeSet.Hour != _initialHour && TimeEditMode == TimeEditMode.Normal) + { + _currentView = OpenTo.Minutes; + } + } + + /// + /// If MouseDown is true enables "dragging" effect on the clock pin/stick. + /// + private void OnMouseOverHour(int value) + { + if (MouseDown) + { + _timeSet.Hour = value; + UpdateTime(); + } + } + + /// + /// On click for the hour "sticks", sets the hour. + /// + private void OnMouseClickHour(int value) + { + var h = value; + if (AmPm) + { + if (IsAm && value == 12) + h = 0; + else if (IsPm && value < 12) + h = value + 12; + } + _timeSet.Hour = h; + UpdateTime(); + + if (TimeEditMode == TimeEditMode.Normal) + { + _currentView = OpenTo.Minutes; + } + else if (TimeEditMode == TimeEditMode.OnlyHours) + { + SubmitAndClose(); + } + } + + /// + /// On mouse over for the minutes "sticks", sets the minute. + /// + private void OnMouseOverMinute(int value) + { + if (MouseDown) + { + _timeSet.Minute = value; + UpdateTime(); + } + } + + /// + /// On click for the minute "sticks", sets the minute. + /// + private void OnMouseClickMinute(int value) + { + _timeSet.Minute = value; + UpdateTime(); + SubmitAndClose(); + } + + protected async void SubmitAndClose() + { + if (PickerActions == null || AutoClose) + { + Submit(); + + if (PickerVariant != PickerVariant.Static) + { + await Task.Delay(ClosingDelay); + Close(false); + } + } + } + + protected internal override void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + base.HandleKeyDown(obj); + switch (obj.Key) + { + case "ArrowRight": + if (IsOpen) + { + if (obj.CtrlKey == true) + { + ChangeHour(1); + } + else if (obj.ShiftKey == true) + { + if (_timeSet.Minute > 55) + { + ChangeHour(1); + } + ChangeMinute(5); + } + else + { + if (_timeSet.Minute == 59) + { + ChangeHour(1); + } + ChangeMinute(1); + } + } + break; + case "ArrowLeft": + if (IsOpen) + { + if (obj.CtrlKey == true) + { + ChangeHour(-1); + } + else if (obj.ShiftKey == true) + { + if (_timeSet.Minute < 5) + { + ChangeHour(-1); + } + ChangeMinute(-5); + } + else + { + if (_timeSet.Minute == 0) + { + ChangeHour(-1); + } + ChangeMinute(-1); + } + } + break; + case "ArrowUp": + if (IsOpen == false && Editable == false) + { + IsOpen = true; + } + else if (obj.AltKey == true) + { + IsOpen = false; + } + else if (obj.ShiftKey == true) + { + ChangeHour(5); + } + else + { + ChangeHour(1); + } + break; + case "ArrowDown": + if (IsOpen == false && Editable == false) + { + IsOpen = true; + } + else if (obj.ShiftKey == true) + { + ChangeHour(-5); + } + else + { + ChangeHour(-1); + } + break; + case "Escape": + ReturnTimeBackUp(); + break; + case "Enter": + case "NumpadEnter": + if (!IsOpen) + { + Open(); + } + else + { + Submit(); + Close(); + _inputReference?.SetText(Text); + } + break; + case " ": + if (!Editable) + { + if (!IsOpen) + { + Open(); + } + else + { + Submit(); + Close(); + _inputReference?.SetText(Text); + } + } + break; + } + } + + protected void ChangeMinute(int val) + { + _currentView = OpenTo.Minutes; + _timeSet.Minute = (_timeSet.Minute + val + 60) % 60; + UpdateTime(); + } + + protected void ChangeHour(int val) + { + _currentView = OpenTo.Hours; + _timeSet.Hour = (_timeSet.Hour + val + 24) % 24; + UpdateTime(); + } + + protected void ReturnTimeBackUp() + { + if (Time == null) + { + TimeIntermediate = null; + } + else + { + _timeSet.Hour = Time.Value.Hours; + _timeSet.Minute = Time.Value.Minutes; + UpdateTime(); + } + } + + private class SetTime + { + public int Hour { get; set; } + + public int Minute { get; set; } + + } +} diff --git a/Components/Timeline/Timeline.razor b/Components/Timeline/Timeline.razor new file mode 100644 index 0000000..3791afb --- /dev/null +++ b/Components/Timeline/Timeline.razor @@ -0,0 +1,8 @@ +@namespace Connected.Components +@inherits ItemsControlBase + +
    + + @ChildContent + +
    \ No newline at end of file diff --git a/Components/Timeline/Timeline.razor.cs b/Components/Timeline/Timeline.razor.cs new file mode 100644 index 0000000..ffc95c9 --- /dev/null +++ b/Components/Timeline/Timeline.razor.cs @@ -0,0 +1,87 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Timeline : ItemsControlBase +{ + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// Sets the orientation of the timeline and its timeline items. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public TimelineOrientation TimelineOrientation { get; set; } = TimelineOrientation.Vertical; + + /// + /// The position the timeline itself and how the timeline items should be displayed. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public TimelinePosition TimelinePosition { get; set; } = TimelinePosition.Alternate; + + /// + /// Aligns the dot and any item modifiers is changed, in default mode they are centered to the item. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public TimelineAlign TimelineAlign { get; set; } = TimelineAlign.Default; + + /// + /// Reverse the order of TimelineItems when TimelinePosition is set to Alternate. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public bool Reverse { get; set; } = false; + + /// + /// If true, disables all TimelineItem modifiers, like adding a caret to a MudCard. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public bool DisableModifiers { get; set; } = false; + + protected string Classnames => + new CssBuilder("mud-timeline") + .AddClass($"mud-timeline-{TimelineOrientation.ToDescriptionString()}") + .AddClass($"mud-timeline-position-{ConvertTimelinePosition().ToDescriptionString()}") + .AddClass($"mud-timeline-reverse", Reverse && TimelinePosition == TimelinePosition.Alternate) + .AddClass($"mud-timeline-align-{TimelineAlign.ToDescriptionString()}") + .AddClass($"mud-timeline-modifiers", !DisableModifiers) + .AddClass($"mud-timeline-rtl", RightToLeft) + .AddClass(Class) + .Build(); + + private TimelinePosition ConvertTimelinePosition() + { + if (TimelineOrientation == TimelineOrientation.Vertical) + { + return TimelinePosition switch + { + TimelinePosition.Left => RightToLeft ? TimelinePosition.End : TimelinePosition.Start, + TimelinePosition.Right => RightToLeft ? TimelinePosition.Start : TimelinePosition.End, + TimelinePosition.Top => TimelinePosition.Alternate, + TimelinePosition.Bottom => TimelinePosition.Alternate, + _ => TimelinePosition + }; + } + else + { + return TimelinePosition switch + { + TimelinePosition.Start => TimelinePosition.Alternate, + TimelinePosition.Left => TimelinePosition.Alternate, + TimelinePosition.Right => TimelinePosition.Alternate, + TimelinePosition.End => TimelinePosition.Alternate, + _ => TimelinePosition + }; + } + } +} diff --git a/Components/Timeline/TimelineItem.razor b/Components/Timeline/TimelineItem.razor new file mode 100644 index 0000000..5c2d6ab --- /dev/null +++ b/Components/Timeline/TimelineItem.razor @@ -0,0 +1,34 @@ +@namespace Connected.Components +@inherits UIComponent + +
    +
    + @if (ChildContent != null) + { + @ChildContent + } + else if (ItemContent != null) + { + @ItemContent + } +
    +
    + @if(!HideDot) + { +
    +
    + @if(ItemDot != null) + { + @ItemDot + } +
    +
    + } +
    + @if (ItemOpposite != null) + { +
    + @ItemOpposite +
    + } +
    \ No newline at end of file diff --git a/Components/Timeline/TimelineItem.razor.cs b/Components/Timeline/TimelineItem.razor.cs new file mode 100644 index 0000000..f5c2e8c --- /dev/null +++ b/Components/Timeline/TimelineItem.razor.cs @@ -0,0 +1,137 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class TimelineItem : UIComponent, IDisposable + +{ + protected string Classnames => + new CssBuilder("mud-timeline-item") + .AddClass($"mud-timeline-item-{TimelineAlign.ToDescriptionString()}") + .AddClass(Class) + .Build(); + + protected string DotClassnames => + new CssBuilder("mud-timeline-item-dot") + .AddClass($"mud-timeline-dot-size-{Size.ToDescriptionString()}") + .AddClass($"mud-elevation-{Elevation.ToString()}") + .Build(); + + protected string DotInnerClassnames => + new CssBuilder("mud-timeline-item-dot-inner") + .AddClass($"mud-timeline-dot-fill", Variant == Variant.Filled) + .AddClass($"mud-timeline-dot-{Color.ToDescriptionString()}") + .Build(); + + [CascadingParameter] protected internal ItemsControlBase Parent { get; set; } + + /// + /// Dot Icon + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public string Icon { get; set; } + + /// + /// Variant of the dot. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public Variant Variant { get; set; } = Variant.Outlined; + + /// + /// User styles, applied to the lineItem dot. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public string DotStyle { get; set; } + + /// + /// Color of the dot. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// Size of the dot. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public Size Size { get; set; } = Size.Small; + + /// + /// Elevation of the dot. The higher the number, the heavier the drop-shadow. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public int Elevation { set; get; } = 1; + + /// + /// Overrides Timeline Parents default sorting method in Default and Reverse mode. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public TimelineAlign TimelineAlign { get; set; } + + /// + /// If true, dot will not be displayed. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public bool HideDot { get; set; } + + /// + /// If used renders child content of the ItemOpposite. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public RenderFragment ItemOpposite { get; set; } + + /// + /// If used renders child content of the ItemContent. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public RenderFragment ItemContent { get; set; } + + /// + /// If used renders child content of the ItemDot. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Dot)] + public RenderFragment ItemDot { get; set; } + + /// + /// Optional child content if no other RenderFragments is used. + /// + [Parameter] + [Category(CategoryTypes.Timeline.Behavior)] + public RenderFragment ChildContent { get; set; } + + protected override Task OnInitializedAsync() + { + Parent?.Items.Add(this); + return Task.CompletedTask; + } + + private void Select() + { + var myIndex = Parent?.Items.IndexOf(this); + Parent?.MoveTo(myIndex ?? 0); + } + + public void Dispose() + { + Parent?.Items.Remove(this); + } + + +} diff --git a/Components/ToolBar/ToolBar.razor b/Components/ToolBar/ToolBar.razor new file mode 100644 index 0000000..52f70e6 --- /dev/null +++ b/Components/ToolBar/ToolBar.razor @@ -0,0 +1,39 @@ +@namespace Connected.Components +@using Connected.Annotations; +@using Connected.Utilities; +@inherits UIComponent + +
    + @ChildContent +
    + +@code { + + protected string Classname => + new CssBuilder("mud-toolbar") + .AddClass($"mud-toolbar-dense", Dense) + .AddClass($"mud-toolbar-gutters", !DisableGutters) + .AddClass(Class) + .Build(); + + /// + /// If true, compact padding will be used. + /// + [Parameter] + [Category(CategoryTypes.ToolBar.Appearance)] + public bool Dense { get; set; } + + /// + /// If true, disables gutter padding. + /// + [Parameter] + [Category(CategoryTypes.ToolBar.Appearance)] + public bool DisableGutters { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.ToolBar.Behavior)] + public RenderFragment ChildContent { get; set; } +} \ No newline at end of file diff --git a/Components/Tooltip/Tooltip.razor b/Components/Tooltip/Tooltip.razor new file mode 100644 index 0000000..9abe92a --- /dev/null +++ b/Components/Tooltip/Tooltip.razor @@ -0,0 +1,19 @@ +@namespace Connected.Components +@inherits UIComponent + +
    + @ChildContent + @if (TooltipContent != null || string.IsNullOrEmpty(Text) == false) + { + + @if (TooltipContent != null) + { + @TooltipContent + } + else if (!String.IsNullOrEmpty(Text)) + { + @Text + } + + } +
    diff --git a/Components/Tooltip/Tooltip.razor.cs b/Components/Tooltip/Tooltip.razor.cs new file mode 100644 index 0000000..a0a0f94 --- /dev/null +++ b/Components/Tooltip/Tooltip.razor.cs @@ -0,0 +1,180 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Tooltip : UIComponent +{ + protected string ContainerClass => new CssBuilder("mud-tooltip-root") + .AddClass("mud-tooltip-inline", Inline) + .AddClass(RootClass) + .Build(); + + protected string Classname => new CssBuilder("mud-tooltip") + .AddClass($"mud-tooltip-default", Color == ThemeColor.Default) + .AddClass($"mud-tooltip-{ConvertPlacement().ToDescriptionString()}") + .AddClass($"mud-tooltip-arrow", Arrow) + .AddClass($"mud-border-{Color.ToDescriptionString()}", Arrow && Color != ThemeColor.Default) + .AddClass($"mud-theme-{Color.ToDescriptionString()}", Color != ThemeColor.Default) + .AddClass($"d-block", TooltipContent != null) + .AddClass($"d-flex", !String.IsNullOrEmpty(Text)) + .AddClass(Class) + .Build(); + + + private bool _isVisible; + + private Origin _anchorOrigin; + private Origin _transformOrigin; + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Default; + + /// + /// Sets the text to be displayed inside the tooltip. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Behavior)] + public string Text { get; set; } = String.Empty; + + /// + /// If true, a arrow will be displayed pointing towards the content from the tooltip. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public bool Arrow { get; set; } = false; + + /// + /// Sets the length of time that the opening transition takes to complete. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public double Duration { get; set; } = 251; + + /// + /// Sets the amount of time in milliseconds to wait from opening the popover before beginning to perform the transition. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public double Delay { get; set; } = 0; + + /// + /// Changes the default transition delay in seconds. + /// + [Obsolete("Use Delay instead.", true)] + [ExcludeFromCodeCoverage] + [Parameter] + public double Delayed + { + get { return Delay / 1000; } + set { Delay = value * 1000; } + } + + /// + /// Tooltip placement. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public Placement Placement { get; set; } = Placement.Bottom; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Tooltip content. May contain any valid html + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Behavior)] + public RenderFragment TooltipContent { get; set; } + + /// + /// Determines if this component should be inline with it's surrounding (default) or if it should behave like a block element. + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public bool Inline { get; set; } = true; + + /// + /// Styles applied directly to root component of the tooltip + /// + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public string RootStyle { get; set; } + + /// Classes applied directly to root component of the tooltip + [Parameter] + [Category(CategoryTypes.Tooltip.Appearance)] + public string RootClass { get; set; } + + /// + /// The visible state of the Tooltip. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool IsVisible + { + get => _isVisible; + set + { + if (value == _isVisible) + return; + _isVisible = value; + IsVisibleChanged.InvokeAsync(_isVisible).AndForget(); + } + } + + /// + /// An event triggered when the state of IsVisible has changed + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public EventCallback IsVisibleChanged { get; set; } + + private void HandleMouseOver() { IsVisible = true; } + private void HandleMouseOut() { IsVisible = false; } + + private Origin ConvertPlacement() + { + if (Placement == Placement.Bottom) + { + _anchorOrigin = Origin.BottomCenter; + _transformOrigin = Origin.TopCenter; + return Origin.BottomCenter; + } + if (Placement == Placement.Top) + { + _anchorOrigin = Origin.TopCenter; + _transformOrigin = Origin.BottomCenter; + return Origin.TopCenter; + } + if (Placement == Placement.Left || Placement == Placement.Start && !RightToLeft || Placement == Placement.End && RightToLeft) + { + _anchorOrigin = Origin.CenterLeft; + _transformOrigin = Origin.CenterRight; + return Origin.CenterLeft; + } + if (Placement == Placement.Right || Placement == Placement.End && !RightToLeft || Placement == Placement.Start && RightToLeft) + { + _anchorOrigin = Origin.CenterRight; + _transformOrigin = Origin.CenterLeft; + return Origin.CenterRight; + } + else + { + return Origin.BottomCenter; + } + } +} diff --git a/Components/TreeView/TreeView.razor b/Components/TreeView/TreeView.razor new file mode 100644 index 0000000..f6a3044 --- /dev/null +++ b/Components/TreeView/TreeView.razor @@ -0,0 +1,19 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + +
      + + @if (ItemTemplate != null && Items != null) + { + @foreach (var item in Items) + { + @ItemTemplate(item) + } + } + else if (ChildContent != null) + { + @ChildContent + } + +
    \ No newline at end of file diff --git a/Components/TreeView/TreeView.razor.cs b/Components/TreeView/TreeView.razor.cs new file mode 100644 index 0000000..d6aa57c --- /dev/null +++ b/Components/TreeView/TreeView.razor.cs @@ -0,0 +1,244 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class TreeView : UIComponent +{ + private TreeViewItem _selectedValue; + private HashSet> _selectedValues; + private List> _childItems = new(); + + protected string Classname => + new CssBuilder("mud-treeview") + .AddClass("mud-treeview-dense", Dense) + .AddClass("mud-treeview-hover", Hover) + .AddClass($"mud-treeview-selected-{Color.ToDescriptionString()}") + .AddClass($"mud-treeview-checked-{CheckBoxColor.ToDescriptionString()}") + .AddClass(Class) + .Build(); + protected string Stylename => + new StyleBuilder() + .AddStyle($"width", Width, !string.IsNullOrWhiteSpace(Width)) + .AddStyle($"height", Height, !string.IsNullOrWhiteSpace(Height)) + .AddStyle($"max-height", MaxHeight, !string.IsNullOrWhiteSpace(MaxHeight)) + .AddStyle(Style) + .Build(); + + /// + /// The color of the selected treeviewitem. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public ThemeColor Color { get; set; } = ThemeColor.Primary; + + /// + /// Check box color if multiselection is used. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public ThemeColor CheckBoxColor { get; set; } + + /// + /// if true, multiple values can be selected via checkboxes which are automatically shown in the tree view. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public bool MultiSelection { get; set; } + + /// + /// if true, multiple values can be selected via checkboxes which are automatically shown in the tree view. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use MultiSelection instead.", true)] + [Parameter] + public bool CanSelect + { + get => MultiSelection; + set => MultiSelection = value; + } + + [ExcludeFromCodeCoverage] + [Obsolete("MudTreeView now automaticly activates when using SelectedValue.", true)] + [Parameter] public bool CanActivate { get; set; } + + /// + /// If true, clicking anywhere on the item will expand it, if it has childs. + /// + [Parameter] + [Category(CategoryTypes.TreeView.ClickAction)] + public bool ExpandOnClick { get; set; } + + /// + /// If true, double clicking anywhere on the item will expand it, if it has childs. + /// + [Parameter] + [Category(CategoryTypes.TreeView.ClickAction)] + public bool ExpandOnDoubleClick { get; set; } + + /// + /// Hover effect for item's on mouse-over. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public bool Hover { get; set; } + + /// + /// Hover effect for item's on mouse-over. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use Hover instead.", true)] + [Parameter] + public bool CanHover + { + get => Hover; + set => Hover = value; + } + + /// + /// If true, compact vertical padding will be applied to all treeview items. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public bool Dense { get; set; } + + /// + /// Setting a height will allow to scroll the treeview. If not set, it will try to grow in height. + /// You can set this to any CSS value that the attribute 'height' accepts, i.e. 500px. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string Height { get; set; } + + /// + /// Setting a maximum height will allow to scroll the treeview. If not set, it will try to grow in height. + /// You can set this to any CSS value that the attribute 'height' accepts, i.e. 500px. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string MaxHeight { get; set; } + + /// + /// Setting a width the treeview. You can set this to any CSS value that the attribute 'height' accepts, i.e. 500px. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string Width { get; set; } + + /// + /// If true, treeview will be disabled and all its childitems. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public bool Disabled { get; set; } + + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public HashSet Items { get; set; } + + [ExcludeFromCodeCoverage] + [Obsolete("Use SelectedValueChanged instead.", true)] + [Parameter] + public EventCallback ActivatedValueChanged + { + get => SelectedValueChanged; + set => SelectedValueChanged = value; + } + + /// + /// Called whenever the selected value changed. + /// + [Parameter] public EventCallback SelectedValueChanged { get; set; } + + /// + /// Called whenever the selectedvalues changed. + /// + [Parameter] public EventCallback> SelectedValuesChanged { get; set; } + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public RenderFragment ChildContent { get; set; } + + /// + /// ItemTemplate for rendering children. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public RenderFragment ItemTemplate { get; set; } + + [CascadingParameter] TreeView MudTreeRoot { get; set; } + + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public Func>> ServerData { get; set; } + + public TreeView() + { + MudTreeRoot = this; + } + + internal bool IsSelectable { get; private set; } + + protected override void OnInitialized() + { + IsSelectable = SelectedValueChanged.HasDelegate; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender && MudTreeRoot == this) + { + await UpdateSelectedItems(); + } + await base.OnAfterRenderAsync(firstRender); + } + + internal async Task UpdateSelected(TreeViewItem item, bool requestedValue) + { + if ((_selectedValue == item && requestedValue) || + (_selectedValue != item && !requestedValue)) + return; + + if (_selectedValue == item && !requestedValue) + { + _selectedValue = default; + await item.Select(requestedValue); + await SelectedValueChanged.InvokeAsync(default); + return; + } + + if (_selectedValue != null) + { + await _selectedValue.Select(false); + } + + _selectedValue = item; + await item.Select(requestedValue); + await SelectedValueChanged.InvokeAsync(item.Value); + } + + internal Task UpdateSelectedItems() + { + _selectedValues ??= new HashSet>(); + + //collect selected items + _selectedValues.Clear(); + foreach (var item in _childItems) + { + foreach (var selectedItem in item.GetSelectedItems()) + { + _selectedValues.Add(selectedItem); + } + } + + return SelectedValuesChanged.InvokeAsync(new HashSet(_selectedValues.Select(i => i.Value))); + } + + internal void AddChild(TreeViewItem item) => _childItems.Add(item); +} diff --git a/Components/TreeView/TreeViewItem.razor b/Components/TreeView/TreeViewItem.razor new file mode 100644 index 0000000..54fa22f --- /dev/null +++ b/Components/TreeView/TreeViewItem.razor @@ -0,0 +1,58 @@ +@namespace Connected.Components +@inherits UIComponent +@typeparam T + +
  • +
    + @if (Content != null) + { + @Content + } + else + { + + + @if (TreeRoot != null && TreeRoot.MultiSelection) + { + + } + + @if (!string.IsNullOrEmpty(Icon)) + { +
    + +
    + } + + + @Text + + + @if (!string.IsNullOrEmpty(EndText)) + { + + @EndText + + } + + @if (!string.IsNullOrEmpty(EndIcon)) + { +
    + +
    + } + } +
    + @if (HasChild) + { + + + + + @ChildContent + + + + + } +
  • \ No newline at end of file diff --git a/Components/TreeView/TreeViewItem.razor.cs b/Components/TreeView/TreeViewItem.razor.cs new file mode 100644 index 0000000..d24bf5a --- /dev/null +++ b/Components/TreeView/TreeViewItem.razor.cs @@ -0,0 +1,421 @@ +using System.Globalization; +using System.Windows.Input; +using Connected.Annotations; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Components; + +public partial class TreeViewItem : UIComponent +{ + private string _text; + private bool _disabled; + private bool _isChecked, _isSelected, _isServerLoaded; + private Converter _converter = new DefaultConverter(); + private readonly List> _childItems = new(); + + protected string Classname => + new CssBuilder("mud-treeview-item") + .AddClass(Class) + .Build(); + + protected string ContentClassname => + new CssBuilder("mud-treeview-item-content") + .AddClass("cursor-pointer", TreeRoot?.IsSelectable == true || TreeRoot?.ExpandOnClick == true && HasChild) + .AddClass($"mud-treeview-item-selected", _isSelected) + .Build(); + + public string TextClassname => + new CssBuilder("mud-treeview-item-label") + .AddClass(TextClass) + .Build(); + + + [CascadingParameter] TreeView TreeRoot { get; set; } + + [CascadingParameter] TreeViewItem Parent { get; set; } + + /// + /// Custom checked icon, leave null for default. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public string CheckedIcon { get; set; } = Icons.Material.Filled.CheckBox; + + /// + /// Custom unchecked icon, leave null for default. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public string UncheckedIcon { get; set; } = Icons.Material.Filled.CheckBoxOutlineBlank; + + /// + /// Value of the treeviewitem. Acts as the displayed text if no text is set. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public T Value { get; set; } + + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public CultureInfo Culture { get; set; } = CultureInfo.CurrentCulture; + + /// + /// The text to display + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public string Text + { + get => string.IsNullOrEmpty(_text) ? _converter.Set(Value) : _text; + set => _text = value; + } + + /// + /// Tyopography for the text. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public Typo TextTypo { get; set; } = Typo.body1; + + /// + /// User class names for the text, separated by space. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string TextClass { get; set; } + + /// + /// The text at the end of the item. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public string EndText { get; set; } + + /// + /// Tyopography for the endtext. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public Typo EndTextTypo { get; set; } = Typo.body1; + + /// + /// User class names for the endtext, separated by space. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string EndTextClass { get; set; } + + /// + /// If true, treeviewitem will be disabled. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public bool Disabled + { + get => _disabled || (TreeRoot?.Disabled ?? false); + set => _disabled = value; + } + + /// + /// Child content of component used to create sub levels. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public RenderFragment ChildContent { get; set; } + + /// + /// Content of the item, if used completly replaced the default rendering. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public RenderFragment Content { get; set; } + + [Parameter] + [Category(CategoryTypes.TreeView.Data)] + public HashSet Items { get; set; } + + /// + /// Command executed when the user clicks on the CommitEdit Button. + /// + [Parameter] + [Category(CategoryTypes.TreeView.ClickAction)] + public ICommand Command { get; set; } + + /// + /// Expand or collapse treeview item when it has children. Two-way bindable. Note: if you directly set this to + /// true or false (instead of using two-way binding) it will force the item's expansion state. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Expanding)] + public bool Expanded { get; set; } + + /// + /// Called whenever expanded changed. + /// + [Parameter] public EventCallback ExpandedChanged { get; set; } + + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public bool Activated + { + get => _isSelected; + set + { + _ = TreeRoot?.UpdateSelected(this, value); + } + } + + [Parameter] + [Category(CategoryTypes.TreeView.Selecting)] + public bool Selected + { + get => _isChecked; + set + { + if (_isChecked == value) + return; + + _isChecked = value; + TreeRoot?.UpdateSelectedItems(); + SelectedChanged.InvokeAsync(_isChecked); + } + } + + /// + /// Icon placed before the text if set. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public string Icon { get; set; } + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public ThemeColor IconColor { get; set; } = ThemeColor.Default; + + /// + /// Icon placed after the text if set. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Behavior)] + public string EndIcon { get; set; } + + /// + /// The color of the icon. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public ThemeColor EndIconColor { get; set; } = ThemeColor.Default; + + /// + /// The expand/collapse icon. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Expanding)] + public string ExpandedIcon { get; set; } = Icons.Material.Filled.ChevronRight; + + /// + /// The color of the expand/collapse button. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Expanding)] + public ThemeColor ExpandedIconColor { get; set; } = ThemeColor.Default; + + /// + /// The loading icon. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public string LoadingIcon { get; set; } = Icons.Material.Filled.Loop; + + /// + /// The color of the loading. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.TreeView.Appearance)] + public ThemeColor LoadingIconColor { get; set; } = ThemeColor.Default; + + /// + /// Called whenever the activated value changed. + /// + [Parameter] public EventCallback ActivatedChanged { get; set; } + + /// + /// Called whenever the selected value changed. + /// + [Parameter] public EventCallback SelectedChanged { get; set; } + + /// + /// Tree item click event. + /// + [Parameter] public EventCallback OnClick { get; set; } + + /// + /// Tree item double click event. + /// + [Parameter] public EventCallback OnDoubleClick { get; set; } + + public bool Loading { get; set; } + + bool HasChild => ChildContent != null || + (TreeRoot != null && Items != null && Items.Count != 0) || + (TreeRoot?.ServerData != null && !_isServerLoaded && (Items == null || Items.Count == 0)); + + protected bool IsChecked + { + get => Selected; + set { _ = SelectItem(value, this); } + } + + protected internal bool ArrowExpanded + { + get => Expanded; + set + { + if (value == Expanded) + return; + + Expanded = value; + ExpandedChanged.InvokeAsync(value); + } + } + + protected override void OnInitialized() + { + if (Parent != null) + { + Parent.AddChild(this); + } + else + { + TreeRoot?.AddChild(this); + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender && _isSelected) + { + await TreeRoot.UpdateSelected(this, _isSelected); + } + + await base.OnAfterRenderAsync(firstRender); + } + + protected async Task OnItemClicked(MouseEventArgs ev) + { + if (TreeRoot?.IsSelectable ?? false) + { + await TreeRoot.UpdateSelected(this, !_isSelected); + } + + if (HasChild && (TreeRoot?.ExpandOnClick ?? false)) + { + Expanded = !Expanded; + TryInvokeServerLoadFunc(); + await ExpandedChanged.InvokeAsync(Expanded); + } + + await OnClick.InvokeAsync(ev); + if (Command?.CanExecute(Value) ?? false) + { + Command.Execute(Value); + } + } + + protected async Task OnItemDoubleClicked(MouseEventArgs ev) + { + if (TreeRoot?.IsSelectable ?? false) + { + await TreeRoot.UpdateSelected(this, !_isSelected); + } + + if (HasChild && (TreeRoot?.ExpandOnDoubleClick ?? false)) + { + Expanded = !Expanded; + TryInvokeServerLoadFunc(); + await ExpandedChanged.InvokeAsync(Expanded); + } + + await OnDoubleClick.InvokeAsync(ev); + } + + protected internal Task OnItemExpanded(bool expanded) + { + if (Expanded == expanded) + return Task.CompletedTask; + + Expanded = expanded; + TryInvokeServerLoadFunc(); + return ExpandedChanged.InvokeAsync(expanded); + } + + internal Task Select(bool value) + { + if (_isSelected == value) + return Task.CompletedTask; + + _isSelected = value; + + StateHasChanged(); + + return ActivatedChanged.InvokeAsync(_isSelected); + } + + internal async Task SelectItem(bool value, TreeViewItem source = null) + { + if (value == _isChecked) + return; + + _isChecked = value; + _childItems.ForEach(async c => await c.SelectItem(value, source)); + + StateHasChanged(); + + await SelectedChanged.InvokeAsync(_isChecked); + + if (source == this) + { + if (TreeRoot != null) + { + await TreeRoot.UpdateSelectedItems(); + } + } + } + + private void AddChild(TreeViewItem item) => _childItems.Add(item); + + internal IEnumerable> GetSelectedItems() + { + if (_isChecked) + yield return this; + + foreach (var treeItem in _childItems) + { + foreach (var selected in treeItem.GetSelectedItems()) + { + yield return selected; + } + } + } + + internal async void TryInvokeServerLoadFunc() + { + if (Expanded && (Items == null || Items.Count == 0) && TreeRoot?.ServerData != null) + { + Loading = true; + StateHasChanged(); + + Items = await TreeRoot.ServerData(Value); + + Loading = false; + _isServerLoaded = true; + + StateHasChanged(); + } + } +} diff --git a/Components/TreeView/TreeViewItemToggleButton.razor b/Components/TreeView/TreeViewItemToggleButton.razor new file mode 100644 index 0000000..d457d7a --- /dev/null +++ b/Components/TreeView/TreeViewItemToggleButton.razor @@ -0,0 +1,65 @@ +@namespace Connected.Components +@using Connected.Annotations; +@using Connected.Utilities; + +
    + @if (Visible) + { + + } +
    + +@code { + protected string Classname => + new CssBuilder() + .AddClass("mud-treeview-item-arrow-expand mud-transform", Expanded && !Loading) + .AddClass("mud-treeview-item-arrow-load", Loading) + .Build(); + + /// + /// If true, displays the button. + /// + [Parameter] [Category(CategoryTypes.TreeView.Behavior)] public bool Visible { get; set; } + + /// + /// Determens when to flip the expanded icon. + /// + [Parameter] [Category(CategoryTypes.TreeView.Behavior)] public bool Expanded { get; set; } + + /// + /// If true, displays the loading icon. + /// + [Parameter] [Category(CategoryTypes.TreeView.Behavior)] public bool Loading { get; set; } + + /// + /// Called whenever expanded changed. + /// + [Parameter] public EventCallback ExpandedChanged { get; set; } + + /// + /// The loading icon. + /// + [Parameter] [Category(CategoryTypes.TreeView.Appearance)] public string LoadingIcon { get; set; } = Icons.Material.Filled.Loop; + + /// + /// The color of the loading. It supports the theme colors. + /// + [Parameter] [Category(CategoryTypes.TreeView.Appearance)] public ThemeColor LoadingIconColor { get; set; } = ThemeColor.Default; + + /// + /// The expand/collapse icon. + /// + [Parameter] [Category(CategoryTypes.TreeView.Appearance)] public string ExpandedIcon { get; set; } = Icons.Material.Filled.ChevronRight; + + /// + /// The color of the expand/collapse. It supports the theme colors. + /// + [Parameter] [Category(CategoryTypes.TreeView.Appearance)] public ThemeColor ExpandedIconColor { get; set; } = ThemeColor.Default; + + + private Task ToggleAsync() + { + Expanded = !Expanded; + return ExpandedChanged.InvokeAsync(Expanded); + } +} diff --git a/Components/Typography/TextContent.razor b/Components/Typography/TextContent.razor new file mode 100644 index 0000000..a06d330 --- /dev/null +++ b/Components/Typography/TextContent.razor @@ -0,0 +1,49 @@ +@namespace Connected.Components +@inherits UIComponent + + +@switch (Typo) +{ + case Typo.h1: +

    @ChildContent

    + break; + case Typo.h2: +

    @ChildContent

    + break; + case Typo.h3: +

    @ChildContent

    + break; + case Typo.h4: +

    @ChildContent

    + break; + case Typo.h5: +
    @ChildContent
    + break; + case Typo.h6: +
    @ChildContent
    + break; + case Typo.subtitle1: +
    @ChildContent
    + break; + case Typo.subtitle2: +
    @ChildContent
    + break; + case Typo.body1: +

    @ChildContent

    + break; + case Typo.body2: +

    @ChildContent

    + break; + case Typo.button: + @ChildContent + break; + case Typo.caption: + @ChildContent + break; + case Typo.overline: + @ChildContent + break; + case Typo.inherit: + @ChildContent + break; +} diff --git a/Components/Typography/TextContent.razor.cs b/Components/Typography/TextContent.razor.cs new file mode 100644 index 0000000..39ec6cb --- /dev/null +++ b/Components/Typography/TextContent.razor.cs @@ -0,0 +1,73 @@ +using Connected.Annotations; +using Connected.Extensions; +using Connected.Utilities; +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class TextContent : UIComponent +{ + protected string Classname => + new CssBuilder("mud-typography") + .AddClass($"mud-typography-{Typo.ToDescriptionString()}") + .AddClass($"mud-{Color.ToDescriptionString()}-text", Color != ThemeColor.Default && Color != ThemeColor.Inherit) + .AddClass("mud-typography-gutterbottom", GutterBottom) + .AddClass($"mud-typography-align-{ConvertAlign(Align).ToDescriptionString()}", Align != Align.Inherit) + .AddClass("mud-typography-display-inline", Inline) + .AddClass(Class) + .Build(); + + private Align ConvertAlign(Align align) + { + return align switch + { + Align.Start => RightToLeft ? Align.Right : Align.Left, + Align.End => RightToLeft ? Align.Left : Align.Right, + _ => align + }; + } + + [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } + + /// + /// Applies the theme typography styles. + /// + [Parameter] + [Category(CategoryTypes.Text.Appearance)] + public Typo Typo { get; set; } = Typo.body1; + + /// + /// Set the text-align on the component. + /// + [Parameter] + [Category(CategoryTypes.Text.Appearance)] + public Align Align { get; set; } = Align.Inherit; + + /// + /// The color of the component. It supports the theme colors. + /// + [Parameter] + [Category(CategoryTypes.Text.Appearance)] + public ThemeColor Color { get; set; } = ThemeColor.Inherit; + + /// + /// If true, the text will have a bottom margin. + /// + [Parameter] + [Category(CategoryTypes.Text.Appearance)] + public bool GutterBottom { get; set; } = false; + + /// + /// Child content of component. + /// + [Parameter] + [Category(CategoryTypes.Text.Behavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// If true, Sets display inline + /// + [Parameter] + [Category(CategoryTypes.Text.Appearance)] + public bool Inline { get; set; } +} diff --git a/Components/UIComponent.cs b/Components/UIComponent.cs new file mode 100644 index 0000000..5827a61 --- /dev/null +++ b/Components/UIComponent.cs @@ -0,0 +1,62 @@ +using Connected.Annotations; +using Connected.Middleware; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Logging; + +namespace Connected.Components; + +public abstract class UIComponent : ComponentBase +{ + [Inject] + private ILoggerFactory LoggerFactory { get; set; } + [Inject] + private IComponentMiddlewareService? MiddlewareService { get; set; } + + private ILogger _logger; + protected ILogger Logger => _logger ??= LoggerFactory.CreateLogger(GetType()); + + /// + /// User class names, separated by space. + /// + [Parameter] + [Category(CategoryTypes.ComponentBase.Common)] + public string Class { get; set; } + + /// + /// User styles, applied on top of the component's own classes and styles. + /// + [Parameter] + [Category(CategoryTypes.ComponentBase.Common)] + public string Style { get; set; } + + /// + /// Use Tag to attach any user data object to the component for your convenience. + /// + [Parameter] + [Category(CategoryTypes.ComponentBase.Common)] + public object Tag { get; set; } + + /// + /// UserAttributes carries all attributes you add to the component that don't match any of its parameters. + /// They will be splatted onto the underlying HTML tag. + /// + [Parameter(CaptureUnmatchedValues = true)] + [Category(CategoryTypes.ComponentBase.Common)] + public Dictionary UserAttributes { get; set; } = new Dictionary(); + + /// + /// If the UserAttributes contain an ID make it accessible for WCAG labelling of input fields + /// + public string FieldId => (UserAttributes?.ContainsKey("id") == true ? UserAttributes["id"].ToString() : $"mudinput-{Guid.NewGuid()}"); + + protected Type ResolveComponent() + { + if (MiddlewareService is null) + return typeof(TComponent); + + if (MiddlewareService.Select() is Type type) + return type; + + return typeof(TComponent); + } +} diff --git a/Components/Virtualize/Virtualize.razor b/Components/Virtualize/Virtualize.razor new file mode 100644 index 0000000..e5a8d44 --- /dev/null +++ b/Components/Virtualize/Virtualize.razor @@ -0,0 +1,21 @@ +@namespace Connected.Components +@inherits ComponentBase +@typeparam T + +@if (IsEnabled) +{ + + @if (@ChildContent != null) + { + @ChildContent(item); + } + +} +else +{ + @foreach (var item in Items ?? Array.Empty()) + { + @ChildContent(item); + } +} + diff --git a/Components/Virtualize/Virtualize.razor.cs b/Components/Virtualize/Virtualize.razor.cs new file mode 100644 index 0000000..63b87d0 --- /dev/null +++ b/Components/Virtualize/Virtualize.razor.cs @@ -0,0 +1,36 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.AspNetCore.Components; + +namespace Connected.Components; + +public partial class Virtualize : ComponentBase +{ + /// + /// Set false to turn off virtualization + /// + [Parameter] public bool IsEnabled { get; set; } + + /// + /// Gets or sets the item template for the list. + /// + [Parameter] + public RenderFragment ChildContent { get; set; } + + /// + /// Gets or sets the fixed item source. + /// + [Parameter] + public ICollection Items { get; set; } + + /// + /// Gets or sets a value that determines how many additional items will be rendered + /// before and after the visible region. This help to reduce the frequency of rendering + /// during scrolling. However, higher values mean that more elements will be present + /// in the page. + /// + [Parameter] + public int OverscanCount { get; set; } = 3; +} diff --git a/Connected.Components.csproj b/Connected.Components.csproj new file mode 100644 index 0000000..6b44f80 --- /dev/null +++ b/Connected.Components.csproj @@ -0,0 +1,41 @@ + + + + net7.0 + enable + enable + Connected + + + + + + + + <_ContentIncludedByDefault Remove="compilerconfig.json" /> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Enums/Adornment.cs b/Enums/Adornment.cs new file mode 100644 index 0000000..66bef65 --- /dev/null +++ b/Enums/Adornment.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; + +namespace Connected; + +public enum Adornment +{ + [Description("none")] + None, + [Description("start")] + Start, + [Description("end")] + End +} diff --git a/Enums/Align.cs b/Enums/Align.cs new file mode 100644 index 0000000..5954e49 --- /dev/null +++ b/Enums/Align.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Align + { + [Description("inherit")] + Inherit, + [Description("left")] + Left, + [Description("center")] + Center, + [Description("right")] + Right, + [Description("justify")] + Justify, + [Description("start")] + Start, + [Description("end")] + End, + } +} diff --git a/Enums/AlignItems.cs b/Enums/AlignItems.cs new file mode 100644 index 0000000..f3be3b4 --- /dev/null +++ b/Enums/AlignItems.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum AlignItems + { + [Description("baseline")] + Baseline, + [Description("center")] + Center, + [Description("start")] + Start, + [Description("end")] + End, + [Description("stretch")] + Stretch + } +} diff --git a/Enums/Anchor.cs b/Enums/Anchor.cs new file mode 100644 index 0000000..e94a4c8 --- /dev/null +++ b/Enums/Anchor.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Anchor + { + [Description("left")] + Left, + [Description("right")] + Right, + [Description("start")] + Start, + [Description("end")] + End, + [Description("top")] + Top, + [Description("bottom")] + Bottom + } +} diff --git a/Enums/Animation.cs b/Enums/Animation.cs new file mode 100644 index 0000000..3d176bd --- /dev/null +++ b/Enums/Animation.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Animation + { + [Description("false")] + False, + [Description("pulse")] + Pulse, + [Description("wave")] + Wave + } +} diff --git a/Enums/ButtonType.cs b/Enums/ButtonType.cs new file mode 100644 index 0000000..6b3a613 --- /dev/null +++ b/Enums/ButtonType.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum ButtonType + { + [Description("button")] + Button, + [Description("submit")] + Submit, + [Description("reset")] + Reset + } +} diff --git a/Enums/Color.cs b/Enums/Color.cs new file mode 100644 index 0000000..efdb463 --- /dev/null +++ b/Enums/Color.cs @@ -0,0 +1,31 @@ +using System.ComponentModel; + +namespace Connected; + +public enum ThemeColor +{ + [Description("default")] + Default, + [Description("primary")] + Primary, + [Description("secondary")] + Secondary, + [Description("tertiary")] + Tertiary, + [Description("info")] + Info, + [Description("success")] + Success, + [Description("warning")] + Warning, + [Description("error")] + Error, + [Description("dark")] + Dark, + [Description("transparent")] + Transparent, + [Description("inherit")] + Inherit, + [Description("surface")] + Surface +} diff --git a/Enums/ColorPickerMode.cs b/Enums/ColorPickerMode.cs new file mode 100644 index 0000000..f890f53 --- /dev/null +++ b/Enums/ColorPickerMode.cs @@ -0,0 +1,13 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected +{ + public enum ColorPickerMode + { + RGB, + HSL, + HEX + } +} diff --git a/Enums/ColorPickerView.cs b/Enums/ColorPickerView.cs new file mode 100644 index 0000000..4dcefdd --- /dev/null +++ b/Enums/ColorPickerView.cs @@ -0,0 +1,14 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected +{ + public enum ColorPickerView + { + Spectrum, + Palette, + Grid, + GridCompact + } +} diff --git a/Enums/ContentNavigationExpandBehaviour.cs b/Enums/ContentNavigationExpandBehaviour.cs new file mode 100644 index 0000000..462182b --- /dev/null +++ b/Enums/ContentNavigationExpandBehaviour.cs @@ -0,0 +1,10 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum ContentNavigationExpandBehaviour + { + Always, + WhenSectionIsActive, + } +} diff --git a/Enums/DefaultFocus.cs b/Enums/DefaultFocus.cs new file mode 100644 index 0000000..4053270 --- /dev/null +++ b/Enums/DefaultFocus.cs @@ -0,0 +1,10 @@ +namespace Connected +{ + public enum DefaultFocus + { + None, + Element, + FirstChild, + LastChild + } +} diff --git a/Enums/Direction.cs b/Enums/Direction.cs new file mode 100644 index 0000000..04c5abf --- /dev/null +++ b/Enums/Direction.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Direction + { + [Description("bottom")] + Bottom, + [Description("top")] + Top, + [Description("left")] + Left, + [Description("right")] + Right, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/DividerType.cs b/Enums/DividerType.cs new file mode 100644 index 0000000..863c2ce --- /dev/null +++ b/Enums/DividerType.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum DividerType + { + [Description("fullwidth")] + FullWidth, + [Description("inset")] + Inset, + [Description("middle")] + Middle + } +} diff --git a/Enums/DrawerClipMode.cs b/Enums/DrawerClipMode.cs new file mode 100644 index 0000000..27ed69f --- /dev/null +++ b/Enums/DrawerClipMode.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum DrawerClipMode + { + [Description("never")] + Never, + [Description("docked")] + Docked, + [Description("always")] + Always + } +} diff --git a/Enums/DrawerVariant.cs b/Enums/DrawerVariant.cs new file mode 100644 index 0000000..104cb96 --- /dev/null +++ b/Enums/DrawerVariant.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum DrawerVariant + { + [Description("temporary")] + Temporary, + [Description("responsive")] + Responsive, + [Description("persistent")] + Persistent, + [Description("mini")] + Mini + } +} diff --git a/Enums/Edge.cs b/Enums/Edge.cs new file mode 100644 index 0000000..dbc8a74 --- /dev/null +++ b/Enums/Edge.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Edge + { + [Description("false")] + False, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/HorizontalAlignment.cs b/Enums/HorizontalAlignment.cs new file mode 100644 index 0000000..2975f0f --- /dev/null +++ b/Enums/HorizontalAlignment.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum HorizontalAlignment + { + [Description("center")] + Center, + [Description("left")] + Left, + [Description("right")] + Right, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/InputMode.cs b/Enums/InputMode.cs new file mode 100644 index 0000000..224d7d7 --- /dev/null +++ b/Enums/InputMode.cs @@ -0,0 +1,40 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; + +namespace Connected +{ + /// + /// The inputmode global attribute is an enumerated attribute that hints at the type of data that might be entered by the user while editing the element or its contents. + /// Not supported by safari. Use Pattern to achieve special mobile keyboards in safari. + /// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode + /// + public enum InputMode + { + [Description("No virtual keyboard. For when the page implements its own keyboard input control.")] + none, + + [Description("Default. Standard input keyboard for the user's current locale.")] + text, + + [Description("Fractional numeric input keyboard containing the digits and decimal separator for the user's locale (typically . or ,). Devices may or may not show a minus key (-).")] + @decimal, + + [Description("Numeric input keyboard, but only requires the digits 0–9. Devices may or may not show a minus key.")] + numeric, + + [Description("A telephone keypad input, including the digits 0–9, the asterisk (*), and the pound (#) key. Inputs that require a telephone number should typically use instead.")] + tel, + + [Description("A virtual keyboard optimized for search input. For instance, the return/submit key may be labeled “Search”, along with possible other optimizations. Inputs that require a search query should typically use instead.")] + search, + + [Description("A virtual keyboard optimized for entering email addresses. Typically includes the @ character as well as other optimizations. Inputs that require email addresses should typically use instead.")] + email, + + [Description("A keypad optimized for entering URLs. This may have the / key more prominent, for example. Enhanced features could include history access and so on. Inputs that require a URL should typically use instead.")] + url + } +} diff --git a/Enums/InputType.cs b/Enums/InputType.cs new file mode 100644 index 0000000..d5f852d --- /dev/null +++ b/Enums/InputType.cs @@ -0,0 +1,38 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum InputType + { + [Description("text")] + Text, + [Description("password")] + Password, + [Description("email")] + Email, + [Description("hidden")] + Hidden, + [Description("number")] + Number, + [Description("search")] + Search, + [Description("tel")] + Telephone, + [Description("url")] + Url, + [Description("color")] + Color, + [Description("date")] + Date, + [Description("datetime-local")] + DateTimeLocal, + [Description("month")] + Month, + [Description("time")] + Time, + [Description("week")] + Week + + + } +} diff --git a/Enums/Justify.cs b/Enums/Justify.cs new file mode 100644 index 0000000..d976f32 --- /dev/null +++ b/Enums/Justify.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Justify + { + [Description("start")] + FlexStart, + [Description("center")] + Center, + [Description("end")] + FlexEnd, + [Description("space-between")] + SpaceBetween, + [Description("space-around")] + SpaceAround, + [Description("space-evenly")] + SpaceEvenly + } +} diff --git a/Enums/LabelPosition.cs b/Enums/LabelPosition.cs new file mode 100644 index 0000000..1226a7a --- /dev/null +++ b/Enums/LabelPosition.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum LabelPosition + { + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/Margin.cs b/Enums/Margin.cs new file mode 100644 index 0000000..fb2ba46 --- /dev/null +++ b/Enums/Margin.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Margin + { + [Description("none")] + None, + [Description("dense")] + Dense, + [Description("normal")] + Normal + } +} diff --git a/Enums/MaxWidth.cs b/Enums/MaxWidth.cs new file mode 100644 index 0000000..216245a --- /dev/null +++ b/Enums/MaxWidth.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum MaxWidth + { + [Description("lg")] + Large, + [Description("md")] + Medium, + [Description("sm")] + Small, + [Description("xl")] + ExtraLarge, + [Description("xxl")] + ExtraExtraLarge, + [Description("xs")] + ExtraSmall, + [Description("false")] + False, + } +} diff --git a/Enums/MouseEvent.cs b/Enums/MouseEvent.cs new file mode 100644 index 0000000..6fef082 --- /dev/null +++ b/Enums/MouseEvent.cs @@ -0,0 +1,9 @@ +namespace Connected +{ + public enum MouseEvent + { + LeftClick, + RightClick, + MouseOver + } +} diff --git a/Enums/ObjectFit.cs b/Enums/ObjectFit.cs new file mode 100644 index 0000000..06df265 --- /dev/null +++ b/Enums/ObjectFit.cs @@ -0,0 +1,20 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System.ComponentModel; + +namespace Connected; + +public enum ObjectFit +{ + [Description("none")] + None, + [Description("cover")] + Cover, + [Description("contain")] + Contain, + [Description("fill")] + Fill, + [Description("scale-down")] + ScaleDown +} diff --git a/Enums/ObjectPosition.cs b/Enums/ObjectPosition.cs new file mode 100644 index 0000000..df6523f --- /dev/null +++ b/Enums/ObjectPosition.cs @@ -0,0 +1,28 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System.ComponentModel; + +namespace Connected; + +public enum ObjectPosition +{ + [Description("center")] + Center, + [Description("top")] + Top, + [Description("bottom")] + Bottom, + [Description("left")] + Left, + [Description("left-top")] + LeftTop, + [Description("left-bottom")] + LeftBottom, + [Description("right")] + Right, + [Description("right-top")] + RightTop, + [Description("right-bottom")] + RightBottom, +} diff --git a/Enums/OpenToView.cs b/Enums/OpenToView.cs new file mode 100644 index 0000000..b77299b --- /dev/null +++ b/Enums/OpenToView.cs @@ -0,0 +1,13 @@ + +namespace Connected +{ + public enum OpenTo + { + None, + Date, + Year, + Month, + Hours, + Minutes + } +} diff --git a/Enums/Orientation.cs b/Enums/Orientation.cs new file mode 100644 index 0000000..ee128f0 --- /dev/null +++ b/Enums/Orientation.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Orientation + { + [Description("portrait")] + Portrait, + [Description("landscape")] + Landscape + } +} diff --git a/Enums/Origin.cs b/Enums/Origin.cs new file mode 100644 index 0000000..25c3a96 --- /dev/null +++ b/Enums/Origin.cs @@ -0,0 +1,26 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Origin + { + [Description("top-left")] + TopLeft, + [Description("top-center")] + TopCenter, + [Description("top-right")] + TopRight, + [Description("center-left")] + CenterLeft, + [Description("center-center")] + CenterCenter, + [Description("center-right")] + CenterRight, + [Description("bottom-left")] + BottomLeft, + [Description("bottom-center")] + BottomCenter, + [Description("bottom-right")] + BottomRight, + } +} diff --git a/Enums/OverflowBehavior.cs b/Enums/OverflowBehavior.cs new file mode 100644 index 0000000..dcac662 --- /dev/null +++ b/Enums/OverflowBehavior.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; +using System; + +namespace Connected +{ + public enum OverflowBehavior + { + [Description("flip-never")] + FlipNever, + [Obsolete("This value has a typo and will be removed. Please use FlipOnOpen")] + [Description("flip-onopen")] + FilpOnOpen, + [Description("flip-onopen")] + FlipOnOpen, + [Description("flip-always")] + FlipAlways, + } +} diff --git a/Enums/Page.cs b/Enums/Page.cs new file mode 100644 index 0000000..f629dff --- /dev/null +++ b/Enums/Page.cs @@ -0,0 +1,12 @@ + + +namespace Connected +{ + public enum Page + { + First, + Previous, + Next, + Last + } +} diff --git a/Enums/PickerVariant.cs b/Enums/PickerVariant.cs new file mode 100644 index 0000000..857024f --- /dev/null +++ b/Enums/PickerVariant.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; + +namespace Connected; + +public enum PickerVariant +{ + [Description("inline")] + Inline, + [Description("dialog")] + Dialog, + [Description("static")] + Static +} diff --git a/Enums/Placement.cs b/Enums/Placement.cs new file mode 100644 index 0000000..9affe7b --- /dev/null +++ b/Enums/Placement.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Placement + { + [Description("left")] + Left, + [Description("right")] + Right, + [Description("end")] + End, + [Description("start")] + Start, + [Description("top")] + Top, + [Description("bottom")] + Bottom + } +} diff --git a/Enums/Position.cs b/Enums/Position.cs new file mode 100644 index 0000000..e487d94 --- /dev/null +++ b/Enums/Position.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Position + { + [Description("bottom")] + Bottom, + [Description("center")] + Center, + [Description("top")] + Top, + [Description("left")] + Left, + [Description("right")] + Right, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/ResizeMode.cs b/Enums/ResizeMode.cs new file mode 100644 index 0000000..8c9755f --- /dev/null +++ b/Enums/ResizeMode.cs @@ -0,0 +1,20 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; + +namespace Connected +{ + public enum ResizeMode + { + [Description("none")] + None, + + [Description("column")] + Column, + + [Description("container")] + Container + } +} diff --git a/Enums/Severity.cs b/Enums/Severity.cs new file mode 100644 index 0000000..d4fe78e --- /dev/null +++ b/Enums/Severity.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Severity + { + [Description("normal")] + Normal, + [Description("info")] + Info, + [Description("success")] + Success, + [Description("warning")] + Warning, + [Description("error")] + Error + } +} diff --git a/Enums/Size.cs b/Enums/Size.cs new file mode 100644 index 0000000..2c22eb2 --- /dev/null +++ b/Enums/Size.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Size + { + [Description("small")] + Small, + [Description("medium")] + Medium, + [Description("large")] + Large + } +} diff --git a/Enums/SkeletonType.cs b/Enums/SkeletonType.cs new file mode 100644 index 0000000..099e374 --- /dev/null +++ b/Enums/SkeletonType.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum SkeletonType + { + [Description("text")] + Text, + [Description("circle")] + Circle, + [Description("rectangle")] + Rectangle + } +} diff --git a/Enums/SortDirection.cs b/Enums/SortDirection.cs new file mode 100644 index 0000000..ec2dd7a --- /dev/null +++ b/Enums/SortDirection.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum SortDirection + { + [Description("none")] + None, + [Description("ascending")] + Ascending, + [Description("descending")] + Descending + } +} diff --git a/Enums/SortMode.cs b/Enums/SortMode.cs new file mode 100644 index 0000000..a5a818a --- /dev/null +++ b/Enums/SortMode.cs @@ -0,0 +1,20 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; + +namespace Connected +{ + public enum SortMode + { + [Description("none")] + None, + + [Description("single")] + Single, + + [Description("multiple")] + Multiple + } +} diff --git a/Enums/SwipeDirection.cs b/Enums/SwipeDirection.cs new file mode 100644 index 0000000..9aa0201 --- /dev/null +++ b/Enums/SwipeDirection.cs @@ -0,0 +1,11 @@ +namespace Connected +{ + public enum SwipeDirection + { + None, + LeftToRight, + RightToLeft, + TopToBottom, + BottomToTop + } +} diff --git a/Enums/TimeEditMode.cs b/Enums/TimeEditMode.cs new file mode 100644 index 0000000..1cc41c3 --- /dev/null +++ b/Enums/TimeEditMode.cs @@ -0,0 +1,9 @@ +namespace Connected +{ + public enum TimeEditMode + { + Normal, + OnlyMinutes, + OnlyHours + } +} diff --git a/Enums/TimelineAlign.cs b/Enums/TimelineAlign.cs new file mode 100644 index 0000000..8eaeb2c --- /dev/null +++ b/Enums/TimelineAlign.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum TimelineAlign + { + [Description("default")] + Default, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/TimelineOrientation.cs b/Enums/TimelineOrientation.cs new file mode 100644 index 0000000..3bfbcd2 --- /dev/null +++ b/Enums/TimelineOrientation.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum TimelineOrientation + { + [Description("vertical")] + Vertical, + [Description("horizontal")] + Horizontal + } +} diff --git a/Enums/TimelinePosition.cs b/Enums/TimelinePosition.cs new file mode 100644 index 0000000..5a0e5b7 --- /dev/null +++ b/Enums/TimelinePosition.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum TimelinePosition + { + [Description("alternate")] + Alternate, + [Description("top")] + Top, + [Description("bottom")] + Bottom, + [Description("left")] + Left, + [Description("right")] + Right, + [Description("start")] + Start, + [Description("end")] + End + } +} diff --git a/Enums/Transition.cs b/Enums/Transition.cs new file mode 100644 index 0000000..7677931 --- /dev/null +++ b/Enums/Transition.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Transition + { + [Description("None")] + None = 0, + [Description("Fade")] + Fade = 1, + [Description("Fade")] + Slide = 2, + [Description("Custom")] + Custom = 99 + } +} diff --git a/Enums/Typo.cs b/Enums/Typo.cs new file mode 100644 index 0000000..6c9d16f --- /dev/null +++ b/Enums/Typo.cs @@ -0,0 +1,36 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Typo + { + [Description("inherit")] + inherit, + [Description("h1")] + h1, + [Description("h2")] + h2, + [Description("h3")] + h3, + [Description("h4")] + h4, + [Description("h5")] + h5, + [Description("h6")] + h6, + [Description("subtitle1")] + subtitle1, + [Description("subtitle2")] + subtitle2, + [Description("body1")] + body1, + [Description("body2")] + body2, + [Description("button")] + button, + [Description("caption")] + caption, + [Description("overline")] + overline + } +} diff --git a/Enums/Underline.cs b/Enums/Underline.cs new file mode 100644 index 0000000..da1777d --- /dev/null +++ b/Enums/Underline.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Underline + { + [Description("none")] + None, + [Description("hover")] + Hover, + [Description("always")] + Always + } +} diff --git a/Enums/Variant.cs b/Enums/Variant.cs new file mode 100644 index 0000000..2f6f66b --- /dev/null +++ b/Enums/Variant.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Variant + { + [Description("text")] + Text, + [Description("filled")] + Filled, + [Description("outlined")] + Outlined + } +} diff --git a/Enums/Width.cs b/Enums/Width.cs new file mode 100644 index 0000000..e2b6d4a --- /dev/null +++ b/Enums/Width.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Connected +{ + public enum Width + { + [Description("xs")] + xs, + [Description("sm")] + sm, + [Description("md")] + md, + [Description("lg")] + lg, + [Description("xl")] + xl, + [Description("xxl")] + xxl, + [Description("false")] + False, + } +} diff --git a/Extensions/DataGridExtensions.cs b/Extensions/DataGridExtensions.cs new file mode 100644 index 0000000..c372ed6 --- /dev/null +++ b/Extensions/DataGridExtensions.cs @@ -0,0 +1,36 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Components; + +namespace Connected; + +public static class DataGridExtensions +{ + public static IEnumerable OrderBySortDefinitions(this IEnumerable source, GridState state) + => OrderBySortDefinitions(source, state?.SortDefinitions); + + public static IEnumerable OrderBySortDefinitions(this IEnumerable source, ICollection> sortDefinitions) + { + if (null == source || !source.Any()) + return source; + + if (null == sortDefinitions || 0 == sortDefinitions.Count) + return source; + + IOrderedEnumerable orderedEnumerable = null; + + foreach (var sortDefinition in sortDefinitions) + { + if (null == orderedEnumerable) + orderedEnumerable = sortDefinition.Descending ? source.OrderByDescending(sortDefinition.SortFunc) + : source.OrderBy(sortDefinition.SortFunc); + else + orderedEnumerable = sortDefinition.Descending ? orderedEnumerable.ThenByDescending(sortDefinition.SortFunc) + : orderedEnumerable.ThenBy(sortDefinition.SortFunc); + } + + return orderedEnumerable ?? source; + } +} diff --git a/Extensions/DateTimeExtensions.cs b/Extensions/DateTimeExtensions.cs new file mode 100644 index 0000000..6a7aebe --- /dev/null +++ b/Extensions/DateTimeExtensions.cs @@ -0,0 +1,48 @@ +// Copyright (c) MudBlazor + +using System; +using System.Globalization; + +namespace Connected.Extensions +{ + + public static class DateTimeExtensions + { + public static string ToIsoDateString(this DateTime self) + { + return $"{self.Year:D4}-{self.Month:D2}-{self.Day:D2}"; + } + + public static string ToIsoDateString(this DateTime? self) + { + if (self == null) + return null; + return $"{self.Value.Year:D4}-{self.Value.Month:D2}-{self.Value.Day:D2}"; + } + + public static DateTime StartOfMonth(this DateTime self, CultureInfo culture) + { + var month = culture.Calendar.GetMonth(self); + var year = culture.Calendar.GetYear(self); + return culture.Calendar.ToDateTime(year, month, 1, 0, 0, 0, 0); + } + + public static DateTime EndOfMonth(this DateTime self, CultureInfo culture) + { + var month = culture.Calendar.GetMonth(self); + var year = culture.Calendar.GetYear(self); + var days = culture.Calendar.GetDaysInMonth(year, month); + return culture.Calendar.ToDateTime(year, month, days, 0, 0, 0, 0); + } + + public static DateTime StartOfWeek(this DateTime self, DayOfWeek firstDayOfWeek) + { + var diff = (7 + (self.DayOfWeek - firstDayOfWeek)) % 7; + if (self.Year == 1 && self.Month == 1 && (self.Day - diff) < 1) + { + return self.Date; + } + return self.AddDays(-1 * diff).Date; + } + } +} diff --git a/Extensions/DoubleExtentions.cs b/Extensions/DoubleExtentions.cs new file mode 100644 index 0000000..995469a --- /dev/null +++ b/Extensions/DoubleExtentions.cs @@ -0,0 +1,13 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Globalization; + +namespace Connected.Extensions +{ + public static class DoubleExtentions + { + public static string ToInvariantString(this double input) => input.ToString(CultureInfo.InvariantCulture); + } +} diff --git a/Extensions/ElementReferenceExtensions.cs b/Extensions/ElementReferenceExtensions.cs new file mode 100644 index 0000000..487d638 --- /dev/null +++ b/Extensions/ElementReferenceExtensions.cs @@ -0,0 +1,66 @@ +#nullable enable +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Connected.Interop; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected +{ + [ExcludeFromCodeCoverage] + public static class ElementReferenceExtensions + { + private static readonly PropertyInfo? jsRuntimeProperty = + typeof(WebElementReferenceContext).GetProperty("JSRuntime", BindingFlags.Instance | BindingFlags.NonPublic); + + internal static IJSRuntime? GetJSRuntime(this ElementReference elementReference) + { + if (elementReference.Context is not WebElementReferenceContext context) + { + return null; + } + + return (IJSRuntime?)jsRuntimeProperty?.GetValue(context); + } + + public static ValueTask FocusFirstAsync(this ElementReference elementReference, int skip = 0, int min = 0) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.focusFirst", elementReference, skip, min) ?? ValueTask.CompletedTask; + + public static ValueTask FocusLastAsync(this ElementReference elementReference, int skip = 0, int min = 0) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.focusLast", elementReference, skip, min) ?? ValueTask.CompletedTask; + + public static ValueTask SaveFocusAsync(this ElementReference elementReference) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.saveFocus", elementReference) ?? ValueTask.CompletedTask; + + public static ValueTask RestoreFocusAsync(this ElementReference elementReference) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.restoreFocus", elementReference) ?? ValueTask.CompletedTask; + + public static ValueTask BlurAsync(this ElementReference elementReference) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.blur", elementReference) ?? ValueTask.CompletedTask; + + public static ValueTask SelectAsync(this ElementReference elementReference) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.select", elementReference) ?? ValueTask.CompletedTask; + + public static ValueTask SelectRangeAsync(this ElementReference elementReference, int pos1, int pos2) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.selectRange", elementReference, pos1, pos2) ?? ValueTask.CompletedTask; + + public static ValueTask ChangeCssAsync(this ElementReference elementReference, string css) => + elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.changeCss", elementReference, css) ?? ValueTask.CompletedTask; + + public static ValueTask MudGetBoundingClientRectAsync(this ElementReference elementReference) => + elementReference.GetJSRuntime()?.InvokeAsync("elementRef.getBoundingClientRect", elementReference) ?? ValueTask.FromResult(new BoundingClientRect()); + + public static ValueTask AddDefaultPreventingHandlers(this ElementReference elementReference, string[] eventNames) => + elementReference.GetJSRuntime()?.InvokeAsync("elementRef.addDefaultPreventingHandlers", elementReference, eventNames) ?? new ValueTask(Array.Empty()); + + public static ValueTask RemoveDefaultPreventingHandlers(this ElementReference elementReference, string[] eventNames, int[] listenerIds) + { + if (eventNames.Length != listenerIds.Length) + { + throw new ArgumentException($"Number of elements in {nameof(eventNames)} and {nameof(listenerIds)} has to match."); + } + + return elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.removeDefaultPreventingHandlers", elementReference, eventNames, listenerIds) ?? ValueTask.CompletedTask; + } + } +} diff --git a/Extensions/EnumExtensions.cs b/Extensions/EnumExtensions.cs new file mode 100644 index 0000000..e7cd9ab --- /dev/null +++ b/Extensions/EnumExtensions.cs @@ -0,0 +1,15 @@ +using System.ComponentModel; + +namespace Connected.Extensions; + +public static class EnumExtensions +{ + public static string ToDescriptionString(this Enum val) + { + var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); + + return attributes.Length > 0 + ? attributes[0].Description + : val.ToString().ToLower(); + } +} diff --git a/Extensions/ExpressionExtensions.cs b/Extensions/ExpressionExtensions.cs new file mode 100644 index 0000000..5382f19 --- /dev/null +++ b/Extensions/ExpressionExtensions.cs @@ -0,0 +1,38 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq.Expressions; +using Connected.Annotations; + +namespace Connected +{ + public static class ExpressionExtensions + { + public static string GetFullPathOfMember(this Expression> property) + { + var resultingString = string.Empty; + var p = property.Body as MemberExpression; + + while (p != null) + { + if (p.Expression is MemberExpression) + { + resultingString = p.Member.Name + (resultingString != string.Empty ? "." : string.Empty) + resultingString; + } + p = p.Expression as MemberExpression; + } + return resultingString; + } + + /// + /// Returns the display name attribute of the provided field property as a string. If this attribute is missing, the member name will be returned. + /// + public static string GetLabelString(this Expression> expression) + { + var memberExpression = (MemberExpression)expression.Body; + var propertyInfo = memberExpression.Expression?.Type.GetProperty(memberExpression.Member.Name); + return propertyInfo?.GetCustomAttributes(typeof(LabelAttribute), true).Cast().FirstOrDefault()?.Name ?? string.Empty; + } + } +} diff --git a/Extensions/KeepInRangeExtensions.cs b/Extensions/KeepInRangeExtensions.cs new file mode 100644 index 0000000..e7e8f62 --- /dev/null +++ b/Extensions/KeepInRangeExtensions.cs @@ -0,0 +1,15 @@ +using System; + +namespace Connected.Extensions +{ + public static class KeepInRangeExtensions + { + public static double EnsureRange(this double input, double max) => EnsureRange(input, 0.0, max); + public static double EnsureRange(this double input, double min, double max) => Math.Max(min, Math.Min(max, input)); + public static byte EnsureRange(this byte input, byte max) => EnsureRange(input, (byte)0, max); + public static byte EnsureRange(this byte input, byte min, byte max) => Math.Max(min, Math.Min(max, input)); + public static byte EnsureRangeToByte(this int input) => (byte)EnsureRange(input, 0, 255); + public static int EnsureRange(this int input, int max) => EnsureRange(input, 0, max); + public static int EnsureRange(this int input, int min, int max) => Math.Max(min, Math.Min(max, input)); + } +} diff --git a/Extensions/MathExtensions.cs b/Extensions/MathExtensions.cs new file mode 100644 index 0000000..3f092a2 --- /dev/null +++ b/Extensions/MathExtensions.cs @@ -0,0 +1,8 @@ +namespace Connected.Extensions +{ + public static class MathExtensions + { + public static double Map(double sourceMin, double sourceMax, double targetMin, double targetMax, double value) => + ((value) / (sourceMax - sourceMin)) * (targetMax - targetMin); + } +} diff --git a/Extensions/ObjectExtensions.cs b/Extensions/ObjectExtensions.cs new file mode 100644 index 0000000..07a55b9 --- /dev/null +++ b/Extensions/ObjectExtensions.cs @@ -0,0 +1,13 @@ +namespace Connected.Extensions +{ + public static class ObjectExtensions + { + + public static T As(this object self) + { + if (self == null || !(self is T)) + return default(T); + return (T)self; + } + } +} diff --git a/Extensions/ParameterViewExtensions.cs b/Extensions/ParameterViewExtensions.cs new file mode 100644 index 0000000..9e15842 --- /dev/null +++ b/Extensions/ParameterViewExtensions.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected +{ + internal static class ParameterViewExtensions + { + public static bool Contains(this ParameterView view, string parameterName) + { + return view.TryGetValue(parameterName, out var _); + } + } +} diff --git a/Extensions/StringExtensions.cs b/Extensions/StringExtensions.cs new file mode 100644 index 0000000..cf1ff04 --- /dev/null +++ b/Extensions/StringExtensions.cs @@ -0,0 +1,15 @@ +// Copyright (c) Alessandro Ghidini. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Globalization; + +// ReSharper disable once CheckNamespace +internal static class StringExtensions +{ + public static bool IsEmpty(this string value) => string.IsNullOrWhiteSpace(value); + public static bool IsNonEmpty(this string value) => !string.IsNullOrWhiteSpace(value); + public static string Trimmed(this string value) => value == null ? string.Empty : value.Trim(); + public static string ToPercentage(this decimal value) => value.ToString("0.##", CultureInfo.InvariantCulture); + public static string ToJsString(this string value) => char.ToLower(value[0]) + value.Substring(1); + public static byte GetByteValue(this string value, int index) => byte.Parse(new string(new char[] { value[index], value[index + 1] }), NumberStyles.HexNumber); +} diff --git a/Extensions/TableExtensions.cs b/Extensions/TableExtensions.cs new file mode 100644 index 0000000..40c849f --- /dev/null +++ b/Extensions/TableExtensions.cs @@ -0,0 +1,27 @@ +using System.Linq.Expressions; +using Connected.Components; + +namespace Connected +{ + public static class TableExtensions + { + public static IOrderedEnumerable OrderByDirection(this IEnumerable source, SortDirection direction, Func keySelector) + { + if (direction == SortDirection.Descending) + return source.OrderByDescending(keySelector); + return source.OrderBy(keySelector); + } + + public static IOrderedQueryable OrderByDirection(this IQueryable source, SortDirection direction, Expression> keySelector) + { + if (direction == SortDirection.Descending) + return source.OrderByDescending(keySelector); + return source.OrderBy(keySelector); + } + + /// + /// Disabled the edit button if edit row switching is blocked and the provided item is not being edited + /// + public static bool EditButtonDisabled(this TableContext context, T item) => (context?.Table.IsEditRowSwitchingBlocked ?? false) && context?.Table._editingItem != null && !ReferenceEquals(context?.Table._editingItem, item); + } +} diff --git a/Extensions/TaskExtensions.cs b/Extensions/TaskExtensions.cs new file mode 100644 index 0000000..f388b09 --- /dev/null +++ b/Extensions/TaskExtensions.cs @@ -0,0 +1,68 @@ +using System; +using System.Threading.Tasks; + +namespace Connected +{ + public enum TaskOption + { + None, + Safe + } + + public static class TaskExtensions + { + /// + /// Task will be awaited and exceptions will be logged to console (TaskOption.Safe) or managed by the Blazor framework (TaskOption.None). + /// + public static async void AndForget(this Task task, TaskOption option = TaskOption.None) + { + try + { + await task; + } + catch (Exception ex) + { + if (option != TaskOption.Safe) + throw; + + Console.WriteLine(ex); + } + } + + /// + /// ValueTask will be awaited and exceptions will be logged to console (TaskOption.Safe) or managed by the Blazor framework (TaskOption.None). + /// + public static async void AndForget(this ValueTask task, TaskOption option = TaskOption.None) + { + try + { + await task; + } + catch (Exception ex) + { + if (option != TaskOption.Safe) + throw; + + Console.WriteLine(ex); + } + } + + /// + /// ValueTask(bool) will be awaited and exceptions will be logged to console (TaskOption.Safe) or managed by the Blazor framework (TaskOption.None). + /// + public static async void AndForget(this ValueTask task, TaskOption option = TaskOption.None) + { + try + { + await task; + } + catch (Exception ex) + { + if (option != TaskOption.Safe) + throw; + + Console.WriteLine(ex); + } + } + } +} diff --git a/Extensions/TimeSpanExtensions.cs b/Extensions/TimeSpanExtensions.cs new file mode 100644 index 0000000..d4d42a8 --- /dev/null +++ b/Extensions/TimeSpanExtensions.cs @@ -0,0 +1,29 @@ +// Copyright (c) MudBlazor + +using System; + +// ReSharper disable once CheckNamespace +internal static class TimeSpanExtensions +{ + public static string ToIsoString(this TimeSpan self, bool seconds = false, bool ms = false) + { + if (!seconds) + return $"{self.Hours:D2}:{self.Minutes:D2}"; + if (!ms) + return $"{self.Hours:D2}:{self.Minutes:D2}-{self.Seconds:D2}"; + return $"{self.Hours:D2}:{self.Minutes:D2}-{self.Seconds:D2},{self.Milliseconds}"; + } + + public static string ToIsoString(this TimeSpan? self, bool seconds = false, bool ms = false) + { + return self?.ToIsoString(seconds, ms); + } + + public static int ToAmPmHour(this TimeSpan time) + { + var h = time.Hours % 12; + if (h == 0) + h = 12; + return h; + } +} diff --git a/Extensions/WebUnitsExtensions.cs b/Extensions/WebUnitsExtensions.cs new file mode 100644 index 0000000..b1380bc --- /dev/null +++ b/Extensions/WebUnitsExtensions.cs @@ -0,0 +1,18 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Globalization; + +namespace Connected.Utilities +{ + public static class WebUnitsExtensions + { + public static string ToPx(this int val) => $"{val}px"; + public static string ToPx(this int? val) => val != null ? val.Value.ToPx() : string.Empty; + public static string ToPx(this long val) => $"{val}px"; + public static string ToPx(this long? val) => val != null ? val.Value.ToPx() : string.Empty; + public static string ToPx(this double val) => $"{val.ToString("0.##", CultureInfo.InvariantCulture)}px"; + public static string ToPx(this double? val) => val != null ? val.Value.ToPx() : string.Empty; + } +} diff --git a/Icons/Custom/Brands.cs b/Icons/Custom/Brands.cs new file mode 100644 index 0000000..49d1543 --- /dev/null +++ b/Icons/Custom/Brands.cs @@ -0,0 +1,45 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Custom + { + [ExcludeFromCodeCoverage] + public class Brands + { + public const string MudBlazor = ""; + public const string GitHub = ""; + public const string Apple = ""; + public const string Facebook = ""; + public const string Awesome = ""; + public const string Google = ""; + public const string Instagram = ""; + public const string LinkedIn = ""; + public const string Pinterest = ""; + public const string Reddit = ""; + public const string Telegram = ""; + public const string Twitter = ""; + public const string TikTok = ""; + public const string Vimeo = ""; + public const string WhatsApp = ""; + public const string YouTube = ""; + public const string Microsoft = ""; + public const string MicrosoftAzure = ""; + public const string MicrosoftAzureDevOps = ""; + public const string MicrosoftVisualStudio = ""; + public const string MicrosoftWindows = ""; + + public const string Discord = ""; + + public const string Steam = "<"; + public const string StackOverflow = ""; + public const string Chrome = ""; + public const string Gmail = ""; + public const string Calculator = ""; + public const string Linux = ""; + } + } + } +} diff --git a/Icons/Custom/FileFormats.cs b/Icons/Custom/FileFormats.cs new file mode 100644 index 0000000..9833ff2 --- /dev/null +++ b/Icons/Custom/FileFormats.cs @@ -0,0 +1,23 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Custom + { + [ExcludeFromCodeCoverage] + public class FileFormats + { + public const string FileCode = ""; + public const string FileDocument = ""; + public const string FileExcel = ""; + public const string FileImage = ""; + public const string FileMusic = ""; + public const string FilePdf = ""; + public const string FileVideo = ""; + public const string FileWord = ""; + } + } + } +} diff --git a/Icons/Custom/Uncategorized.cs b/Icons/Custom/Uncategorized.cs new file mode 100644 index 0000000..9ddae93 --- /dev/null +++ b/Icons/Custom/Uncategorized.cs @@ -0,0 +1,33 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Custom + { + [ExcludeFromCodeCoverage] + public class Uncategorized + { + public const string Radioactive = ""; + public const string BioHazard = ""; + public const string FoodApple = ""; + public const string Bacteria = ""; + public const string Baguette = ""; + public const string Sausage = ""; + public const string WaterMelon = ""; + public const string AlertSuccess = ""; + public const string ColorPalette = ""; + public const string Fish = ""; + public const string Folder = ""; + public const string FolderOpen = ""; + public const string ChessQueen = ""; + public const string ChessKing = ""; + public const string ChessBishop = ">"; + public const string ChessKnight = ""; + public const string ChessPawn = ""; + public const string ChessRook = ""; + } + } + } +} diff --git a/Icons/Icons.cs b/Icons/Icons.cs new file mode 100644 index 0000000..62e8da4 --- /dev/null +++ b/Icons/Icons.cs @@ -0,0 +1,19 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + [ExcludeFromCodeCoverage] + public partial class Icons + { + [ExcludeFromCodeCoverage] + public partial class Custom + { + } + + [ExcludeFromCodeCoverage] + public partial class Material + { + } + } +} + diff --git a/Icons/Material/Filled.cs b/Icons/Material/Filled.cs new file mode 100644 index 0000000..c59d11e --- /dev/null +++ b/Icons/Material/Filled.cs @@ -0,0 +1,2069 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Material + { + [ExcludeFromCodeCoverage] + public partial class Filled + { + public const string _10k = ""; + public const string _10mp = ""; + public const string _11mp = ""; + public const string _123 = ""; + public const string _12mp = ""; + public const string _13mp = ""; + public const string _14mp = ""; + public const string _15mp = ""; + public const string _16mp = ""; + public const string _17mp = ""; + public const string _18mp = ""; + public const string _19mp = ""; + public const string _1k = ""; + public const string _1kPlus = ""; + public const string _1xMobiledata = ""; + public const string _20mp = ""; + public const string _21mp = ""; + public const string _22mp = ""; + public const string _23mp = ""; + public const string _24mp = ""; + public const string _2k = ""; + public const string _2kPlus = ""; + public const string _2mp = ""; + public const string _30fps = ""; + public const string _30fpsSelect = ""; + public const string _360 = ""; + public const string _3dRotation = ""; + public const string _3gMobiledata = ""; + public const string _3k = ""; + public const string _3kPlus = ""; + public const string _3mp = ""; + public const string _3p = ""; + public const string _4gMobiledata = ""; + public const string _4gPlusMobiledata = ""; + public const string _4k = ""; + public const string _4kPlus = ""; + public const string _4mp = ""; + public const string _5g = ""; + public const string _5k = ""; + public const string _5kPlus = ""; + public const string _5mp = ""; + public const string _60fps = ""; + public const string _60fpsSelect = ""; + public const string _6FtApart = ""; + public const string _6k = ""; + public const string _6kPlus = ""; + public const string _6mp = ""; + public const string _7k = ""; + public const string _7kPlus = ""; + public const string _7mp = ""; + public const string _8k = ""; + public const string _8kPlus = ""; + public const string _8mp = ""; + public const string _9k = ""; + public const string _9kPlus = ""; + public const string _9mp = ""; + public const string Abc = ""; + public const string AcUnit = ""; + public const string AccessAlarm = ""; + public const string AccessAlarms = ""; + public const string AccessTime = ""; + public const string AccessTimeFilled = ""; + public const string Accessibility = ""; + public const string AccessibilityNew = ""; + public const string Accessible = ""; + public const string AccessibleForward = ""; + public const string AccountBalance = ""; + public const string AccountBalanceWallet = ""; + public const string AccountBox = ""; + public const string AccountCircle = ""; + public const string AccountTree = ""; + public const string AdUnits = ""; + public const string Adb = ""; + public const string Add = ""; + public const string AddAPhoto = ""; + public const string AddAlarm = ""; + public const string AddAlert = ""; + public const string AddBox = ""; + public const string AddBusiness = ""; + public const string AddCard = ""; + public const string AddChart = ""; + public const string AddCircle = ""; + public const string AddCircleOutline = ""; + public const string AddComment = ""; + public const string AddIcCall = ""; + public const string AddLink = ""; + public const string AddLocation = ""; + public const string AddLocationAlt = ""; + public const string AddModerator = ""; + public const string AddPhotoAlternate = ""; + public const string AddReaction = ""; + public const string AddRoad = ""; + public const string AddShoppingCart = ""; + public const string AddTask = ""; + public const string AddToDrive = ""; + public const string AddToHomeScreen = ""; + public const string AddToPhotos = ""; + public const string AddToQueue = ""; + public const string Addchart = ""; + public const string AdfScanner = ""; + public const string Adjust = ""; + public const string AdminPanelSettings = ""; + public const string AdsClick = ""; + public const string Agriculture = ""; + public const string Air = ""; + public const string AirlineSeatFlat = ""; + public const string AirlineSeatFlatAngled = ""; + public const string AirlineSeatIndividualSuite = ""; + public const string AirlineSeatLegroomExtra = ""; + public const string AirlineSeatLegroomNormal = ""; + public const string AirlineSeatLegroomReduced = ""; + public const string AirlineSeatReclineExtra = ""; + public const string AirlineSeatReclineNormal = ""; + public const string AirlineStops = ""; + public const string Airlines = ""; + public const string AirplaneTicket = ""; + public const string AirplanemodeActive = ""; + public const string AirplanemodeInactive = ""; + public const string Airplay = ""; + public const string AirportShuttle = ""; + public const string Alarm = ""; + public const string AlarmAdd = ""; + public const string AlarmOff = ""; + public const string AlarmOn = ""; + public const string Album = ""; + public const string AlignHorizontalCenter = ""; + public const string AlignHorizontalLeft = ""; + public const string AlignHorizontalRight = ""; + public const string AlignVerticalBottom = ""; + public const string AlignVerticalCenter = ""; + public const string AlignVerticalTop = ""; + public const string AllInbox = ""; + public const string AllInclusive = ""; + public const string AllOut = ""; + public const string AltRoute = ""; + public const string AlternateEmail = ""; + public const string Analytics = ""; + public const string Anchor = ""; + public const string Android = ""; + public const string Animation = ""; + public const string Announcement = ""; + public const string Aod = ""; + public const string Apartment = ""; + public const string Api = ""; + public const string AppBlocking = ""; + public const string AppRegistration = ""; + public const string AppSettingsAlt = ""; + public const string AppShortcut = ""; + public const string Approval = ""; + public const string Apps = ""; + public const string AppsOutage = ""; + public const string Architecture = ""; + public const string Archive = ""; + public const string AreaChart = ""; + public const string ArrowBack = ""; + public const string ArrowBackIos = ""; + public const string ArrowBackIosNew = ""; + public const string ArrowCircleDown = ""; + public const string ArrowCircleLeft = ""; + public const string ArrowCircleRight = ""; + public const string ArrowCircleUp = ""; + public const string ArrowDownward = ""; + public const string ArrowDropDown = ""; + public const string ArrowDropDownCircle = ""; + public const string ArrowDropUp = ""; + public const string ArrowForward = ""; + public const string ArrowForwardIos = ""; + public const string ArrowLeft = ""; + public const string ArrowRight = ""; + public const string ArrowRightAlt = ""; + public const string ArrowUpward = ""; + public const string ArtTrack = ""; + public const string Article = ""; + public const string AspectRatio = ""; + public const string Assessment = ""; + public const string Assignment = ""; + public const string AssignmentInd = ""; + public const string AssignmentLate = ""; + public const string AssignmentReturn = ""; + public const string AssignmentReturned = ""; + public const string AssignmentTurnedIn = ""; + public const string Assistant = ""; + public const string AssistantDirection = "Asset 1"; + public const string AssistantPhoto = ""; + public const string AssuredWorkload = ""; + public const string Atm = ""; + public const string AttachEmail = ""; + public const string AttachFile = ""; + public const string AttachMoney = ""; + public const string Attachment = ""; + public const string Attractions = ""; + public const string Attribution = ""; + public const string AudioFile = ""; + public const string Audiotrack = ""; + public const string AutoAwesome = ""; + public const string AutoAwesomeMosaic = ""; + public const string AutoAwesomeMotion = ""; + public const string AutoDelete = ""; + public const string AutoFixHigh = ""; + public const string AutoFixNormal = ""; + public const string AutoFixOff = ""; + public const string AutoGraph = ""; + public const string AutoStories = ""; + public const string AutofpsSelect = ""; + public const string Autorenew = ""; + public const string AvTimer = ""; + public const string BabyChangingStation = ""; + public const string BackHand = ""; + public const string Backpack = ""; + public const string Backspace = ""; + public const string Backup = ""; + public const string BackupTable = ""; + public const string Badge = ""; + public const string BakeryDining = ""; + public const string Balance = ""; + public const string Balcony = ""; + public const string Ballot = ""; + public const string BarChart = ""; + public const string BatchPrediction = ""; + public const string Bathroom = ""; + public const string Bathtub = ""; + public const string Battery0Bar = ""; + public const string Battery1Bar = ""; + public const string Battery2Bar = ""; + public const string Battery3Bar = ""; + public const string Battery4Bar = ""; + public const string Battery5Bar = ""; + public const string Battery6Bar = ""; + public const string BatteryAlert = ""; + public const string BatteryChargingFull = ""; + public const string BatteryFull = ""; + public const string BatterySaver = ""; + public const string BatteryStd = ""; + public const string BatteryUnknown = ""; + public const string BeachAccess = ""; + public const string Bed = ""; + public const string BedroomBaby = ""; + public const string BedroomChild = ""; + public const string BedroomParent = ""; + public const string Bedtime = ""; + public const string BedtimeOff = ""; + public const string Beenhere = ""; + public const string Bento = ""; + public const string BikeScooter = ""; + public const string Biotech = ""; + public const string Blender = ""; + public const string Block = ""; + public const string Bloodtype = ""; + public const string Bluetooth = ""; + public const string BluetoothAudio = ""; + public const string BluetoothConnected = ""; + public const string BluetoothDisabled = ""; + public const string BluetoothDrive = ""; + public const string BluetoothSearching = ""; + public const string BlurCircular = ""; + public const string BlurLinear = ""; + public const string BlurOff = ""; + public const string BlurOn = ""; + public const string Bolt = ""; + public const string Book = ""; + public const string BookOnline = ""; + public const string Bookmark = ""; + public const string BookmarkAdd = ""; + public const string BookmarkAdded = ""; + public const string BookmarkBorder = ""; + public const string BookmarkRemove = ""; + public const string Bookmarks = ""; + public const string BorderAll = ""; + public const string BorderBottom = ""; + public const string BorderClear = ""; + public const string BorderColor = ""; + public const string BorderHorizontal = ""; + public const string BorderInner = ""; + public const string BorderLeft = ""; + public const string BorderOuter = ""; + public const string BorderRight = ""; + public const string BorderStyle = ""; + public const string BorderTop = ""; + public const string BorderVertical = ""; + public const string Boy = ""; + public const string BrandingWatermark = ""; + public const string BreakfastDining = ""; + public const string Brightness1 = ""; + public const string Brightness2 = ""; + public const string Brightness3 = ""; + public const string Brightness4 = ""; + public const string Brightness5 = ""; + public const string Brightness6 = ""; + public const string Brightness7 = ""; + public const string BrightnessAuto = ""; + public const string BrightnessHigh = ""; + public const string BrightnessLow = ""; + public const string BrightnessMedium = ""; + public const string BrokenImage = ""; + public const string BrowseGallery = ""; + public const string BrowserNotSupported = ""; + public const string BrowserUpdated = ""; + public const string BrunchDining = ""; + public const string Brush = ""; + public const string BubbleChart = ""; + public const string BugReport = ""; + public const string Build = ""; + public const string BuildCircle = ""; + public const string Bungalow = ""; + public const string BurstMode = ""; + public const string BusAlert = ""; + public const string Business = ""; + public const string BusinessCenter = ""; + public const string Cabin = ""; + public const string Cable = ""; + public const string Cached = ""; + public const string Cake = ""; + public const string Calculate = ""; + public const string CalendarMonth = ""; + public const string CalendarToday = ""; + public const string CalendarViewDay = ""; + public const string CalendarViewMonth = ""; + public const string CalendarViewWeek = ""; + public const string Call = ""; + public const string CallEnd = ""; + public const string CallMade = ""; + public const string CallMerge = ""; + public const string CallMissed = ""; + public const string CallMissedOutgoing = ""; + public const string CallReceived = ""; + public const string CallSplit = ""; + public const string CallToAction = ""; + public const string Camera = ""; + public const string CameraAlt = ""; + public const string CameraEnhance = ""; + public const string CameraFront = ""; + public const string CameraIndoor = ""; + public const string CameraOutdoor = ""; + public const string CameraRear = ""; + public const string CameraRoll = ""; + public const string Cameraswitch = ""; + public const string Campaign = ""; + public const string Cancel = ""; + public const string CancelPresentation = ""; + public const string CancelScheduleSend = ""; + public const string CandlestickChart = ""; + public const string CarCrash = ""; + public const string CarRental = ""; + public const string CarRepair = ""; + public const string CardGiftcard = ""; + public const string CardMembership = ""; + public const string CardTravel = ""; + public const string Carpenter = ""; + public const string Cases = ""; + public const string Casino = ""; + public const string Cast = ""; + public const string CastConnected = ""; + public const string CastForEducation = ""; + public const string Castle = ""; + public const string CatchingPokemon = ""; + public const string Category = ""; + public const string Celebration = ""; + public const string CellTower = ""; + public const string CellWifi = ""; + public const string CenterFocusStrong = ""; + public const string CenterFocusWeak = ""; + public const string Chair = ""; + public const string ChairAlt = ""; + public const string Chalet = ""; + public const string ChangeCircle = ""; + public const string ChangeHistory = ""; + public const string ChargingStation = ""; + public const string Chat = ""; + public const string ChatBubble = ""; + public const string ChatBubbleOutline = ""; + public const string Check = ""; + public const string CheckBox = ""; + public const string CheckBoxOutlineBlank = ""; + public const string CheckCircle = ""; + public const string CheckCircleOutline = ""; + public const string Checklist = ""; + public const string ChecklistRtl = ""; + public const string Checkroom = ""; + public const string ChevronLeft = ""; + public const string ChevronRight = ""; + public const string ChildCare = ""; + public const string ChildFriendly = ""; + public const string ChromeReaderMode = ""; + public const string Church = ""; + public const string Circle = ""; + public const string CircleNotifications = ""; + public const string Class = ""; + public const string CleanHands = ""; + public const string CleaningServices = ""; + public const string Clear = ""; + public const string ClearAll = ""; + public const string Close = ""; + public const string CloseFullscreen = ""; + public const string ClosedCaption = ""; + public const string ClosedCaptionDisabled = ""; + public const string ClosedCaptionOff = ""; + public const string Cloud = ""; + public const string CloudCircle = ""; + public const string CloudDone = ""; + public const string CloudDownload = ""; + public const string CloudOff = ""; + public const string CloudQueue = ""; + public const string CloudSync = ""; + public const string CloudUpload = ""; + public const string Co2 = ""; + public const string CoPresent = ""; + public const string Code = ""; + public const string CodeOff = ""; + public const string Coffee = ""; + public const string CoffeeMaker = ""; + public const string Collections = ""; + public const string CollectionsBookmark = ""; + public const string ColorLens = ""; + public const string Colorize = ""; + public const string Comment = ""; + public const string CommentBank = ""; + public const string CommentsDisabled = ""; + public const string Commit = ""; + public const string Commute = ""; + public const string Compare = ""; + public const string CompareArrows = ""; + public const string CompassCalibration = ""; + public const string Compost = ""; + public const string Compress = ""; + public const string Computer = ""; + public const string ConfirmationNumber = ""; + public const string ConnectWithoutContact = ""; + public const string ConnectedTv = ""; + public const string ConnectingAirports = ""; + public const string Construction = ""; + public const string ContactMail = ""; + public const string ContactPage = ""; + public const string ContactPhone = ""; + public const string ContactSupport = ""; + public const string Contactless = ""; + public const string Contacts = ""; + public const string ContentCopy = ""; + public const string ContentCut = ""; + public const string ContentPaste = ""; + public const string ContentPasteGo = ""; + public const string ContentPasteOff = ""; + public const string ContentPasteSearch = ""; + public const string Contrast = ""; + public const string ControlCamera = ""; + public const string ControlPoint = ""; + public const string ControlPointDuplicate = ""; + public const string Cookie = ""; + public const string CopyAll = ""; + public const string Copyright = ""; + public const string Coronavirus = ""; + public const string CorporateFare = ""; + public const string Cottage = ""; + public const string Countertops = ""; + public const string Create = ""; + public const string CreateNewFolder = ""; + public const string CreditCard = ""; + public const string CreditCardOff = ""; + public const string CreditScore = ""; + public const string Crib = ""; + public const string CrisisAlert = ""; + public const string Crop = ""; + public const string Crop169 = ""; + public const string Crop32 = ""; + public const string Crop54 = ""; + public const string Crop75 = ""; + public const string CropDin = ""; + public const string CropFree = ""; + public const string CropLandscape = ""; + public const string CropOriginal = ""; + public const string CropPortrait = ""; + public const string CropRotate = ""; + public const string CropSquare = ""; + public const string CrueltyFree = ""; + public const string Css = ""; + public const string CurrencyBitcoin = ""; + public const string CurrencyExchange = ""; + public const string CurrencyFranc = ""; + public const string CurrencyLira = ""; + public const string CurrencyPound = ""; + public const string CurrencyRuble = ""; + public const string CurrencyRupee = ""; + public const string CurrencyYen = ""; + public const string CurrencyYuan = ""; + public const string Cyclone = ""; + public const string Dangerous = ""; + public const string DarkMode = ""; + public const string Dashboard = ""; + public const string DashboardCustomize = ""; + public const string DataArray = ""; + public const string DataExploration = ""; + public const string DataObject = ""; + public const string DataSaverOff = ""; + public const string DataSaverOn = ""; + public const string DataThresholding = ""; + public const string DataUsage = ""; + public const string DateRange = ""; + public const string Deblur = ""; + public const string Deck = ""; + public const string Dehaze = ""; + public const string Delete = ""; + public const string DeleteForever = ""; + public const string DeleteOutline = ""; + public const string DeleteSweep = ""; + public const string DeliveryDining = ""; + public const string DensityLarge = ""; + public const string DensityMedium = ""; + public const string DensitySmall = ""; + public const string DepartureBoard = ""; + public const string Description = ""; + public const string Deselect = ""; + public const string DesignServices = ""; + public const string DesktopAccessDisabled = ""; + public const string DesktopMac = ""; + public const string DesktopWindows = ""; + public const string Details = ""; + public const string DeveloperBoard = ""; + public const string DeveloperBoardOff = ""; + public const string DeveloperMode = ""; + public const string DeviceHub = ""; + public const string DeviceThermostat = ""; + public const string DeviceUnknown = ""; + public const string Devices = ""; + public const string DevicesFold = ""; + public const string DevicesOther = ""; + public const string DialerSip = ""; + public const string Dialpad = ""; + public const string Diamond = ""; + public const string Difference = ""; + public const string Dining = ""; + public const string DinnerDining = ""; + public const string Directions = ""; + public const string DirectionsBike = ""; + public const string DirectionsBoat = ""; + public const string DirectionsBoatFilled = ""; + public const string DirectionsBus = ""; + public const string DirectionsBusFilled = ""; + public const string DirectionsCar = ""; + public const string DirectionsCarFilled = ""; + public const string DirectionsOff = ""; + public const string DirectionsRailway = ""; + public const string DirectionsRailwayFilled = ""; + public const string DirectionsRun = ""; + public const string DirectionsSubway = ""; + public const string DirectionsSubwayFilled = ""; + public const string DirectionsTransit = ""; + public const string DirectionsTransitFilled = ""; + public const string DirectionsWalk = ""; + public const string DirtyLens = ""; + public const string DisabledByDefault = ""; + public const string DisabledVisible = ""; + public const string DiscFull = ""; + public const string Discount = ""; + public const string DisplaySettings = ""; + public const string Dns = ""; + public const string DoDisturb = ""; + public const string DoDisturbAlt = ""; + public const string DoDisturbOff = ""; + public const string DoDisturbOn = ""; + public const string DoNotDisturb = ""; + public const string DoNotDisturbAlt = ""; + public const string DoNotDisturbOff = ""; + public const string DoNotDisturbOn = ""; + public const string DoNotDisturbOnTotalSilence = ""; + public const string DoNotStep = ""; + public const string DoNotTouch = ""; + public const string Dock = ""; + public const string DocumentScanner = ""; + public const string Domain = ""; + public const string DomainAdd = ""; + public const string DomainDisabled = ""; + public const string DomainVerification = ""; + public const string Done = ""; + public const string DoneAll = ""; + public const string DoneOutline = ""; + public const string DonutLarge = ""; + public const string DonutSmall = ""; + public const string DoorBack = ""; + public const string DoorFront = ""; + public const string DoorSliding = ""; + public const string Doorbell = ""; + public const string DoubleArrow = ""; + public const string DownhillSkiing = ""; + public const string Download = ""; + public const string DownloadDone = ""; + public const string DownloadForOffline = ""; + public const string Downloading = ""; + public const string Drafts = ""; + public const string DragHandle = ""; + public const string DragIndicator = ""; + public const string Draw = ""; + public const string DriveEta = ""; + public const string DriveFileMove = ""; + public const string DriveFileMoveRtl = ""; + public const string DriveFileRenameOutline = ""; + public const string DriveFolderUpload = ""; + public const string Dry = ""; + public const string DryCleaning = ""; + public const string Duo = ""; + public const string Dvr = ""; + public const string DynamicFeed = ""; + public const string DynamicForm = ""; + public const string EMobiledata = ""; + public const string Earbuds = ""; + public const string EarbudsBattery = ""; + public const string East = ""; + public const string EdgesensorHigh = ""; + public const string EdgesensorLow = ""; + public const string Edit = ""; + public const string EditAttributes = ""; + public const string EditCalendar = ""; + public const string EditLocation = ""; + public const string EditLocationAlt = ""; + public const string EditNote = ""; + public const string EditNotifications = ""; + public const string EditOff = "ic_edit_off_24px"; + public const string EditRoad = ""; + public const string Egg = ""; + public const string EggAlt = ""; + public const string Eject = ""; + public const string Elderly = ""; + public const string ElderlyWoman = ""; + public const string ElectricBike = ""; + public const string ElectricCar = ""; + public const string ElectricMoped = ""; + public const string ElectricRickshaw = ""; + public const string ElectricScooter = ""; + public const string ElectricalServices = ""; + public const string Elevator = ""; + public const string Email = ""; + public const string Emergency = ""; + public const string EmergencyRecording = ""; + public const string EmergencyShare = ""; + public const string EmojiEmotions = ""; + public const string EmojiEvents = ""; + public const string EmojiFoodBeverage = ""; + public const string EmojiNature = ""; + public const string EmojiObjects = ""; + public const string EmojiPeople = ""; + public const string EmojiSymbols = ""; + public const string EmojiTransportation = ""; + public const string Engineering = ""; + public const string EnhancedEncryption = ""; + public const string Equalizer = ""; + public const string Error = ""; + public const string ErrorOutline = ""; + public const string Escalator = ""; + public const string EscalatorWarning = ""; + public const string Euro = ""; + public const string EuroSymbol = ""; + public const string EvStation = ""; + public const string Event = ""; + public const string EventAvailable = ""; + public const string EventBusy = ""; + public const string EventNote = ""; + public const string EventRepeat = ""; + public const string EventSeat = ""; + public const string ExitToApp = ""; + public const string Expand = ""; + public const string ExpandCircleDown = ""; + public const string ExpandLess = ""; + public const string ExpandMore = ""; + public const string Explicit = ""; + public const string Explore = ""; + public const string ExploreOff = ""; + public const string Exposure = ""; + public const string ExposureNeg1 = ""; + public const string ExposureNeg2 = ""; + public const string ExposurePlus1 = ""; + public const string ExposurePlus2 = ""; + public const string ExposureZero = ""; + public const string Extension = ""; + public const string ExtensionOff = ""; + public const string Face = ""; + public const string FaceRetouchingNatural = ""; + public const string FaceRetouchingOff = ""; + public const string FactCheck = ""; + public const string Factory = ""; + public const string FamilyRestroom = ""; + public const string FastForward = ""; + public const string FastRewind = ""; + public const string Fastfood = ""; + public const string Favorite = ""; + public const string FavoriteBorder = ""; + public const string Fax = ""; + public const string FeaturedPlayList = ""; + public const string FeaturedVideo = ""; + public const string Feed = ""; + public const string Feedback = ""; + public const string Female = ""; + public const string Fence = ""; + public const string Festival = ""; + public const string FiberDvr = ""; + public const string FiberManualRecord = ""; + public const string FiberNew = ""; + public const string FiberPin = ""; + public const string FiberSmartRecord = ""; + public const string FileCopy = ""; + public const string FileDownload = ""; + public const string FileDownloadDone = ""; + public const string FileDownloadOff = ""; + public const string FileOpen = ""; + public const string FilePresent = ""; + public const string FileUpload = ""; + public const string Filter = ""; + public const string Filter1 = ""; + public const string Filter2 = ""; + public const string Filter3 = ""; + public const string Filter4 = ""; + public const string Filter5 = ""; + public const string Filter6 = ""; + public const string Filter7 = ""; + public const string Filter8 = ""; + public const string Filter9 = ""; + public const string Filter9Plus = ""; + public const string FilterAlt = ""; + public const string FilterAltOff = ""; + public const string FilterBAndW = ""; + public const string FilterCenterFocus = ""; + public const string FilterDrama = ""; + public const string FilterFrames = ""; + public const string FilterHdr = ""; + public const string FilterList = ""; + public const string FilterListOff = ""; + public const string FilterNone = ""; + public const string FilterTiltShift = ""; + public const string FilterVintage = ""; + public const string FindInPage = ""; + public const string FindReplace = ""; + public const string Fingerprint = ""; + public const string FireExtinguisher = ""; + public const string Fireplace = ""; + public const string FirstPage = ""; + public const string FitScreen = ""; + public const string Fitbit = ""; + public const string FitnessCenter = ""; + public const string Flag = ""; + public const string FlagCircle = ""; + public const string Flaky = ""; + public const string Flare = ""; + public const string FlashAuto = ""; + public const string FlashOff = ""; + public const string FlashOn = ""; + public const string FlashlightOff = ""; + public const string FlashlightOn = ""; + public const string Flatware = ""; + public const string Flight = ""; + public const string FlightClass = ""; + public const string FlightLand = ""; + public const string FlightTakeoff = ""; + public const string Flip = ""; + public const string FlipCameraAndroid = ""; + public const string FlipCameraIos = ""; + public const string FlipToBack = ""; + public const string FlipToFront = ""; + public const string Flood = ""; + public const string Flourescent = ""; + public const string FlutterDash = ""; + public const string FmdBad = ""; + public const string FmdGood = ""; + public const string Folder = ""; + public const string FolderCopy = ""; + public const string FolderDelete = ""; + public const string FolderOff = ""; + public const string FolderOpen = ""; + public const string FolderShared = ""; + public const string FolderSpecial = ""; + public const string FolderZip = ""; + public const string FollowTheSigns = ""; + public const string FontDownload = ""; + public const string FontDownloadOff = ""; + public const string FoodBank = ""; + public const string Forest = ""; + public const string ForkLeft = ""; + public const string ForkRight = ""; + public const string FormatAlignCenter = ""; + public const string FormatAlignJustify = ""; + public const string FormatAlignLeft = ""; + public const string FormatAlignRight = ""; + public const string FormatBold = ""; + public const string FormatClear = ""; + public const string FormatColorFill = ""; + public const string FormatColorReset = ""; + public const string FormatColorText = ""; + public const string FormatIndentDecrease = ""; + public const string FormatIndentIncrease = ""; + public const string FormatItalic = ""; + public const string FormatLineSpacing = ""; + public const string FormatListBulleted = ""; + public const string FormatListNumbered = ""; + public const string FormatListNumberedRtl = ""; + public const string FormatOverline = ""; + public const string FormatPaint = ""; + public const string FormatQuote = ""; + public const string FormatShapes = ""; + public const string FormatSize = ""; + public const string FormatStrikethrough = ""; + public const string FormatTextdirectionLToR = ""; + public const string FormatTextdirectionRToL = ""; + public const string FormatUnderlined = ""; + public const string Fort = ""; + public const string Forum = ""; + public const string Forward = ""; + public const string Forward10 = ""; + public const string Forward30 = ""; + public const string Forward5 = ""; + public const string ForwardToInbox = ""; + public const string Foundation = ""; + public const string FreeBreakfast = ""; + public const string FreeCancellation = ""; + public const string FrontHand = ""; + public const string Fullscreen = ""; + public const string FullscreenExit = ""; + public const string Functions = ""; + public const string GMobiledata = ""; + public const string GTranslate = ""; + public const string Gamepad = ""; + public const string Games = ""; + public const string Garage = ""; + public const string Gavel = ""; + public const string GeneratingTokens = ""; + public const string Gesture = ""; + public const string GetApp = ""; + public const string Gif = ""; + public const string GifBox = ""; + public const string Girl = ""; + public const string Gite = ""; + public const string GolfCourse = ""; + public const string GppBad = ""; + public const string GppGood = ""; + public const string GppMaybe = ""; + public const string GpsFixed = ""; + public const string GpsNotFixed = ""; + public const string GpsOff = ""; + public const string Grade = ""; + public const string Gradient = ""; + public const string Grading = ""; + public const string Grain = ""; + public const string GraphicEq = ""; + public const string Grass = ""; + public const string Grid3x3 = ""; + public const string Grid4x4 = ""; + public const string GridGoldenratio = ""; + public const string GridOff = ""; + public const string GridOn = ""; + public const string GridView = ""; + public const string Group = ""; + public const string GroupAdd = ""; + public const string GroupOff = ""; + public const string GroupRemove = ""; + public const string GroupWork = ""; + public const string Groups = ""; + public const string HMobiledata = ""; + public const string HPlusMobiledata = ""; + public const string Hail = ""; + public const string Handshake = ""; + public const string Handyman = ""; + public const string Hardware = ""; + public const string Hd = ""; + public const string HdrAuto = ""; + public const string HdrAutoSelect = ""; + public const string HdrEnhancedSelect = ""; + public const string HdrOff = ""; + public const string HdrOffSelect = ""; + public const string HdrOn = ""; + public const string HdrOnSelect = ""; + public const string HdrPlus = ""; + public const string HdrStrong = ""; + public const string HdrWeak = ""; + public const string Headphones = ""; + public const string HeadphonesBattery = ""; + public const string Headset = ""; + public const string HeadsetMic = ""; + public const string HeadsetOff = ""; + public const string Healing = ""; + public const string HealthAndSafety = ""; + public const string Hearing = ""; + public const string HearingDisabled = ""; + public const string HeartBroken = ""; + public const string Height = ""; + public const string Help = ""; + public const string HelpCenter = ""; + public const string HelpOutline = ""; + public const string Hevc = ""; + public const string Hexagon = ""; + public const string HideImage = ""; + public const string HideSource = ""; + public const string HighQuality = ""; + public const string Highlight = ""; + public const string HighlightAlt = ""; + public const string HighlightOff = ""; + public const string Hiking = ""; + public const string History = ""; + public const string HistoryEdu = ""; + public const string HistoryToggleOff = ""; + public const string Hive = ""; + public const string Hls = ""; + public const string HlsOff = ""; + public const string HolidayVillage = ""; + public const string Home = ""; + public const string HomeMax = ""; + public const string HomeMini = ""; + public const string HomeRepairService = ""; + public const string HomeWork = ""; + public const string HorizontalDistribute = ""; + public const string HorizontalRule = ""; + public const string HorizontalSplit = ""; + public const string HotTub = ""; + public const string Hotel = ""; + public const string HotelClass = ""; + public const string HourglassBottom = ""; + public const string HourglassDisabled = ""; + public const string HourglassEmpty = ""; + public const string HourglassFull = ""; + public const string HourglassTop = ""; + public const string House = ""; + public const string HouseSiding = ""; + public const string Houseboat = ""; + public const string HowToReg = ""; + public const string HowToVote = ""; + public const string Html = ""; + public const string Http = ""; + public const string Https = ""; + public const string Hub = ""; + public const string Hvac = ""; + public const string IceSkating = ""; + public const string Icecream = ""; + public const string Image = ""; + public const string ImageAspectRatio = ""; + public const string ImageNotSupported = ""; + public const string ImageSearch = ""; + public const string ImagesearchRoller = ""; + public const string ImportContacts = ""; + public const string ImportExport = ""; + public const string ImportantDevices = ""; + public const string Inbox = ""; + public const string IncompleteCircle = ""; + public const string IndeterminateCheckBox = ""; + public const string Info = ""; + public const string Input = ""; + public const string InsertChart = ""; + public const string InsertChartOutlined = ""; + public const string InsertComment = ""; + public const string InsertDriveFile = ""; + public const string InsertEmoticon = ""; + public const string InsertInvitation = ""; + public const string InsertLink = ""; + public const string InsertPageBreak = ""; + public const string InsertPhoto = ""; + public const string Insights = ""; + public const string InstallDesktop = ""; + public const string InstallMobile = ""; + public const string IntegrationInstructions = ""; + public const string Interests = ""; + public const string InterpreterMode = ""; + public const string Inventory = ""; + public const string Inventory2 = ""; + public const string InvertColors = ""; + public const string InvertColorsOff = ""; + public const string IosShare = ""; + public const string Iron = ""; + public const string Iso = ""; + public const string Javascript = ""; + public const string JoinFull = ""; + public const string JoinInner = ""; + public const string JoinLeft = ""; + public const string JoinRight = ""; + public const string Kayaking = ""; + public const string KebabDining = ""; + public const string Key = ""; + public const string KeyOff = ""; + public const string Keyboard = ""; + public const string KeyboardAlt = ""; + public const string KeyboardArrowDown = ""; + public const string KeyboardArrowLeft = ""; + public const string KeyboardArrowRight = ""; + public const string KeyboardArrowUp = ""; + public const string KeyboardBackspace = ""; + public const string KeyboardCapslock = ""; + public const string KeyboardCommandKey = ""; + public const string KeyboardControlKey = ""; + public const string KeyboardDoubleArrowDown = ""; + public const string KeyboardDoubleArrowLeft = ""; + public const string KeyboardDoubleArrowRight = ""; + public const string KeyboardDoubleArrowUp = ""; + public const string KeyboardHide = ""; + public const string KeyboardOptionKey = ""; + public const string KeyboardReturn = ""; + public const string KeyboardTab = ""; + public const string KeyboardVoice = ""; + public const string KingBed = ""; + public const string Kitchen = ""; + public const string Kitesurfing = ""; + public const string Label = ""; + public const string LabelImportant = ""; + public const string LabelOff = ""; + public const string Lan = ""; + public const string Landscape = ""; + public const string Landslide = ""; + public const string Language = ""; + public const string Laptop = ""; + public const string LaptopChromebook = ""; + public const string LaptopMac = ""; + public const string LaptopWindows = ""; + public const string LastPage = ""; + public const string Launch = ""; + public const string Layers = ""; + public const string LayersClear = ""; + public const string Leaderboard = ""; + public const string LeakAdd = ""; + public const string LeakRemove = ""; + public const string LegendToggle = ""; + public const string Lens = ""; + public const string LensBlur = ""; + public const string LibraryAdd = ""; + public const string LibraryAddCheck = ""; + public const string LibraryBooks = ""; + public const string LibraryMusic = ""; + public const string Light = ""; + public const string LightMode = ""; + public const string Lightbulb = ""; + public const string LightbulbCircle = ""; + public const string LineAxis = ""; + public const string LineStyle = ""; + public const string LineWeight = ""; + public const string LinearScale = ""; + public const string Link = ""; + public const string LinkOff = ""; + public const string LinkedCamera = ""; + public const string Liquor = ""; + public const string List = ""; + public const string ListAlt = ""; + public const string LiveHelp = ""; + public const string LiveTv = ""; + public const string Living = ""; + public const string LocalActivity = ""; + public const string LocalAirport = ""; + public const string LocalAtm = ""; + public const string LocalBar = ""; + public const string LocalCafe = ""; + public const string LocalCarWash = ""; + public const string LocalConvenienceStore = ""; + public const string LocalDining = ""; + public const string LocalDrink = ""; + public const string LocalFireDepartment = ""; + public const string LocalFlorist = ""; + public const string LocalGasStation = ""; + public const string LocalGroceryStore = ""; + public const string LocalHospital = ""; + public const string LocalHotel = ""; + public const string LocalLaundryService = ""; + public const string LocalLibrary = ""; + public const string LocalMall = ""; + public const string LocalMovies = ""; + public const string LocalOffer = ""; + public const string LocalParking = ""; + public const string LocalPharmacy = ""; + public const string LocalPhone = ""; + public const string LocalPizza = ""; + public const string LocalPlay = ""; + public const string LocalPolice = ""; + public const string LocalPostOffice = ""; + public const string LocalPrintshop = ""; + public const string LocalSee = ""; + public const string LocalShipping = ""; + public const string LocalTaxi = ""; + public const string LocationCity = ""; + public const string LocationDisabled = ""; + public const string LocationOff = ""; + public const string LocationOn = ""; + public const string LocationSearching = ""; + public const string Lock = ""; + public const string LockClock = ""; + public const string LockOpen = ""; + public const string LockReset = ""; + public const string Login = ""; + public const string LogoDev = ""; + public const string Logout = ""; + public const string Looks = ""; + public const string Looks3 = ""; + public const string Looks4 = ""; + public const string Looks5 = ""; + public const string Looks6 = ""; + public const string LooksOne = ""; + public const string LooksTwo = ""; + public const string Loop = ""; + public const string Loupe = ""; + public const string LowPriority = ""; + public const string Loyalty = ""; + public const string LteMobiledata = ""; + public const string LtePlusMobiledata = ""; + public const string Luggage = ""; + public const string LunchDining = ""; + public const string Mail = ""; + public const string MailOutline = ""; + public const string Male = ""; + public const string Man = ""; + public const string ManageAccounts = ""; + public const string ManageHistory = ""; + public const string ManageSearch = ""; + public const string Map = ""; + public const string MapsHomeWork = ""; + public const string MapsUgc = ""; + public const string Margin = ""; + public const string MarkAsUnread = ""; + public const string MarkChatRead = ""; + public const string MarkChatUnread = ""; + public const string MarkEmailRead = ""; + public const string MarkEmailUnread = ""; + public const string MarkUnreadChatAlt = ""; + public const string Markunread = ""; + public const string MarkunreadMailbox = ""; + public const string Masks = ""; + public const string Maximize = ""; + public const string MediaBluetoothOff = ""; + public const string MediaBluetoothOn = ""; + public const string Mediation = ""; + public const string MedicalInformation = ""; + public const string MedicalServices = ""; + public const string Medication = ""; + public const string MedicationLiquid = ""; + public const string MeetingRoom = ""; + public const string Memory = ""; + public const string Menu = ""; + public const string MenuBook = ""; + public const string MenuOpen = ""; + public const string Merge = ""; + public const string MergeType = ""; + public const string Message = ""; + public const string Mic = ""; + public const string MicExternalOff = ""; + public const string MicExternalOn = ""; + public const string MicNone = ""; + public const string MicOff = ""; + public const string Microwave = ""; + public const string MilitaryTech = ""; + public const string Minimize = ""; + public const string MinorCrash = ""; + public const string MiscellaneousServices = ""; + public const string MissedVideoCall = ""; + public const string Mms = ""; + public const string MobileFriendly = ""; + public const string MobileOff = ""; + public const string MobileScreenShare = ""; + public const string MobiledataOff = ""; + public const string Mode = ""; + public const string ModeComment = ""; + public const string ModeEdit = ""; + public const string ModeEditOutline = ""; + public const string ModeNight = ""; + public const string ModeOfTravel = ""; + public const string ModeStandby = ""; + public const string ModelTraining = ""; + public const string MonetizationOn = ""; + public const string Money = ""; + public const string MoneyOff = ""; + public const string MoneyOffCsred = ""; + public const string Monitor = ""; + public const string MonitorHeart = ""; + public const string MonitorWeight = ""; + public const string MonochromePhotos = ""; + public const string Mood = ""; + public const string MoodBad = ""; + public const string Moped = ""; + public const string More = ""; + public const string MoreHoriz = ""; + public const string MoreTime = ""; + public const string MoreVert = ""; + public const string Mosque = ""; + public const string MotionPhotosAuto = ""; + public const string MotionPhotosOff = ""; + public const string MotionPhotosOn = ""; + public const string MotionPhotosPause = ""; + public const string MotionPhotosPaused = ""; + public const string Mouse = ""; + public const string MoveDown = ""; + public const string MoveToInbox = ""; + public const string MoveUp = ""; + public const string Movie = ""; + public const string MovieCreation = ""; + public const string MovieFilter = ""; + public const string Moving = ""; + public const string Mp = ""; + public const string MultilineChart = ""; + public const string MultipleStop = ""; + public const string Museum = ""; + public const string MusicNote = ""; + public const string MusicOff = ""; + public const string MusicVideo = ""; + public const string MyLocation = ""; + public const string Nat = ""; + public const string Nature = ""; + public const string NaturePeople = ""; + public const string NavigateBefore = ""; + public const string NavigateNext = ""; + public const string Navigation = ""; + public const string NearMe = ""; + public const string NearMeDisabled = ""; + public const string NearbyError = ""; + public const string NearbyOff = ""; + public const string NetworkCell = ""; + public const string NetworkCheck = ""; + public const string NetworkLocked = ""; + public const string NetworkPing = ""; + public const string NetworkWifi = ""; + public const string NetworkWifi1Bar = ""; + public const string NetworkWifi2Bar = ""; + public const string NetworkWifi3Bar = ""; + public const string NewLabel = ""; + public const string NewReleases = ""; + public const string Newspaper = ""; + public const string NextPlan = ""; + public const string NextWeek = ""; + public const string Nfc = ""; + public const string NightShelter = ""; + public const string Nightlife = ""; + public const string Nightlight = ""; + public const string NightlightRound = ""; + public const string NightsStay = ""; + public const string NoAccounts = ""; + public const string NoBackpack = ""; + public const string NoCell = ""; + public const string NoCrash = ""; + public const string NoDrinks = ""; + public const string NoEncryption = ""; + public const string NoEncryptionGmailerrorred = ""; + public const string NoFlash = ""; + public const string NoFood = ""; + public const string NoLuggage = ""; + public const string NoMeals = ""; + public const string NoMeetingRoom = ""; + public const string NoPhotography = ""; + public const string NoSim = ""; + public const string NoStroller = ""; + public const string NoTransfer = ""; + public const string NoiseAware = ""; + public const string NoiseControlOff = ""; + public const string NordicWalking = ""; + public const string North = ""; + public const string NorthEast = ""; + public const string NorthWest = ""; + public const string NotAccessible = ""; + public const string NotInterested = ""; + public const string NotListedLocation = ""; + public const string NotStarted = ""; + public const string Note = ""; + public const string NoteAdd = ""; + public const string NoteAlt = ""; + public const string Notes = ""; + public const string NotificationAdd = ""; + public const string NotificationImportant = ""; + public const string Notifications = ""; + public const string NotificationsActive = ""; + public const string NotificationsNone = ""; + public const string NotificationsOff = ""; + public const string NotificationsPaused = ""; + public const string Numbers = ""; + public const string OfflineBolt = ""; + public const string OfflinePin = ""; + public const string OfflineShare = ""; + public const string OnDeviceTraining = ""; + public const string OndemandVideo = ""; + public const string OnlinePrediction = ""; + public const string Opacity = ""; + public const string OpenInBrowser = ""; + public const string OpenInFull = ""; + public const string OpenInNew = ""; + public const string OpenInNewOff = ""; + public const string OpenWith = ""; + public const string OtherHouses = ""; + public const string Outbound = ""; + public const string Outbox = ""; + public const string OutdoorGrill = ""; + public const string Outlet = ""; + public const string OutlinedFlag = ""; + public const string Output = ""; + public const string Padding = ""; + public const string Pages = ""; + public const string Pageview = ""; + public const string Paid = ""; + public const string Palette = ""; + public const string PanTool = ""; + public const string PanToolAlt = ""; + public const string Panorama = ""; + public const string PanoramaFishEye = ""; + public const string PanoramaHorizontal = ""; + public const string PanoramaHorizontalSelect = ""; + public const string PanoramaPhotosphere = ""; + public const string PanoramaPhotosphereSelect = ""; + public const string PanoramaVertical = ""; + public const string PanoramaVerticalSelect = ""; + public const string PanoramaWideAngle = ""; + public const string PanoramaWideAngleSelect = ""; + public const string Paragliding = ""; + public const string Park = ""; + public const string PartyMode = ""; + public const string Password = ""; + public const string Pattern = ""; + public const string Pause = ""; + public const string PauseCircle = ""; + public const string PauseCircleFilled = ""; + public const string PauseCircleOutline = ""; + public const string PausePresentation = ""; + public const string Payment = ""; + public const string Payments = ""; + public const string PedalBike = ""; + public const string Pending = ""; + public const string PendingActions = ""; + public const string Pentagon = ""; + public const string People = ""; + public const string PeopleAlt = ""; + public const string PeopleOutline = ""; + public const string Percent = ""; + public const string PermCameraMic = ""; + public const string PermContactCalendar = ""; + public const string PermDataSetting = ""; + public const string PermDeviceInformation = ""; + public const string PermIdentity = ""; + public const string PermMedia = ""; + public const string PermPhoneMsg = ""; + public const string PermScanWifi = ""; + public const string Person = ""; + public const string PersonAdd = ""; + public const string PersonAddAlt = ""; + public const string PersonAddAlt1 = ""; + public const string PersonAddDisabled = ""; + public const string PersonOff = ""; + public const string PersonOutline = ""; + public const string PersonPin = ""; + public const string PersonPinCircle = ""; + public const string PersonRemove = ""; + public const string PersonRemoveAlt1 = ""; + public const string PersonSearch = ""; + public const string PersonalInjury = ""; + public const string PersonalVideo = ""; + public const string PestControl = ""; + public const string PestControlRodent = ""; + public const string Pets = ""; + public const string Phishing = ""; + public const string Phone = ""; + public const string PhoneAndroid = ""; + public const string PhoneBluetoothSpeaker = ""; + public const string PhoneCallback = ""; + public const string PhoneDisabled = ""; + public const string PhoneEnabled = ""; + public const string PhoneForwarded = ""; + public const string PhoneInTalk = ""; + public const string PhoneIphone = ""; + public const string PhoneLocked = ""; + public const string PhoneMissed = ""; + public const string PhonePaused = ""; + public const string Phonelink = ""; + public const string PhonelinkErase = ""; + public const string PhonelinkLock = ""; + public const string PhonelinkOff = ""; + public const string PhonelinkRing = ""; + public const string PhonelinkSetup = ""; + public const string Photo = ""; + public const string PhotoAlbum = ""; + public const string PhotoCamera = ""; + public const string PhotoCameraBack = ""; + public const string PhotoCameraFront = ""; + public const string PhotoFilter = ""; + public const string PhotoLibrary = ""; + public const string PhotoSizeSelectActual = ""; + public const string PhotoSizeSelectLarge = ""; + public const string PhotoSizeSelectSmall = ""; + public const string Php = ""; + public const string Piano = ""; + public const string PianoOff = ""; + public const string PictureAsPdf = ""; + public const string PictureInPicture = ""; + public const string PictureInPictureAlt = ""; + public const string PieChart = ""; + public const string PieChartOutline = ""; + public const string Pin = ""; + public const string PinDrop = ""; + public const string PinEnd = ""; + public const string PinInvoke = ""; + public const string Pinch = ""; + public const string PivotTableChart = ""; + public const string Pix = ""; + public const string Place = ""; + public const string Plagiarism = ""; + public const string PlayArrow = ""; + public const string PlayCircle = ""; + public const string PlayCircleFilled = ""; + public const string PlayCircleOutline = ""; + public const string PlayDisabled = ""; + public const string PlayForWork = ""; + public const string PlayLesson = ""; + public const string PlaylistAdd = ""; + public const string PlaylistAddCheck = ""; + public const string PlaylistAddCheckCircle = ""; + public const string PlaylistAddCircle = ""; + public const string PlaylistPlay = ""; + public const string PlaylistRemove = ""; + public const string Plumbing = ""; + public const string PlusOne = ""; + public const string Podcasts = ""; + public const string PointOfSale = ""; + public const string Policy = ""; + public const string Poll = ""; + public const string Polyline = ""; + public const string Polymer = ""; + public const string Pool = ""; + public const string PortableWifiOff = ""; + public const string Portrait = ""; + public const string PostAdd = ""; + public const string Power = ""; + public const string PowerInput = ""; + public const string PowerOff = ""; + public const string PowerSettingsNew = ""; + public const string PrecisionManufacturing = ""; + public const string PregnantWoman = ""; + public const string PresentToAll = ""; + public const string Preview = ""; + public const string PriceChange = ""; + public const string PriceCheck = ""; + public const string Print = ""; + public const string PrintDisabled = ""; + public const string PriorityHigh = ""; + public const string PrivacyTip = ""; + public const string PrivateConnectivity = ""; + public const string ProductionQuantityLimits = ""; + public const string Psychology = ""; + public const string Public = ""; + public const string PublicOff = ""; + public const string Publish = ""; + public const string PublishedWithChanges = ""; + public const string PunchClock = ""; + public const string PushPin = ""; + public const string QrCode = ""; + public const string QrCode2 = ""; + public const string QrCodeScanner = ""; + public const string QueryBuilder = ""; + public const string QueryStats = ""; + public const string QuestionAnswer = ""; + public const string QuestionMark = ""; + public const string Queue = ""; + public const string QueueMusic = ""; + public const string QueuePlayNext = ""; + public const string Quickreply = ""; + public const string Quiz = ""; + public const string RMobiledata = ""; + public const string Radar = ""; + public const string Radio = ""; + public const string RadioButtonChecked = ""; + public const string RadioButtonUnchecked = ""; + public const string RailwayAlert = ""; + public const string RamenDining = ""; + public const string RampLeft = ""; + public const string RampRight = ""; + public const string RateReview = ""; + public const string RawOff = ""; + public const string RawOn = ""; + public const string ReadMore = ""; + public const string RealEstateAgent = ""; + public const string Receipt = ""; + public const string ReceiptLong = ""; + public const string RecentActors = ""; + public const string Recommend = "ic_recommend_24px"; + public const string RecordVoiceOver = ""; + public const string Rectangle = ""; + public const string Recycling = ""; + public const string Redeem = ""; + public const string Redo = ""; + public const string ReduceCapacity = ""; + public const string Refresh = ""; + public const string RememberMe = ""; + public const string Remove = ""; + public const string RemoveCircle = ""; + public const string RemoveCircleOutline = ""; + public const string RemoveDone = ""; + public const string RemoveFromQueue = ""; + public const string RemoveModerator = ""; + public const string RemoveRedEye = ""; + public const string RemoveRoad = ""; + public const string RemoveShoppingCart = ""; + public const string Reorder = ""; + public const string Repeat = ""; + public const string RepeatOn = ""; + public const string RepeatOne = ""; + public const string RepeatOneOn = ""; + public const string Replay = ""; + public const string Replay10 = ""; + public const string Replay30 = ""; + public const string Replay5 = ""; + public const string ReplayCircleFilled = ""; + public const string Reply = ""; + public const string ReplyAll = ""; + public const string Report = ""; + public const string ReportGmailerrorred = ""; + public const string ReportOff = ""; + public const string ReportProblem = ""; + public const string RequestPage = ""; + public const string RequestQuote = ""; + public const string ResetTv = ""; + public const string RestartAlt = ""; + public const string Restaurant = ""; + public const string RestaurantMenu = ""; + public const string Restore = ""; + public const string RestoreFromTrash = ""; + public const string RestorePage = ""; + public const string Reviews = ""; + public const string RiceBowl = ""; + public const string RingVolume = ""; + public const string Rocket = ""; + public const string RocketLaunch = ""; + public const string RollerSkating = ""; + public const string Roofing = ""; + public const string Room = ""; + public const string RoomPreferences = ""; + public const string RoomService = ""; + public const string Rotate90DegreesCcw = ""; + public const string Rotate90DegreesCw = ""; + public const string RotateLeft = ""; + public const string RotateRight = ""; + public const string RoundaboutLeft = ""; + public const string RoundaboutRight = ""; + public const string RoundedCorner = ""; + public const string Route = ""; + public const string Router = ""; + public const string Rowing = ""; + public const string RssFeed = ""; + public const string Rsvp = ""; + public const string Rtt = "ic_dialer_rtt_revised_24px"; + public const string Rule = ""; + public const string RuleFolder = ""; + public const string RunCircle = ""; + public const string RunningWithErrors = ""; + public const string RvHookup = ""; + public const string SafetyCheck = ""; + public const string SafetyDivider = ""; + public const string Sailing = ""; + public const string Sanitizer = ""; + public const string Satellite = ""; + public const string SatelliteAlt = ""; + public const string Save = ""; + public const string SaveAlt = ""; + public const string SaveAs = ""; + public const string SavedSearch = ""; + public const string Savings = ""; + public const string Scale = ""; + public const string Scanner = ""; + public const string ScatterPlot = ""; + public const string Schedule = ""; + public const string ScheduleSend = ""; + public const string Schema = ""; + public const string School = ""; + public const string Science = ""; + public const string Score = ""; + public const string Scoreboard = ""; + public const string ScreenLockLandscape = ""; + public const string ScreenLockPortrait = ""; + public const string ScreenLockRotation = ""; + public const string ScreenRotation = ""; + public const string ScreenRotationAlt = ""; + public const string ScreenSearchDesktop = ""; + public const string ScreenShare = ""; + public const string Screenshot = ""; + public const string ScubaDiving = ""; + public const string Sd = ""; + public const string SdCard = ""; + public const string SdCardAlert = ""; + public const string SdStorage = ""; + public const string Search = ""; + public const string SearchOff = ""; + public const string Security = ""; + public const string SecurityUpdate = ""; + public const string SecurityUpdateGood = ""; + public const string SecurityUpdateWarning = ""; + public const string Segment = ""; + public const string SelectAll = ""; + public const string SelfImprovement = ""; + public const string Sell = ""; + public const string Send = ""; + public const string SendAndArchive = ""; + public const string SendTimeExtension = ""; + public const string SendToMobile = ""; + public const string SensorDoor = ""; + public const string SensorWindow = ""; + public const string Sensors = ""; + public const string SensorsOff = ""; + public const string SentimentDissatisfied = ""; + public const string SentimentNeutral = ""; + public const string SentimentSatisfied = ""; + public const string SentimentSatisfiedAlt = ""; + public const string SentimentVeryDissatisfied = ""; + public const string SentimentVerySatisfied = ""; + public const string SetMeal = ""; + public const string Settings = ""; + public const string SettingsAccessibility = ""; + public const string SettingsApplications = ""; + public const string SettingsBackupRestore = ""; + public const string SettingsBluetooth = ""; + public const string SettingsBrightness = ""; + public const string SettingsCell = ""; + public const string SettingsEthernet = ""; + public const string SettingsInputAntenna = ""; + public const string SettingsInputComponent = ""; + public const string SettingsInputComposite = ""; + public const string SettingsInputHdmi = ""; + public const string SettingsInputSvideo = ""; + public const string SettingsOverscan = ""; + public const string SettingsPhone = ""; + public const string SettingsPower = ""; + public const string SettingsRemote = ""; + public const string SettingsSuggest = ""; + public const string SettingsSystemDaydream = ""; + public const string SettingsVoice = ""; + public const string SevereCold = ""; + public const string Share = ""; + public const string ShareLocation = ""; + public const string Shield = ""; + public const string ShieldMoon = ""; + public const string Shop = ""; + public const string Shop2 = ""; + public const string ShopTwo = ""; + public const string ShoppingBag = ""; + public const string ShoppingBasket = ""; + public const string ShoppingCart = ""; + public const string ShoppingCartCheckout = ""; + public const string ShortText = ""; + public const string Shortcut = ""; + public const string ShowChart = ""; + public const string Shower = ""; + public const string Shuffle = ""; + public const string ShuffleOn = ""; + public const string ShutterSpeed = ""; + public const string Sick = ""; + public const string SignLanguage = ""; + public const string SignalCellular0Bar = ""; + public const string SignalCellular4Bar = ""; + public const string SignalCellularAlt = ""; + public const string SignalCellularAlt1Bar = ""; + public const string SignalCellularAlt2Bar = ""; + public const string SignalCellularConnectedNoInternet0Bar = ""; + public const string SignalCellularConnectedNoInternet4Bar = ""; + public const string SignalCellularNoSim = ""; + public const string SignalCellularNodata = ""; + public const string SignalCellularNull = ""; + public const string SignalCellularOff = ""; + public const string SignalWifi0Bar = ""; + public const string SignalWifi4Bar = ""; + public const string SignalWifi4BarLock = ""; + public const string SignalWifiBad = ""; + public const string SignalWifiConnectedNoInternet4 = ""; + public const string SignalWifiOff = ""; + public const string SignalWifiStatusbar4Bar = ""; + public const string SignalWifiStatusbarConnectedNoInternet4 = ""; + public const string SignalWifiStatusbarNull = ""; + public const string Signpost = ""; + public const string SimCard = ""; + public const string SimCardAlert = ""; + public const string SimCardDownload = ""; + public const string SingleBed = ""; + public const string Sip = ""; + public const string Skateboarding = ""; + public const string SkipNext = ""; + public const string SkipPrevious = ""; + public const string Sledding = ""; + public const string Slideshow = ""; + public const string SlowMotionVideo = ""; + public const string SmartButton = ""; + public const string SmartDisplay = ""; + public const string SmartScreen = ""; + public const string SmartToy = ""; + public const string Smartphone = ""; + public const string SmokeFree = ""; + public const string SmokingRooms = ""; + public const string Sms = ""; + public const string SmsFailed = ""; + public const string SnippetFolder = ""; + public const string Snooze = ""; + public const string Snowboarding = ""; + public const string Snowmobile = ""; + public const string Snowshoeing = ""; + public const string Soap = ""; + public const string SocialDistance = ""; + public const string Sort = ""; + public const string SortByAlpha = ""; + public const string Sos = ""; + public const string SoupKitchen = ""; + public const string Source = ""; + public const string South = ""; + public const string SouthAmerica = ""; + public const string SouthEast = ""; + public const string SouthWest = ""; + public const string Spa = ""; + public const string SpaceBar = ""; + public const string SpaceDashboard = ""; + public const string SpatialAudio = ""; + public const string SpatialAudioOff = ""; + public const string SpatialTracking = ""; + public const string Speaker = ""; + public const string SpeakerGroup = ""; + public const string SpeakerNotes = ""; + public const string SpeakerNotesOff = ""; + public const string SpeakerPhone = ""; + public const string Speed = ""; + public const string Spellcheck = ""; + public const string Splitscreen = ""; + public const string Spoke = ""; + public const string Sports = ""; + public const string SportsBar = ""; + public const string SportsBaseball = ""; + public const string SportsBasketball = ""; + public const string SportsCricket = ""; + public const string SportsEsports = ""; + public const string SportsFootball = ""; + public const string SportsGolf = ""; + public const string SportsGymnastics = ""; + public const string SportsHandball = ""; + public const string SportsHockey = ""; + public const string SportsKabaddi = ""; + public const string SportsMartialArts = ""; + public const string SportsMma = ""; + public const string SportsMotorsports = ""; + public const string SportsRugby = ""; + public const string SportsScore = ""; + public const string SportsSoccer = ""; + public const string SportsTennis = ""; + public const string SportsVolleyball = ""; + public const string Square = ""; + public const string SquareFoot = ""; + public const string SsidChart = ""; + public const string StackedBarChart = ""; + public const string StackedLineChart = ""; + public const string Stadium = ""; + public const string Stairs = ""; + public const string Star = ""; + public const string StarBorder = ""; + public const string StarBorderPurple500 = ""; + public const string StarHalf = ""; + public const string StarOutline = ""; + public const string StarPurple500 = ""; + public const string StarRate = ""; + public const string Stars = ""; + public const string Start = ""; + public const string StayCurrentLandscape = ""; + public const string StayCurrentPortrait = ""; + public const string StayPrimaryLandscape = ""; + public const string StayPrimaryPortrait = ""; + public const string StickyNote2 = ""; + public const string Stop = ""; + public const string StopCircle = ""; + public const string StopScreenShare = ""; + public const string Storage = ""; + public const string Store = ""; + public const string StoreMallDirectory = ""; + public const string Storefront = ""; + public const string Storm = ""; + public const string Straight = ""; + public const string Straighten = ""; + public const string Stream = ""; + public const string Streetview = ""; + public const string StrikethroughS = ""; + public const string Stroller = ""; + public const string Style = ""; + public const string SubdirectoryArrowLeft = ""; + public const string SubdirectoryArrowRight = ""; + public const string Subject = ""; + public const string Subscript = ""; + public const string Subscriptions = ""; + public const string Subtitles = ""; + public const string SubtitlesOff = ""; + public const string Subway = ""; + public const string Summarize = ""; + public const string Superscript = ""; + public const string SupervisedUserCircle = ""; + public const string SupervisorAccount = ""; + public const string Support = ""; + public const string SupportAgent = ""; + public const string Surfing = ""; + public const string SurroundSound = ""; + public const string SwapCalls = ""; + public const string SwapHoriz = ""; + public const string SwapHorizontalCircle = ""; + public const string SwapVert = ""; + public const string SwapVerticalCircle = ""; + public const string Swipe = ""; + public const string SwipeDown = ""; + public const string SwipeDownAlt = ""; + public const string SwipeLeft = ""; + public const string SwipeLeftAlt = ""; + public const string SwipeRight = ""; + public const string SwipeRightAlt = ""; + public const string SwipeUp = ""; + public const string SwipeUpAlt = ""; + public const string SwipeVertical = ""; + public const string SwitchAccessShortcut = ""; + public const string SwitchAccessShortcutAdd = ""; + public const string SwitchAccount = ""; + public const string SwitchCamera = ""; + public const string SwitchLeft = ""; + public const string SwitchRight = ""; + public const string SwitchVideo = ""; + public const string Synagogue = ""; + public const string Sync = ""; + public const string SyncAlt = ""; + public const string SyncDisabled = ""; + public const string SyncLock = ""; + public const string SyncProblem = ""; + public const string SystemSecurityUpdate = ""; + public const string SystemSecurityUpdateGood = ""; + public const string SystemSecurityUpdateWarning = ""; + public const string SystemUpdate = ""; + public const string SystemUpdateAlt = ""; + public const string Tab = ""; + public const string TabUnselected = ""; + public const string TableBar = ""; + public const string TableChart = ""; + public const string TableRestaurant = ""; + public const string TableRows = ""; + public const string TableView = ""; + public const string Tablet = ""; + public const string TabletAndroid = ""; + public const string TabletMac = ""; + public const string Tag = ""; + public const string TagFaces = ""; + public const string TakeoutDining = ""; + public const string TapAndPlay = ""; + public const string Tapas = ""; + public const string Task = ""; + public const string TaskAlt = ""; + public const string TaxiAlert = ""; + public const string TempleBuddhist = ""; + public const string TempleHindu = ""; + public const string Terminal = ""; + public const string Terrain = ""; + public const string TextDecrease = ""; + public const string TextFields = ""; + public const string TextFormat = ""; + public const string TextIncrease = ""; + public const string TextRotateUp = ""; + public const string TextRotateVertical = ""; + public const string TextRotationAngledown = ""; + public const string TextRotationAngleup = ""; + public const string TextRotationDown = ""; + public const string TextRotationNone = ""; + public const string TextSnippet = ""; + public const string Textsms = ""; + public const string Texture = ""; + public const string TheaterComedy = ""; + public const string Theaters = ""; + public const string Thermostat = ""; + public const string ThermostatAuto = ""; + public const string ThumbDown = ""; + public const string ThumbDownAlt = ""; + public const string ThumbDownOffAlt = ""; + public const string ThumbUp = ""; + public const string ThumbUpAlt = ""; + public const string ThumbUpOffAlt = ""; + public const string ThumbsUpDown = ""; + public const string Thunderstorm = ""; + public const string TimeToLeave = ""; + public const string Timelapse = ""; + public const string Timeline = ""; + public const string Timer = ""; + public const string Timer10 = ""; + public const string Timer10Select = ""; + public const string Timer3 = ""; + public const string Timer3Select = ""; + public const string TimerOff = ""; + public const string TipsAndUpdates = ""; + public const string TireRepair = ""; + public const string Title = ""; + public const string Toc = ""; + public const string Today = ""; + public const string ToggleOff = ""; + public const string ToggleOn = ""; + public const string Token = ""; + public const string Toll = ""; + public const string Tonality = ""; + public const string Topic = ""; + public const string TouchApp = ""; + public const string Tour = ""; + public const string Toys = ""; + public const string TrackChanges = ""; + public const string Traffic = ""; + public const string Train = ""; + public const string Tram = ""; + public const string TransferWithinAStation = ""; + public const string Transform = ""; + public const string Transgender = ""; + public const string TransitEnterexit = ""; + public const string Translate = ""; + public const string TravelExplore = ""; + public const string TrendingDown = ""; + public const string TrendingFlat = ""; + public const string TrendingUp = ""; + public const string TripOrigin = ""; + public const string Try = ""; + public const string Tsunami = ""; + public const string Tty = ""; + public const string Tune = ""; + public const string Tungsten = ""; + public const string TurnLeft = ""; + public const string TurnRight = ""; + public const string TurnSharpLeft = ""; + public const string TurnSharpRight = ""; + public const string TurnSlightLeft = ""; + public const string TurnSlightRight = ""; + public const string TurnedIn = ""; + public const string TurnedInNot = ""; + public const string Tv = ""; + public const string TvOff = ""; + public const string TwoWheeler = ""; + public const string UTurnLeft = ""; + public const string UTurnRight = ""; + public const string Umbrella = ""; + public const string Unarchive = ""; + public const string Undo = ""; + public const string UnfoldLess = ""; + public const string UnfoldMore = ""; + public const string Unpublished = ""; + public const string Unsubscribe = ""; + public const string Upcoming = ""; + public const string Update = ""; + public const string UpdateDisabled = ""; + public const string Upgrade = ""; + public const string Upload = ""; + public const string UploadFile = ""; + public const string Usb = ""; + public const string UsbOff = ""; + public const string Vaccines = ""; + public const string VapeFree = ""; + public const string VapingRooms = ""; + public const string Verified = ""; + public const string VerifiedUser = ""; + public const string VerticalAlignBottom = ""; + public const string VerticalAlignCenter = ""; + public const string VerticalAlignTop = ""; + public const string VerticalDistribute = ""; + public const string VerticalSplit = ""; + public const string Vibration = ""; + public const string VideoCall = ""; + public const string VideoCameraBack = ""; + public const string VideoCameraFront = ""; + public const string VideoFile = ""; + public const string VideoLabel = ""; + public const string VideoLibrary = ""; + public const string VideoSettings = ""; + public const string VideoStable = ""; + public const string Videocam = ""; + public const string VideocamOff = ""; + public const string VideogameAsset = ""; + public const string VideogameAssetOff = ""; + public const string ViewAgenda = ""; + public const string ViewArray = ""; + public const string ViewCarousel = ""; + public const string ViewColumn = ""; + public const string ViewComfy = ""; + public const string ViewComfyAlt = ""; + public const string ViewCompact = ""; + public const string ViewCompactAlt = ""; + public const string ViewCozy = ""; + public const string ViewDay = ""; + public const string ViewHeadline = ""; + public const string ViewInAr = ""; + public const string ViewKanban = ""; + public const string ViewList = ""; + public const string ViewModule = ""; + public const string ViewQuilt = ""; + public const string ViewSidebar = ""; + public const string ViewStream = ""; + public const string ViewTimeline = ""; + public const string ViewWeek = ""; + public const string Vignette = ""; + public const string Villa = ""; + public const string Visibility = ""; + public const string VisibilityOff = ""; + public const string VoiceChat = ""; + public const string VoiceOverOff = ""; + public const string Voicemail = ""; + public const string Volcano = ""; + public const string VolumeDown = ""; + public const string VolumeMute = ""; + public const string VolumeOff = ""; + public const string VolumeUp = ""; + public const string VolunteerActivism = ""; + public const string VpnKey = ""; + public const string VpnKeyOff = ""; + public const string VpnLock = ""; + public const string Vrpano = ""; + public const string Wallpaper = ""; + public const string Warehouse = ""; + public const string Warning = ""; + public const string WarningAmber = ""; + public const string Wash = ""; + public const string Watch = ""; + public const string WatchLater = ""; + public const string WatchOff = ""; + public const string Water = ""; + public const string WaterDamage = ""; + public const string WaterDrop = ""; + public const string WaterfallChart = ""; + public const string Waves = ""; + public const string WavingHand = ""; + public const string WbAuto = ""; + public const string WbCloudy = ""; + public const string WbIncandescent = ""; + public const string WbIridescent = ""; + public const string WbShade = ""; + public const string WbSunny = ""; + public const string WbTwilight = ""; + public const string Wc = ""; + public const string Web = ""; + public const string WebAsset = ""; + public const string WebAssetOff = ""; + public const string Webhook = ""; + public const string Weekend = ""; + public const string West = ""; + public const string Whatsapp = ""; + public const string Whatshot = ""; + public const string WheelchairPickup = ""; + public const string WhereToVote = ""; + public const string Widgets = ""; + public const string Wifi = ""; + public const string Wifi1Bar = ""; + public const string Wifi2Bar = ""; + public const string WifiCalling = ""; + public const string WifiCalling3 = ""; + public const string WifiChannel = ""; + public const string WifiFind = ""; + public const string WifiLock = ""; + public const string WifiOff = ""; + public const string WifiPassword = ""; + public const string WifiProtectedSetup = ""; + public const string WifiTethering = ""; + public const string WifiTetheringError = ""; + public const string WifiTetheringOff = ""; + public const string Window = ""; + public const string WineBar = ""; + public const string Woman = ""; + public const string Work = ""; + public const string WorkOff = ""; + public const string WorkOutline = ""; + public const string WorkspacePremium = ""; + public const string Workspaces = ""; + public const string WrapText = ""; + public const string WrongLocation = ""; + public const string Wysiwyg = ""; + public const string Yard = ""; + public const string YoutubeSearchedFor = ""; + public const string ZoomIn = ""; + public const string ZoomInMap = ""; + public const string ZoomOut = ""; + public const string ZoomOutMap = ""; + } + } + } +} diff --git a/Icons/Material/Outlined.cs b/Icons/Material/Outlined.cs new file mode 100644 index 0000000..6898d0b --- /dev/null +++ b/Icons/Material/Outlined.cs @@ -0,0 +1,2069 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Material + { + [ExcludeFromCodeCoverage] + public partial class Outlined + { + public const string _10k = ""; + public const string _10mp = ""; + public const string _11mp = ""; + public const string _123 = ""; + public const string _12mp = ""; + public const string _13mp = ""; + public const string _14mp = ""; + public const string _15mp = ""; + public const string _16mp = ""; + public const string _17mp = ""; + public const string _18mp = ""; + public const string _19mp = ""; + public const string _1k = ""; + public const string _1kPlus = ""; + public const string _1xMobiledata = ""; + public const string _20mp = ""; + public const string _21mp = ""; + public const string _22mp = ""; + public const string _23mp = ""; + public const string _24mp = ""; + public const string _2k = ""; + public const string _2kPlus = ""; + public const string _2mp = ""; + public const string _30fps = ""; + public const string _30fpsSelect = ""; + public const string _360 = ""; + public const string _3dRotation = ""; + public const string _3gMobiledata = ""; + public const string _3k = ""; + public const string _3kPlus = ""; + public const string _3mp = ""; + public const string _3p = ""; + public const string _4gMobiledata = ""; + public const string _4gPlusMobiledata = ""; + public const string _4k = ""; + public const string _4kPlus = ""; + public const string _4mp = ""; + public const string _5g = ""; + public const string _5k = ""; + public const string _5kPlus = ""; + public const string _5mp = ""; + public const string _60fps = ""; + public const string _60fpsSelect = ""; + public const string _6FtApart = ""; + public const string _6k = ""; + public const string _6kPlus = ""; + public const string _6mp = ""; + public const string _7k = ""; + public const string _7kPlus = ""; + public const string _7mp = ""; + public const string _8k = ""; + public const string _8kPlus = ""; + public const string _8mp = ""; + public const string _9k = ""; + public const string _9kPlus = ""; + public const string _9mp = ""; + public const string Abc = ""; + public const string AcUnit = ""; + public const string AccessAlarm = ""; + public const string AccessAlarms = ""; + public const string AccessTime = ""; + public const string AccessTimeFilled = ""; + public const string Accessibility = ""; + public const string AccessibilityNew = ""; + public const string Accessible = ""; + public const string AccessibleForward = ""; + public const string AccountBalance = ""; + public const string AccountBalanceWallet = ""; + public const string AccountBox = ""; + public const string AccountCircle = ""; + public const string AccountTree = ""; + public const string AdUnits = ""; + public const string Adb = ""; + public const string Add = ""; + public const string AddAPhoto = ""; + public const string AddAlarm = ""; + public const string AddAlert = ""; + public const string AddBox = ""; + public const string AddBusiness = ""; + public const string AddCard = ""; + public const string AddChart = ""; + public const string AddCircle = ""; + public const string AddCircleOutline = ""; + public const string AddComment = ""; + public const string AddIcCall = ""; + public const string AddLink = ""; + public const string AddLocation = ""; + public const string AddLocationAlt = ""; + public const string AddModerator = ""; + public const string AddPhotoAlternate = ""; + public const string AddReaction = ""; + public const string AddRoad = ""; + public const string AddShoppingCart = ""; + public const string AddTask = ""; + public const string AddToDrive = ""; + public const string AddToHomeScreen = ""; + public const string AddToPhotos = ""; + public const string AddToQueue = ""; + public const string Addchart = ""; + public const string AdfScanner = ""; + public const string Adjust = ""; + public const string AdminPanelSettings = ""; + public const string AdsClick = ""; + public const string Agriculture = ""; + public const string Air = ""; + public const string AirlineSeatFlat = ""; + public const string AirlineSeatFlatAngled = ""; + public const string AirlineSeatIndividualSuite = ""; + public const string AirlineSeatLegroomExtra = ""; + public const string AirlineSeatLegroomNormal = ""; + public const string AirlineSeatLegroomReduced = ""; + public const string AirlineSeatReclineExtra = ""; + public const string AirlineSeatReclineNormal = ""; + public const string AirlineStops = ""; + public const string Airlines = ""; + public const string AirplaneTicket = ""; + public const string AirplanemodeActive = ""; + public const string AirplanemodeInactive = ""; + public const string Airplay = ""; + public const string AirportShuttle = ""; + public const string Alarm = ""; + public const string AlarmAdd = ""; + public const string AlarmOff = ""; + public const string AlarmOn = ""; + public const string Album = ""; + public const string AlignHorizontalCenter = ""; + public const string AlignHorizontalLeft = ""; + public const string AlignHorizontalRight = ""; + public const string AlignVerticalBottom = ""; + public const string AlignVerticalCenter = ""; + public const string AlignVerticalTop = ""; + public const string AllInbox = ""; + public const string AllInclusive = ""; + public const string AllOut = ""; + public const string AltRoute = ""; + public const string AlternateEmail = ""; + public const string Analytics = ""; + public const string Anchor = ""; + public const string Android = ""; + public const string Animation = ""; + public const string Announcement = ""; + public const string Aod = ""; + public const string Apartment = ""; + public const string Api = ""; + public const string AppBlocking = ""; + public const string AppRegistration = ""; + public const string AppSettingsAlt = ""; + public const string AppShortcut = ""; + public const string Approval = ""; + public const string Apps = ""; + public const string AppsOutage = ""; + public const string Architecture = ""; + public const string Archive = ""; + public const string AreaChart = ""; + public const string ArrowBack = ""; + public const string ArrowBackIos = ""; + public const string ArrowBackIosNew = ""; + public const string ArrowCircleDown = ""; + public const string ArrowCircleLeft = ""; + public const string ArrowCircleRight = ""; + public const string ArrowCircleUp = ""; + public const string ArrowDownward = ""; + public const string ArrowDropDown = ""; + public const string ArrowDropDownCircle = ""; + public const string ArrowDropUp = ""; + public const string ArrowForward = ""; + public const string ArrowForwardIos = ""; + public const string ArrowLeft = ""; + public const string ArrowRight = ""; + public const string ArrowRightAlt = ""; + public const string ArrowUpward = ""; + public const string ArtTrack = ""; + public const string Article = ""; + public const string AspectRatio = ""; + public const string Assessment = ""; + public const string Assignment = ""; + public const string AssignmentInd = ""; + public const string AssignmentLate = ""; + public const string AssignmentReturn = ""; + public const string AssignmentReturned = ""; + public const string AssignmentTurnedIn = ""; + public const string Assistant = ""; + public const string AssistantDirection = ""; + public const string AssistantPhoto = ""; + public const string AssuredWorkload = ""; + public const string Atm = ""; + public const string AttachEmail = ""; + public const string AttachFile = ""; + public const string AttachMoney = ""; + public const string Attachment = ""; + public const string Attractions = ""; + public const string Attribution = ""; + public const string AudioFile = ""; + public const string Audiotrack = ""; + public const string AutoAwesome = ""; + public const string AutoAwesomeMosaic = ""; + public const string AutoAwesomeMotion = ""; + public const string AutoDelete = ""; + public const string AutoFixHigh = ""; + public const string AutoFixNormal = ""; + public const string AutoFixOff = ""; + public const string AutoGraph = ""; + public const string AutoStories = ""; + public const string AutofpsSelect = ""; + public const string Autorenew = ""; + public const string AvTimer = ""; + public const string BabyChangingStation = ""; + public const string BackHand = ""; + public const string Backpack = ""; + public const string Backspace = ""; + public const string Backup = ""; + public const string BackupTable = ""; + public const string Badge = ""; + public const string BakeryDining = ""; + public const string Balance = ""; + public const string Balcony = ""; + public const string Ballot = ""; + public const string BarChart = ""; + public const string BatchPrediction = ""; + public const string Bathroom = ""; + public const string Bathtub = ""; + public const string Battery0Bar = ""; + public const string Battery1Bar = ""; + public const string Battery2Bar = ""; + public const string Battery3Bar = ""; + public const string Battery4Bar = ""; + public const string Battery5Bar = ""; + public const string Battery6Bar = ""; + public const string BatteryAlert = ""; + public const string BatteryChargingFull = ""; + public const string BatteryFull = ""; + public const string BatterySaver = ""; + public const string BatteryStd = ""; + public const string BatteryUnknown = ""; + public const string BeachAccess = ""; + public const string Bed = ""; + public const string BedroomBaby = ""; + public const string BedroomChild = ""; + public const string BedroomParent = ""; + public const string Bedtime = ""; + public const string BedtimeOff = ""; + public const string Beenhere = ""; + public const string Bento = ""; + public const string BikeScooter = ""; + public const string Biotech = ""; + public const string Blender = ""; + public const string Block = ""; + public const string Bloodtype = ""; + public const string Bluetooth = ""; + public const string BluetoothAudio = ""; + public const string BluetoothConnected = ""; + public const string BluetoothDisabled = ""; + public const string BluetoothDrive = ""; + public const string BluetoothSearching = ""; + public const string BlurCircular = ""; + public const string BlurLinear = ""; + public const string BlurOff = ""; + public const string BlurOn = ""; + public const string Bolt = ""; + public const string Book = ""; + public const string BookOnline = ""; + public const string Bookmark = ""; + public const string BookmarkAdd = ""; + public const string BookmarkAdded = ""; + public const string BookmarkBorder = ""; + public const string BookmarkRemove = ""; + public const string Bookmarks = ""; + public const string BorderAll = ""; + public const string BorderBottom = ""; + public const string BorderClear = ""; + public const string BorderColor = ""; + public const string BorderHorizontal = ""; + public const string BorderInner = ""; + public const string BorderLeft = ""; + public const string BorderOuter = ""; + public const string BorderRight = ""; + public const string BorderStyle = ""; + public const string BorderTop = ""; + public const string BorderVertical = ""; + public const string Boy = ""; + public const string BrandingWatermark = ""; + public const string BreakfastDining = ""; + public const string Brightness1 = ""; + public const string Brightness2 = ""; + public const string Brightness3 = ""; + public const string Brightness4 = ""; + public const string Brightness5 = ""; + public const string Brightness6 = ""; + public const string Brightness7 = ""; + public const string BrightnessAuto = ""; + public const string BrightnessHigh = ""; + public const string BrightnessLow = ""; + public const string BrightnessMedium = ""; + public const string BrokenImage = ""; + public const string BrowseGallery = ""; + public const string BrowserNotSupported = ""; + public const string BrowserUpdated = ""; + public const string BrunchDining = ""; + public const string Brush = ""; + public const string BubbleChart = ""; + public const string BugReport = ""; + public const string Build = ""; + public const string BuildCircle = ""; + public const string Bungalow = ""; + public const string BurstMode = ""; + public const string BusAlert = ""; + public const string Business = ""; + public const string BusinessCenter = ""; + public const string Cabin = ""; + public const string Cable = ""; + public const string Cached = ""; + public const string Cake = ""; + public const string Calculate = ""; + public const string CalendarMonth = ""; + public const string CalendarToday = ""; + public const string CalendarViewDay = ""; + public const string CalendarViewMonth = ""; + public const string CalendarViewWeek = ""; + public const string Call = ""; + public const string CallEnd = ""; + public const string CallMade = ""; + public const string CallMerge = ""; + public const string CallMissed = ""; + public const string CallMissedOutgoing = ""; + public const string CallReceived = ""; + public const string CallSplit = ""; + public const string CallToAction = ""; + public const string Camera = ""; + public const string CameraAlt = ""; + public const string CameraEnhance = ""; + public const string CameraFront = ""; + public const string CameraIndoor = ""; + public const string CameraOutdoor = ""; + public const string CameraRear = ""; + public const string CameraRoll = ""; + public const string Cameraswitch = ""; + public const string Campaign = ""; + public const string Cancel = ""; + public const string CancelPresentation = ""; + public const string CancelScheduleSend = ""; + public const string CandlestickChart = ""; + public const string CarCrash = ""; + public const string CarRental = ""; + public const string CarRepair = ""; + public const string CardGiftcard = ""; + public const string CardMembership = ""; + public const string CardTravel = ""; + public const string Carpenter = ""; + public const string Cases = ""; + public const string Casino = ""; + public const string Cast = ""; + public const string CastConnected = ""; + public const string CastForEducation = ""; + public const string Castle = ""; + public const string CatchingPokemon = ""; + public const string Category = ""; + public const string Celebration = ""; + public const string CellTower = ""; + public const string CellWifi = ""; + public const string CenterFocusStrong = ""; + public const string CenterFocusWeak = ""; + public const string Chair = ""; + public const string ChairAlt = ""; + public const string Chalet = ""; + public const string ChangeCircle = ""; + public const string ChangeHistory = ""; + public const string ChargingStation = ""; + public const string Chat = ""; + public const string ChatBubble = ""; + public const string ChatBubbleOutline = ""; + public const string Check = ""; + public const string CheckBox = ""; + public const string CheckBoxOutlineBlank = ""; + public const string CheckCircle = ""; + public const string CheckCircleOutline = ""; + public const string Checklist = ""; + public const string ChecklistRtl = ""; + public const string Checkroom = ""; + public const string ChevronLeft = ""; + public const string ChevronRight = ""; + public const string ChildCare = ""; + public const string ChildFriendly = ""; + public const string ChromeReaderMode = ""; + public const string Church = ""; + public const string Circle = ""; + public const string CircleNotifications = ""; + public const string Class = ""; + public const string CleanHands = ""; + public const string CleaningServices = ""; + public const string Clear = ""; + public const string ClearAll = ""; + public const string Close = ""; + public const string CloseFullscreen = ""; + public const string ClosedCaption = ""; + public const string ClosedCaptionDisabled = ""; + public const string ClosedCaptionOff = ""; + public const string Cloud = ""; + public const string CloudCircle = ""; + public const string CloudDone = ""; + public const string CloudDownload = ""; + public const string CloudOff = ""; + public const string CloudQueue = ""; + public const string CloudSync = ""; + public const string CloudUpload = ""; + public const string Co2 = ""; + public const string CoPresent = ""; + public const string Code = ""; + public const string CodeOff = ""; + public const string Coffee = ""; + public const string CoffeeMaker = ""; + public const string Collections = ""; + public const string CollectionsBookmark = ""; + public const string ColorLens = ""; + public const string Colorize = ""; + public const string Comment = ""; + public const string CommentBank = ""; + public const string CommentsDisabled = ""; + public const string Commit = ""; + public const string Commute = ""; + public const string Compare = ""; + public const string CompareArrows = ""; + public const string CompassCalibration = ""; + public const string Compost = ""; + public const string Compress = ""; + public const string Computer = ""; + public const string ConfirmationNumber = ""; + public const string ConnectWithoutContact = ""; + public const string ConnectedTv = ""; + public const string ConnectingAirports = ""; + public const string Construction = ""; + public const string ContactMail = ""; + public const string ContactPage = ""; + public const string ContactPhone = ""; + public const string ContactSupport = ""; + public const string Contactless = ""; + public const string Contacts = ""; + public const string ContentCopy = ""; + public const string ContentCut = ""; + public const string ContentPaste = ""; + public const string ContentPasteGo = ""; + public const string ContentPasteOff = ""; + public const string ContentPasteSearch = ""; + public const string Contrast = ""; + public const string ControlCamera = ""; + public const string ControlPoint = ""; + public const string ControlPointDuplicate = ""; + public const string Cookie = ""; + public const string CopyAll = ""; + public const string Copyright = ""; + public const string Coronavirus = ""; + public const string CorporateFare = ""; + public const string Cottage = ""; + public const string Countertops = ""; + public const string Create = ""; + public const string CreateNewFolder = ""; + public const string CreditCard = ""; + public const string CreditCardOff = ""; + public const string CreditScore = ""; + public const string Crib = ""; + public const string CrisisAlert = ""; + public const string Crop = ""; + public const string Crop169 = ""; + public const string Crop32 = ""; + public const string Crop54 = ""; + public const string Crop75 = ""; + public const string CropDin = ""; + public const string CropFree = ""; + public const string CropLandscape = ""; + public const string CropOriginal = ""; + public const string CropPortrait = ""; + public const string CropRotate = ""; + public const string CropSquare = ""; + public const string CrueltyFree = ""; + public const string Css = ""; + public const string CurrencyBitcoin = ""; + public const string CurrencyExchange = ""; + public const string CurrencyFranc = ""; + public const string CurrencyLira = ""; + public const string CurrencyPound = ""; + public const string CurrencyRuble = ""; + public const string CurrencyRupee = ""; + public const string CurrencyYen = ""; + public const string CurrencyYuan = ""; + public const string Cyclone = ""; + public const string Dangerous = ""; + public const string DarkMode = ""; + public const string Dashboard = ""; + public const string DashboardCustomize = ""; + public const string DataArray = ""; + public const string DataExploration = ""; + public const string DataObject = ""; + public const string DataSaverOff = ""; + public const string DataSaverOn = ""; + public const string DataThresholding = ""; + public const string DataUsage = ""; + public const string DateRange = ""; + public const string Deblur = ""; + public const string Deck = ""; + public const string Dehaze = ""; + public const string Delete = ""; + public const string DeleteForever = ""; + public const string DeleteOutline = ""; + public const string DeleteSweep = ""; + public const string DeliveryDining = ""; + public const string DensityLarge = ""; + public const string DensityMedium = ""; + public const string DensitySmall = ""; + public const string DepartureBoard = ""; + public const string Description = ""; + public const string Deselect = ""; + public const string DesignServices = ""; + public const string DesktopAccessDisabled = ""; + public const string DesktopMac = ""; + public const string DesktopWindows = ""; + public const string Details = ""; + public const string DeveloperBoard = ""; + public const string DeveloperBoardOff = ""; + public const string DeveloperMode = ""; + public const string DeviceHub = ""; + public const string DeviceThermostat = ""; + public const string DeviceUnknown = ""; + public const string Devices = ""; + public const string DevicesFold = ""; + public const string DevicesOther = ""; + public const string DialerSip = ""; + public const string Dialpad = ""; + public const string Diamond = ""; + public const string Difference = ""; + public const string Dining = ""; + public const string DinnerDining = ""; + public const string Directions = ""; + public const string DirectionsBike = ""; + public const string DirectionsBoat = ""; + public const string DirectionsBoatFilled = ""; + public const string DirectionsBus = ""; + public const string DirectionsBusFilled = ""; + public const string DirectionsCar = ""; + public const string DirectionsCarFilled = ""; + public const string DirectionsOff = ""; + public const string DirectionsRailway = ""; + public const string DirectionsRailwayFilled = ""; + public const string DirectionsRun = ""; + public const string DirectionsSubway = ""; + public const string DirectionsSubwayFilled = ""; + public const string DirectionsTransit = ""; + public const string DirectionsTransitFilled = ""; + public const string DirectionsWalk = ""; + public const string DirtyLens = ""; + public const string DisabledByDefault = ""; + public const string DisabledVisible = ""; + public const string DiscFull = ""; + public const string Discount = ""; + public const string DisplaySettings = ""; + public const string Dns = ""; + public const string DoDisturb = ""; + public const string DoDisturbAlt = ""; + public const string DoDisturbOff = ""; + public const string DoDisturbOn = ""; + public const string DoNotDisturb = ""; + public const string DoNotDisturbAlt = ""; + public const string DoNotDisturbOff = ""; + public const string DoNotDisturbOn = ""; + public const string DoNotDisturbOnTotalSilence = ""; + public const string DoNotStep = ""; + public const string DoNotTouch = ""; + public const string Dock = ""; + public const string DocumentScanner = ""; + public const string Domain = ""; + public const string DomainAdd = ""; + public const string DomainDisabled = ""; + public const string DomainVerification = ""; + public const string Done = ""; + public const string DoneAll = ""; + public const string DoneOutline = ""; + public const string DonutLarge = ""; + public const string DonutSmall = ""; + public const string DoorBack = ""; + public const string DoorFront = ""; + public const string DoorSliding = ""; + public const string Doorbell = ""; + public const string DoubleArrow = ""; + public const string DownhillSkiing = ""; + public const string Download = ""; + public const string DownloadDone = ""; + public const string DownloadForOffline = ""; + public const string Downloading = ""; + public const string Drafts = ""; + public const string DragHandle = ""; + public const string DragIndicator = ""; + public const string Draw = ""; + public const string DriveEta = ""; + public const string DriveFileMove = ""; + public const string DriveFileMoveRtl = ""; + public const string DriveFileRenameOutline = ""; + public const string DriveFolderUpload = ""; + public const string Dry = ""; + public const string DryCleaning = ""; + public const string Duo = ""; + public const string Dvr = ""; + public const string DynamicFeed = ""; + public const string DynamicForm = ""; + public const string EMobiledata = ""; + public const string Earbuds = ""; + public const string EarbudsBattery = ""; + public const string East = ""; + public const string EdgesensorHigh = ""; + public const string EdgesensorLow = ""; + public const string Edit = ""; + public const string EditAttributes = ""; + public const string EditCalendar = ""; + public const string EditLocation = ""; + public const string EditLocationAlt = ""; + public const string EditNote = ""; + public const string EditNotifications = ""; + public const string EditOff = ""; + public const string EditRoad = ""; + public const string Egg = ""; + public const string EggAlt = ""; + public const string Eject = ""; + public const string Elderly = ""; + public const string ElderlyWoman = ""; + public const string ElectricBike = ""; + public const string ElectricCar = ""; + public const string ElectricMoped = ""; + public const string ElectricRickshaw = ""; + public const string ElectricScooter = ""; + public const string ElectricalServices = ""; + public const string Elevator = ""; + public const string Email = ""; + public const string Emergency = ""; + public const string EmergencyRecording = ""; + public const string EmergencyShare = ""; + public const string EmojiEmotions = ""; + public const string EmojiEvents = ""; + public const string EmojiFoodBeverage = ""; + public const string EmojiNature = ""; + public const string EmojiObjects = ""; + public const string EmojiPeople = ""; + public const string EmojiSymbols = ""; + public const string EmojiTransportation = ""; + public const string Engineering = ""; + public const string EnhancedEncryption = ""; + public const string Equalizer = ""; + public const string Error = ""; + public const string ErrorOutline = ""; + public const string Escalator = ""; + public const string EscalatorWarning = ""; + public const string Euro = ""; + public const string EuroSymbol = ""; + public const string EvStation = ""; + public const string Event = ""; + public const string EventAvailable = ""; + public const string EventBusy = ""; + public const string EventNote = ""; + public const string EventRepeat = ""; + public const string EventSeat = ""; + public const string ExitToApp = ""; + public const string Expand = ""; + public const string ExpandCircleDown = ""; + public const string ExpandLess = ""; + public const string ExpandMore = ""; + public const string Explicit = ""; + public const string Explore = ""; + public const string ExploreOff = ""; + public const string Exposure = ""; + public const string ExposureNeg1 = ""; + public const string ExposureNeg2 = ""; + public const string ExposurePlus1 = ""; + public const string ExposurePlus2 = ""; + public const string ExposureZero = ""; + public const string Extension = ""; + public const string ExtensionOff = ""; + public const string Face = ""; + public const string FaceRetouchingNatural = ""; + public const string FaceRetouchingOff = ""; + public const string FactCheck = ""; + public const string Factory = ""; + public const string FamilyRestroom = ""; + public const string FastForward = ""; + public const string FastRewind = ""; + public const string Fastfood = ""; + public const string Favorite = ""; + public const string FavoriteBorder = ""; + public const string Fax = ""; + public const string FeaturedPlayList = ""; + public const string FeaturedVideo = ""; + public const string Feed = ""; + public const string Feedback = ""; + public const string Female = ""; + public const string Fence = ""; + public const string Festival = ""; + public const string FiberDvr = ""; + public const string FiberManualRecord = ""; + public const string FiberNew = ""; + public const string FiberPin = ""; + public const string FiberSmartRecord = ""; + public const string FileCopy = ""; + public const string FileDownload = ""; + public const string FileDownloadDone = ""; + public const string FileDownloadOff = ""; + public const string FileOpen = ""; + public const string FilePresent = ""; + public const string FileUpload = ""; + public const string Filter = ""; + public const string Filter1 = ""; + public const string Filter2 = ""; + public const string Filter3 = ""; + public const string Filter4 = ""; + public const string Filter5 = ""; + public const string Filter6 = ""; + public const string Filter7 = ""; + public const string Filter8 = ""; + public const string Filter9 = ""; + public const string Filter9Plus = ""; + public const string FilterAlt = ""; + public const string FilterAltOff = ""; + public const string FilterBAndW = ""; + public const string FilterCenterFocus = ""; + public const string FilterDrama = ""; + public const string FilterFrames = ""; + public const string FilterHdr = ""; + public const string FilterList = ""; + public const string FilterListOff = ""; + public const string FilterNone = ""; + public const string FilterTiltShift = ""; + public const string FilterVintage = ""; + public const string FindInPage = ""; + public const string FindReplace = ""; + public const string Fingerprint = ""; + public const string FireExtinguisher = ""; + public const string Fireplace = ""; + public const string FirstPage = ""; + public const string FitScreen = ""; + public const string Fitbit = ""; + public const string FitnessCenter = ""; + public const string Flag = ""; + public const string FlagCircle = ""; + public const string Flaky = ""; + public const string Flare = ""; + public const string FlashAuto = ""; + public const string FlashOff = ""; + public const string FlashOn = ""; + public const string FlashlightOff = ""; + public const string FlashlightOn = ""; + public const string Flatware = ""; + public const string Flight = ""; + public const string FlightClass = ""; + public const string FlightLand = ""; + public const string FlightTakeoff = ""; + public const string Flip = ""; + public const string FlipCameraAndroid = ""; + public const string FlipCameraIos = ""; + public const string FlipToBack = ""; + public const string FlipToFront = ""; + public const string Flood = ""; + public const string Flourescent = ""; + public const string FlutterDash = ""; + public const string FmdBad = ""; + public const string FmdGood = ""; + public const string Folder = ""; + public const string FolderCopy = ""; + public const string FolderDelete = ""; + public const string FolderOff = ""; + public const string FolderOpen = ""; + public const string FolderShared = ""; + public const string FolderSpecial = ""; + public const string FolderZip = ""; + public const string FollowTheSigns = ""; + public const string FontDownload = ""; + public const string FontDownloadOff = ""; + public const string FoodBank = ""; + public const string Forest = ""; + public const string ForkLeft = ""; + public const string ForkRight = ""; + public const string FormatAlignCenter = ""; + public const string FormatAlignJustify = ""; + public const string FormatAlignLeft = ""; + public const string FormatAlignRight = ""; + public const string FormatBold = ""; + public const string FormatClear = ""; + public const string FormatColorFill = ""; + public const string FormatColorReset = ""; + public const string FormatColorText = ""; + public const string FormatIndentDecrease = ""; + public const string FormatIndentIncrease = ""; + public const string FormatItalic = ""; + public const string FormatLineSpacing = ""; + public const string FormatListBulleted = ""; + public const string FormatListNumbered = ""; + public const string FormatListNumberedRtl = ""; + public const string FormatOverline = ""; + public const string FormatPaint = ""; + public const string FormatQuote = ""; + public const string FormatShapes = ""; + public const string FormatSize = ""; + public const string FormatStrikethrough = ""; + public const string FormatTextdirectionLToR = ""; + public const string FormatTextdirectionRToL = ""; + public const string FormatUnderlined = ""; + public const string Fort = ""; + public const string Forum = ""; + public const string Forward = ""; + public const string Forward10 = ""; + public const string Forward30 = ""; + public const string Forward5 = ""; + public const string ForwardToInbox = ""; + public const string Foundation = ""; + public const string FreeBreakfast = ""; + public const string FreeCancellation = ""; + public const string FrontHand = ""; + public const string Fullscreen = ""; + public const string FullscreenExit = ""; + public const string Functions = ""; + public const string GMobiledata = ""; + public const string GTranslate = ""; + public const string Gamepad = ""; + public const string Games = ""; + public const string Garage = ""; + public const string Gavel = ""; + public const string GeneratingTokens = ""; + public const string Gesture = ""; + public const string GetApp = ""; + public const string Gif = ""; + public const string GifBox = ""; + public const string Girl = ""; + public const string Gite = ""; + public const string GolfCourse = ""; + public const string GppBad = ""; + public const string GppGood = ""; + public const string GppMaybe = ""; + public const string GpsFixed = ""; + public const string GpsNotFixed = ""; + public const string GpsOff = ""; + public const string Grade = ""; + public const string Gradient = ""; + public const string Grading = ""; + public const string Grain = ""; + public const string GraphicEq = ""; + public const string Grass = ""; + public const string Grid3x3 = ""; + public const string Grid4x4 = ""; + public const string GridGoldenratio = ""; + public const string GridOff = ""; + public const string GridOn = ""; + public const string GridView = ""; + public const string Group = ""; + public const string GroupAdd = ""; + public const string GroupOff = ""; + public const string GroupRemove = ""; + public const string GroupWork = ""; + public const string Groups = ""; + public const string HMobiledata = ""; + public const string HPlusMobiledata = ""; + public const string Hail = ""; + public const string Handshake = ""; + public const string Handyman = ""; + public const string Hardware = ""; + public const string Hd = ""; + public const string HdrAuto = ""; + public const string HdrAutoSelect = ""; + public const string HdrEnhancedSelect = ""; + public const string HdrOff = ""; + public const string HdrOffSelect = ""; + public const string HdrOn = ""; + public const string HdrOnSelect = ""; + public const string HdrPlus = ""; + public const string HdrStrong = ""; + public const string HdrWeak = ""; + public const string Headphones = ""; + public const string HeadphonesBattery = ""; + public const string Headset = ""; + public const string HeadsetMic = ""; + public const string HeadsetOff = ""; + public const string Healing = ""; + public const string HealthAndSafety = ""; + public const string Hearing = ""; + public const string HearingDisabled = ""; + public const string HeartBroken = ""; + public const string Height = ""; + public const string Help = ""; + public const string HelpCenter = ""; + public const string HelpOutline = ""; + public const string Hevc = ""; + public const string Hexagon = ""; + public const string HideImage = ""; + public const string HideSource = ""; + public const string HighQuality = ""; + public const string Highlight = ""; + public const string HighlightAlt = ""; + public const string HighlightOff = ""; + public const string Hiking = ""; + public const string History = ""; + public const string HistoryEdu = ""; + public const string HistoryToggleOff = ""; + public const string Hive = ""; + public const string Hls = ""; + public const string HlsOff = ""; + public const string HolidayVillage = ""; + public const string Home = ""; + public const string HomeMax = ""; + public const string HomeMini = ""; + public const string HomeRepairService = ""; + public const string HomeWork = ""; + public const string HorizontalDistribute = ""; + public const string HorizontalRule = ""; + public const string HorizontalSplit = ""; + public const string HotTub = ""; + public const string Hotel = ""; + public const string HotelClass = ""; + public const string HourglassBottom = ""; + public const string HourglassDisabled = ""; + public const string HourglassEmpty = ""; + public const string HourglassFull = ""; + public const string HourglassTop = ""; + public const string House = ""; + public const string HouseSiding = ""; + public const string Houseboat = ""; + public const string HowToReg = ""; + public const string HowToVote = ""; + public const string Html = ""; + public const string Http = ""; + public const string Https = ""; + public const string Hub = ""; + public const string Hvac = ""; + public const string IceSkating = ""; + public const string Icecream = ""; + public const string Image = ""; + public const string ImageAspectRatio = ""; + public const string ImageNotSupported = ""; + public const string ImageSearch = ""; + public const string ImagesearchRoller = ""; + public const string ImportContacts = ""; + public const string ImportExport = ""; + public const string ImportantDevices = ""; + public const string Inbox = ""; + public const string IncompleteCircle = ""; + public const string IndeterminateCheckBox = ""; + public const string Info = ""; + public const string Input = ""; + public const string InsertChart = ""; + public const string InsertChartOutlined = ""; + public const string InsertComment = ""; + public const string InsertDriveFile = ""; + public const string InsertEmoticon = ""; + public const string InsertInvitation = ""; + public const string InsertLink = ""; + public const string InsertPageBreak = ""; + public const string InsertPhoto = ""; + public const string Insights = ""; + public const string InstallDesktop = ""; + public const string InstallMobile = ""; + public const string IntegrationInstructions = ""; + public const string Interests = ""; + public const string InterpreterMode = ""; + public const string Inventory = ""; + public const string Inventory2 = ""; + public const string InvertColors = ""; + public const string InvertColorsOff = ""; + public const string IosShare = ""; + public const string Iron = ""; + public const string Iso = ""; + public const string Javascript = ""; + public const string JoinFull = ""; + public const string JoinInner = ""; + public const string JoinLeft = ""; + public const string JoinRight = ""; + public const string Kayaking = ""; + public const string KebabDining = ""; + public const string Key = ""; + public const string KeyOff = ""; + public const string Keyboard = ""; + public const string KeyboardAlt = ""; + public const string KeyboardArrowDown = ""; + public const string KeyboardArrowLeft = ""; + public const string KeyboardArrowRight = ""; + public const string KeyboardArrowUp = ""; + public const string KeyboardBackspace = ""; + public const string KeyboardCapslock = ""; + public const string KeyboardCommandKey = ""; + public const string KeyboardControlKey = ""; + public const string KeyboardDoubleArrowDown = ""; + public const string KeyboardDoubleArrowLeft = ""; + public const string KeyboardDoubleArrowRight = ""; + public const string KeyboardDoubleArrowUp = ""; + public const string KeyboardHide = ""; + public const string KeyboardOptionKey = ""; + public const string KeyboardReturn = ""; + public const string KeyboardTab = ""; + public const string KeyboardVoice = ""; + public const string KingBed = ""; + public const string Kitchen = ""; + public const string Kitesurfing = ""; + public const string Label = ""; + public const string LabelImportant = ""; + public const string LabelOff = ""; + public const string Lan = ""; + public const string Landscape = ""; + public const string Landslide = ""; + public const string Language = ""; + public const string Laptop = ""; + public const string LaptopChromebook = ""; + public const string LaptopMac = ""; + public const string LaptopWindows = ""; + public const string LastPage = ""; + public const string Launch = ""; + public const string Layers = ""; + public const string LayersClear = ""; + public const string Leaderboard = ""; + public const string LeakAdd = ""; + public const string LeakRemove = ""; + public const string LegendToggle = ""; + public const string Lens = ""; + public const string LensBlur = ""; + public const string LibraryAdd = ""; + public const string LibraryAddCheck = ""; + public const string LibraryBooks = ""; + public const string LibraryMusic = ""; + public const string Light = ""; + public const string LightMode = ""; + public const string Lightbulb = ""; + public const string LightbulbCircle = ""; + public const string LineAxis = ""; + public const string LineStyle = ""; + public const string LineWeight = ""; + public const string LinearScale = ""; + public const string Link = ""; + public const string LinkOff = ""; + public const string LinkedCamera = ""; + public const string Liquor = ""; + public const string List = ""; + public const string ListAlt = ""; + public const string LiveHelp = ""; + public const string LiveTv = ""; + public const string Living = ""; + public const string LocalActivity = ""; + public const string LocalAirport = ""; + public const string LocalAtm = ""; + public const string LocalBar = ""; + public const string LocalCafe = ""; + public const string LocalCarWash = ""; + public const string LocalConvenienceStore = ""; + public const string LocalDining = ""; + public const string LocalDrink = ""; + public const string LocalFireDepartment = ""; + public const string LocalFlorist = ""; + public const string LocalGasStation = ""; + public const string LocalGroceryStore = ""; + public const string LocalHospital = ""; + public const string LocalHotel = ""; + public const string LocalLaundryService = ""; + public const string LocalLibrary = ""; + public const string LocalMall = ""; + public const string LocalMovies = ""; + public const string LocalOffer = ""; + public const string LocalParking = ""; + public const string LocalPharmacy = ""; + public const string LocalPhone = ""; + public const string LocalPizza = ""; + public const string LocalPlay = ""; + public const string LocalPolice = ""; + public const string LocalPostOffice = ""; + public const string LocalPrintshop = ""; + public const string LocalSee = ""; + public const string LocalShipping = ""; + public const string LocalTaxi = ""; + public const string LocationCity = ""; + public const string LocationDisabled = ""; + public const string LocationOff = ""; + public const string LocationOn = ""; + public const string LocationSearching = ""; + public const string Lock = ""; + public const string LockClock = ""; + public const string LockOpen = ""; + public const string LockReset = ""; + public const string Login = ""; + public const string LogoDev = ""; + public const string Logout = ""; + public const string Looks = ""; + public const string Looks3 = ""; + public const string Looks4 = ""; + public const string Looks5 = ""; + public const string Looks6 = ""; + public const string LooksOne = ""; + public const string LooksTwo = ""; + public const string Loop = ""; + public const string Loupe = ""; + public const string LowPriority = ""; + public const string Loyalty = ""; + public const string LteMobiledata = ""; + public const string LtePlusMobiledata = ""; + public const string Luggage = ""; + public const string LunchDining = ""; + public const string Mail = ""; + public const string MailOutline = ""; + public const string Male = ""; + public const string Man = ""; + public const string ManageAccounts = ""; + public const string ManageHistory = ""; + public const string ManageSearch = ""; + public const string Map = ""; + public const string MapsHomeWork = ""; + public const string MapsUgc = ""; + public const string Margin = ""; + public const string MarkAsUnread = ""; + public const string MarkChatRead = ""; + public const string MarkChatUnread = ""; + public const string MarkEmailRead = ""; + public const string MarkEmailUnread = ""; + public const string MarkUnreadChatAlt = ""; + public const string Markunread = ""; + public const string MarkunreadMailbox = ""; + public const string Masks = ""; + public const string Maximize = ""; + public const string MediaBluetoothOff = ""; + public const string MediaBluetoothOn = ""; + public const string Mediation = ""; + public const string MedicalInformation = ""; + public const string MedicalServices = ""; + public const string Medication = ""; + public const string MedicationLiquid = ""; + public const string MeetingRoom = ""; + public const string Memory = ""; + public const string Menu = ""; + public const string MenuBook = ""; + public const string MenuOpen = ""; + public const string Merge = ""; + public const string MergeType = ""; + public const string Message = ""; + public const string Mic = ""; + public const string MicExternalOff = ""; + public const string MicExternalOn = ""; + public const string MicNone = ""; + public const string MicOff = ""; + public const string Microwave = ""; + public const string MilitaryTech = ""; + public const string Minimize = ""; + public const string MinorCrash = ""; + public const string MiscellaneousServices = ""; + public const string MissedVideoCall = ""; + public const string Mms = ""; + public const string MobileFriendly = ""; + public const string MobileOff = ""; + public const string MobileScreenShare = ""; + public const string MobiledataOff = ""; + public const string Mode = ""; + public const string ModeComment = ""; + public const string ModeEdit = ""; + public const string ModeEditOutline = ""; + public const string ModeNight = ""; + public const string ModeOfTravel = ""; + public const string ModeStandby = ""; + public const string ModelTraining = ""; + public const string MonetizationOn = ""; + public const string Money = ""; + public const string MoneyOff = ""; + public const string MoneyOffCsred = ""; + public const string Monitor = ""; + public const string MonitorHeart = ""; + public const string MonitorWeight = ""; + public const string MonochromePhotos = ""; + public const string Mood = ""; + public const string MoodBad = ""; + public const string Moped = ""; + public const string More = ""; + public const string MoreHoriz = ""; + public const string MoreTime = ""; + public const string MoreVert = ""; + public const string Mosque = ""; + public const string MotionPhotosAuto = ""; + public const string MotionPhotosOff = ""; + public const string MotionPhotosOn = ""; + public const string MotionPhotosPause = ""; + public const string MotionPhotosPaused = ""; + public const string Mouse = ""; + public const string MoveDown = ""; + public const string MoveToInbox = ""; + public const string MoveUp = ""; + public const string Movie = ""; + public const string MovieCreation = ""; + public const string MovieFilter = ""; + public const string Moving = ""; + public const string Mp = ""; + public const string MultilineChart = ""; + public const string MultipleStop = ""; + public const string Museum = ""; + public const string MusicNote = ""; + public const string MusicOff = ""; + public const string MusicVideo = ""; + public const string MyLocation = ""; + public const string Nat = ""; + public const string Nature = ""; + public const string NaturePeople = ""; + public const string NavigateBefore = ""; + public const string NavigateNext = ""; + public const string Navigation = ""; + public const string NearMe = ""; + public const string NearMeDisabled = ""; + public const string NearbyError = ""; + public const string NearbyOff = ""; + public const string NetworkCell = ""; + public const string NetworkCheck = ""; + public const string NetworkLocked = ""; + public const string NetworkPing = ""; + public const string NetworkWifi = ""; + public const string NetworkWifi1Bar = ""; + public const string NetworkWifi2Bar = ""; + public const string NetworkWifi3Bar = ""; + public const string NewLabel = ""; + public const string NewReleases = ""; + public const string Newspaper = ""; + public const string NextPlan = ""; + public const string NextWeek = ""; + public const string Nfc = ""; + public const string NightShelter = ""; + public const string Nightlife = ""; + public const string Nightlight = ""; + public const string NightlightRound = ""; + public const string NightsStay = ""; + public const string NoAccounts = ""; + public const string NoBackpack = ""; + public const string NoCell = ""; + public const string NoCrash = ""; + public const string NoDrinks = ""; + public const string NoEncryption = ""; + public const string NoEncryptionGmailerrorred = ""; + public const string NoFlash = ""; + public const string NoFood = ""; + public const string NoLuggage = ""; + public const string NoMeals = ""; + public const string NoMeetingRoom = ""; + public const string NoPhotography = ""; + public const string NoSim = ""; + public const string NoStroller = ""; + public const string NoTransfer = ""; + public const string NoiseAware = ""; + public const string NoiseControlOff = ""; + public const string NordicWalking = ""; + public const string North = ""; + public const string NorthEast = ""; + public const string NorthWest = ""; + public const string NotAccessible = ""; + public const string NotInterested = ""; + public const string NotListedLocation = ""; + public const string NotStarted = ""; + public const string Note = ""; + public const string NoteAdd = ""; + public const string NoteAlt = ""; + public const string Notes = ""; + public const string NotificationAdd = ""; + public const string NotificationImportant = ""; + public const string Notifications = ""; + public const string NotificationsActive = ""; + public const string NotificationsNone = ""; + public const string NotificationsOff = ""; + public const string NotificationsPaused = ""; + public const string Numbers = ""; + public const string OfflineBolt = ""; + public const string OfflinePin = ""; + public const string OfflineShare = ""; + public const string OnDeviceTraining = ""; + public const string OndemandVideo = ""; + public const string OnlinePrediction = ""; + public const string Opacity = ""; + public const string OpenInBrowser = ""; + public const string OpenInFull = ""; + public const string OpenInNew = ""; + public const string OpenInNewOff = ""; + public const string OpenWith = ""; + public const string OtherHouses = ""; + public const string Outbound = ""; + public const string Outbox = ""; + public const string OutdoorGrill = ""; + public const string Outlet = ""; + public const string OutlinedFlag = ""; + public const string Output = ""; + public const string Padding = ""; + public const string Pages = ""; + public const string Pageview = ""; + public const string Paid = ""; + public const string Palette = ""; + public const string PanTool = ""; + public const string PanToolAlt = ""; + public const string Panorama = ""; + public const string PanoramaFishEye = ""; + public const string PanoramaHorizontal = ""; + public const string PanoramaHorizontalSelect = ""; + public const string PanoramaPhotosphere = ""; + public const string PanoramaPhotosphereSelect = ""; + public const string PanoramaVertical = ""; + public const string PanoramaVerticalSelect = ""; + public const string PanoramaWideAngle = ""; + public const string PanoramaWideAngleSelect = ""; + public const string Paragliding = ""; + public const string Park = ""; + public const string PartyMode = ""; + public const string Password = ""; + public const string Pattern = ""; + public const string Pause = ""; + public const string PauseCircle = ""; + public const string PauseCircleFilled = ""; + public const string PauseCircleOutline = ""; + public const string PausePresentation = ""; + public const string Payment = ""; + public const string Payments = ""; + public const string PedalBike = ""; + public const string Pending = ""; + public const string PendingActions = ""; + public const string Pentagon = ""; + public const string People = ""; + public const string PeopleAlt = ""; + public const string PeopleOutline = ""; + public const string Percent = ""; + public const string PermCameraMic = ""; + public const string PermContactCalendar = ""; + public const string PermDataSetting = ""; + public const string PermDeviceInformation = ""; + public const string PermIdentity = ""; + public const string PermMedia = ""; + public const string PermPhoneMsg = ""; + public const string PermScanWifi = ""; + public const string Person = ""; + public const string PersonAdd = ""; + public const string PersonAddAlt = ""; + public const string PersonAddAlt1 = ""; + public const string PersonAddDisabled = ""; + public const string PersonOff = ""; + public const string PersonOutline = ""; + public const string PersonPin = ""; + public const string PersonPinCircle = ""; + public const string PersonRemove = ""; + public const string PersonRemoveAlt1 = ""; + public const string PersonSearch = ""; + public const string PersonalInjury = ""; + public const string PersonalVideo = ""; + public const string PestControl = ""; + public const string PestControlRodent = ""; + public const string Pets = ""; + public const string Phishing = ""; + public const string Phone = ""; + public const string PhoneAndroid = ""; + public const string PhoneBluetoothSpeaker = ""; + public const string PhoneCallback = ""; + public const string PhoneDisabled = ""; + public const string PhoneEnabled = ""; + public const string PhoneForwarded = ""; + public const string PhoneInTalk = ""; + public const string PhoneIphone = ""; + public const string PhoneLocked = ""; + public const string PhoneMissed = ""; + public const string PhonePaused = ""; + public const string Phonelink = ""; + public const string PhonelinkErase = ""; + public const string PhonelinkLock = ""; + public const string PhonelinkOff = ""; + public const string PhonelinkRing = ""; + public const string PhonelinkSetup = ""; + public const string Photo = ""; + public const string PhotoAlbum = ""; + public const string PhotoCamera = ""; + public const string PhotoCameraBack = ""; + public const string PhotoCameraFront = ""; + public const string PhotoFilter = ""; + public const string PhotoLibrary = ""; + public const string PhotoSizeSelectActual = ""; + public const string PhotoSizeSelectLarge = ""; + public const string PhotoSizeSelectSmall = ""; + public const string Php = ""; + public const string Piano = ""; + public const string PianoOff = ""; + public const string PictureAsPdf = ""; + public const string PictureInPicture = ""; + public const string PictureInPictureAlt = ""; + public const string PieChart = ""; + public const string PieChartOutline = ""; + public const string Pin = ""; + public const string PinDrop = ""; + public const string PinEnd = ""; + public const string PinInvoke = ""; + public const string Pinch = ""; + public const string PivotTableChart = ""; + public const string Pix = ""; + public const string Place = ""; + public const string Plagiarism = ""; + public const string PlayArrow = ""; + public const string PlayCircle = ""; + public const string PlayCircleFilled = ""; + public const string PlayCircleOutline = ""; + public const string PlayDisabled = ""; + public const string PlayForWork = ""; + public const string PlayLesson = ""; + public const string PlaylistAdd = ""; + public const string PlaylistAddCheck = ""; + public const string PlaylistAddCheckCircle = ""; + public const string PlaylistAddCircle = ""; + public const string PlaylistPlay = ""; + public const string PlaylistRemove = ""; + public const string Plumbing = ""; + public const string PlusOne = ""; + public const string Podcasts = ""; + public const string PointOfSale = ""; + public const string Policy = ""; + public const string Poll = ""; + public const string Polyline = ""; + public const string Polymer = ""; + public const string Pool = ""; + public const string PortableWifiOff = ""; + public const string Portrait = ""; + public const string PostAdd = ""; + public const string Power = ""; + public const string PowerInput = ""; + public const string PowerOff = ""; + public const string PowerSettingsNew = ""; + public const string PrecisionManufacturing = ""; + public const string PregnantWoman = ""; + public const string PresentToAll = ""; + public const string Preview = ""; + public const string PriceChange = ""; + public const string PriceCheck = ""; + public const string Print = ""; + public const string PrintDisabled = ""; + public const string PriorityHigh = ""; + public const string PrivacyTip = ""; + public const string PrivateConnectivity = ""; + public const string ProductionQuantityLimits = ""; + public const string Psychology = ""; + public const string Public = ""; + public const string PublicOff = ""; + public const string Publish = ""; + public const string PublishedWithChanges = ""; + public const string PunchClock = ""; + public const string PushPin = ""; + public const string QrCode = ""; + public const string QrCode2 = ""; + public const string QrCodeScanner = ""; + public const string QueryBuilder = ""; + public const string QueryStats = ""; + public const string QuestionAnswer = ""; + public const string QuestionMark = ""; + public const string Queue = ""; + public const string QueueMusic = ""; + public const string QueuePlayNext = ""; + public const string Quickreply = ""; + public const string Quiz = ""; + public const string RMobiledata = ""; + public const string Radar = ""; + public const string Radio = ""; + public const string RadioButtonChecked = ""; + public const string RadioButtonUnchecked = ""; + public const string RailwayAlert = ""; + public const string RamenDining = ""; + public const string RampLeft = ""; + public const string RampRight = ""; + public const string RateReview = ""; + public const string RawOff = ""; + public const string RawOn = ""; + public const string ReadMore = ""; + public const string RealEstateAgent = ""; + public const string Receipt = ""; + public const string ReceiptLong = ""; + public const string RecentActors = ""; + public const string Recommend = ""; + public const string RecordVoiceOver = ""; + public const string Rectangle = ""; + public const string Recycling = ""; + public const string Redeem = ""; + public const string Redo = ""; + public const string ReduceCapacity = ""; + public const string Refresh = ""; + public const string RememberMe = ""; + public const string Remove = ""; + public const string RemoveCircle = ""; + public const string RemoveCircleOutline = ""; + public const string RemoveDone = ""; + public const string RemoveFromQueue = ""; + public const string RemoveModerator = ""; + public const string RemoveRedEye = ""; + public const string RemoveRoad = ""; + public const string RemoveShoppingCart = ""; + public const string Reorder = ""; + public const string Repeat = ""; + public const string RepeatOn = ""; + public const string RepeatOne = ""; + public const string RepeatOneOn = ""; + public const string Replay = ""; + public const string Replay10 = ""; + public const string Replay30 = ""; + public const string Replay5 = ""; + public const string ReplayCircleFilled = ""; + public const string Reply = ""; + public const string ReplyAll = ""; + public const string Report = ""; + public const string ReportGmailerrorred = ""; + public const string ReportOff = ""; + public const string ReportProblem = ""; + public const string RequestPage = ""; + public const string RequestQuote = ""; + public const string ResetTv = ""; + public const string RestartAlt = ""; + public const string Restaurant = ""; + public const string RestaurantMenu = ""; + public const string Restore = ""; + public const string RestoreFromTrash = ""; + public const string RestorePage = ""; + public const string Reviews = ""; + public const string RiceBowl = ""; + public const string RingVolume = ""; + public const string Rocket = ""; + public const string RocketLaunch = ""; + public const string RollerSkating = ""; + public const string Roofing = ""; + public const string Room = ""; + public const string RoomPreferences = ""; + public const string RoomService = ""; + public const string Rotate90DegreesCcw = ""; + public const string Rotate90DegreesCw = ""; + public const string RotateLeft = ""; + public const string RotateRight = ""; + public const string RoundaboutLeft = ""; + public const string RoundaboutRight = ""; + public const string RoundedCorner = ""; + public const string Route = ""; + public const string Router = ""; + public const string Rowing = ""; + public const string RssFeed = ""; + public const string Rsvp = ""; + public const string Rtt = ""; + public const string Rule = ""; + public const string RuleFolder = ""; + public const string RunCircle = ""; + public const string RunningWithErrors = ""; + public const string RvHookup = ""; + public const string SafetyCheck = ""; + public const string SafetyDivider = ""; + public const string Sailing = ""; + public const string Sanitizer = ""; + public const string Satellite = ""; + public const string SatelliteAlt = ""; + public const string Save = ""; + public const string SaveAlt = ""; + public const string SaveAs = ""; + public const string SavedSearch = ""; + public const string Savings = ""; + public const string Scale = ""; + public const string Scanner = ""; + public const string ScatterPlot = ""; + public const string Schedule = ""; + public const string ScheduleSend = ""; + public const string Schema = ""; + public const string School = ""; + public const string Science = ""; + public const string Score = ""; + public const string Scoreboard = ""; + public const string ScreenLockLandscape = ""; + public const string ScreenLockPortrait = ""; + public const string ScreenLockRotation = ""; + public const string ScreenRotation = ""; + public const string ScreenRotationAlt = ""; + public const string ScreenSearchDesktop = ""; + public const string ScreenShare = ""; + public const string Screenshot = ""; + public const string ScubaDiving = ""; + public const string Sd = ""; + public const string SdCard = ""; + public const string SdCardAlert = ""; + public const string SdStorage = ""; + public const string Search = ""; + public const string SearchOff = ""; + public const string Security = ""; + public const string SecurityUpdate = ""; + public const string SecurityUpdateGood = ""; + public const string SecurityUpdateWarning = ""; + public const string Segment = ""; + public const string SelectAll = ""; + public const string SelfImprovement = ""; + public const string Sell = ""; + public const string Send = ""; + public const string SendAndArchive = ""; + public const string SendTimeExtension = ""; + public const string SendToMobile = ""; + public const string SensorDoor = ""; + public const string SensorWindow = ""; + public const string Sensors = ""; + public const string SensorsOff = ""; + public const string SentimentDissatisfied = ""; + public const string SentimentNeutral = ""; + public const string SentimentSatisfied = ""; + public const string SentimentSatisfiedAlt = ""; + public const string SentimentVeryDissatisfied = ""; + public const string SentimentVerySatisfied = ""; + public const string SetMeal = ""; + public const string Settings = ""; + public const string SettingsAccessibility = ""; + public const string SettingsApplications = ""; + public const string SettingsBackupRestore = ""; + public const string SettingsBluetooth = ""; + public const string SettingsBrightness = ""; + public const string SettingsCell = ""; + public const string SettingsEthernet = ""; + public const string SettingsInputAntenna = ""; + public const string SettingsInputComponent = ""; + public const string SettingsInputComposite = ""; + public const string SettingsInputHdmi = ""; + public const string SettingsInputSvideo = ""; + public const string SettingsOverscan = ""; + public const string SettingsPhone = ""; + public const string SettingsPower = ""; + public const string SettingsRemote = ""; + public const string SettingsSuggest = ""; + public const string SettingsSystemDaydream = ""; + public const string SettingsVoice = ""; + public const string SevereCold = ""; + public const string Share = ""; + public const string ShareLocation = ""; + public const string Shield = ""; + public const string ShieldMoon = ""; + public const string Shop = ""; + public const string Shop2 = ""; + public const string ShopTwo = ""; + public const string ShoppingBag = ""; + public const string ShoppingBasket = ""; + public const string ShoppingCart = ""; + public const string ShoppingCartCheckout = ""; + public const string ShortText = ""; + public const string Shortcut = ""; + public const string ShowChart = ""; + public const string Shower = ""; + public const string Shuffle = ""; + public const string ShuffleOn = ""; + public const string ShutterSpeed = ""; + public const string Sick = ""; + public const string SignLanguage = ""; + public const string SignalCellular0Bar = ""; + public const string SignalCellular4Bar = ""; + public const string SignalCellularAlt = ""; + public const string SignalCellularAlt1Bar = ""; + public const string SignalCellularAlt2Bar = ""; + public const string SignalCellularConnectedNoInternet0Bar = ""; + public const string SignalCellularConnectedNoInternet4Bar = ""; + public const string SignalCellularNoSim = ""; + public const string SignalCellularNodata = ""; + public const string SignalCellularNull = ""; + public const string SignalCellularOff = ""; + public const string SignalWifi0Bar = ""; + public const string SignalWifi4Bar = ""; + public const string SignalWifi4BarLock = ""; + public const string SignalWifiBad = ""; + public const string SignalWifiConnectedNoInternet4 = ""; + public const string SignalWifiOff = ""; + public const string SignalWifiStatusbar4Bar = ""; + public const string SignalWifiStatusbarConnectedNoInternet4 = ""; + public const string SignalWifiStatusbarNull = ""; + public const string Signpost = ""; + public const string SimCard = ""; + public const string SimCardAlert = ""; + public const string SimCardDownload = ""; + public const string SingleBed = ""; + public const string Sip = ""; + public const string Skateboarding = ""; + public const string SkipNext = ""; + public const string SkipPrevious = ""; + public const string Sledding = ""; + public const string Slideshow = ""; + public const string SlowMotionVideo = ""; + public const string SmartButton = ""; + public const string SmartDisplay = ""; + public const string SmartScreen = ""; + public const string SmartToy = ""; + public const string Smartphone = ""; + public const string SmokeFree = ""; + public const string SmokingRooms = ""; + public const string Sms = ""; + public const string SmsFailed = ""; + public const string SnippetFolder = ""; + public const string Snooze = ""; + public const string Snowboarding = ""; + public const string Snowmobile = ""; + public const string Snowshoeing = ""; + public const string Soap = ""; + public const string SocialDistance = ""; + public const string Sort = ""; + public const string SortByAlpha = ""; + public const string Sos = ""; + public const string SoupKitchen = ""; + public const string Source = ""; + public const string South = ""; + public const string SouthAmerica = ""; + public const string SouthEast = ""; + public const string SouthWest = ""; + public const string Spa = ""; + public const string SpaceBar = ""; + public const string SpaceDashboard = ""; + public const string SpatialAudio = ""; + public const string SpatialAudioOff = ""; + public const string SpatialTracking = ""; + public const string Speaker = ""; + public const string SpeakerGroup = ""; + public const string SpeakerNotes = ""; + public const string SpeakerNotesOff = ""; + public const string SpeakerPhone = ""; + public const string Speed = ""; + public const string Spellcheck = ""; + public const string Splitscreen = ""; + public const string Spoke = ""; + public const string Sports = ""; + public const string SportsBar = ""; + public const string SportsBaseball = ""; + public const string SportsBasketball = ""; + public const string SportsCricket = ""; + public const string SportsEsports = ""; + public const string SportsFootball = ""; + public const string SportsGolf = ""; + public const string SportsGymnastics = ""; + public const string SportsHandball = ""; + public const string SportsHockey = ""; + public const string SportsKabaddi = ""; + public const string SportsMartialArts = ""; + public const string SportsMma = ""; + public const string SportsMotorsports = ""; + public const string SportsRugby = ""; + public const string SportsScore = ""; + public const string SportsSoccer = ""; + public const string SportsTennis = ""; + public const string SportsVolleyball = ""; + public const string Square = ""; + public const string SquareFoot = ""; + public const string SsidChart = ""; + public const string StackedBarChart = ""; + public const string StackedLineChart = ""; + public const string Stadium = ""; + public const string Stairs = ""; + public const string Star = ""; + public const string StarBorder = ""; + public const string StarBorderPurple500 = ""; + public const string StarHalf = ""; + public const string StarOutline = ""; + public const string StarPurple500 = ""; + public const string StarRate = ""; + public const string Stars = ""; + public const string Start = ""; + public const string StayCurrentLandscape = ""; + public const string StayCurrentPortrait = ""; + public const string StayPrimaryLandscape = ""; + public const string StayPrimaryPortrait = ""; + public const string StickyNote2 = ""; + public const string Stop = ""; + public const string StopCircle = ""; + public const string StopScreenShare = ""; + public const string Storage = ""; + public const string Store = ""; + public const string StoreMallDirectory = ""; + public const string Storefront = ""; + public const string Storm = ""; + public const string Straight = ""; + public const string Straighten = ""; + public const string Stream = ""; + public const string Streetview = ""; + public const string StrikethroughS = ""; + public const string Stroller = ""; + public const string Style = ""; + public const string SubdirectoryArrowLeft = ""; + public const string SubdirectoryArrowRight = ""; + public const string Subject = ""; + public const string Subscript = ""; + public const string Subscriptions = ""; + public const string Subtitles = ""; + public const string SubtitlesOff = ""; + public const string Subway = ""; + public const string Summarize = ""; + public const string Superscript = ""; + public const string SupervisedUserCircle = ""; + public const string SupervisorAccount = ""; + public const string Support = ""; + public const string SupportAgent = ""; + public const string Surfing = ""; + public const string SurroundSound = ""; + public const string SwapCalls = ""; + public const string SwapHoriz = ""; + public const string SwapHorizontalCircle = ""; + public const string SwapVert = ""; + public const string SwapVerticalCircle = ""; + public const string Swipe = ""; + public const string SwipeDown = ""; + public const string SwipeDownAlt = ""; + public const string SwipeLeft = ""; + public const string SwipeLeftAlt = ""; + public const string SwipeRight = ""; + public const string SwipeRightAlt = ""; + public const string SwipeUp = ""; + public const string SwipeUpAlt = ""; + public const string SwipeVertical = ""; + public const string SwitchAccessShortcut = ""; + public const string SwitchAccessShortcutAdd = ""; + public const string SwitchAccount = ""; + public const string SwitchCamera = ""; + public const string SwitchLeft = ""; + public const string SwitchRight = ""; + public const string SwitchVideo = ""; + public const string Synagogue = ""; + public const string Sync = ""; + public const string SyncAlt = ""; + public const string SyncDisabled = ""; + public const string SyncLock = ""; + public const string SyncProblem = ""; + public const string SystemSecurityUpdate = ""; + public const string SystemSecurityUpdateGood = ""; + public const string SystemSecurityUpdateWarning = ""; + public const string SystemUpdate = ""; + public const string SystemUpdateAlt = ""; + public const string Tab = ""; + public const string TabUnselected = ""; + public const string TableBar = ""; + public const string TableChart = ""; + public const string TableRestaurant = ""; + public const string TableRows = ""; + public const string TableView = ""; + public const string Tablet = ""; + public const string TabletAndroid = ""; + public const string TabletMac = ""; + public const string Tag = ""; + public const string TagFaces = ""; + public const string TakeoutDining = ""; + public const string TapAndPlay = ""; + public const string Tapas = ""; + public const string Task = ""; + public const string TaskAlt = ""; + public const string TaxiAlert = ""; + public const string TempleBuddhist = ""; + public const string TempleHindu = ""; + public const string Terminal = ""; + public const string Terrain = ""; + public const string TextDecrease = ""; + public const string TextFields = ""; + public const string TextFormat = ""; + public const string TextIncrease = ""; + public const string TextRotateUp = ""; + public const string TextRotateVertical = ""; + public const string TextRotationAngledown = ""; + public const string TextRotationAngleup = ""; + public const string TextRotationDown = ""; + public const string TextRotationNone = ""; + public const string TextSnippet = ""; + public const string Textsms = ""; + public const string Texture = ""; + public const string TheaterComedy = ""; + public const string Theaters = ""; + public const string Thermostat = ""; + public const string ThermostatAuto = ""; + public const string ThumbDown = ""; + public const string ThumbDownAlt = ""; + public const string ThumbDownOffAlt = ""; + public const string ThumbUp = ""; + public const string ThumbUpAlt = ""; + public const string ThumbUpOffAlt = ""; + public const string ThumbsUpDown = ""; + public const string Thunderstorm = ""; + public const string TimeToLeave = ""; + public const string Timelapse = ""; + public const string Timeline = ""; + public const string Timer = ""; + public const string Timer10 = ""; + public const string Timer10Select = ""; + public const string Timer3 = ""; + public const string Timer3Select = ""; + public const string TimerOff = ""; + public const string TipsAndUpdates = ""; + public const string TireRepair = ""; + public const string Title = ""; + public const string Toc = ""; + public const string Today = ""; + public const string ToggleOff = ""; + public const string ToggleOn = ""; + public const string Token = ""; + public const string Toll = ""; + public const string Tonality = ""; + public const string Topic = ""; + public const string TouchApp = ""; + public const string Tour = ""; + public const string Toys = ""; + public const string TrackChanges = ""; + public const string Traffic = ""; + public const string Train = ""; + public const string Tram = ""; + public const string TransferWithinAStation = ""; + public const string Transform = ""; + public const string Transgender = ""; + public const string TransitEnterexit = ""; + public const string Translate = ""; + public const string TravelExplore = ""; + public const string TrendingDown = ""; + public const string TrendingFlat = ""; + public const string TrendingUp = ""; + public const string TripOrigin = ""; + public const string Try = ""; + public const string Tsunami = ""; + public const string Tty = ""; + public const string Tune = ""; + public const string Tungsten = ""; + public const string TurnLeft = ""; + public const string TurnRight = ""; + public const string TurnSharpLeft = ""; + public const string TurnSharpRight = ""; + public const string TurnSlightLeft = ""; + public const string TurnSlightRight = ""; + public const string TurnedIn = ""; + public const string TurnedInNot = ""; + public const string Tv = ""; + public const string TvOff = ""; + public const string TwoWheeler = ""; + public const string UTurnLeft = ""; + public const string UTurnRight = ""; + public const string Umbrella = ""; + public const string Unarchive = ""; + public const string Undo = ""; + public const string UnfoldLess = ""; + public const string UnfoldMore = ""; + public const string Unpublished = ""; + public const string Unsubscribe = ""; + public const string Upcoming = ""; + public const string Update = ""; + public const string UpdateDisabled = ""; + public const string Upgrade = ""; + public const string Upload = ""; + public const string UploadFile = ""; + public const string Usb = ""; + public const string UsbOff = ""; + public const string Vaccines = ""; + public const string VapeFree = ""; + public const string VapingRooms = ""; + public const string Verified = ""; + public const string VerifiedUser = ""; + public const string VerticalAlignBottom = ""; + public const string VerticalAlignCenter = ""; + public const string VerticalAlignTop = ""; + public const string VerticalDistribute = ""; + public const string VerticalSplit = ""; + public const string Vibration = ""; + public const string VideoCall = ""; + public const string VideoCameraBack = ""; + public const string VideoCameraFront = ""; + public const string VideoFile = ""; + public const string VideoLabel = ""; + public const string VideoLibrary = ""; + public const string VideoSettings = ""; + public const string VideoStable = ""; + public const string Videocam = ""; + public const string VideocamOff = ""; + public const string VideogameAsset = ""; + public const string VideogameAssetOff = ""; + public const string ViewAgenda = ""; + public const string ViewArray = ""; + public const string ViewCarousel = ""; + public const string ViewColumn = ""; + public const string ViewComfy = ""; + public const string ViewComfyAlt = ""; + public const string ViewCompact = ""; + public const string ViewCompactAlt = ""; + public const string ViewCozy = ""; + public const string ViewDay = ""; + public const string ViewHeadline = ""; + public const string ViewInAr = ""; + public const string ViewKanban = ""; + public const string ViewList = ""; + public const string ViewModule = ""; + public const string ViewQuilt = ""; + public const string ViewSidebar = ""; + public const string ViewStream = ""; + public const string ViewTimeline = ""; + public const string ViewWeek = ""; + public const string Vignette = ""; + public const string Villa = ""; + public const string Visibility = ""; + public const string VisibilityOff = ""; + public const string VoiceChat = ""; + public const string VoiceOverOff = ""; + public const string Voicemail = ""; + public const string Volcano = ""; + public const string VolumeDown = ""; + public const string VolumeMute = ""; + public const string VolumeOff = ""; + public const string VolumeUp = ""; + public const string VolunteerActivism = ""; + public const string VpnKey = ""; + public const string VpnKeyOff = ""; + public const string VpnLock = ""; + public const string Vrpano = ""; + public const string Wallpaper = ""; + public const string Warehouse = ""; + public const string Warning = ""; + public const string WarningAmber = ""; + public const string Wash = ""; + public const string Watch = ""; + public const string WatchLater = ""; + public const string WatchOff = ""; + public const string Water = ""; + public const string WaterDamage = ""; + public const string WaterDrop = ""; + public const string WaterfallChart = ""; + public const string Waves = ""; + public const string WavingHand = ""; + public const string WbAuto = ""; + public const string WbCloudy = ""; + public const string WbIncandescent = ""; + public const string WbIridescent = ""; + public const string WbShade = ""; + public const string WbSunny = ""; + public const string WbTwilight = ""; + public const string Wc = ""; + public const string Web = ""; + public const string WebAsset = ""; + public const string WebAssetOff = ""; + public const string Webhook = ""; + public const string Weekend = ""; + public const string West = ""; + public const string Whatsapp = ""; + public const string Whatshot = ""; + public const string WheelchairPickup = ""; + public const string WhereToVote = ""; + public const string Widgets = ""; + public const string Wifi = ""; + public const string Wifi1Bar = ""; + public const string Wifi2Bar = ""; + public const string WifiCalling = ""; + public const string WifiCalling3 = ""; + public const string WifiChannel = ""; + public const string WifiFind = ""; + public const string WifiLock = ""; + public const string WifiOff = ""; + public const string WifiPassword = ""; + public const string WifiProtectedSetup = ""; + public const string WifiTethering = ""; + public const string WifiTetheringError = ""; + public const string WifiTetheringOff = ""; + public const string Window = ""; + public const string WineBar = ""; + public const string Woman = ""; + public const string Work = ""; + public const string WorkOff = ""; + public const string WorkOutline = ""; + public const string WorkspacePremium = ""; + public const string Workspaces = ""; + public const string WrapText = ""; + public const string WrongLocation = ""; + public const string Wysiwyg = ""; + public const string Yard = ""; + public const string YoutubeSearchedFor = ""; + public const string ZoomIn = ""; + public const string ZoomInMap = ""; + public const string ZoomOut = ""; + public const string ZoomOutMap = ""; + } + } + } +} diff --git a/Icons/Material/Rounded.cs b/Icons/Material/Rounded.cs new file mode 100644 index 0000000..5f4811e --- /dev/null +++ b/Icons/Material/Rounded.cs @@ -0,0 +1,2069 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Material + { + [ExcludeFromCodeCoverage] + public partial class Rounded + { + public const string _10k = ""; + public const string _10mp = ""; + public const string _11mp = ""; + public const string _123 = ""; + public const string _12mp = ""; + public const string _13mp = ""; + public const string _14mp = ""; + public const string _15mp = ""; + public const string _16mp = ""; + public const string _17mp = ""; + public const string _18mp = ""; + public const string _19mp = ""; + public const string _1k = ""; + public const string _1kPlus = ""; + public const string _1xMobiledata = ""; + public const string _20mp = ""; + public const string _21mp = ""; + public const string _22mp = ""; + public const string _23mp = ""; + public const string _24mp = ""; + public const string _2k = ""; + public const string _2kPlus = ""; + public const string _2mp = ""; + public const string _30fps = ""; + public const string _30fpsSelect = ""; + public const string _360 = ""; + public const string _3dRotation = ""; + public const string _3gMobiledata = ""; + public const string _3k = ""; + public const string _3kPlus = ""; + public const string _3mp = ""; + public const string _3p = ""; + public const string _4gMobiledata = ""; + public const string _4gPlusMobiledata = ""; + public const string _4k = ""; + public const string _4kPlus = ""; + public const string _4mp = ""; + public const string _5g = ""; + public const string _5k = ""; + public const string _5kPlus = ""; + public const string _5mp = ""; + public const string _60fps = ""; + public const string _60fpsSelect = ""; + public const string _6FtApart = ""; + public const string _6k = ""; + public const string _6kPlus = ""; + public const string _6mp = ""; + public const string _7k = ""; + public const string _7kPlus = ""; + public const string _7mp = ""; + public const string _8k = ""; + public const string _8kPlus = ""; + public const string _8mp = ""; + public const string _9k = ""; + public const string _9kPlus = ""; + public const string _9mp = ""; + public const string Abc = ""; + public const string AcUnit = ""; + public const string AccessAlarm = ""; + public const string AccessAlarms = ""; + public const string AccessTime = ""; + public const string AccessTimeFilled = ""; + public const string Accessibility = ""; + public const string AccessibilityNew = ""; + public const string Accessible = ""; + public const string AccessibleForward = ""; + public const string AccountBalance = ""; + public const string AccountBalanceWallet = ""; + public const string AccountBox = ""; + public const string AccountCircle = ""; + public const string AccountTree = ""; + public const string AdUnits = ""; + public const string Adb = ""; + public const string Add = ""; + public const string AddAPhoto = ""; + public const string AddAlarm = ""; + public const string AddAlert = ""; + public const string AddBox = ""; + public const string AddBusiness = ""; + public const string AddCard = ""; + public const string AddChart = ""; + public const string AddCircle = ""; + public const string AddCircleOutline = ""; + public const string AddComment = ""; + public const string AddIcCall = ""; + public const string AddLink = ""; + public const string AddLocation = ""; + public const string AddLocationAlt = ""; + public const string AddModerator = ""; + public const string AddPhotoAlternate = ""; + public const string AddReaction = ""; + public const string AddRoad = ""; + public const string AddShoppingCart = ""; + public const string AddTask = ""; + public const string AddToDrive = ""; + public const string AddToHomeScreen = ""; + public const string AddToPhotos = ""; + public const string AddToQueue = ""; + public const string Addchart = ""; + public const string AdfScanner = ""; + public const string Adjust = ""; + public const string AdminPanelSettings = ""; + public const string AdsClick = ""; + public const string Agriculture = ""; + public const string Air = ""; + public const string AirlineSeatFlat = ""; + public const string AirlineSeatFlatAngled = ""; + public const string AirlineSeatIndividualSuite = ""; + public const string AirlineSeatLegroomExtra = ""; + public const string AirlineSeatLegroomNormal = ""; + public const string AirlineSeatLegroomReduced = ""; + public const string AirlineSeatReclineExtra = ""; + public const string AirlineSeatReclineNormal = ""; + public const string AirlineStops = ""; + public const string Airlines = ""; + public const string AirplaneTicket = ""; + public const string AirplanemodeActive = ""; + public const string AirplanemodeInactive = ""; + public const string Airplay = ""; + public const string AirportShuttle = ""; + public const string Alarm = ""; + public const string AlarmAdd = ""; + public const string AlarmOff = ""; + public const string AlarmOn = ""; + public const string Album = ""; + public const string AlignHorizontalCenter = ""; + public const string AlignHorizontalLeft = ""; + public const string AlignHorizontalRight = ""; + public const string AlignVerticalBottom = ""; + public const string AlignVerticalCenter = ""; + public const string AlignVerticalTop = ""; + public const string AllInbox = ""; + public const string AllInclusive = ""; + public const string AllOut = ""; + public const string AltRoute = ""; + public const string AlternateEmail = ""; + public const string Analytics = ""; + public const string Anchor = ""; + public const string Android = ""; + public const string Animation = ""; + public const string Announcement = ""; + public const string Aod = ""; + public const string Apartment = ""; + public const string Api = ""; + public const string AppBlocking = ""; + public const string AppRegistration = ""; + public const string AppSettingsAlt = ""; + public const string AppShortcut = ""; + public const string Approval = ""; + public const string Apps = ""; + public const string AppsOutage = ""; + public const string Architecture = ""; + public const string Archive = ""; + public const string AreaChart = ""; + public const string ArrowBack = ""; + public const string ArrowBackIos = ""; + public const string ArrowBackIosNew = ""; + public const string ArrowCircleDown = ""; + public const string ArrowCircleLeft = ""; + public const string ArrowCircleRight = ""; + public const string ArrowCircleUp = ""; + public const string ArrowDownward = ""; + public const string ArrowDropDown = ""; + public const string ArrowDropDownCircle = ""; + public const string ArrowDropUp = ""; + public const string ArrowForward = ""; + public const string ArrowForwardIos = ""; + public const string ArrowLeft = ""; + public const string ArrowRight = ""; + public const string ArrowRightAlt = ""; + public const string ArrowUpward = ""; + public const string ArtTrack = ""; + public const string Article = ""; + public const string AspectRatio = ""; + public const string Assessment = ""; + public const string Assignment = ""; + public const string AssignmentInd = ""; + public const string AssignmentLate = ""; + public const string AssignmentReturn = ""; + public const string AssignmentReturned = ""; + public const string AssignmentTurnedIn = ""; + public const string Assistant = ""; + public const string AssistantDirection = ""; + public const string AssistantPhoto = ""; + public const string AssuredWorkload = ""; + public const string Atm = ""; + public const string AttachEmail = ""; + public const string AttachFile = ""; + public const string AttachMoney = ""; + public const string Attachment = ""; + public const string Attractions = ""; + public const string Attribution = ""; + public const string AudioFile = ""; + public const string Audiotrack = ""; + public const string AutoAwesome = ""; + public const string AutoAwesomeMosaic = ""; + public const string AutoAwesomeMotion = ""; + public const string AutoDelete = ""; + public const string AutoFixHigh = ""; + public const string AutoFixNormal = ""; + public const string AutoFixOff = ""; + public const string AutoGraph = ""; + public const string AutoStories = ""; + public const string AutofpsSelect = ""; + public const string Autorenew = ""; + public const string AvTimer = ""; + public const string BabyChangingStation = ""; + public const string BackHand = ""; + public const string Backpack = ""; + public const string Backspace = ""; + public const string Backup = ""; + public const string BackupTable = ""; + public const string Badge = ""; + public const string BakeryDining = ""; + public const string Balance = ""; + public const string Balcony = ""; + public const string Ballot = ""; + public const string BarChart = ""; + public const string BatchPrediction = ""; + public const string Bathroom = ""; + public const string Bathtub = ""; + public const string Battery0Bar = ""; + public const string Battery1Bar = ""; + public const string Battery2Bar = ""; + public const string Battery3Bar = ""; + public const string Battery4Bar = ""; + public const string Battery5Bar = ""; + public const string Battery6Bar = ""; + public const string BatteryAlert = ""; + public const string BatteryChargingFull = ""; + public const string BatteryFull = ""; + public const string BatterySaver = ""; + public const string BatteryStd = ""; + public const string BatteryUnknown = ""; + public const string BeachAccess = ""; + public const string Bed = ""; + public const string BedroomBaby = ""; + public const string BedroomChild = ""; + public const string BedroomParent = ""; + public const string Bedtime = ""; + public const string BedtimeOff = ""; + public const string Beenhere = ""; + public const string Bento = ""; + public const string BikeScooter = ""; + public const string Biotech = ""; + public const string Blender = ""; + public const string Block = ""; + public const string Bloodtype = ""; + public const string Bluetooth = ""; + public const string BluetoothAudio = ""; + public const string BluetoothConnected = ""; + public const string BluetoothDisabled = ""; + public const string BluetoothDrive = ""; + public const string BluetoothSearching = ""; + public const string BlurCircular = ""; + public const string BlurLinear = ""; + public const string BlurOff = ""; + public const string BlurOn = ""; + public const string Bolt = ""; + public const string Book = ""; + public const string BookOnline = ""; + public const string Bookmark = ""; + public const string BookmarkAdd = ""; + public const string BookmarkAdded = ""; + public const string BookmarkBorder = ""; + public const string BookmarkRemove = ""; + public const string Bookmarks = ""; + public const string BorderAll = ""; + public const string BorderBottom = ""; + public const string BorderClear = ""; + public const string BorderColor = ""; + public const string BorderHorizontal = ""; + public const string BorderInner = ""; + public const string BorderLeft = ""; + public const string BorderOuter = ""; + public const string BorderRight = ""; + public const string BorderStyle = ""; + public const string BorderTop = ""; + public const string BorderVertical = ""; + public const string Boy = ""; + public const string BrandingWatermark = ""; + public const string BreakfastDining = ""; + public const string Brightness1 = ""; + public const string Brightness2 = ""; + public const string Brightness3 = ""; + public const string Brightness4 = ""; + public const string Brightness5 = ""; + public const string Brightness6 = ""; + public const string Brightness7 = ""; + public const string BrightnessAuto = ""; + public const string BrightnessHigh = ""; + public const string BrightnessLow = ""; + public const string BrightnessMedium = ""; + public const string BrokenImage = ""; + public const string BrowseGallery = ""; + public const string BrowserNotSupported = ""; + public const string BrowserUpdated = ""; + public const string BrunchDining = ""; + public const string Brush = ""; + public const string BubbleChart = ""; + public const string BugReport = ""; + public const string Build = ""; + public const string BuildCircle = ""; + public const string Bungalow = ""; + public const string BurstMode = ""; + public const string BusAlert = ""; + public const string Business = ""; + public const string BusinessCenter = ""; + public const string Cabin = ""; + public const string Cable = ""; + public const string Cached = ""; + public const string Cake = ""; + public const string Calculate = ""; + public const string CalendarMonth = ""; + public const string CalendarToday = ""; + public const string CalendarViewDay = ""; + public const string CalendarViewMonth = ""; + public const string CalendarViewWeek = ""; + public const string Call = ""; + public const string CallEnd = ""; + public const string CallMade = ""; + public const string CallMerge = ""; + public const string CallMissed = ""; + public const string CallMissedOutgoing = ""; + public const string CallReceived = ""; + public const string CallSplit = ""; + public const string CallToAction = ""; + public const string Camera = ""; + public const string CameraAlt = ""; + public const string CameraEnhance = ""; + public const string CameraFront = ""; + public const string CameraIndoor = ""; + public const string CameraOutdoor = ""; + public const string CameraRear = ""; + public const string CameraRoll = ""; + public const string Cameraswitch = ""; + public const string Campaign = ""; + public const string Cancel = ""; + public const string CancelPresentation = ""; + public const string CancelScheduleSend = ""; + public const string CandlestickChart = ""; + public const string CarCrash = ""; + public const string CarRental = ""; + public const string CarRepair = ""; + public const string CardGiftcard = ""; + public const string CardMembership = ""; + public const string CardTravel = ""; + public const string Carpenter = ""; + public const string Cases = ""; + public const string Casino = ""; + public const string Cast = ""; + public const string CastConnected = ""; + public const string CastForEducation = ""; + public const string Castle = ""; + public const string CatchingPokemon = ""; + public const string Category = ""; + public const string Celebration = ""; + public const string CellTower = ""; + public const string CellWifi = ""; + public const string CenterFocusStrong = ""; + public const string CenterFocusWeak = ""; + public const string Chair = ""; + public const string ChairAlt = ""; + public const string Chalet = ""; + public const string ChangeCircle = ""; + public const string ChangeHistory = ""; + public const string ChargingStation = ""; + public const string Chat = ""; + public const string ChatBubble = ""; + public const string ChatBubbleOutline = ""; + public const string Check = ""; + public const string CheckBox = ""; + public const string CheckBoxOutlineBlank = ""; + public const string CheckCircle = ""; + public const string CheckCircleOutline = ""; + public const string Checklist = ""; + public const string ChecklistRtl = ""; + public const string Checkroom = ""; + public const string ChevronLeft = ""; + public const string ChevronRight = ""; + public const string ChildCare = ""; + public const string ChildFriendly = ""; + public const string ChromeReaderMode = ""; + public const string Church = ""; + public const string Circle = ""; + public const string CircleNotifications = ""; + public const string Class = ""; + public const string CleanHands = ""; + public const string CleaningServices = ""; + public const string Clear = ""; + public const string ClearAll = ""; + public const string Close = ""; + public const string CloseFullscreen = ""; + public const string ClosedCaption = ""; + public const string ClosedCaptionDisabled = ""; + public const string ClosedCaptionOff = ""; + public const string Cloud = ""; + public const string CloudCircle = ""; + public const string CloudDone = ""; + public const string CloudDownload = ""; + public const string CloudOff = ""; + public const string CloudQueue = ""; + public const string CloudSync = ""; + public const string CloudUpload = ""; + public const string Co2 = ""; + public const string CoPresent = ""; + public const string Code = ""; + public const string CodeOff = ""; + public const string Coffee = ""; + public const string CoffeeMaker = ""; + public const string Collections = ""; + public const string CollectionsBookmark = ""; + public const string ColorLens = ""; + public const string Colorize = ""; + public const string Comment = ""; + public const string CommentBank = ""; + public const string CommentsDisabled = ""; + public const string Commit = ""; + public const string Commute = ""; + public const string Compare = ""; + public const string CompareArrows = ""; + public const string CompassCalibration = ""; + public const string Compost = ""; + public const string Compress = ""; + public const string Computer = ""; + public const string ConfirmationNumber = ""; + public const string ConnectWithoutContact = ""; + public const string ConnectedTv = ""; + public const string ConnectingAirports = ""; + public const string Construction = ""; + public const string ContactMail = ""; + public const string ContactPage = ""; + public const string ContactPhone = ""; + public const string ContactSupport = ""; + public const string Contactless = ""; + public const string Contacts = ""; + public const string ContentCopy = ""; + public const string ContentCut = ""; + public const string ContentPaste = ""; + public const string ContentPasteGo = ""; + public const string ContentPasteOff = ""; + public const string ContentPasteSearch = ""; + public const string Contrast = ""; + public const string ControlCamera = ""; + public const string ControlPoint = ""; + public const string ControlPointDuplicate = ""; + public const string Cookie = ""; + public const string CopyAll = ""; + public const string Copyright = ""; + public const string Coronavirus = ""; + public const string CorporateFare = ""; + public const string Cottage = ""; + public const string Countertops = ""; + public const string Create = ""; + public const string CreateNewFolder = ""; + public const string CreditCard = ""; + public const string CreditCardOff = ""; + public const string CreditScore = ""; + public const string Crib = ""; + public const string CrisisAlert = ""; + public const string Crop = ""; + public const string Crop169 = ""; + public const string Crop32 = ""; + public const string Crop54 = ""; + public const string Crop75 = ""; + public const string CropDin = ""; + public const string CropFree = ""; + public const string CropLandscape = ""; + public const string CropOriginal = ""; + public const string CropPortrait = ""; + public const string CropRotate = ""; + public const string CropSquare = ""; + public const string CrueltyFree = ""; + public const string Css = ""; + public const string CurrencyBitcoin = ""; + public const string CurrencyExchange = ""; + public const string CurrencyFranc = ""; + public const string CurrencyLira = ""; + public const string CurrencyPound = ""; + public const string CurrencyRuble = ""; + public const string CurrencyRupee = ""; + public const string CurrencyYen = ""; + public const string CurrencyYuan = ""; + public const string Cyclone = ""; + public const string Dangerous = ""; + public const string DarkMode = ""; + public const string Dashboard = ""; + public const string DashboardCustomize = ""; + public const string DataArray = ""; + public const string DataExploration = ""; + public const string DataObject = ""; + public const string DataSaverOff = ""; + public const string DataSaverOn = ""; + public const string DataThresholding = ""; + public const string DataUsage = ""; + public const string DateRange = ""; + public const string Deblur = ""; + public const string Deck = ""; + public const string Dehaze = ""; + public const string Delete = ""; + public const string DeleteForever = ""; + public const string DeleteOutline = ""; + public const string DeleteSweep = ""; + public const string DeliveryDining = ""; + public const string DensityLarge = ""; + public const string DensityMedium = ""; + public const string DensitySmall = ""; + public const string DepartureBoard = ""; + public const string Description = ""; + public const string Deselect = ""; + public const string DesignServices = ""; + public const string DesktopAccessDisabled = ""; + public const string DesktopMac = ""; + public const string DesktopWindows = ""; + public const string Details = ""; + public const string DeveloperBoard = ""; + public const string DeveloperBoardOff = ""; + public const string DeveloperMode = ""; + public const string DeviceHub = ""; + public const string DeviceThermostat = ""; + public const string DeviceUnknown = ""; + public const string Devices = ""; + public const string DevicesFold = ""; + public const string DevicesOther = ""; + public const string DialerSip = ""; + public const string Dialpad = ""; + public const string Diamond = ""; + public const string Difference = ""; + public const string Dining = ""; + public const string DinnerDining = ""; + public const string Directions = ""; + public const string DirectionsBike = ""; + public const string DirectionsBoat = ""; + public const string DirectionsBoatFilled = ""; + public const string DirectionsBus = ""; + public const string DirectionsBusFilled = ""; + public const string DirectionsCar = ""; + public const string DirectionsCarFilled = ""; + public const string DirectionsOff = ""; + public const string DirectionsRailway = ""; + public const string DirectionsRailwayFilled = ""; + public const string DirectionsRun = ""; + public const string DirectionsSubway = ""; + public const string DirectionsSubwayFilled = ""; + public const string DirectionsTransit = ""; + public const string DirectionsTransitFilled = ""; + public const string DirectionsWalk = ""; + public const string DirtyLens = ""; + public const string DisabledByDefault = ""; + public const string DisabledVisible = ""; + public const string DiscFull = ""; + public const string Discount = ""; + public const string DisplaySettings = ""; + public const string Dns = ""; + public const string DoDisturb = ""; + public const string DoDisturbAlt = ""; + public const string DoDisturbOff = ""; + public const string DoDisturbOn = ""; + public const string DoNotDisturb = ""; + public const string DoNotDisturbAlt = ""; + public const string DoNotDisturbOff = ""; + public const string DoNotDisturbOn = ""; + public const string DoNotDisturbOnTotalSilence = ""; + public const string DoNotStep = ""; + public const string DoNotTouch = ""; + public const string Dock = ""; + public const string DocumentScanner = ""; + public const string Domain = ""; + public const string DomainAdd = ""; + public const string DomainDisabled = ""; + public const string DomainVerification = ""; + public const string Done = ""; + public const string DoneAll = ""; + public const string DoneOutline = ""; + public const string DonutLarge = ""; + public const string DonutSmall = ""; + public const string DoorBack = ""; + public const string DoorFront = ""; + public const string DoorSliding = ""; + public const string Doorbell = ""; + public const string DoubleArrow = ""; + public const string DownhillSkiing = ""; + public const string Download = ""; + public const string DownloadDone = ""; + public const string DownloadForOffline = ""; + public const string Downloading = ""; + public const string Drafts = ""; + public const string DragHandle = ""; + public const string DragIndicator = ""; + public const string Draw = ""; + public const string DriveEta = ""; + public const string DriveFileMove = ""; + public const string DriveFileMoveRtl = ""; + public const string DriveFileRenameOutline = ""; + public const string DriveFolderUpload = ""; + public const string Dry = ""; + public const string DryCleaning = ""; + public const string Duo = ""; + public const string Dvr = ""; + public const string DynamicFeed = ""; + public const string DynamicForm = ""; + public const string EMobiledata = ""; + public const string Earbuds = ""; + public const string EarbudsBattery = ""; + public const string East = ""; + public const string EdgesensorHigh = ""; + public const string EdgesensorLow = ""; + public const string Edit = ""; + public const string EditAttributes = ""; + public const string EditCalendar = ""; + public const string EditLocation = ""; + public const string EditLocationAlt = ""; + public const string EditNote = ""; + public const string EditNotifications = ""; + public const string EditOff = ""; + public const string EditRoad = ""; + public const string Egg = ""; + public const string EggAlt = ""; + public const string Eject = ""; + public const string Elderly = ""; + public const string ElderlyWoman = ""; + public const string ElectricBike = ""; + public const string ElectricCar = ""; + public const string ElectricMoped = ""; + public const string ElectricRickshaw = ""; + public const string ElectricScooter = ""; + public const string ElectricalServices = ""; + public const string Elevator = ""; + public const string Email = ""; + public const string Emergency = ""; + public const string EmergencyRecording = ""; + public const string EmergencyShare = ""; + public const string EmojiEmotions = ""; + public const string EmojiEvents = ""; + public const string EmojiFoodBeverage = ""; + public const string EmojiNature = ""; + public const string EmojiObjects = ""; + public const string EmojiPeople = ""; + public const string EmojiSymbols = ""; + public const string EmojiTransportation = ""; + public const string Engineering = ""; + public const string EnhancedEncryption = ""; + public const string Equalizer = ""; + public const string Error = ""; + public const string ErrorOutline = ""; + public const string Escalator = ""; + public const string EscalatorWarning = ""; + public const string Euro = ""; + public const string EuroSymbol = ""; + public const string EvStation = ""; + public const string Event = ""; + public const string EventAvailable = ""; + public const string EventBusy = ""; + public const string EventNote = ""; + public const string EventRepeat = ""; + public const string EventSeat = ""; + public const string ExitToApp = ""; + public const string Expand = ""; + public const string ExpandCircleDown = ""; + public const string ExpandLess = ""; + public const string ExpandMore = ""; + public const string Explicit = ""; + public const string Explore = ""; + public const string ExploreOff = ""; + public const string Exposure = ""; + public const string ExposureNeg1 = ""; + public const string ExposureNeg2 = ""; + public const string ExposurePlus1 = ""; + public const string ExposurePlus2 = ""; + public const string ExposureZero = ""; + public const string Extension = ""; + public const string ExtensionOff = ""; + public const string Face = ""; + public const string FaceRetouchingNatural = ""; + public const string FaceRetouchingOff = ""; + public const string FactCheck = ""; + public const string Factory = ""; + public const string FamilyRestroom = ""; + public const string FastForward = ""; + public const string FastRewind = ""; + public const string Fastfood = ""; + public const string Favorite = ""; + public const string FavoriteBorder = ""; + public const string Fax = ""; + public const string FeaturedPlayList = ""; + public const string FeaturedVideo = ""; + public const string Feed = ""; + public const string Feedback = ""; + public const string Female = ""; + public const string Fence = ""; + public const string Festival = ""; + public const string FiberDvr = ""; + public const string FiberManualRecord = ""; + public const string FiberNew = ""; + public const string FiberPin = ""; + public const string FiberSmartRecord = ""; + public const string FileCopy = ""; + public const string FileDownload = ""; + public const string FileDownloadDone = ""; + public const string FileDownloadOff = ""; + public const string FileOpen = ""; + public const string FilePresent = ""; + public const string FileUpload = ""; + public const string Filter = ""; + public const string Filter1 = ""; + public const string Filter2 = ""; + public const string Filter3 = ""; + public const string Filter4 = ""; + public const string Filter5 = ""; + public const string Filter6 = ""; + public const string Filter7 = ""; + public const string Filter8 = ""; + public const string Filter9 = ""; + public const string Filter9Plus = ""; + public const string FilterAlt = ""; + public const string FilterAltOff = ""; + public const string FilterBAndW = ""; + public const string FilterCenterFocus = ""; + public const string FilterDrama = ""; + public const string FilterFrames = ""; + public const string FilterHdr = ""; + public const string FilterList = ""; + public const string FilterListOff = ""; + public const string FilterNone = ""; + public const string FilterTiltShift = ""; + public const string FilterVintage = ""; + public const string FindInPage = ""; + public const string FindReplace = ""; + public const string Fingerprint = ""; + public const string FireExtinguisher = ""; + public const string Fireplace = ""; + public const string FirstPage = ""; + public const string FitScreen = ""; + public const string Fitbit = ""; + public const string FitnessCenter = ""; + public const string Flag = ""; + public const string FlagCircle = ""; + public const string Flaky = ""; + public const string Flare = ""; + public const string FlashAuto = ""; + public const string FlashOff = ""; + public const string FlashOn = ""; + public const string FlashlightOff = ""; + public const string FlashlightOn = ""; + public const string Flatware = ""; + public const string Flight = ""; + public const string FlightClass = ""; + public const string FlightLand = ""; + public const string FlightTakeoff = ""; + public const string Flip = ""; + public const string FlipCameraAndroid = ""; + public const string FlipCameraIos = ""; + public const string FlipToBack = ""; + public const string FlipToFront = ""; + public const string Flood = ""; + public const string Flourescent = ""; + public const string FlutterDash = ""; + public const string FmdBad = ""; + public const string FmdGood = ""; + public const string Folder = ""; + public const string FolderCopy = ""; + public const string FolderDelete = ""; + public const string FolderOff = ""; + public const string FolderOpen = ""; + public const string FolderShared = ""; + public const string FolderSpecial = ""; + public const string FolderZip = ""; + public const string FollowTheSigns = ""; + public const string FontDownload = ""; + public const string FontDownloadOff = ""; + public const string FoodBank = ""; + public const string Forest = ""; + public const string ForkLeft = ""; + public const string ForkRight = ""; + public const string FormatAlignCenter = ""; + public const string FormatAlignJustify = ""; + public const string FormatAlignLeft = ""; + public const string FormatAlignRight = ""; + public const string FormatBold = ""; + public const string FormatClear = ""; + public const string FormatColorFill = ""; + public const string FormatColorReset = ""; + public const string FormatColorText = ""; + public const string FormatIndentDecrease = ""; + public const string FormatIndentIncrease = ""; + public const string FormatItalic = ""; + public const string FormatLineSpacing = ""; + public const string FormatListBulleted = ""; + public const string FormatListNumbered = ""; + public const string FormatListNumberedRtl = ""; + public const string FormatOverline = ""; + public const string FormatPaint = ""; + public const string FormatQuote = ""; + public const string FormatShapes = ""; + public const string FormatSize = ""; + public const string FormatStrikethrough = ""; + public const string FormatTextdirectionLToR = ""; + public const string FormatTextdirectionRToL = ""; + public const string FormatUnderlined = ""; + public const string Fort = ""; + public const string Forum = ""; + public const string Forward = ""; + public const string Forward10 = ""; + public const string Forward30 = ""; + public const string Forward5 = ""; + public const string ForwardToInbox = ""; + public const string Foundation = ""; + public const string FreeBreakfast = ""; + public const string FreeCancellation = ""; + public const string FrontHand = ""; + public const string Fullscreen = ""; + public const string FullscreenExit = ""; + public const string Functions = ""; + public const string GMobiledata = ""; + public const string GTranslate = ""; + public const string Gamepad = ""; + public const string Games = ""; + public const string Garage = ""; + public const string Gavel = ""; + public const string GeneratingTokens = ""; + public const string Gesture = ""; + public const string GetApp = ""; + public const string Gif = ""; + public const string GifBox = ""; + public const string Girl = ""; + public const string Gite = ""; + public const string GolfCourse = ""; + public const string GppBad = ""; + public const string GppGood = ""; + public const string GppMaybe = ""; + public const string GpsFixed = ""; + public const string GpsNotFixed = ""; + public const string GpsOff = ""; + public const string Grade = ""; + public const string Gradient = ""; + public const string Grading = ""; + public const string Grain = ""; + public const string GraphicEq = ""; + public const string Grass = ""; + public const string Grid3x3 = ""; + public const string Grid4x4 = ""; + public const string GridGoldenratio = ""; + public const string GridOff = ""; + public const string GridOn = ""; + public const string GridView = ""; + public const string Group = ""; + public const string GroupAdd = ""; + public const string GroupOff = ""; + public const string GroupRemove = ""; + public const string GroupWork = ""; + public const string Groups = ""; + public const string HMobiledata = ""; + public const string HPlusMobiledata = ""; + public const string Hail = ""; + public const string Handshake = ""; + public const string Handyman = ""; + public const string Hardware = ""; + public const string Hd = ""; + public const string HdrAuto = ""; + public const string HdrAutoSelect = ""; + public const string HdrEnhancedSelect = ""; + public const string HdrOff = ""; + public const string HdrOffSelect = ""; + public const string HdrOn = ""; + public const string HdrOnSelect = ""; + public const string HdrPlus = ""; + public const string HdrStrong = ""; + public const string HdrWeak = ""; + public const string Headphones = ""; + public const string HeadphonesBattery = ""; + public const string Headset = ""; + public const string HeadsetMic = ""; + public const string HeadsetOff = ""; + public const string Healing = ""; + public const string HealthAndSafety = ""; + public const string Hearing = ""; + public const string HearingDisabled = ""; + public const string HeartBroken = ""; + public const string Height = ""; + public const string Help = ""; + public const string HelpCenter = ""; + public const string HelpOutline = ""; + public const string Hevc = ""; + public const string Hexagon = ""; + public const string HideImage = ""; + public const string HideSource = ""; + public const string HighQuality = ""; + public const string Highlight = ""; + public const string HighlightAlt = ""; + public const string HighlightOff = ""; + public const string Hiking = ""; + public const string History = ""; + public const string HistoryEdu = ""; + public const string HistoryToggleOff = ""; + public const string Hive = ""; + public const string Hls = ""; + public const string HlsOff = ""; + public const string HolidayVillage = ""; + public const string Home = ""; + public const string HomeMax = ""; + public const string HomeMini = ""; + public const string HomeRepairService = ""; + public const string HomeWork = ""; + public const string HorizontalDistribute = ""; + public const string HorizontalRule = ""; + public const string HorizontalSplit = ""; + public const string HotTub = ""; + public const string Hotel = ""; + public const string HotelClass = ""; + public const string HourglassBottom = ""; + public const string HourglassDisabled = ""; + public const string HourglassEmpty = ""; + public const string HourglassFull = ""; + public const string HourglassTop = ""; + public const string House = ""; + public const string HouseSiding = ""; + public const string Houseboat = ""; + public const string HowToReg = ""; + public const string HowToVote = ""; + public const string Html = ""; + public const string Http = ""; + public const string Https = ""; + public const string Hub = ""; + public const string Hvac = ""; + public const string IceSkating = ""; + public const string Icecream = ""; + public const string Image = ""; + public const string ImageAspectRatio = ""; + public const string ImageNotSupported = ""; + public const string ImageSearch = ""; + public const string ImagesearchRoller = ""; + public const string ImportContacts = ""; + public const string ImportExport = ""; + public const string ImportantDevices = ""; + public const string Inbox = ""; + public const string IncompleteCircle = ""; + public const string IndeterminateCheckBox = ""; + public const string Info = ""; + public const string Input = ""; + public const string InsertChart = ""; + public const string InsertChartOutlined = ""; + public const string InsertComment = ""; + public const string InsertDriveFile = ""; + public const string InsertEmoticon = ""; + public const string InsertInvitation = ""; + public const string InsertLink = ""; + public const string InsertPageBreak = ""; + public const string InsertPhoto = ""; + public const string Insights = ""; + public const string InstallDesktop = ""; + public const string InstallMobile = ""; + public const string IntegrationInstructions = ""; + public const string Interests = ""; + public const string InterpreterMode = ""; + public const string Inventory = ""; + public const string Inventory2 = ""; + public const string InvertColors = ""; + public const string InvertColorsOff = ""; + public const string IosShare = ""; + public const string Iron = ""; + public const string Iso = ""; + public const string Javascript = ""; + public const string JoinFull = ""; + public const string JoinInner = ""; + public const string JoinLeft = ""; + public const string JoinRight = ""; + public const string Kayaking = ""; + public const string KebabDining = ""; + public const string Key = ""; + public const string KeyOff = ""; + public const string Keyboard = ""; + public const string KeyboardAlt = ""; + public const string KeyboardArrowDown = ""; + public const string KeyboardArrowLeft = ""; + public const string KeyboardArrowRight = ""; + public const string KeyboardArrowUp = ""; + public const string KeyboardBackspace = ""; + public const string KeyboardCapslock = ""; + public const string KeyboardCommandKey = ""; + public const string KeyboardControlKey = ""; + public const string KeyboardDoubleArrowDown = ""; + public const string KeyboardDoubleArrowLeft = ""; + public const string KeyboardDoubleArrowRight = ""; + public const string KeyboardDoubleArrowUp = ""; + public const string KeyboardHide = ""; + public const string KeyboardOptionKey = ""; + public const string KeyboardReturn = ""; + public const string KeyboardTab = ""; + public const string KeyboardVoice = ""; + public const string KingBed = ""; + public const string Kitchen = ""; + public const string Kitesurfing = ""; + public const string Label = ""; + public const string LabelImportant = ""; + public const string LabelOff = ""; + public const string Lan = ""; + public const string Landscape = ""; + public const string Landslide = ""; + public const string Language = ""; + public const string Laptop = ""; + public const string LaptopChromebook = ""; + public const string LaptopMac = ""; + public const string LaptopWindows = ""; + public const string LastPage = ""; + public const string Launch = ""; + public const string Layers = ""; + public const string LayersClear = ""; + public const string Leaderboard = ""; + public const string LeakAdd = ""; + public const string LeakRemove = ""; + public const string LegendToggle = ""; + public const string Lens = ""; + public const string LensBlur = ""; + public const string LibraryAdd = ""; + public const string LibraryAddCheck = ""; + public const string LibraryBooks = ""; + public const string LibraryMusic = ""; + public const string Light = ""; + public const string LightMode = ""; + public const string Lightbulb = ""; + public const string LightbulbCircle = ""; + public const string LineAxis = ""; + public const string LineStyle = ""; + public const string LineWeight = ""; + public const string LinearScale = ""; + public const string Link = ""; + public const string LinkOff = ""; + public const string LinkedCamera = ""; + public const string Liquor = ""; + public const string List = ""; + public const string ListAlt = ""; + public const string LiveHelp = ""; + public const string LiveTv = ""; + public const string Living = ""; + public const string LocalActivity = ""; + public const string LocalAirport = ""; + public const string LocalAtm = ""; + public const string LocalBar = ""; + public const string LocalCafe = ""; + public const string LocalCarWash = ""; + public const string LocalConvenienceStore = ""; + public const string LocalDining = ""; + public const string LocalDrink = ""; + public const string LocalFireDepartment = ""; + public const string LocalFlorist = ""; + public const string LocalGasStation = ""; + public const string LocalGroceryStore = ""; + public const string LocalHospital = ""; + public const string LocalHotel = ""; + public const string LocalLaundryService = ""; + public const string LocalLibrary = ""; + public const string LocalMall = ""; + public const string LocalMovies = ""; + public const string LocalOffer = ""; + public const string LocalParking = ""; + public const string LocalPharmacy = ""; + public const string LocalPhone = ""; + public const string LocalPizza = ""; + public const string LocalPlay = ""; + public const string LocalPolice = ""; + public const string LocalPostOffice = ""; + public const string LocalPrintshop = ""; + public const string LocalSee = ""; + public const string LocalShipping = ""; + public const string LocalTaxi = ""; + public const string LocationCity = ""; + public const string LocationDisabled = ""; + public const string LocationOff = ""; + public const string LocationOn = ""; + public const string LocationSearching = ""; + public const string Lock = ""; + public const string LockClock = ""; + public const string LockOpen = ""; + public const string LockReset = ""; + public const string Login = ""; + public const string LogoDev = ""; + public const string Logout = ""; + public const string Looks = ""; + public const string Looks3 = ""; + public const string Looks4 = ""; + public const string Looks5 = ""; + public const string Looks6 = ""; + public const string LooksOne = ""; + public const string LooksTwo = ""; + public const string Loop = ""; + public const string Loupe = ""; + public const string LowPriority = ""; + public const string Loyalty = ""; + public const string LteMobiledata = ""; + public const string LtePlusMobiledata = ""; + public const string Luggage = ""; + public const string LunchDining = ""; + public const string Mail = ""; + public const string MailOutline = ""; + public const string Male = ""; + public const string Man = ""; + public const string ManageAccounts = ""; + public const string ManageHistory = ""; + public const string ManageSearch = ""; + public const string Map = ""; + public const string MapsHomeWork = ""; + public const string MapsUgc = ""; + public const string Margin = ""; + public const string MarkAsUnread = ""; + public const string MarkChatRead = ""; + public const string MarkChatUnread = ""; + public const string MarkEmailRead = ""; + public const string MarkEmailUnread = ""; + public const string MarkUnreadChatAlt = ""; + public const string Markunread = ""; + public const string MarkunreadMailbox = ""; + public const string Masks = ""; + public const string Maximize = ""; + public const string MediaBluetoothOff = ""; + public const string MediaBluetoothOn = ""; + public const string Mediation = ""; + public const string MedicalInformation = ""; + public const string MedicalServices = ""; + public const string Medication = ""; + public const string MedicationLiquid = ""; + public const string MeetingRoom = ""; + public const string Memory = ""; + public const string Menu = ""; + public const string MenuBook = ""; + public const string MenuOpen = ""; + public const string Merge = ""; + public const string MergeType = ""; + public const string Message = ""; + public const string Mic = ""; + public const string MicExternalOff = ""; + public const string MicExternalOn = ""; + public const string MicNone = ""; + public const string MicOff = ""; + public const string Microwave = ""; + public const string MilitaryTech = ""; + public const string Minimize = ""; + public const string MinorCrash = ""; + public const string MiscellaneousServices = ""; + public const string MissedVideoCall = ""; + public const string Mms = ""; + public const string MobileFriendly = ""; + public const string MobileOff = ""; + public const string MobileScreenShare = ""; + public const string MobiledataOff = ""; + public const string Mode = ""; + public const string ModeComment = ""; + public const string ModeEdit = ""; + public const string ModeEditOutline = ""; + public const string ModeNight = ""; + public const string ModeOfTravel = ""; + public const string ModeStandby = ""; + public const string ModelTraining = ""; + public const string MonetizationOn = ""; + public const string Money = ""; + public const string MoneyOff = ""; + public const string MoneyOffCsred = ""; + public const string Monitor = ""; + public const string MonitorHeart = ""; + public const string MonitorWeight = ""; + public const string MonochromePhotos = ""; + public const string Mood = ""; + public const string MoodBad = ""; + public const string Moped = ""; + public const string More = ""; + public const string MoreHoriz = ""; + public const string MoreTime = ""; + public const string MoreVert = ""; + public const string Mosque = ""; + public const string MotionPhotosAuto = ""; + public const string MotionPhotosOff = ""; + public const string MotionPhotosOn = ""; + public const string MotionPhotosPause = ""; + public const string MotionPhotosPaused = ""; + public const string Mouse = ""; + public const string MoveDown = ""; + public const string MoveToInbox = ""; + public const string MoveUp = ""; + public const string Movie = ""; + public const string MovieCreation = ""; + public const string MovieFilter = ""; + public const string Moving = ""; + public const string Mp = ""; + public const string MultilineChart = ""; + public const string MultipleStop = ""; + public const string Museum = ""; + public const string MusicNote = ""; + public const string MusicOff = ""; + public const string MusicVideo = ""; + public const string MyLocation = ""; + public const string Nat = ""; + public const string Nature = ""; + public const string NaturePeople = ""; + public const string NavigateBefore = ""; + public const string NavigateNext = ""; + public const string Navigation = ""; + public const string NearMe = ""; + public const string NearMeDisabled = ""; + public const string NearbyError = ""; + public const string NearbyOff = ""; + public const string NetworkCell = ""; + public const string NetworkCheck = ""; + public const string NetworkLocked = ""; + public const string NetworkPing = ""; + public const string NetworkWifi = ""; + public const string NetworkWifi1Bar = ""; + public const string NetworkWifi2Bar = ""; + public const string NetworkWifi3Bar = ""; + public const string NewLabel = ""; + public const string NewReleases = ""; + public const string Newspaper = ""; + public const string NextPlan = ""; + public const string NextWeek = ""; + public const string Nfc = ""; + public const string NightShelter = ""; + public const string Nightlife = ""; + public const string Nightlight = ""; + public const string NightlightRound = ""; + public const string NightsStay = ""; + public const string NoAccounts = ""; + public const string NoBackpack = ""; + public const string NoCell = ""; + public const string NoCrash = ""; + public const string NoDrinks = ""; + public const string NoEncryption = ""; + public const string NoEncryptionGmailerrorred = ""; + public const string NoFlash = ""; + public const string NoFood = ""; + public const string NoLuggage = ""; + public const string NoMeals = ""; + public const string NoMeetingRoom = ""; + public const string NoPhotography = ""; + public const string NoSim = ""; + public const string NoStroller = ""; + public const string NoTransfer = ""; + public const string NoiseAware = ""; + public const string NoiseControlOff = ""; + public const string NordicWalking = ""; + public const string North = ""; + public const string NorthEast = ""; + public const string NorthWest = ""; + public const string NotAccessible = ""; + public const string NotInterested = ""; + public const string NotListedLocation = ""; + public const string NotStarted = ""; + public const string Note = ""; + public const string NoteAdd = ""; + public const string NoteAlt = ""; + public const string Notes = ""; + public const string NotificationAdd = ""; + public const string NotificationImportant = ""; + public const string Notifications = ""; + public const string NotificationsActive = ""; + public const string NotificationsNone = ""; + public const string NotificationsOff = ""; + public const string NotificationsPaused = ""; + public const string Numbers = ""; + public const string OfflineBolt = ""; + public const string OfflinePin = ""; + public const string OfflineShare = ""; + public const string OnDeviceTraining = ""; + public const string OndemandVideo = ""; + public const string OnlinePrediction = ""; + public const string Opacity = ""; + public const string OpenInBrowser = ""; + public const string OpenInFull = ""; + public const string OpenInNew = ""; + public const string OpenInNewOff = ""; + public const string OpenWith = ""; + public const string OtherHouses = ""; + public const string Outbound = ""; + public const string Outbox = ""; + public const string OutdoorGrill = ""; + public const string Outlet = ""; + public const string OutlinedFlag = ""; + public const string Output = ""; + public const string Padding = ""; + public const string Pages = ""; + public const string Pageview = ""; + public const string Paid = ""; + public const string Palette = ""; + public const string PanTool = ""; + public const string PanToolAlt = ""; + public const string Panorama = ""; + public const string PanoramaFishEye = ""; + public const string PanoramaHorizontal = ""; + public const string PanoramaHorizontalSelect = ""; + public const string PanoramaPhotosphere = ""; + public const string PanoramaPhotosphereSelect = ""; + public const string PanoramaVertical = ""; + public const string PanoramaVerticalSelect = ""; + public const string PanoramaWideAngle = ""; + public const string PanoramaWideAngleSelect = ""; + public const string Paragliding = ""; + public const string Park = ""; + public const string PartyMode = ""; + public const string Password = ""; + public const string Pattern = ""; + public const string Pause = ""; + public const string PauseCircle = ""; + public const string PauseCircleFilled = ""; + public const string PauseCircleOutline = ""; + public const string PausePresentation = ""; + public const string Payment = ""; + public const string Payments = ""; + public const string PedalBike = ""; + public const string Pending = ""; + public const string PendingActions = ""; + public const string Pentagon = ""; + public const string People = ""; + public const string PeopleAlt = ""; + public const string PeopleOutline = ""; + public const string Percent = ""; + public const string PermCameraMic = ""; + public const string PermContactCalendar = ""; + public const string PermDataSetting = ""; + public const string PermDeviceInformation = ""; + public const string PermIdentity = ""; + public const string PermMedia = ""; + public const string PermPhoneMsg = ""; + public const string PermScanWifi = ""; + public const string Person = ""; + public const string PersonAdd = ""; + public const string PersonAddAlt = ""; + public const string PersonAddAlt1 = ""; + public const string PersonAddDisabled = ""; + public const string PersonOff = ""; + public const string PersonOutline = ""; + public const string PersonPin = ""; + public const string PersonPinCircle = ""; + public const string PersonRemove = ""; + public const string PersonRemoveAlt1 = ""; + public const string PersonSearch = ""; + public const string PersonalInjury = ""; + public const string PersonalVideo = ""; + public const string PestControl = ""; + public const string PestControlRodent = ""; + public const string Pets = ""; + public const string Phishing = ""; + public const string Phone = ""; + public const string PhoneAndroid = ""; + public const string PhoneBluetoothSpeaker = ""; + public const string PhoneCallback = ""; + public const string PhoneDisabled = ""; + public const string PhoneEnabled = ""; + public const string PhoneForwarded = ""; + public const string PhoneInTalk = ""; + public const string PhoneIphone = ""; + public const string PhoneLocked = ""; + public const string PhoneMissed = ""; + public const string PhonePaused = ""; + public const string Phonelink = ""; + public const string PhonelinkErase = ""; + public const string PhonelinkLock = ""; + public const string PhonelinkOff = ""; + public const string PhonelinkRing = ""; + public const string PhonelinkSetup = ""; + public const string Photo = ""; + public const string PhotoAlbum = ""; + public const string PhotoCamera = ""; + public const string PhotoCameraBack = ""; + public const string PhotoCameraFront = ""; + public const string PhotoFilter = ""; + public const string PhotoLibrary = ""; + public const string PhotoSizeSelectActual = ""; + public const string PhotoSizeSelectLarge = ""; + public const string PhotoSizeSelectSmall = ""; + public const string Php = ""; + public const string Piano = ""; + public const string PianoOff = ""; + public const string PictureAsPdf = ""; + public const string PictureInPicture = ""; + public const string PictureInPictureAlt = ""; + public const string PieChart = ""; + public const string PieChartOutline = ""; + public const string Pin = ""; + public const string PinDrop = ""; + public const string PinEnd = ""; + public const string PinInvoke = ""; + public const string Pinch = ""; + public const string PivotTableChart = ""; + public const string Pix = ""; + public const string Place = ""; + public const string Plagiarism = ""; + public const string PlayArrow = ""; + public const string PlayCircle = ""; + public const string PlayCircleFilled = ""; + public const string PlayCircleOutline = ""; + public const string PlayDisabled = ""; + public const string PlayForWork = ""; + public const string PlayLesson = ""; + public const string PlaylistAdd = ""; + public const string PlaylistAddCheck = ""; + public const string PlaylistAddCheckCircle = ""; + public const string PlaylistAddCircle = ""; + public const string PlaylistPlay = ""; + public const string PlaylistRemove = ""; + public const string Plumbing = ""; + public const string PlusOne = ""; + public const string Podcasts = ""; + public const string PointOfSale = ""; + public const string Policy = ""; + public const string Poll = ""; + public const string Polyline = ""; + public const string Polymer = ""; + public const string Pool = ""; + public const string PortableWifiOff = ""; + public const string Portrait = ""; + public const string PostAdd = ""; + public const string Power = ""; + public const string PowerInput = ""; + public const string PowerOff = ""; + public const string PowerSettingsNew = ""; + public const string PrecisionManufacturing = ""; + public const string PregnantWoman = ""; + public const string PresentToAll = ""; + public const string Preview = ""; + public const string PriceChange = ""; + public const string PriceCheck = ""; + public const string Print = ""; + public const string PrintDisabled = ""; + public const string PriorityHigh = ""; + public const string PrivacyTip = ""; + public const string PrivateConnectivity = ""; + public const string ProductionQuantityLimits = ""; + public const string Psychology = ""; + public const string Public = ""; + public const string PublicOff = ""; + public const string Publish = ""; + public const string PublishedWithChanges = ""; + public const string PunchClock = ""; + public const string PushPin = ""; + public const string QrCode = ""; + public const string QrCode2 = ""; + public const string QrCodeScanner = ""; + public const string QueryBuilder = ""; + public const string QueryStats = ""; + public const string QuestionAnswer = ""; + public const string QuestionMark = ""; + public const string Queue = ""; + public const string QueueMusic = ""; + public const string QueuePlayNext = ""; + public const string Quickreply = ""; + public const string Quiz = ""; + public const string RMobiledata = ""; + public const string Radar = ""; + public const string Radio = ""; + public const string RadioButtonChecked = ""; + public const string RadioButtonUnchecked = ""; + public const string RailwayAlert = ""; + public const string RamenDining = ""; + public const string RampLeft = ""; + public const string RampRight = ""; + public const string RateReview = ""; + public const string RawOff = ""; + public const string RawOn = ""; + public const string ReadMore = ""; + public const string RealEstateAgent = ""; + public const string Receipt = ""; + public const string ReceiptLong = ""; + public const string RecentActors = ""; + public const string Recommend = ""; + public const string RecordVoiceOver = ""; + public const string Rectangle = ""; + public const string Recycling = ""; + public const string Redeem = ""; + public const string Redo = ""; + public const string ReduceCapacity = ""; + public const string Refresh = ""; + public const string RememberMe = ""; + public const string Remove = ""; + public const string RemoveCircle = ""; + public const string RemoveCircleOutline = ""; + public const string RemoveDone = ""; + public const string RemoveFromQueue = ""; + public const string RemoveModerator = ""; + public const string RemoveRedEye = ""; + public const string RemoveRoad = ""; + public const string RemoveShoppingCart = ""; + public const string Reorder = ""; + public const string Repeat = ""; + public const string RepeatOn = ""; + public const string RepeatOne = ""; + public const string RepeatOneOn = ""; + public const string Replay = ""; + public const string Replay10 = ""; + public const string Replay30 = ""; + public const string Replay5 = ""; + public const string ReplayCircleFilled = ""; + public const string Reply = ""; + public const string ReplyAll = ""; + public const string Report = ""; + public const string ReportGmailerrorred = ""; + public const string ReportOff = ""; + public const string ReportProblem = ""; + public const string RequestPage = ""; + public const string RequestQuote = ""; + public const string ResetTv = ""; + public const string RestartAlt = ""; + public const string Restaurant = ""; + public const string RestaurantMenu = ""; + public const string Restore = ""; + public const string RestoreFromTrash = ""; + public const string RestorePage = ""; + public const string Reviews = ""; + public const string RiceBowl = ""; + public const string RingVolume = ""; + public const string Rocket = ""; + public const string RocketLaunch = ""; + public const string RollerSkating = ""; + public const string Roofing = ""; + public const string Room = ""; + public const string RoomPreferences = ""; + public const string RoomService = ""; + public const string Rotate90DegreesCcw = ""; + public const string Rotate90DegreesCw = ""; + public const string RotateLeft = ""; + public const string RotateRight = ""; + public const string RoundaboutLeft = ""; + public const string RoundaboutRight = ""; + public const string RoundedCorner = ""; + public const string Route = ""; + public const string Router = ""; + public const string Rowing = ""; + public const string RssFeed = ""; + public const string Rsvp = ""; + public const string Rtt = ""; + public const string Rule = ""; + public const string RuleFolder = ""; + public const string RunCircle = ""; + public const string RunningWithErrors = ""; + public const string RvHookup = ""; + public const string SafetyCheck = ""; + public const string SafetyDivider = ""; + public const string Sailing = ""; + public const string Sanitizer = ""; + public const string Satellite = ""; + public const string SatelliteAlt = ""; + public const string Save = ""; + public const string SaveAlt = ""; + public const string SaveAs = ""; + public const string SavedSearch = ""; + public const string Savings = ""; + public const string Scale = ""; + public const string Scanner = ""; + public const string ScatterPlot = ""; + public const string Schedule = ""; + public const string ScheduleSend = ""; + public const string Schema = ""; + public const string School = ""; + public const string Science = ""; + public const string Score = ""; + public const string Scoreboard = ""; + public const string ScreenLockLandscape = ""; + public const string ScreenLockPortrait = ""; + public const string ScreenLockRotation = ""; + public const string ScreenRotation = ""; + public const string ScreenRotationAlt = ""; + public const string ScreenSearchDesktop = ""; + public const string ScreenShare = ""; + public const string Screenshot = ""; + public const string ScubaDiving = ""; + public const string Sd = ""; + public const string SdCard = ""; + public const string SdCardAlert = ""; + public const string SdStorage = ""; + public const string Search = ""; + public const string SearchOff = ""; + public const string Security = ""; + public const string SecurityUpdate = ""; + public const string SecurityUpdateGood = ""; + public const string SecurityUpdateWarning = ""; + public const string Segment = ""; + public const string SelectAll = ""; + public const string SelfImprovement = ""; + public const string Sell = ""; + public const string Send = ""; + public const string SendAndArchive = ""; + public const string SendTimeExtension = ""; + public const string SendToMobile = ""; + public const string SensorDoor = ""; + public const string SensorWindow = ""; + public const string Sensors = ""; + public const string SensorsOff = ""; + public const string SentimentDissatisfied = ""; + public const string SentimentNeutral = ""; + public const string SentimentSatisfied = ""; + public const string SentimentSatisfiedAlt = ""; + public const string SentimentVeryDissatisfied = ""; + public const string SentimentVerySatisfied = ""; + public const string SetMeal = ""; + public const string Settings = ""; + public const string SettingsAccessibility = ""; + public const string SettingsApplications = ""; + public const string SettingsBackupRestore = ""; + public const string SettingsBluetooth = ""; + public const string SettingsBrightness = ""; + public const string SettingsCell = ""; + public const string SettingsEthernet = ""; + public const string SettingsInputAntenna = ""; + public const string SettingsInputComponent = ""; + public const string SettingsInputComposite = ""; + public const string SettingsInputHdmi = ""; + public const string SettingsInputSvideo = ""; + public const string SettingsOverscan = ""; + public const string SettingsPhone = ""; + public const string SettingsPower = ""; + public const string SettingsRemote = ""; + public const string SettingsSuggest = ""; + public const string SettingsSystemDaydream = ""; + public const string SettingsVoice = ""; + public const string SevereCold = ""; + public const string Share = ""; + public const string ShareLocation = ""; + public const string Shield = ""; + public const string ShieldMoon = ""; + public const string Shop = ""; + public const string Shop2 = ""; + public const string ShopTwo = ""; + public const string ShoppingBag = ""; + public const string ShoppingBasket = ""; + public const string ShoppingCart = ""; + public const string ShoppingCartCheckout = ""; + public const string ShortText = ""; + public const string Shortcut = ""; + public const string ShowChart = ""; + public const string Shower = ""; + public const string Shuffle = ""; + public const string ShuffleOn = ""; + public const string ShutterSpeed = ""; + public const string Sick = ""; + public const string SignLanguage = ""; + public const string SignalCellular0Bar = ""; + public const string SignalCellular4Bar = ""; + public const string SignalCellularAlt = ""; + public const string SignalCellularAlt1Bar = ""; + public const string SignalCellularAlt2Bar = ""; + public const string SignalCellularConnectedNoInternet0Bar = ""; + public const string SignalCellularConnectedNoInternet4Bar = ""; + public const string SignalCellularNoSim = ""; + public const string SignalCellularNodata = ""; + public const string SignalCellularNull = ""; + public const string SignalCellularOff = ""; + public const string SignalWifi0Bar = ""; + public const string SignalWifi4Bar = ""; + public const string SignalWifi4BarLock = ""; + public const string SignalWifiBad = ""; + public const string SignalWifiConnectedNoInternet4 = ""; + public const string SignalWifiOff = ""; + public const string SignalWifiStatusbar4Bar = ""; + public const string SignalWifiStatusbarConnectedNoInternet4 = ""; + public const string SignalWifiStatusbarNull = ""; + public const string Signpost = ""; + public const string SimCard = ""; + public const string SimCardAlert = ""; + public const string SimCardDownload = ""; + public const string SingleBed = ""; + public const string Sip = ""; + public const string Skateboarding = ""; + public const string SkipNext = ""; + public const string SkipPrevious = ""; + public const string Sledding = ""; + public const string Slideshow = ""; + public const string SlowMotionVideo = ""; + public const string SmartButton = ""; + public const string SmartDisplay = ""; + public const string SmartScreen = ""; + public const string SmartToy = ""; + public const string Smartphone = ""; + public const string SmokeFree = ""; + public const string SmokingRooms = ""; + public const string Sms = ""; + public const string SmsFailed = ""; + public const string SnippetFolder = ""; + public const string Snooze = ""; + public const string Snowboarding = ""; + public const string Snowmobile = ""; + public const string Snowshoeing = ""; + public const string Soap = ""; + public const string SocialDistance = ""; + public const string Sort = ""; + public const string SortByAlpha = ""; + public const string Sos = ""; + public const string SoupKitchen = ""; + public const string Source = ""; + public const string South = ""; + public const string SouthAmerica = ""; + public const string SouthEast = ""; + public const string SouthWest = ""; + public const string Spa = ""; + public const string SpaceBar = ""; + public const string SpaceDashboard = ""; + public const string SpatialAudio = ""; + public const string SpatialAudioOff = ""; + public const string SpatialTracking = ""; + public const string Speaker = ""; + public const string SpeakerGroup = ""; + public const string SpeakerNotes = ""; + public const string SpeakerNotesOff = ""; + public const string SpeakerPhone = ""; + public const string Speed = ""; + public const string Spellcheck = ""; + public const string Splitscreen = ""; + public const string Spoke = ""; + public const string Sports = ""; + public const string SportsBar = ""; + public const string SportsBaseball = ""; + public const string SportsBasketball = ""; + public const string SportsCricket = ""; + public const string SportsEsports = ""; + public const string SportsFootball = ""; + public const string SportsGolf = ""; + public const string SportsGymnastics = ""; + public const string SportsHandball = ""; + public const string SportsHockey = ""; + public const string SportsKabaddi = ""; + public const string SportsMartialArts = ""; + public const string SportsMma = ""; + public const string SportsMotorsports = ""; + public const string SportsRugby = ""; + public const string SportsScore = ""; + public const string SportsSoccer = ""; + public const string SportsTennis = ""; + public const string SportsVolleyball = ""; + public const string Square = ""; + public const string SquareFoot = ""; + public const string SsidChart = ""; + public const string StackedBarChart = ""; + public const string StackedLineChart = ""; + public const string Stadium = ""; + public const string Stairs = ""; + public const string Star = ""; + public const string StarBorder = ""; + public const string StarBorderPurple500 = ""; + public const string StarHalf = ""; + public const string StarOutline = ""; + public const string StarPurple500 = ""; + public const string StarRate = ""; + public const string Stars = ""; + public const string Start = ""; + public const string StayCurrentLandscape = ""; + public const string StayCurrentPortrait = ""; + public const string StayPrimaryLandscape = ""; + public const string StayPrimaryPortrait = ""; + public const string StickyNote2 = ""; + public const string Stop = ""; + public const string StopCircle = ""; + public const string StopScreenShare = ""; + public const string Storage = ""; + public const string Store = ""; + public const string StoreMallDirectory = ""; + public const string Storefront = ""; + public const string Storm = ""; + public const string Straight = ""; + public const string Straighten = ""; + public const string Stream = ""; + public const string Streetview = ""; + public const string StrikethroughS = ""; + public const string Stroller = ""; + public const string Style = ""; + public const string SubdirectoryArrowLeft = ""; + public const string SubdirectoryArrowRight = ""; + public const string Subject = ""; + public const string Subscript = ""; + public const string Subscriptions = ""; + public const string Subtitles = ""; + public const string SubtitlesOff = ""; + public const string Subway = ""; + public const string Summarize = ""; + public const string Superscript = ""; + public const string SupervisedUserCircle = ""; + public const string SupervisorAccount = ""; + public const string Support = ""; + public const string SupportAgent = ""; + public const string Surfing = ""; + public const string SurroundSound = ""; + public const string SwapCalls = ""; + public const string SwapHoriz = ""; + public const string SwapHorizontalCircle = ""; + public const string SwapVert = ""; + public const string SwapVerticalCircle = ""; + public const string Swipe = ""; + public const string SwipeDown = ""; + public const string SwipeDownAlt = ""; + public const string SwipeLeft = ""; + public const string SwipeLeftAlt = ""; + public const string SwipeRight = ""; + public const string SwipeRightAlt = ""; + public const string SwipeUp = ""; + public const string SwipeUpAlt = ""; + public const string SwipeVertical = ""; + public const string SwitchAccessShortcut = ""; + public const string SwitchAccessShortcutAdd = ""; + public const string SwitchAccount = ""; + public const string SwitchCamera = ""; + public const string SwitchLeft = ""; + public const string SwitchRight = ""; + public const string SwitchVideo = ""; + public const string Synagogue = ""; + public const string Sync = ""; + public const string SyncAlt = ""; + public const string SyncDisabled = ""; + public const string SyncLock = ""; + public const string SyncProblem = ""; + public const string SystemSecurityUpdate = ""; + public const string SystemSecurityUpdateGood = ""; + public const string SystemSecurityUpdateWarning = ""; + public const string SystemUpdate = ""; + public const string SystemUpdateAlt = ""; + public const string Tab = ""; + public const string TabUnselected = ""; + public const string TableBar = ""; + public const string TableChart = ""; + public const string TableRestaurant = ""; + public const string TableRows = ""; + public const string TableView = ""; + public const string Tablet = ""; + public const string TabletAndroid = ""; + public const string TabletMac = ""; + public const string Tag = ""; + public const string TagFaces = ""; + public const string TakeoutDining = ""; + public const string TapAndPlay = ""; + public const string Tapas = ""; + public const string Task = ""; + public const string TaskAlt = ""; + public const string TaxiAlert = ""; + public const string TempleBuddhist = ""; + public const string TempleHindu = ""; + public const string Terminal = ""; + public const string Terrain = ""; + public const string TextDecrease = ""; + public const string TextFields = ""; + public const string TextFormat = ""; + public const string TextIncrease = ""; + public const string TextRotateUp = ""; + public const string TextRotateVertical = ""; + public const string TextRotationAngledown = ""; + public const string TextRotationAngleup = ""; + public const string TextRotationDown = ""; + public const string TextRotationNone = ""; + public const string TextSnippet = ""; + public const string Textsms = ""; + public const string Texture = ""; + public const string TheaterComedy = ""; + public const string Theaters = ""; + public const string Thermostat = ""; + public const string ThermostatAuto = ""; + public const string ThumbDown = ""; + public const string ThumbDownAlt = ""; + public const string ThumbDownOffAlt = ""; + public const string ThumbUp = ""; + public const string ThumbUpAlt = ""; + public const string ThumbUpOffAlt = ""; + public const string ThumbsUpDown = ""; + public const string Thunderstorm = ""; + public const string TimeToLeave = ""; + public const string Timelapse = ""; + public const string Timeline = ""; + public const string Timer = ""; + public const string Timer10 = ""; + public const string Timer10Select = ""; + public const string Timer3 = ""; + public const string Timer3Select = ""; + public const string TimerOff = ""; + public const string TipsAndUpdates = ""; + public const string TireRepair = ""; + public const string Title = ""; + public const string Toc = ""; + public const string Today = ""; + public const string ToggleOff = ""; + public const string ToggleOn = ""; + public const string Token = ""; + public const string Toll = ""; + public const string Tonality = ""; + public const string Topic = ""; + public const string TouchApp = ""; + public const string Tour = ""; + public const string Toys = ""; + public const string TrackChanges = ""; + public const string Traffic = ""; + public const string Train = ""; + public const string Tram = ""; + public const string TransferWithinAStation = ""; + public const string Transform = ""; + public const string Transgender = ""; + public const string TransitEnterexit = ""; + public const string Translate = ""; + public const string TravelExplore = ""; + public const string TrendingDown = ""; + public const string TrendingFlat = ""; + public const string TrendingUp = ""; + public const string TripOrigin = ""; + public const string Try = ""; + public const string Tsunami = ""; + public const string Tty = ""; + public const string Tune = ""; + public const string Tungsten = ""; + public const string TurnLeft = ""; + public const string TurnRight = ""; + public const string TurnSharpLeft = ""; + public const string TurnSharpRight = ""; + public const string TurnSlightLeft = ""; + public const string TurnSlightRight = ""; + public const string TurnedIn = ""; + public const string TurnedInNot = ""; + public const string Tv = ""; + public const string TvOff = ""; + public const string TwoWheeler = ""; + public const string UTurnLeft = ""; + public const string UTurnRight = ""; + public const string Umbrella = ""; + public const string Unarchive = ""; + public const string Undo = ""; + public const string UnfoldLess = ""; + public const string UnfoldMore = ""; + public const string Unpublished = ""; + public const string Unsubscribe = ""; + public const string Upcoming = ""; + public const string Update = ""; + public const string UpdateDisabled = ""; + public const string Upgrade = ""; + public const string Upload = ""; + public const string UploadFile = ""; + public const string Usb = ""; + public const string UsbOff = ""; + public const string Vaccines = ""; + public const string VapeFree = ""; + public const string VapingRooms = ""; + public const string Verified = ""; + public const string VerifiedUser = ""; + public const string VerticalAlignBottom = ""; + public const string VerticalAlignCenter = ""; + public const string VerticalAlignTop = ""; + public const string VerticalDistribute = ""; + public const string VerticalSplit = ""; + public const string Vibration = ""; + public const string VideoCall = ""; + public const string VideoCameraBack = ""; + public const string VideoCameraFront = ""; + public const string VideoFile = ""; + public const string VideoLabel = ""; + public const string VideoLibrary = ""; + public const string VideoSettings = ""; + public const string VideoStable = ""; + public const string Videocam = ""; + public const string VideocamOff = ""; + public const string VideogameAsset = ""; + public const string VideogameAssetOff = ""; + public const string ViewAgenda = ""; + public const string ViewArray = ""; + public const string ViewCarousel = ""; + public const string ViewColumn = ""; + public const string ViewComfy = ""; + public const string ViewComfyAlt = ""; + public const string ViewCompact = ""; + public const string ViewCompactAlt = ""; + public const string ViewCozy = ""; + public const string ViewDay = ""; + public const string ViewHeadline = ""; + public const string ViewInAr = ""; + public const string ViewKanban = ""; + public const string ViewList = ""; + public const string ViewModule = ""; + public const string ViewQuilt = ""; + public const string ViewSidebar = ""; + public const string ViewStream = ""; + public const string ViewTimeline = ""; + public const string ViewWeek = ""; + public const string Vignette = ""; + public const string Villa = ""; + public const string Visibility = ""; + public const string VisibilityOff = ""; + public const string VoiceChat = ""; + public const string VoiceOverOff = ""; + public const string Voicemail = ""; + public const string Volcano = ""; + public const string VolumeDown = ""; + public const string VolumeMute = ""; + public const string VolumeOff = ""; + public const string VolumeUp = ""; + public const string VolunteerActivism = ""; + public const string VpnKey = ""; + public const string VpnKeyOff = ""; + public const string VpnLock = ""; + public const string Vrpano = ""; + public const string Wallpaper = ""; + public const string Warehouse = ""; + public const string Warning = ""; + public const string WarningAmber = ""; + public const string Wash = ""; + public const string Watch = ""; + public const string WatchLater = ""; + public const string WatchOff = ""; + public const string Water = ""; + public const string WaterDamage = ""; + public const string WaterDrop = ""; + public const string WaterfallChart = ""; + public const string Waves = ""; + public const string WavingHand = ""; + public const string WbAuto = ""; + public const string WbCloudy = ""; + public const string WbIncandescent = ""; + public const string WbIridescent = ""; + public const string WbShade = ""; + public const string WbSunny = ""; + public const string WbTwilight = ""; + public const string Wc = ""; + public const string Web = ""; + public const string WebAsset = ""; + public const string WebAssetOff = ""; + public const string Webhook = ""; + public const string Weekend = ""; + public const string West = ""; + public const string Whatsapp = ""; + public const string Whatshot = ""; + public const string WheelchairPickup = ""; + public const string WhereToVote = ""; + public const string Widgets = ""; + public const string Wifi = ""; + public const string Wifi1Bar = ""; + public const string Wifi2Bar = ""; + public const string WifiCalling = ""; + public const string WifiCalling3 = ""; + public const string WifiChannel = ""; + public const string WifiFind = ""; + public const string WifiLock = ""; + public const string WifiOff = ""; + public const string WifiPassword = ""; + public const string WifiProtectedSetup = ""; + public const string WifiTethering = ""; + public const string WifiTetheringError = ""; + public const string WifiTetheringOff = ""; + public const string Window = ""; + public const string WineBar = ""; + public const string Woman = ""; + public const string Work = ""; + public const string WorkOff = ""; + public const string WorkOutline = ""; + public const string WorkspacePremium = ""; + public const string Workspaces = ""; + public const string WrapText = ""; + public const string WrongLocation = ""; + public const string Wysiwyg = ""; + public const string Yard = ""; + public const string YoutubeSearchedFor = ""; + public const string ZoomIn = ""; + public const string ZoomInMap = ""; + public const string ZoomOut = ""; + public const string ZoomOutMap = ""; + } + } + } +} diff --git a/Icons/Material/Sharp.cs b/Icons/Material/Sharp.cs new file mode 100644 index 0000000..f6405c6 --- /dev/null +++ b/Icons/Material/Sharp.cs @@ -0,0 +1,2069 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Material + { + [ExcludeFromCodeCoverage] + public partial class Sharp + { + public const string _10k = ""; + public const string _10mp = ""; + public const string _11mp = ""; + public const string _123 = ""; + public const string _12mp = ""; + public const string _13mp = ""; + public const string _14mp = ""; + public const string _15mp = ""; + public const string _16mp = ""; + public const string _17mp = ""; + public const string _18mp = ""; + public const string _19mp = ""; + public const string _1k = ""; + public const string _1kPlus = ""; + public const string _1xMobiledata = ""; + public const string _20mp = ""; + public const string _21mp = ""; + public const string _22mp = ""; + public const string _23mp = ""; + public const string _24mp = ""; + public const string _2k = ""; + public const string _2kPlus = ""; + public const string _2mp = ""; + public const string _30fps = ""; + public const string _30fpsSelect = ""; + public const string _360 = ""; + public const string _3dRotation = ""; + public const string _3gMobiledata = ""; + public const string _3k = ""; + public const string _3kPlus = ""; + public const string _3mp = ""; + public const string _3p = ""; + public const string _4gMobiledata = ""; + public const string _4gPlusMobiledata = ""; + public const string _4k = ""; + public const string _4kPlus = ""; + public const string _4mp = ""; + public const string _5g = ""; + public const string _5k = ""; + public const string _5kPlus = ""; + public const string _5mp = ""; + public const string _60fps = ""; + public const string _60fpsSelect = ""; + public const string _6FtApart = ""; + public const string _6k = ""; + public const string _6kPlus = ""; + public const string _6mp = ""; + public const string _7k = ""; + public const string _7kPlus = ""; + public const string _7mp = ""; + public const string _8k = ""; + public const string _8kPlus = ""; + public const string _8mp = ""; + public const string _9k = ""; + public const string _9kPlus = ""; + public const string _9mp = ""; + public const string Abc = ""; + public const string AcUnit = ""; + public const string AccessAlarm = ""; + public const string AccessAlarms = ""; + public const string AccessTime = ""; + public const string AccessTimeFilled = ""; + public const string Accessibility = ""; + public const string AccessibilityNew = ""; + public const string Accessible = ""; + public const string AccessibleForward = ""; + public const string AccountBalance = ""; + public const string AccountBalanceWallet = ""; + public const string AccountBox = ""; + public const string AccountCircle = ""; + public const string AccountTree = ""; + public const string AdUnits = ""; + public const string Adb = ""; + public const string Add = ""; + public const string AddAPhoto = ""; + public const string AddAlarm = ""; + public const string AddAlert = ""; + public const string AddBox = ""; + public const string AddBusiness = ""; + public const string AddCard = ""; + public const string AddChart = ""; + public const string AddCircle = ""; + public const string AddCircleOutline = ""; + public const string AddComment = ""; + public const string AddIcCall = ""; + public const string AddLink = ""; + public const string AddLocation = ""; + public const string AddLocationAlt = ""; + public const string AddModerator = ""; + public const string AddPhotoAlternate = ""; + public const string AddReaction = ""; + public const string AddRoad = ""; + public const string AddShoppingCart = ""; + public const string AddTask = ""; + public const string AddToDrive = ""; + public const string AddToHomeScreen = ""; + public const string AddToPhotos = ""; + public const string AddToQueue = ""; + public const string Addchart = ""; + public const string AdfScanner = ""; + public const string Adjust = ""; + public const string AdminPanelSettings = ""; + public const string AdsClick = ""; + public const string Agriculture = ""; + public const string Air = ""; + public const string AirlineSeatFlat = ""; + public const string AirlineSeatFlatAngled = ""; + public const string AirlineSeatIndividualSuite = ""; + public const string AirlineSeatLegroomExtra = ""; + public const string AirlineSeatLegroomNormal = ""; + public const string AirlineSeatLegroomReduced = ""; + public const string AirlineSeatReclineExtra = ""; + public const string AirlineSeatReclineNormal = ""; + public const string AirlineStops = ""; + public const string Airlines = ""; + public const string AirplaneTicket = ""; + public const string AirplanemodeActive = ""; + public const string AirplanemodeInactive = ""; + public const string Airplay = ""; + public const string AirportShuttle = ""; + public const string Alarm = ""; + public const string AlarmAdd = ""; + public const string AlarmOff = ""; + public const string AlarmOn = ""; + public const string Album = ""; + public const string AlignHorizontalCenter = ""; + public const string AlignHorizontalLeft = ""; + public const string AlignHorizontalRight = ""; + public const string AlignVerticalBottom = ""; + public const string AlignVerticalCenter = ""; + public const string AlignVerticalTop = ""; + public const string AllInbox = ""; + public const string AllInclusive = ""; + public const string AllOut = ""; + public const string AltRoute = ""; + public const string AlternateEmail = ""; + public const string Analytics = ""; + public const string Anchor = ""; + public const string Android = ""; + public const string Animation = ""; + public const string Announcement = ""; + public const string Aod = ""; + public const string Apartment = ""; + public const string Api = ""; + public const string AppBlocking = ""; + public const string AppRegistration = ""; + public const string AppSettingsAlt = ""; + public const string AppShortcut = ""; + public const string Approval = ""; + public const string Apps = ""; + public const string AppsOutage = ""; + public const string Architecture = ""; + public const string Archive = ""; + public const string AreaChart = ""; + public const string ArrowBack = ""; + public const string ArrowBackIos = ""; + public const string ArrowBackIosNew = ""; + public const string ArrowCircleDown = ""; + public const string ArrowCircleLeft = ""; + public const string ArrowCircleRight = ""; + public const string ArrowCircleUp = ""; + public const string ArrowDownward = ""; + public const string ArrowDropDown = ""; + public const string ArrowDropDownCircle = ""; + public const string ArrowDropUp = ""; + public const string ArrowForward = ""; + public const string ArrowForwardIos = ""; + public const string ArrowLeft = ""; + public const string ArrowRight = ""; + public const string ArrowRightAlt = ""; + public const string ArrowUpward = ""; + public const string ArtTrack = ""; + public const string Article = ""; + public const string AspectRatio = ""; + public const string Assessment = ""; + public const string Assignment = ""; + public const string AssignmentInd = ""; + public const string AssignmentLate = ""; + public const string AssignmentReturn = ""; + public const string AssignmentReturned = ""; + public const string AssignmentTurnedIn = ""; + public const string Assistant = ""; + public const string AssistantDirection = ""; + public const string AssistantPhoto = ""; + public const string AssuredWorkload = ""; + public const string Atm = ""; + public const string AttachEmail = ""; + public const string AttachFile = ""; + public const string AttachMoney = ""; + public const string Attachment = ""; + public const string Attractions = ""; + public const string Attribution = ""; + public const string AudioFile = ""; + public const string Audiotrack = ""; + public const string AutoAwesome = ""; + public const string AutoAwesomeMosaic = ""; + public const string AutoAwesomeMotion = ""; + public const string AutoDelete = ""; + public const string AutoFixHigh = ""; + public const string AutoFixNormal = ""; + public const string AutoFixOff = ""; + public const string AutoGraph = ""; + public const string AutoStories = ""; + public const string AutofpsSelect = ""; + public const string Autorenew = ""; + public const string AvTimer = ""; + public const string BabyChangingStation = ""; + public const string BackHand = ""; + public const string Backpack = ""; + public const string Backspace = ""; + public const string Backup = ""; + public const string BackupTable = ""; + public const string Badge = ""; + public const string BakeryDining = ""; + public const string Balance = ""; + public const string Balcony = ""; + public const string Ballot = ""; + public const string BarChart = ""; + public const string BatchPrediction = ""; + public const string Bathroom = ""; + public const string Bathtub = ""; + public const string Battery0Bar = ""; + public const string Battery1Bar = ""; + public const string Battery2Bar = ""; + public const string Battery3Bar = ""; + public const string Battery4Bar = ""; + public const string Battery5Bar = ""; + public const string Battery6Bar = ""; + public const string BatteryAlert = ""; + public const string BatteryChargingFull = ""; + public const string BatteryFull = ""; + public const string BatterySaver = ""; + public const string BatteryStd = ""; + public const string BatteryUnknown = ""; + public const string BeachAccess = ""; + public const string Bed = ""; + public const string BedroomBaby = ""; + public const string BedroomChild = ""; + public const string BedroomParent = ""; + public const string Bedtime = ""; + public const string BedtimeOff = ""; + public const string Beenhere = ""; + public const string Bento = ""; + public const string BikeScooter = ""; + public const string Biotech = ""; + public const string Blender = ""; + public const string Block = ""; + public const string Bloodtype = ""; + public const string Bluetooth = ""; + public const string BluetoothAudio = ""; + public const string BluetoothConnected = ""; + public const string BluetoothDisabled = ""; + public const string BluetoothDrive = ""; + public const string BluetoothSearching = ""; + public const string BlurCircular = ""; + public const string BlurLinear = ""; + public const string BlurOff = ""; + public const string BlurOn = ""; + public const string Bolt = ""; + public const string Book = ""; + public const string BookOnline = ""; + public const string Bookmark = ""; + public const string BookmarkAdd = ""; + public const string BookmarkAdded = ""; + public const string BookmarkBorder = ""; + public const string BookmarkRemove = ""; + public const string Bookmarks = ""; + public const string BorderAll = ""; + public const string BorderBottom = ""; + public const string BorderClear = ""; + public const string BorderColor = ""; + public const string BorderHorizontal = ""; + public const string BorderInner = ""; + public const string BorderLeft = ""; + public const string BorderOuter = ""; + public const string BorderRight = ""; + public const string BorderStyle = ""; + public const string BorderTop = ""; + public const string BorderVertical = ""; + public const string Boy = ""; + public const string BrandingWatermark = ""; + public const string BreakfastDining = ""; + public const string Brightness1 = ""; + public const string Brightness2 = ""; + public const string Brightness3 = ""; + public const string Brightness4 = ""; + public const string Brightness5 = ""; + public const string Brightness6 = ""; + public const string Brightness7 = ""; + public const string BrightnessAuto = ""; + public const string BrightnessHigh = ""; + public const string BrightnessLow = ""; + public const string BrightnessMedium = ""; + public const string BrokenImage = ""; + public const string BrowseGallery = ""; + public const string BrowserNotSupported = ""; + public const string BrowserUpdated = ""; + public const string BrunchDining = ""; + public const string Brush = ""; + public const string BubbleChart = ""; + public const string BugReport = ""; + public const string Build = ""; + public const string BuildCircle = ""; + public const string Bungalow = ""; + public const string BurstMode = ""; + public const string BusAlert = ""; + public const string Business = ""; + public const string BusinessCenter = ""; + public const string Cabin = ""; + public const string Cable = ""; + public const string Cached = ""; + public const string Cake = ""; + public const string Calculate = ""; + public const string CalendarMonth = ""; + public const string CalendarToday = ""; + public const string CalendarViewDay = ""; + public const string CalendarViewMonth = ""; + public const string CalendarViewWeek = ""; + public const string Call = ""; + public const string CallEnd = ""; + public const string CallMade = ""; + public const string CallMerge = ""; + public const string CallMissed = ""; + public const string CallMissedOutgoing = ""; + public const string CallReceived = ""; + public const string CallSplit = ""; + public const string CallToAction = ""; + public const string Camera = ""; + public const string CameraAlt = ""; + public const string CameraEnhance = ""; + public const string CameraFront = ""; + public const string CameraIndoor = ""; + public const string CameraOutdoor = ""; + public const string CameraRear = ""; + public const string CameraRoll = ""; + public const string Cameraswitch = ""; + public const string Campaign = ""; + public const string Cancel = ""; + public const string CancelPresentation = ""; + public const string CancelScheduleSend = ""; + public const string CandlestickChart = ""; + public const string CarCrash = ""; + public const string CarRental = ""; + public const string CarRepair = ""; + public const string CardGiftcard = ""; + public const string CardMembership = ""; + public const string CardTravel = ""; + public const string Carpenter = ""; + public const string Cases = ""; + public const string Casino = ""; + public const string Cast = ""; + public const string CastConnected = ""; + public const string CastForEducation = ""; + public const string Castle = ""; + public const string CatchingPokemon = ""; + public const string Category = ""; + public const string Celebration = ""; + public const string CellTower = ""; + public const string CellWifi = ""; + public const string CenterFocusStrong = ""; + public const string CenterFocusWeak = ""; + public const string Chair = ""; + public const string ChairAlt = ""; + public const string Chalet = ""; + public const string ChangeCircle = ""; + public const string ChangeHistory = ""; + public const string ChargingStation = ""; + public const string Chat = ""; + public const string ChatBubble = ""; + public const string ChatBubbleOutline = ""; + public const string Check = ""; + public const string CheckBox = ""; + public const string CheckBoxOutlineBlank = ""; + public const string CheckCircle = ""; + public const string CheckCircleOutline = ""; + public const string Checklist = ""; + public const string ChecklistRtl = ""; + public const string Checkroom = ""; + public const string ChevronLeft = ""; + public const string ChevronRight = ""; + public const string ChildCare = ""; + public const string ChildFriendly = ""; + public const string ChromeReaderMode = ""; + public const string Church = ""; + public const string Circle = ""; + public const string CircleNotifications = ""; + public const string Class = ""; + public const string CleanHands = ""; + public const string CleaningServices = ""; + public const string Clear = ""; + public const string ClearAll = ""; + public const string Close = ""; + public const string CloseFullscreen = ""; + public const string ClosedCaption = ""; + public const string ClosedCaptionDisabled = ""; + public const string ClosedCaptionOff = ""; + public const string Cloud = ""; + public const string CloudCircle = ""; + public const string CloudDone = ""; + public const string CloudDownload = ""; + public const string CloudOff = ""; + public const string CloudQueue = ""; + public const string CloudSync = ""; + public const string CloudUpload = ""; + public const string Co2 = ""; + public const string CoPresent = ""; + public const string Code = ""; + public const string CodeOff = ""; + public const string Coffee = ""; + public const string CoffeeMaker = ""; + public const string Collections = ""; + public const string CollectionsBookmark = ""; + public const string ColorLens = ""; + public const string Colorize = ""; + public const string Comment = ""; + public const string CommentBank = ""; + public const string CommentsDisabled = ""; + public const string Commit = ""; + public const string Commute = ""; + public const string Compare = ""; + public const string CompareArrows = ""; + public const string CompassCalibration = ""; + public const string Compost = ""; + public const string Compress = ""; + public const string Computer = ""; + public const string ConfirmationNumber = ""; + public const string ConnectWithoutContact = ""; + public const string ConnectedTv = ""; + public const string ConnectingAirports = ""; + public const string Construction = ""; + public const string ContactMail = ""; + public const string ContactPage = ""; + public const string ContactPhone = ""; + public const string ContactSupport = ""; + public const string Contactless = ""; + public const string Contacts = ""; + public const string ContentCopy = ""; + public const string ContentCut = ""; + public const string ContentPaste = ""; + public const string ContentPasteGo = ""; + public const string ContentPasteOff = ""; + public const string ContentPasteSearch = ""; + public const string Contrast = ""; + public const string ControlCamera = ""; + public const string ControlPoint = ""; + public const string ControlPointDuplicate = ""; + public const string Cookie = ""; + public const string CopyAll = ""; + public const string Copyright = ""; + public const string Coronavirus = ""; + public const string CorporateFare = ""; + public const string Cottage = ""; + public const string Countertops = ""; + public const string Create = ""; + public const string CreateNewFolder = ""; + public const string CreditCard = ""; + public const string CreditCardOff = ""; + public const string CreditScore = ""; + public const string Crib = ""; + public const string CrisisAlert = ""; + public const string Crop = ""; + public const string Crop169 = ""; + public const string Crop32 = ""; + public const string Crop54 = ""; + public const string Crop75 = ""; + public const string CropDin = ""; + public const string CropFree = ""; + public const string CropLandscape = ""; + public const string CropOriginal = ""; + public const string CropPortrait = ""; + public const string CropRotate = ""; + public const string CropSquare = ""; + public const string CrueltyFree = ""; + public const string Css = ""; + public const string CurrencyBitcoin = ""; + public const string CurrencyExchange = ""; + public const string CurrencyFranc = ""; + public const string CurrencyLira = ""; + public const string CurrencyPound = ""; + public const string CurrencyRuble = ""; + public const string CurrencyRupee = ""; + public const string CurrencyYen = ""; + public const string CurrencyYuan = ""; + public const string Cyclone = ""; + public const string Dangerous = ""; + public const string DarkMode = ""; + public const string Dashboard = ""; + public const string DashboardCustomize = ""; + public const string DataArray = ""; + public const string DataExploration = ""; + public const string DataObject = ""; + public const string DataSaverOff = ""; + public const string DataSaverOn = ""; + public const string DataThresholding = ""; + public const string DataUsage = ""; + public const string DateRange = ""; + public const string Deblur = ""; + public const string Deck = ""; + public const string Dehaze = ""; + public const string Delete = ""; + public const string DeleteForever = ""; + public const string DeleteOutline = ""; + public const string DeleteSweep = ""; + public const string DeliveryDining = ""; + public const string DensityLarge = ""; + public const string DensityMedium = ""; + public const string DensitySmall = ""; + public const string DepartureBoard = ""; + public const string Description = ""; + public const string Deselect = ""; + public const string DesignServices = ""; + public const string DesktopAccessDisabled = ""; + public const string DesktopMac = ""; + public const string DesktopWindows = ""; + public const string Details = ""; + public const string DeveloperBoard = ""; + public const string DeveloperBoardOff = ""; + public const string DeveloperMode = ""; + public const string DeviceHub = ""; + public const string DeviceThermostat = ""; + public const string DeviceUnknown = ""; + public const string Devices = ""; + public const string DevicesFold = ""; + public const string DevicesOther = ""; + public const string DialerSip = ""; + public const string Dialpad = ""; + public const string Diamond = ""; + public const string Difference = ""; + public const string Dining = ""; + public const string DinnerDining = ""; + public const string Directions = ""; + public const string DirectionsBike = ""; + public const string DirectionsBoat = ""; + public const string DirectionsBoatFilled = ""; + public const string DirectionsBus = ""; + public const string DirectionsBusFilled = ""; + public const string DirectionsCar = ""; + public const string DirectionsCarFilled = ""; + public const string DirectionsOff = ""; + public const string DirectionsRailway = ""; + public const string DirectionsRailwayFilled = ""; + public const string DirectionsRun = ""; + public const string DirectionsSubway = ""; + public const string DirectionsSubwayFilled = ""; + public const string DirectionsTransit = ""; + public const string DirectionsTransitFilled = ""; + public const string DirectionsWalk = ""; + public const string DirtyLens = ""; + public const string DisabledByDefault = ""; + public const string DisabledVisible = ""; + public const string DiscFull = ""; + public const string Discount = ""; + public const string DisplaySettings = ""; + public const string Dns = ""; + public const string DoDisturb = ""; + public const string DoDisturbAlt = ""; + public const string DoDisturbOff = ""; + public const string DoDisturbOn = ""; + public const string DoNotDisturb = ""; + public const string DoNotDisturbAlt = ""; + public const string DoNotDisturbOff = ""; + public const string DoNotDisturbOn = ""; + public const string DoNotDisturbOnTotalSilence = ""; + public const string DoNotStep = ""; + public const string DoNotTouch = ""; + public const string Dock = ""; + public const string DocumentScanner = ""; + public const string Domain = ""; + public const string DomainAdd = ""; + public const string DomainDisabled = ""; + public const string DomainVerification = ""; + public const string Done = ""; + public const string DoneAll = ""; + public const string DoneOutline = ""; + public const string DonutLarge = ""; + public const string DonutSmall = ""; + public const string DoorBack = ""; + public const string DoorFront = ""; + public const string DoorSliding = ""; + public const string Doorbell = ""; + public const string DoubleArrow = ""; + public const string DownhillSkiing = ""; + public const string Download = ""; + public const string DownloadDone = ""; + public const string DownloadForOffline = ""; + public const string Downloading = ""; + public const string Drafts = ""; + public const string DragHandle = ""; + public const string DragIndicator = ""; + public const string Draw = ""; + public const string DriveEta = ""; + public const string DriveFileMove = ""; + public const string DriveFileMoveRtl = ""; + public const string DriveFileRenameOutline = ""; + public const string DriveFolderUpload = ""; + public const string Dry = ""; + public const string DryCleaning = ""; + public const string Duo = ""; + public const string Dvr = ""; + public const string DynamicFeed = ""; + public const string DynamicForm = ""; + public const string EMobiledata = ""; + public const string Earbuds = ""; + public const string EarbudsBattery = ""; + public const string East = ""; + public const string EdgesensorHigh = ""; + public const string EdgesensorLow = ""; + public const string Edit = ""; + public const string EditAttributes = ""; + public const string EditCalendar = ""; + public const string EditLocation = ""; + public const string EditLocationAlt = ""; + public const string EditNote = ""; + public const string EditNotifications = ""; + public const string EditOff = ""; + public const string EditRoad = ""; + public const string Egg = ""; + public const string EggAlt = ""; + public const string Eject = ""; + public const string Elderly = ""; + public const string ElderlyWoman = ""; + public const string ElectricBike = ""; + public const string ElectricCar = ""; + public const string ElectricMoped = ""; + public const string ElectricRickshaw = ""; + public const string ElectricScooter = ""; + public const string ElectricalServices = ""; + public const string Elevator = ""; + public const string Email = ""; + public const string Emergency = ""; + public const string EmergencyRecording = ""; + public const string EmergencyShare = ""; + public const string EmojiEmotions = ""; + public const string EmojiEvents = ""; + public const string EmojiFoodBeverage = ""; + public const string EmojiNature = ""; + public const string EmojiObjects = ""; + public const string EmojiPeople = ""; + public const string EmojiSymbols = ""; + public const string EmojiTransportation = ""; + public const string Engineering = ""; + public const string EnhancedEncryption = ""; + public const string Equalizer = ""; + public const string Error = ""; + public const string ErrorOutline = ""; + public const string Escalator = ""; + public const string EscalatorWarning = ""; + public const string Euro = ""; + public const string EuroSymbol = ""; + public const string EvStation = ""; + public const string Event = ""; + public const string EventAvailable = ""; + public const string EventBusy = ""; + public const string EventNote = ""; + public const string EventRepeat = ""; + public const string EventSeat = ""; + public const string ExitToApp = ""; + public const string Expand = ""; + public const string ExpandCircleDown = ""; + public const string ExpandLess = ""; + public const string ExpandMore = ""; + public const string Explicit = ""; + public const string Explore = ""; + public const string ExploreOff = ""; + public const string Exposure = ""; + public const string ExposureNeg1 = ""; + public const string ExposureNeg2 = ""; + public const string ExposurePlus1 = ""; + public const string ExposurePlus2 = ""; + public const string ExposureZero = ""; + public const string Extension = ""; + public const string ExtensionOff = ""; + public const string Face = ""; + public const string FaceRetouchingNatural = ""; + public const string FaceRetouchingOff = ""; + public const string FactCheck = ""; + public const string Factory = ""; + public const string FamilyRestroom = ""; + public const string FastForward = ""; + public const string FastRewind = ""; + public const string Fastfood = ""; + public const string Favorite = ""; + public const string FavoriteBorder = ""; + public const string Fax = ""; + public const string FeaturedPlayList = ""; + public const string FeaturedVideo = ""; + public const string Feed = ""; + public const string Feedback = ""; + public const string Female = ""; + public const string Fence = ""; + public const string Festival = ""; + public const string FiberDvr = ""; + public const string FiberManualRecord = ""; + public const string FiberNew = ""; + public const string FiberPin = ""; + public const string FiberSmartRecord = ""; + public const string FileCopy = ""; + public const string FileDownload = ""; + public const string FileDownloadDone = ""; + public const string FileDownloadOff = ""; + public const string FileOpen = ""; + public const string FilePresent = ""; + public const string FileUpload = ""; + public const string Filter = ""; + public const string Filter1 = ""; + public const string Filter2 = ""; + public const string Filter3 = ""; + public const string Filter4 = ""; + public const string Filter5 = ""; + public const string Filter6 = ""; + public const string Filter7 = ""; + public const string Filter8 = ""; + public const string Filter9 = ""; + public const string Filter9Plus = ""; + public const string FilterAlt = ""; + public const string FilterAltOff = ""; + public const string FilterBAndW = ""; + public const string FilterCenterFocus = ""; + public const string FilterDrama = ""; + public const string FilterFrames = ""; + public const string FilterHdr = ""; + public const string FilterList = ""; + public const string FilterListOff = ""; + public const string FilterNone = ""; + public const string FilterTiltShift = ""; + public const string FilterVintage = ""; + public const string FindInPage = ""; + public const string FindReplace = ""; + public const string Fingerprint = ""; + public const string FireExtinguisher = ""; + public const string Fireplace = ""; + public const string FirstPage = ""; + public const string FitScreen = ""; + public const string Fitbit = ""; + public const string FitnessCenter = ""; + public const string Flag = ""; + public const string FlagCircle = ""; + public const string Flaky = ""; + public const string Flare = ""; + public const string FlashAuto = ""; + public const string FlashOff = ""; + public const string FlashOn = ""; + public const string FlashlightOff = ""; + public const string FlashlightOn = ""; + public const string Flatware = ""; + public const string Flight = ""; + public const string FlightClass = ""; + public const string FlightLand = ""; + public const string FlightTakeoff = ""; + public const string Flip = ""; + public const string FlipCameraAndroid = ""; + public const string FlipCameraIos = ""; + public const string FlipToBack = ""; + public const string FlipToFront = ""; + public const string Flood = ""; + public const string Flourescent = ""; + public const string FlutterDash = ""; + public const string FmdBad = ""; + public const string FmdGood = ""; + public const string Folder = ""; + public const string FolderCopy = ""; + public const string FolderDelete = ""; + public const string FolderOff = ""; + public const string FolderOpen = ""; + public const string FolderShared = ""; + public const string FolderSpecial = ""; + public const string FolderZip = ""; + public const string FollowTheSigns = ""; + public const string FontDownload = ""; + public const string FontDownloadOff = ""; + public const string FoodBank = ""; + public const string Forest = ""; + public const string ForkLeft = ""; + public const string ForkRight = ""; + public const string FormatAlignCenter = ""; + public const string FormatAlignJustify = ""; + public const string FormatAlignLeft = ""; + public const string FormatAlignRight = ""; + public const string FormatBold = ""; + public const string FormatClear = ""; + public const string FormatColorFill = ""; + public const string FormatColorReset = ""; + public const string FormatColorText = ""; + public const string FormatIndentDecrease = ""; + public const string FormatIndentIncrease = ""; + public const string FormatItalic = ""; + public const string FormatLineSpacing = ""; + public const string FormatListBulleted = ""; + public const string FormatListNumbered = ""; + public const string FormatListNumberedRtl = ""; + public const string FormatOverline = ""; + public const string FormatPaint = ""; + public const string FormatQuote = ""; + public const string FormatShapes = ""; + public const string FormatSize = ""; + public const string FormatStrikethrough = ""; + public const string FormatTextdirectionLToR = ""; + public const string FormatTextdirectionRToL = ""; + public const string FormatUnderlined = ""; + public const string Fort = ""; + public const string Forum = ""; + public const string Forward = ""; + public const string Forward10 = ""; + public const string Forward30 = ""; + public const string Forward5 = ""; + public const string ForwardToInbox = ""; + public const string Foundation = ""; + public const string FreeBreakfast = ""; + public const string FreeCancellation = ""; + public const string FrontHand = ""; + public const string Fullscreen = ""; + public const string FullscreenExit = ""; + public const string Functions = ""; + public const string GMobiledata = ""; + public const string GTranslate = ""; + public const string Gamepad = ""; + public const string Games = ""; + public const string Garage = ""; + public const string Gavel = ""; + public const string GeneratingTokens = ""; + public const string Gesture = ""; + public const string GetApp = ""; + public const string Gif = ""; + public const string GifBox = ""; + public const string Girl = ""; + public const string Gite = ""; + public const string GolfCourse = ""; + public const string GppBad = ""; + public const string GppGood = ""; + public const string GppMaybe = ""; + public const string GpsFixed = ""; + public const string GpsNotFixed = ""; + public const string GpsOff = ""; + public const string Grade = ""; + public const string Gradient = ""; + public const string Grading = ""; + public const string Grain = ""; + public const string GraphicEq = ""; + public const string Grass = ""; + public const string Grid3x3 = ""; + public const string Grid4x4 = ""; + public const string GridGoldenratio = ""; + public const string GridOff = ""; + public const string GridOn = ""; + public const string GridView = ""; + public const string Group = ""; + public const string GroupAdd = ""; + public const string GroupOff = ""; + public const string GroupRemove = ""; + public const string GroupWork = ""; + public const string Groups = ""; + public const string HMobiledata = ""; + public const string HPlusMobiledata = ""; + public const string Hail = ""; + public const string Handshake = ""; + public const string Handyman = ""; + public const string Hardware = ""; + public const string Hd = ""; + public const string HdrAuto = ""; + public const string HdrAutoSelect = ""; + public const string HdrEnhancedSelect = ""; + public const string HdrOff = ""; + public const string HdrOffSelect = ""; + public const string HdrOn = ""; + public const string HdrOnSelect = ""; + public const string HdrPlus = ""; + public const string HdrStrong = ""; + public const string HdrWeak = ""; + public const string Headphones = ""; + public const string HeadphonesBattery = ""; + public const string Headset = ""; + public const string HeadsetMic = ""; + public const string HeadsetOff = ""; + public const string Healing = ""; + public const string HealthAndSafety = ""; + public const string Hearing = ""; + public const string HearingDisabled = ""; + public const string HeartBroken = ""; + public const string Height = ""; + public const string Help = ""; + public const string HelpCenter = ""; + public const string HelpOutline = ""; + public const string Hevc = ""; + public const string Hexagon = ""; + public const string HideImage = ""; + public const string HideSource = ""; + public const string HighQuality = ""; + public const string Highlight = ""; + public const string HighlightAlt = ""; + public const string HighlightOff = ""; + public const string Hiking = ""; + public const string History = ""; + public const string HistoryEdu = ""; + public const string HistoryToggleOff = ""; + public const string Hive = ""; + public const string Hls = ""; + public const string HlsOff = ""; + public const string HolidayVillage = ""; + public const string Home = ""; + public const string HomeMax = ""; + public const string HomeMini = ""; + public const string HomeRepairService = ""; + public const string HomeWork = ""; + public const string HorizontalDistribute = ""; + public const string HorizontalRule = ""; + public const string HorizontalSplit = ""; + public const string HotTub = ""; + public const string Hotel = ""; + public const string HotelClass = ""; + public const string HourglassBottom = ""; + public const string HourglassDisabled = ""; + public const string HourglassEmpty = ""; + public const string HourglassFull = ""; + public const string HourglassTop = ""; + public const string House = ""; + public const string HouseSiding = ""; + public const string Houseboat = ""; + public const string HowToReg = ""; + public const string HowToVote = ""; + public const string Html = ""; + public const string Http = ""; + public const string Https = ""; + public const string Hub = ""; + public const string Hvac = ""; + public const string IceSkating = ""; + public const string Icecream = ""; + public const string Image = ""; + public const string ImageAspectRatio = ""; + public const string ImageNotSupported = ""; + public const string ImageSearch = ""; + public const string ImagesearchRoller = ""; + public const string ImportContacts = ""; + public const string ImportExport = ""; + public const string ImportantDevices = ""; + public const string Inbox = ""; + public const string IncompleteCircle = ""; + public const string IndeterminateCheckBox = ""; + public const string Info = ""; + public const string Input = ""; + public const string InsertChart = ""; + public const string InsertChartOutlined = ""; + public const string InsertComment = ""; + public const string InsertDriveFile = ""; + public const string InsertEmoticon = ""; + public const string InsertInvitation = ""; + public const string InsertLink = ""; + public const string InsertPageBreak = ""; + public const string InsertPhoto = ""; + public const string Insights = ""; + public const string InstallDesktop = ""; + public const string InstallMobile = ""; + public const string IntegrationInstructions = ""; + public const string Interests = ""; + public const string InterpreterMode = ""; + public const string Inventory = ""; + public const string Inventory2 = ""; + public const string InvertColors = ""; + public const string InvertColorsOff = ""; + public const string IosShare = ""; + public const string Iron = ""; + public const string Iso = ""; + public const string Javascript = ""; + public const string JoinFull = ""; + public const string JoinInner = ""; + public const string JoinLeft = ""; + public const string JoinRight = ""; + public const string Kayaking = ""; + public const string KebabDining = ""; + public const string Key = ""; + public const string KeyOff = ""; + public const string Keyboard = ""; + public const string KeyboardAlt = ""; + public const string KeyboardArrowDown = ""; + public const string KeyboardArrowLeft = ""; + public const string KeyboardArrowRight = ""; + public const string KeyboardArrowUp = ""; + public const string KeyboardBackspace = ""; + public const string KeyboardCapslock = ""; + public const string KeyboardCommandKey = ""; + public const string KeyboardControlKey = ""; + public const string KeyboardDoubleArrowDown = ""; + public const string KeyboardDoubleArrowLeft = ""; + public const string KeyboardDoubleArrowRight = ""; + public const string KeyboardDoubleArrowUp = ""; + public const string KeyboardHide = ""; + public const string KeyboardOptionKey = ""; + public const string KeyboardReturn = ""; + public const string KeyboardTab = ""; + public const string KeyboardVoice = ""; + public const string KingBed = ""; + public const string Kitchen = ""; + public const string Kitesurfing = ""; + public const string Label = ""; + public const string LabelImportant = ""; + public const string LabelOff = ""; + public const string Lan = ""; + public const string Landscape = ""; + public const string Landslide = ""; + public const string Language = ""; + public const string Laptop = ""; + public const string LaptopChromebook = ""; + public const string LaptopMac = ""; + public const string LaptopWindows = ""; + public const string LastPage = ""; + public const string Launch = ""; + public const string Layers = ""; + public const string LayersClear = ""; + public const string Leaderboard = ""; + public const string LeakAdd = ""; + public const string LeakRemove = ""; + public const string LegendToggle = ""; + public const string Lens = ""; + public const string LensBlur = ""; + public const string LibraryAdd = ""; + public const string LibraryAddCheck = ""; + public const string LibraryBooks = ""; + public const string LibraryMusic = ""; + public const string Light = ""; + public const string LightMode = ""; + public const string Lightbulb = ""; + public const string LightbulbCircle = ""; + public const string LineAxis = ""; + public const string LineStyle = ""; + public const string LineWeight = ""; + public const string LinearScale = ""; + public const string Link = ""; + public const string LinkOff = ""; + public const string LinkedCamera = ""; + public const string Liquor = ""; + public const string List = ""; + public const string ListAlt = ""; + public const string LiveHelp = ""; + public const string LiveTv = ""; + public const string Living = ""; + public const string LocalActivity = ""; + public const string LocalAirport = ""; + public const string LocalAtm = ""; + public const string LocalBar = ""; + public const string LocalCafe = ""; + public const string LocalCarWash = ""; + public const string LocalConvenienceStore = ""; + public const string LocalDining = ""; + public const string LocalDrink = ""; + public const string LocalFireDepartment = ""; + public const string LocalFlorist = ""; + public const string LocalGasStation = ""; + public const string LocalGroceryStore = ""; + public const string LocalHospital = ""; + public const string LocalHotel = ""; + public const string LocalLaundryService = ""; + public const string LocalLibrary = ""; + public const string LocalMall = ""; + public const string LocalMovies = ""; + public const string LocalOffer = ""; + public const string LocalParking = ""; + public const string LocalPharmacy = ""; + public const string LocalPhone = ""; + public const string LocalPizza = ""; + public const string LocalPlay = ""; + public const string LocalPolice = ""; + public const string LocalPostOffice = ""; + public const string LocalPrintshop = ""; + public const string LocalSee = ""; + public const string LocalShipping = ""; + public const string LocalTaxi = ""; + public const string LocationCity = ""; + public const string LocationDisabled = ""; + public const string LocationOff = ""; + public const string LocationOn = ""; + public const string LocationSearching = ""; + public const string Lock = ""; + public const string LockClock = ""; + public const string LockOpen = ""; + public const string LockReset = ""; + public const string Login = ""; + public const string LogoDev = ""; + public const string Logout = ""; + public const string Looks = ""; + public const string Looks3 = ""; + public const string Looks4 = ""; + public const string Looks5 = ""; + public const string Looks6 = ""; + public const string LooksOne = ""; + public const string LooksTwo = ""; + public const string Loop = ""; + public const string Loupe = ""; + public const string LowPriority = ""; + public const string Loyalty = ""; + public const string LteMobiledata = ""; + public const string LtePlusMobiledata = ""; + public const string Luggage = ""; + public const string LunchDining = ""; + public const string Mail = ""; + public const string MailOutline = ""; + public const string Male = ""; + public const string Man = ""; + public const string ManageAccounts = ""; + public const string ManageHistory = ""; + public const string ManageSearch = ""; + public const string Map = ""; + public const string MapsHomeWork = ""; + public const string MapsUgc = ""; + public const string Margin = ""; + public const string MarkAsUnread = ""; + public const string MarkChatRead = ""; + public const string MarkChatUnread = ""; + public const string MarkEmailRead = ""; + public const string MarkEmailUnread = ""; + public const string MarkUnreadChatAlt = ""; + public const string Markunread = ""; + public const string MarkunreadMailbox = ""; + public const string Masks = ""; + public const string Maximize = ""; + public const string MediaBluetoothOff = ""; + public const string MediaBluetoothOn = ""; + public const string Mediation = ""; + public const string MedicalInformation = ""; + public const string MedicalServices = ""; + public const string Medication = ""; + public const string MedicationLiquid = ""; + public const string MeetingRoom = ""; + public const string Memory = ""; + public const string Menu = ""; + public const string MenuBook = ""; + public const string MenuOpen = ""; + public const string Merge = ""; + public const string MergeType = ""; + public const string Message = ""; + public const string Mic = ""; + public const string MicExternalOff = ""; + public const string MicExternalOn = ""; + public const string MicNone = ""; + public const string MicOff = ""; + public const string Microwave = ""; + public const string MilitaryTech = ""; + public const string Minimize = ""; + public const string MinorCrash = ""; + public const string MiscellaneousServices = ""; + public const string MissedVideoCall = ""; + public const string Mms = ""; + public const string MobileFriendly = ""; + public const string MobileOff = ""; + public const string MobileScreenShare = ""; + public const string MobiledataOff = ""; + public const string Mode = ""; + public const string ModeComment = ""; + public const string ModeEdit = ""; + public const string ModeEditOutline = ""; + public const string ModeNight = ""; + public const string ModeOfTravel = ""; + public const string ModeStandby = ""; + public const string ModelTraining = ""; + public const string MonetizationOn = ""; + public const string Money = ""; + public const string MoneyOff = ""; + public const string MoneyOffCsred = ""; + public const string Monitor = ""; + public const string MonitorHeart = ""; + public const string MonitorWeight = ""; + public const string MonochromePhotos = ""; + public const string Mood = ""; + public const string MoodBad = ""; + public const string Moped = ""; + public const string More = ""; + public const string MoreHoriz = ""; + public const string MoreTime = ""; + public const string MoreVert = ""; + public const string Mosque = ""; + public const string MotionPhotosAuto = ""; + public const string MotionPhotosOff = ""; + public const string MotionPhotosOn = ""; + public const string MotionPhotosPause = ""; + public const string MotionPhotosPaused = ""; + public const string Mouse = ""; + public const string MoveDown = ""; + public const string MoveToInbox = ""; + public const string MoveUp = ""; + public const string Movie = ""; + public const string MovieCreation = ""; + public const string MovieFilter = ""; + public const string Moving = ""; + public const string Mp = ""; + public const string MultilineChart = ""; + public const string MultipleStop = ""; + public const string Museum = ""; + public const string MusicNote = ""; + public const string MusicOff = ""; + public const string MusicVideo = ""; + public const string MyLocation = ""; + public const string Nat = ""; + public const string Nature = ""; + public const string NaturePeople = ""; + public const string NavigateBefore = ""; + public const string NavigateNext = ""; + public const string Navigation = ""; + public const string NearMe = ""; + public const string NearMeDisabled = ""; + public const string NearbyError = ""; + public const string NearbyOff = ""; + public const string NetworkCell = ""; + public const string NetworkCheck = ""; + public const string NetworkLocked = ""; + public const string NetworkPing = ""; + public const string NetworkWifi = ""; + public const string NetworkWifi1Bar = ""; + public const string NetworkWifi2Bar = ""; + public const string NetworkWifi3Bar = ""; + public const string NewLabel = ""; + public const string NewReleases = ""; + public const string Newspaper = ""; + public const string NextPlan = ""; + public const string NextWeek = ""; + public const string Nfc = ""; + public const string NightShelter = ""; + public const string Nightlife = ""; + public const string Nightlight = ""; + public const string NightlightRound = ""; + public const string NightsStay = ""; + public const string NoAccounts = ""; + public const string NoBackpack = ""; + public const string NoCell = ""; + public const string NoCrash = ""; + public const string NoDrinks = ""; + public const string NoEncryption = ""; + public const string NoEncryptionGmailerrorred = ""; + public const string NoFlash = ""; + public const string NoFood = ""; + public const string NoLuggage = ""; + public const string NoMeals = ""; + public const string NoMeetingRoom = ""; + public const string NoPhotography = ""; + public const string NoSim = ""; + public const string NoStroller = ""; + public const string NoTransfer = ""; + public const string NoiseAware = ""; + public const string NoiseControlOff = ""; + public const string NordicWalking = ""; + public const string North = ""; + public const string NorthEast = ""; + public const string NorthWest = ""; + public const string NotAccessible = ""; + public const string NotInterested = ""; + public const string NotListedLocation = ""; + public const string NotStarted = ""; + public const string Note = ""; + public const string NoteAdd = ""; + public const string NoteAlt = ""; + public const string Notes = ""; + public const string NotificationAdd = ""; + public const string NotificationImportant = ""; + public const string Notifications = ""; + public const string NotificationsActive = ""; + public const string NotificationsNone = ""; + public const string NotificationsOff = ""; + public const string NotificationsPaused = ""; + public const string Numbers = ""; + public const string OfflineBolt = ""; + public const string OfflinePin = ""; + public const string OfflineShare = ""; + public const string OnDeviceTraining = ""; + public const string OndemandVideo = ""; + public const string OnlinePrediction = ""; + public const string Opacity = ""; + public const string OpenInBrowser = ""; + public const string OpenInFull = ""; + public const string OpenInNew = ""; + public const string OpenInNewOff = ""; + public const string OpenWith = ""; + public const string OtherHouses = ""; + public const string Outbound = ""; + public const string Outbox = ""; + public const string OutdoorGrill = ""; + public const string Outlet = ""; + public const string OutlinedFlag = ""; + public const string Output = ""; + public const string Padding = ""; + public const string Pages = ""; + public const string Pageview = ""; + public const string Paid = ""; + public const string Palette = ""; + public const string PanTool = ""; + public const string PanToolAlt = ""; + public const string Panorama = ""; + public const string PanoramaFishEye = ""; + public const string PanoramaHorizontal = ""; + public const string PanoramaHorizontalSelect = ""; + public const string PanoramaPhotosphere = ""; + public const string PanoramaPhotosphereSelect = ""; + public const string PanoramaVertical = ""; + public const string PanoramaVerticalSelect = ""; + public const string PanoramaWideAngle = ""; + public const string PanoramaWideAngleSelect = ""; + public const string Paragliding = ""; + public const string Park = ""; + public const string PartyMode = ""; + public const string Password = ""; + public const string Pattern = ""; + public const string Pause = ""; + public const string PauseCircle = ""; + public const string PauseCircleFilled = ""; + public const string PauseCircleOutline = ""; + public const string PausePresentation = ""; + public const string Payment = ""; + public const string Payments = ""; + public const string PedalBike = ""; + public const string Pending = ""; + public const string PendingActions = ""; + public const string Pentagon = ""; + public const string People = ""; + public const string PeopleAlt = ""; + public const string PeopleOutline = ""; + public const string Percent = ""; + public const string PermCameraMic = ""; + public const string PermContactCalendar = ""; + public const string PermDataSetting = ""; + public const string PermDeviceInformation = ""; + public const string PermIdentity = ""; + public const string PermMedia = ""; + public const string PermPhoneMsg = ""; + public const string PermScanWifi = ""; + public const string Person = ""; + public const string PersonAdd = ""; + public const string PersonAddAlt = ""; + public const string PersonAddAlt1 = ""; + public const string PersonAddDisabled = ""; + public const string PersonOff = ""; + public const string PersonOutline = ""; + public const string PersonPin = ""; + public const string PersonPinCircle = ""; + public const string PersonRemove = ""; + public const string PersonRemoveAlt1 = ""; + public const string PersonSearch = ""; + public const string PersonalInjury = ""; + public const string PersonalVideo = ""; + public const string PestControl = ""; + public const string PestControlRodent = ""; + public const string Pets = ""; + public const string Phishing = ""; + public const string Phone = ""; + public const string PhoneAndroid = ""; + public const string PhoneBluetoothSpeaker = ""; + public const string PhoneCallback = ""; + public const string PhoneDisabled = ""; + public const string PhoneEnabled = ""; + public const string PhoneForwarded = ""; + public const string PhoneInTalk = ""; + public const string PhoneIphone = ""; + public const string PhoneLocked = ""; + public const string PhoneMissed = ""; + public const string PhonePaused = ""; + public const string Phonelink = ""; + public const string PhonelinkErase = ""; + public const string PhonelinkLock = ""; + public const string PhonelinkOff = ""; + public const string PhonelinkRing = ""; + public const string PhonelinkSetup = ""; + public const string Photo = ""; + public const string PhotoAlbum = ""; + public const string PhotoCamera = ""; + public const string PhotoCameraBack = ""; + public const string PhotoCameraFront = ""; + public const string PhotoFilter = ""; + public const string PhotoLibrary = ""; + public const string PhotoSizeSelectActual = ""; + public const string PhotoSizeSelectLarge = ""; + public const string PhotoSizeSelectSmall = ""; + public const string Php = ""; + public const string Piano = ""; + public const string PianoOff = ""; + public const string PictureAsPdf = ""; + public const string PictureInPicture = ""; + public const string PictureInPictureAlt = ""; + public const string PieChart = ""; + public const string PieChartOutline = ""; + public const string Pin = ""; + public const string PinDrop = ""; + public const string PinEnd = ""; + public const string PinInvoke = ""; + public const string Pinch = ""; + public const string PivotTableChart = ""; + public const string Pix = ""; + public const string Place = ""; + public const string Plagiarism = ""; + public const string PlayArrow = ""; + public const string PlayCircle = ""; + public const string PlayCircleFilled = ""; + public const string PlayCircleOutline = ""; + public const string PlayDisabled = ""; + public const string PlayForWork = ""; + public const string PlayLesson = ""; + public const string PlaylistAdd = ""; + public const string PlaylistAddCheck = ""; + public const string PlaylistAddCheckCircle = ""; + public const string PlaylistAddCircle = ""; + public const string PlaylistPlay = ""; + public const string PlaylistRemove = ""; + public const string Plumbing = ""; + public const string PlusOne = ""; + public const string Podcasts = ""; + public const string PointOfSale = ""; + public const string Policy = ""; + public const string Poll = ""; + public const string Polyline = ""; + public const string Polymer = ""; + public const string Pool = ""; + public const string PortableWifiOff = ""; + public const string Portrait = ""; + public const string PostAdd = ""; + public const string Power = ""; + public const string PowerInput = ""; + public const string PowerOff = ""; + public const string PowerSettingsNew = ""; + public const string PrecisionManufacturing = ""; + public const string PregnantWoman = ""; + public const string PresentToAll = ""; + public const string Preview = ""; + public const string PriceChange = ""; + public const string PriceCheck = ""; + public const string Print = ""; + public const string PrintDisabled = ""; + public const string PriorityHigh = ""; + public const string PrivacyTip = ""; + public const string PrivateConnectivity = ""; + public const string ProductionQuantityLimits = ""; + public const string Psychology = ""; + public const string Public = ""; + public const string PublicOff = ""; + public const string Publish = ""; + public const string PublishedWithChanges = ""; + public const string PunchClock = ""; + public const string PushPin = ""; + public const string QrCode = ""; + public const string QrCode2 = ""; + public const string QrCodeScanner = ""; + public const string QueryBuilder = ""; + public const string QueryStats = ""; + public const string QuestionAnswer = ""; + public const string QuestionMark = ""; + public const string Queue = ""; + public const string QueueMusic = ""; + public const string QueuePlayNext = ""; + public const string Quickreply = ""; + public const string Quiz = ""; + public const string RMobiledata = ""; + public const string Radar = ""; + public const string Radio = ""; + public const string RadioButtonChecked = ""; + public const string RadioButtonUnchecked = ""; + public const string RailwayAlert = ""; + public const string RamenDining = ""; + public const string RampLeft = ""; + public const string RampRight = ""; + public const string RateReview = ""; + public const string RawOff = ""; + public const string RawOn = ""; + public const string ReadMore = ""; + public const string RealEstateAgent = ""; + public const string Receipt = ""; + public const string ReceiptLong = ""; + public const string RecentActors = ""; + public const string Recommend = ""; + public const string RecordVoiceOver = ""; + public const string Rectangle = ""; + public const string Recycling = ""; + public const string Redeem = ""; + public const string Redo = ""; + public const string ReduceCapacity = ""; + public const string Refresh = ""; + public const string RememberMe = ""; + public const string Remove = ""; + public const string RemoveCircle = ""; + public const string RemoveCircleOutline = ""; + public const string RemoveDone = ""; + public const string RemoveFromQueue = ""; + public const string RemoveModerator = ""; + public const string RemoveRedEye = ""; + public const string RemoveRoad = ""; + public const string RemoveShoppingCart = ""; + public const string Reorder = ""; + public const string Repeat = ""; + public const string RepeatOn = ""; + public const string RepeatOne = ""; + public const string RepeatOneOn = ""; + public const string Replay = ""; + public const string Replay10 = ""; + public const string Replay30 = ""; + public const string Replay5 = ""; + public const string ReplayCircleFilled = ""; + public const string Reply = ""; + public const string ReplyAll = ""; + public const string Report = ""; + public const string ReportGmailerrorred = ""; + public const string ReportOff = ""; + public const string ReportProblem = ""; + public const string RequestPage = ""; + public const string RequestQuote = ""; + public const string ResetTv = ""; + public const string RestartAlt = ""; + public const string Restaurant = ""; + public const string RestaurantMenu = ""; + public const string Restore = ""; + public const string RestoreFromTrash = ""; + public const string RestorePage = ""; + public const string Reviews = ""; + public const string RiceBowl = ""; + public const string RingVolume = ""; + public const string Rocket = ""; + public const string RocketLaunch = ""; + public const string RollerSkating = ""; + public const string Roofing = ""; + public const string Room = ""; + public const string RoomPreferences = ""; + public const string RoomService = ""; + public const string Rotate90DegreesCcw = ""; + public const string Rotate90DegreesCw = ""; + public const string RotateLeft = ""; + public const string RotateRight = ""; + public const string RoundaboutLeft = ""; + public const string RoundaboutRight = ""; + public const string RoundedCorner = ""; + public const string Route = ""; + public const string Router = ""; + public const string Rowing = ""; + public const string RssFeed = ""; + public const string Rsvp = ""; + public const string Rtt = ""; + public const string Rule = ""; + public const string RuleFolder = ""; + public const string RunCircle = ""; + public const string RunningWithErrors = ""; + public const string RvHookup = ""; + public const string SafetyCheck = ""; + public const string SafetyDivider = ""; + public const string Sailing = ""; + public const string Sanitizer = ""; + public const string Satellite = ""; + public const string SatelliteAlt = ""; + public const string Save = ""; + public const string SaveAlt = ""; + public const string SaveAs = ""; + public const string SavedSearch = ""; + public const string Savings = ""; + public const string Scale = ""; + public const string Scanner = ""; + public const string ScatterPlot = ""; + public const string Schedule = ""; + public const string ScheduleSend = ""; + public const string Schema = ""; + public const string School = ""; + public const string Science = ""; + public const string Score = ""; + public const string Scoreboard = ""; + public const string ScreenLockLandscape = ""; + public const string ScreenLockPortrait = ""; + public const string ScreenLockRotation = ""; + public const string ScreenRotation = ""; + public const string ScreenRotationAlt = ""; + public const string ScreenSearchDesktop = ""; + public const string ScreenShare = ""; + public const string Screenshot = ""; + public const string ScubaDiving = ""; + public const string Sd = ""; + public const string SdCard = ""; + public const string SdCardAlert = ""; + public const string SdStorage = ""; + public const string Search = ""; + public const string SearchOff = ""; + public const string Security = ""; + public const string SecurityUpdate = ""; + public const string SecurityUpdateGood = ""; + public const string SecurityUpdateWarning = ""; + public const string Segment = ""; + public const string SelectAll = ""; + public const string SelfImprovement = ""; + public const string Sell = ""; + public const string Send = ""; + public const string SendAndArchive = ""; + public const string SendTimeExtension = ""; + public const string SendToMobile = ""; + public const string SensorDoor = ""; + public const string SensorWindow = ""; + public const string Sensors = ""; + public const string SensorsOff = ""; + public const string SentimentDissatisfied = ""; + public const string SentimentNeutral = ""; + public const string SentimentSatisfied = ""; + public const string SentimentSatisfiedAlt = ""; + public const string SentimentVeryDissatisfied = ""; + public const string SentimentVerySatisfied = ""; + public const string SetMeal = ""; + public const string Settings = ""; + public const string SettingsAccessibility = ""; + public const string SettingsApplications = ""; + public const string SettingsBackupRestore = ""; + public const string SettingsBluetooth = ""; + public const string SettingsBrightness = ""; + public const string SettingsCell = ""; + public const string SettingsEthernet = ""; + public const string SettingsInputAntenna = ""; + public const string SettingsInputComponent = ""; + public const string SettingsInputComposite = ""; + public const string SettingsInputHdmi = ""; + public const string SettingsInputSvideo = ""; + public const string SettingsOverscan = ""; + public const string SettingsPhone = ""; + public const string SettingsPower = ""; + public const string SettingsRemote = ""; + public const string SettingsSuggest = ""; + public const string SettingsSystemDaydream = ""; + public const string SettingsVoice = ""; + public const string SevereCold = ""; + public const string Share = ""; + public const string ShareLocation = ""; + public const string Shield = ""; + public const string ShieldMoon = ""; + public const string Shop = ""; + public const string Shop2 = ""; + public const string ShopTwo = ""; + public const string ShoppingBag = ""; + public const string ShoppingBasket = ""; + public const string ShoppingCart = ""; + public const string ShoppingCartCheckout = ""; + public const string ShortText = ""; + public const string Shortcut = ""; + public const string ShowChart = ""; + public const string Shower = ""; + public const string Shuffle = ""; + public const string ShuffleOn = ""; + public const string ShutterSpeed = ""; + public const string Sick = ""; + public const string SignLanguage = ""; + public const string SignalCellular0Bar = ""; + public const string SignalCellular4Bar = ""; + public const string SignalCellularAlt = ""; + public const string SignalCellularAlt1Bar = ""; + public const string SignalCellularAlt2Bar = ""; + public const string SignalCellularConnectedNoInternet0Bar = ""; + public const string SignalCellularConnectedNoInternet4Bar = ""; + public const string SignalCellularNoSim = ""; + public const string SignalCellularNodata = ""; + public const string SignalCellularNull = ""; + public const string SignalCellularOff = ""; + public const string SignalWifi0Bar = ""; + public const string SignalWifi4Bar = ""; + public const string SignalWifi4BarLock = ""; + public const string SignalWifiBad = ""; + public const string SignalWifiConnectedNoInternet4 = ""; + public const string SignalWifiOff = ""; + public const string SignalWifiStatusbar4Bar = ""; + public const string SignalWifiStatusbarConnectedNoInternet4 = ""; + public const string SignalWifiStatusbarNull = ""; + public const string Signpost = ""; + public const string SimCard = ""; + public const string SimCardAlert = ""; + public const string SimCardDownload = ""; + public const string SingleBed = ""; + public const string Sip = ""; + public const string Skateboarding = ""; + public const string SkipNext = ""; + public const string SkipPrevious = ""; + public const string Sledding = ""; + public const string Slideshow = ""; + public const string SlowMotionVideo = ""; + public const string SmartButton = ""; + public const string SmartDisplay = ""; + public const string SmartScreen = ""; + public const string SmartToy = ""; + public const string Smartphone = ""; + public const string SmokeFree = ""; + public const string SmokingRooms = ""; + public const string Sms = ""; + public const string SmsFailed = ""; + public const string SnippetFolder = ""; + public const string Snooze = ""; + public const string Snowboarding = ""; + public const string Snowmobile = ""; + public const string Snowshoeing = ""; + public const string Soap = ""; + public const string SocialDistance = ""; + public const string Sort = ""; + public const string SortByAlpha = ""; + public const string Sos = ""; + public const string SoupKitchen = ""; + public const string Source = ""; + public const string South = ""; + public const string SouthAmerica = ""; + public const string SouthEast = ""; + public const string SouthWest = ""; + public const string Spa = ""; + public const string SpaceBar = ""; + public const string SpaceDashboard = ""; + public const string SpatialAudio = ""; + public const string SpatialAudioOff = ""; + public const string SpatialTracking = ""; + public const string Speaker = ""; + public const string SpeakerGroup = ""; + public const string SpeakerNotes = ""; + public const string SpeakerNotesOff = ""; + public const string SpeakerPhone = ""; + public const string Speed = ""; + public const string Spellcheck = ""; + public const string Splitscreen = ""; + public const string Spoke = ""; + public const string Sports = ""; + public const string SportsBar = ""; + public const string SportsBaseball = ""; + public const string SportsBasketball = ""; + public const string SportsCricket = ""; + public const string SportsEsports = ""; + public const string SportsFootball = ""; + public const string SportsGolf = ""; + public const string SportsGymnastics = ""; + public const string SportsHandball = ""; + public const string SportsHockey = ""; + public const string SportsKabaddi = ""; + public const string SportsMartialArts = ""; + public const string SportsMma = ""; + public const string SportsMotorsports = ""; + public const string SportsRugby = ""; + public const string SportsScore = ""; + public const string SportsSoccer = ""; + public const string SportsTennis = ""; + public const string SportsVolleyball = ""; + public const string Square = ""; + public const string SquareFoot = ""; + public const string SsidChart = ""; + public const string StackedBarChart = ""; + public const string StackedLineChart = ""; + public const string Stadium = ""; + public const string Stairs = ""; + public const string Star = ""; + public const string StarBorder = ""; + public const string StarBorderPurple500 = ""; + public const string StarHalf = ""; + public const string StarOutline = ""; + public const string StarPurple500 = ""; + public const string StarRate = ""; + public const string Stars = ""; + public const string Start = ""; + public const string StayCurrentLandscape = ""; + public const string StayCurrentPortrait = ""; + public const string StayPrimaryLandscape = ""; + public const string StayPrimaryPortrait = ""; + public const string StickyNote2 = ""; + public const string Stop = ""; + public const string StopCircle = ""; + public const string StopScreenShare = ""; + public const string Storage = ""; + public const string Store = ""; + public const string StoreMallDirectory = ""; + public const string Storefront = ""; + public const string Storm = ""; + public const string Straight = ""; + public const string Straighten = ""; + public const string Stream = ""; + public const string Streetview = ""; + public const string StrikethroughS = ""; + public const string Stroller = ""; + public const string Style = ""; + public const string SubdirectoryArrowLeft = ""; + public const string SubdirectoryArrowRight = ""; + public const string Subject = ""; + public const string Subscript = ""; + public const string Subscriptions = ""; + public const string Subtitles = ""; + public const string SubtitlesOff = ""; + public const string Subway = ""; + public const string Summarize = ""; + public const string Superscript = ""; + public const string SupervisedUserCircle = ""; + public const string SupervisorAccount = ""; + public const string Support = ""; + public const string SupportAgent = ""; + public const string Surfing = ""; + public const string SurroundSound = ""; + public const string SwapCalls = ""; + public const string SwapHoriz = ""; + public const string SwapHorizontalCircle = ""; + public const string SwapVert = ""; + public const string SwapVerticalCircle = ""; + public const string Swipe = ""; + public const string SwipeDown = ""; + public const string SwipeDownAlt = ""; + public const string SwipeLeft = ""; + public const string SwipeLeftAlt = ""; + public const string SwipeRight = ""; + public const string SwipeRightAlt = ""; + public const string SwipeUp = ""; + public const string SwipeUpAlt = ""; + public const string SwipeVertical = ""; + public const string SwitchAccessShortcut = ""; + public const string SwitchAccessShortcutAdd = ""; + public const string SwitchAccount = ""; + public const string SwitchCamera = ""; + public const string SwitchLeft = ""; + public const string SwitchRight = ""; + public const string SwitchVideo = ""; + public const string Synagogue = ""; + public const string Sync = ""; + public const string SyncAlt = ""; + public const string SyncDisabled = ""; + public const string SyncLock = ""; + public const string SyncProblem = ""; + public const string SystemSecurityUpdate = ""; + public const string SystemSecurityUpdateGood = ""; + public const string SystemSecurityUpdateWarning = ""; + public const string SystemUpdate = ""; + public const string SystemUpdateAlt = ""; + public const string Tab = ""; + public const string TabUnselected = ""; + public const string TableBar = ""; + public const string TableChart = ""; + public const string TableRestaurant = ""; + public const string TableRows = ""; + public const string TableView = ""; + public const string Tablet = ""; + public const string TabletAndroid = ""; + public const string TabletMac = ""; + public const string Tag = ""; + public const string TagFaces = ""; + public const string TakeoutDining = ""; + public const string TapAndPlay = ""; + public const string Tapas = ""; + public const string Task = ""; + public const string TaskAlt = ""; + public const string TaxiAlert = ""; + public const string TempleBuddhist = ""; + public const string TempleHindu = ""; + public const string Terminal = ""; + public const string Terrain = ""; + public const string TextDecrease = ""; + public const string TextFields = ""; + public const string TextFormat = ""; + public const string TextIncrease = ""; + public const string TextRotateUp = ""; + public const string TextRotateVertical = ""; + public const string TextRotationAngledown = ""; + public const string TextRotationAngleup = ""; + public const string TextRotationDown = ""; + public const string TextRotationNone = ""; + public const string TextSnippet = ""; + public const string Textsms = ""; + public const string Texture = ""; + public const string TheaterComedy = ""; + public const string Theaters = ""; + public const string Thermostat = ""; + public const string ThermostatAuto = ""; + public const string ThumbDown = ""; + public const string ThumbDownAlt = ""; + public const string ThumbDownOffAlt = ""; + public const string ThumbUp = ""; + public const string ThumbUpAlt = ""; + public const string ThumbUpOffAlt = ""; + public const string ThumbsUpDown = ""; + public const string Thunderstorm = ""; + public const string TimeToLeave = ""; + public const string Timelapse = ""; + public const string Timeline = ""; + public const string Timer = ""; + public const string Timer10 = ""; + public const string Timer10Select = ""; + public const string Timer3 = ""; + public const string Timer3Select = ""; + public const string TimerOff = ""; + public const string TipsAndUpdates = ""; + public const string TireRepair = ""; + public const string Title = ""; + public const string Toc = ""; + public const string Today = ""; + public const string ToggleOff = ""; + public const string ToggleOn = ""; + public const string Token = ""; + public const string Toll = ""; + public const string Tonality = ""; + public const string Topic = ""; + public const string TouchApp = ""; + public const string Tour = ""; + public const string Toys = ""; + public const string TrackChanges = ""; + public const string Traffic = ""; + public const string Train = ""; + public const string Tram = ""; + public const string TransferWithinAStation = ""; + public const string Transform = ""; + public const string Transgender = ""; + public const string TransitEnterexit = ""; + public const string Translate = ""; + public const string TravelExplore = ""; + public const string TrendingDown = ""; + public const string TrendingFlat = ""; + public const string TrendingUp = ""; + public const string TripOrigin = ""; + public const string Try = ""; + public const string Tsunami = ""; + public const string Tty = ""; + public const string Tune = ""; + public const string Tungsten = ""; + public const string TurnLeft = ""; + public const string TurnRight = ""; + public const string TurnSharpLeft = ""; + public const string TurnSharpRight = ""; + public const string TurnSlightLeft = ""; + public const string TurnSlightRight = ""; + public const string TurnedIn = ""; + public const string TurnedInNot = ""; + public const string Tv = ""; + public const string TvOff = ""; + public const string TwoWheeler = ""; + public const string UTurnLeft = ""; + public const string UTurnRight = ""; + public const string Umbrella = ""; + public const string Unarchive = ""; + public const string Undo = ""; + public const string UnfoldLess = ""; + public const string UnfoldMore = ""; + public const string Unpublished = ""; + public const string Unsubscribe = ""; + public const string Upcoming = ""; + public const string Update = ""; + public const string UpdateDisabled = ""; + public const string Upgrade = ""; + public const string Upload = ""; + public const string UploadFile = ""; + public const string Usb = ""; + public const string UsbOff = ""; + public const string Vaccines = ""; + public const string VapeFree = ""; + public const string VapingRooms = ""; + public const string Verified = ""; + public const string VerifiedUser = ""; + public const string VerticalAlignBottom = ""; + public const string VerticalAlignCenter = ""; + public const string VerticalAlignTop = ""; + public const string VerticalDistribute = ""; + public const string VerticalSplit = ""; + public const string Vibration = ""; + public const string VideoCall = ""; + public const string VideoCameraBack = ""; + public const string VideoCameraFront = ""; + public const string VideoFile = ""; + public const string VideoLabel = ""; + public const string VideoLibrary = ""; + public const string VideoSettings = ""; + public const string VideoStable = ""; + public const string Videocam = ""; + public const string VideocamOff = ""; + public const string VideogameAsset = ""; + public const string VideogameAssetOff = ""; + public const string ViewAgenda = ""; + public const string ViewArray = ""; + public const string ViewCarousel = ""; + public const string ViewColumn = ""; + public const string ViewComfy = ""; + public const string ViewComfyAlt = ""; + public const string ViewCompact = ""; + public const string ViewCompactAlt = ""; + public const string ViewCozy = ""; + public const string ViewDay = ""; + public const string ViewHeadline = ""; + public const string ViewInAr = ""; + public const string ViewKanban = ""; + public const string ViewList = ""; + public const string ViewModule = ""; + public const string ViewQuilt = ""; + public const string ViewSidebar = ""; + public const string ViewStream = ""; + public const string ViewTimeline = ""; + public const string ViewWeek = ""; + public const string Vignette = ""; + public const string Villa = ""; + public const string Visibility = ""; + public const string VisibilityOff = ""; + public const string VoiceChat = ""; + public const string VoiceOverOff = ""; + public const string Voicemail = ""; + public const string Volcano = ""; + public const string VolumeDown = ""; + public const string VolumeMute = ""; + public const string VolumeOff = ""; + public const string VolumeUp = ""; + public const string VolunteerActivism = ""; + public const string VpnKey = ""; + public const string VpnKeyOff = ""; + public const string VpnLock = ""; + public const string Vrpano = ""; + public const string Wallpaper = ""; + public const string Warehouse = ""; + public const string Warning = ""; + public const string WarningAmber = ""; + public const string Wash = ""; + public const string Watch = ""; + public const string WatchLater = ""; + public const string WatchOff = ""; + public const string Water = ""; + public const string WaterDamage = ""; + public const string WaterDrop = ""; + public const string WaterfallChart = ""; + public const string Waves = ""; + public const string WavingHand = ""; + public const string WbAuto = ""; + public const string WbCloudy = ""; + public const string WbIncandescent = ""; + public const string WbIridescent = ""; + public const string WbShade = ""; + public const string WbSunny = ""; + public const string WbTwilight = ""; + public const string Wc = ""; + public const string Web = ""; + public const string WebAsset = ""; + public const string WebAssetOff = ""; + public const string Webhook = ""; + public const string Weekend = ""; + public const string West = ""; + public const string Whatsapp = ""; + public const string Whatshot = ""; + public const string WheelchairPickup = ""; + public const string WhereToVote = ""; + public const string Widgets = ""; + public const string Wifi = ""; + public const string Wifi1Bar = ""; + public const string Wifi2Bar = ""; + public const string WifiCalling = ""; + public const string WifiCalling3 = ""; + public const string WifiChannel = ""; + public const string WifiFind = ""; + public const string WifiLock = ""; + public const string WifiOff = ""; + public const string WifiPassword = ""; + public const string WifiProtectedSetup = ""; + public const string WifiTethering = ""; + public const string WifiTetheringError = ""; + public const string WifiTetheringOff = ""; + public const string Window = ""; + public const string WineBar = ""; + public const string Woman = ""; + public const string Work = ""; + public const string WorkOff = ""; + public const string WorkOutline = ""; + public const string WorkspacePremium = ""; + public const string Workspaces = ""; + public const string WrapText = ""; + public const string WrongLocation = ""; + public const string Wysiwyg = ""; + public const string Yard = ""; + public const string YoutubeSearchedFor = ""; + public const string ZoomIn = ""; + public const string ZoomInMap = ""; + public const string ZoomOut = ""; + public const string ZoomOutMap = ""; + } + } + } +} diff --git a/Icons/Material/TwoTone.cs b/Icons/Material/TwoTone.cs new file mode 100644 index 0000000..2cd5e57 --- /dev/null +++ b/Icons/Material/TwoTone.cs @@ -0,0 +1,2069 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + public partial class Material + { + [ExcludeFromCodeCoverage] + public class TwoTone + { + public const string _10k = ""; + public const string _10mp = ""; + public const string _11mp = ""; + public const string _123 = ""; + public const string _12mp = ""; + public const string _13mp = ""; + public const string _14mp = ""; + public const string _15mp = ""; + public const string _16mp = ""; + public const string _17mp = ""; + public const string _18mp = ""; + public const string _19mp = ""; + public const string _1k = ""; + public const string _1kPlus = ""; + public const string _1xMobiledata = ""; + public const string _20mp = ""; + public const string _21mp = ""; + public const string _22mp = ""; + public const string _23mp = ""; + public const string _24mp = ""; + public const string _2k = ""; + public const string _2kPlus = ""; + public const string _2mp = ""; + public const string _30fps = ""; + public const string _30fpsSelect = ""; + public const string _360 = ""; + public const string _3dRotation = ""; + public const string _3gMobiledata = ""; + public const string _3k = ""; + public const string _3kPlus = ""; + public const string _3mp = ""; + public const string _3p = ""; + public const string _4gMobiledata = ""; + public const string _4gPlusMobiledata = ""; + public const string _4k = ""; + public const string _4kPlus = ""; + public const string _4mp = ""; + public const string _5g = ""; + public const string _5k = ""; + public const string _5kPlus = ""; + public const string _5mp = ""; + public const string _60fps = ""; + public const string _60fpsSelect = ""; + public const string _6FtApart = ""; + public const string _6k = ""; + public const string _6kPlus = ""; + public const string _6mp = ""; + public const string _7k = ""; + public const string _7kPlus = ""; + public const string _7mp = ""; + public const string _8k = ""; + public const string _8kPlus = ""; + public const string _8mp = ""; + public const string _9k = ""; + public const string _9kPlus = ""; + public const string _9mp = ""; + public const string Abc = ""; + public const string AcUnit = ""; + public const string AccessAlarm = ""; + public const string AccessAlarms = ""; + public const string AccessTime = ""; + public const string AccessTimeFilled = ""; + public const string Accessibility = ""; + public const string AccessibilityNew = ""; + public const string Accessible = ""; + public const string AccessibleForward = ""; + public const string AccountBalance = ""; + public const string AccountBalanceWallet = ""; + public const string AccountBox = ""; + public const string AccountCircle = ""; + public const string AccountTree = ""; + public const string AdUnits = ""; + public const string Adb = ""; + public const string Add = ""; + public const string AddAPhoto = ""; + public const string AddAlarm = ""; + public const string AddAlert = ""; + public const string AddBox = ""; + public const string AddBusiness = ""; + public const string AddCard = ""; + public const string AddChart = ""; + public const string AddCircle = ""; + public const string AddCircleOutline = ""; + public const string AddComment = ""; + public const string AddIcCall = ""; + public const string AddLink = ""; + public const string AddLocation = ""; + public const string AddLocationAlt = ""; + public const string AddModerator = ""; + public const string AddPhotoAlternate = ""; + public const string AddReaction = ""; + public const string AddRoad = ""; + public const string AddShoppingCart = ""; + public const string AddTask = ""; + public const string AddToDrive = ""; + public const string AddToHomeScreen = ""; + public const string AddToPhotos = ""; + public const string AddToQueue = ""; + public const string Addchart = ""; + public const string AdfScanner = ""; + public const string Adjust = ""; + public const string AdminPanelSettings = ""; + public const string AdsClick = ""; + public const string Agriculture = ""; + public const string Air = ""; + public const string AirlineSeatFlat = ""; + public const string AirlineSeatFlatAngled = ""; + public const string AirlineSeatIndividualSuite = ""; + public const string AirlineSeatLegroomExtra = ""; + public const string AirlineSeatLegroomNormal = ""; + public const string AirlineSeatLegroomReduced = ""; + public const string AirlineSeatReclineExtra = ""; + public const string AirlineSeatReclineNormal = ""; + public const string AirlineStops = ""; + public const string Airlines = ""; + public const string AirplaneTicket = ""; + public const string AirplanemodeActive = ""; + public const string AirplanemodeInactive = ""; + public const string Airplay = ""; + public const string AirportShuttle = ""; + public const string Alarm = ""; + public const string AlarmAdd = ""; + public const string AlarmOff = ""; + public const string AlarmOn = ""; + public const string Album = ""; + public const string AlignHorizontalCenter = ""; + public const string AlignHorizontalLeft = ""; + public const string AlignHorizontalRight = ""; + public const string AlignVerticalBottom = ""; + public const string AlignVerticalCenter = ""; + public const string AlignVerticalTop = ""; + public const string AllInbox = ""; + public const string AllInclusive = ""; + public const string AllOut = ""; + public const string AltRoute = ""; + public const string AlternateEmail = ""; + public const string Analytics = ""; + public const string Anchor = ""; + public const string Android = ""; + public const string Animation = ""; + public const string Announcement = ""; + public const string Aod = ""; + public const string Apartment = ""; + public const string Api = ""; + public const string AppBlocking = ""; + public const string AppRegistration = ""; + public const string AppSettingsAlt = ""; + public const string AppShortcut = ""; + public const string Approval = ""; + public const string Apps = ""; + public const string AppsOutage = ""; + public const string Architecture = ""; + public const string Archive = ""; + public const string AreaChart = ""; + public const string ArrowBack = ""; + public const string ArrowBackIos = ""; + public const string ArrowBackIosNew = ""; + public const string ArrowCircleDown = ""; + public const string ArrowCircleLeft = ""; + public const string ArrowCircleRight = ""; + public const string ArrowCircleUp = ""; + public const string ArrowDownward = ""; + public const string ArrowDropDown = ""; + public const string ArrowDropDownCircle = ""; + public const string ArrowDropUp = ""; + public const string ArrowForward = ""; + public const string ArrowForwardIos = ""; + public const string ArrowLeft = ""; + public const string ArrowRight = ""; + public const string ArrowRightAlt = ""; + public const string ArrowUpward = ""; + public const string ArtTrack = ""; + public const string Article = ""; + public const string AspectRatio = ""; + public const string Assessment = ""; + public const string Assignment = ""; + public const string AssignmentInd = ""; + public const string AssignmentLate = ""; + public const string AssignmentReturn = ""; + public const string AssignmentReturned = ""; + public const string AssignmentTurnedIn = ""; + public const string Assistant = ""; + public const string AssistantDirection = ""; + public const string AssistantPhoto = ""; + public const string AssuredWorkload = ""; + public const string Atm = ""; + public const string AttachEmail = ""; + public const string AttachFile = ""; + public const string AttachMoney = ""; + public const string Attachment = ""; + public const string Attractions = ""; + public const string Attribution = ""; + public const string AudioFile = ""; + public const string Audiotrack = ""; + public const string AutoAwesome = ""; + public const string AutoAwesomeMosaic = ""; + public const string AutoAwesomeMotion = ""; + public const string AutoDelete = ""; + public const string AutoFixHigh = ""; + public const string AutoFixNormal = ""; + public const string AutoFixOff = ""; + public const string AutoGraph = ""; + public const string AutoStories = ""; + public const string AutofpsSelect = ""; + public const string Autorenew = ""; + public const string AvTimer = ""; + public const string BabyChangingStation = ""; + public const string BackHand = ""; + public const string Backpack = ""; + public const string Backspace = ""; + public const string Backup = ""; + public const string BackupTable = ""; + public const string Badge = ""; + public const string BakeryDining = ""; + public const string Balance = ""; + public const string Balcony = ""; + public const string Ballot = ""; + public const string BarChart = ""; + public const string BatchPrediction = ""; + public const string Bathroom = ""; + public const string Bathtub = ""; + public const string Battery0Bar = ""; + public const string Battery1Bar = ""; + public const string Battery2Bar = ""; + public const string Battery3Bar = ""; + public const string Battery4Bar = ""; + public const string Battery5Bar = ""; + public const string Battery6Bar = ""; + public const string BatteryAlert = ""; + public const string BatteryChargingFull = ""; + public const string BatteryFull = ""; + public const string BatterySaver = ""; + public const string BatteryStd = ""; + public const string BatteryUnknown = ""; + public const string BeachAccess = ""; + public const string Bed = ""; + public const string BedroomBaby = ""; + public const string BedroomChild = ""; + public const string BedroomParent = ""; + public const string Bedtime = ""; + public const string BedtimeOff = ""; + public const string Beenhere = ""; + public const string Bento = ""; + public const string BikeScooter = ""; + public const string Biotech = ""; + public const string Blender = ""; + public const string Block = ""; + public const string Bloodtype = ""; + public const string Bluetooth = ""; + public const string BluetoothAudio = ""; + public const string BluetoothConnected = ""; + public const string BluetoothDisabled = ""; + public const string BluetoothDrive = ""; + public const string BluetoothSearching = ""; + public const string BlurCircular = ""; + public const string BlurLinear = ""; + public const string BlurOff = ""; + public const string BlurOn = ""; + public const string Bolt = ""; + public const string Book = ""; + public const string BookOnline = ""; + public const string Bookmark = ""; + public const string BookmarkAdd = ""; + public const string BookmarkAdded = ""; + public const string BookmarkBorder = ""; + public const string BookmarkRemove = ""; + public const string Bookmarks = ""; + public const string BorderAll = ""; + public const string BorderBottom = ""; + public const string BorderClear = ""; + public const string BorderColor = ""; + public const string BorderHorizontal = ""; + public const string BorderInner = ""; + public const string BorderLeft = ""; + public const string BorderOuter = ""; + public const string BorderRight = ""; + public const string BorderStyle = ""; + public const string BorderTop = ""; + public const string BorderVertical = ""; + public const string Boy = ""; + public const string BrandingWatermark = ""; + public const string BreakfastDining = ""; + public const string Brightness1 = ""; + public const string Brightness2 = ""; + public const string Brightness3 = ""; + public const string Brightness4 = ""; + public const string Brightness5 = ""; + public const string Brightness6 = ""; + public const string Brightness7 = ""; + public const string BrightnessAuto = ""; + public const string BrightnessHigh = ""; + public const string BrightnessLow = ""; + public const string BrightnessMedium = ""; + public const string BrokenImage = ""; + public const string BrowseGallery = ""; + public const string BrowserNotSupported = ""; + public const string BrowserUpdated = ""; + public const string BrunchDining = ""; + public const string Brush = ""; + public const string BubbleChart = ""; + public const string BugReport = ""; + public const string Build = ""; + public const string BuildCircle = ""; + public const string Bungalow = ""; + public const string BurstMode = ""; + public const string BusAlert = ""; + public const string Business = ""; + public const string BusinessCenter = ""; + public const string Cabin = ""; + public const string Cable = ""; + public const string Cached = ""; + public const string Cake = ""; + public const string Calculate = ""; + public const string CalendarMonth = ""; + public const string CalendarToday = ""; + public const string CalendarViewDay = ""; + public const string CalendarViewMonth = ""; + public const string CalendarViewWeek = ""; + public const string Call = ""; + public const string CallEnd = ""; + public const string CallMade = ""; + public const string CallMerge = ""; + public const string CallMissed = ""; + public const string CallMissedOutgoing = ""; + public const string CallReceived = ""; + public const string CallSplit = ""; + public const string CallToAction = ""; + public const string Camera = ""; + public const string CameraAlt = ""; + public const string CameraEnhance = ""; + public const string CameraFront = ""; + public const string CameraIndoor = ""; + public const string CameraOutdoor = ""; + public const string CameraRear = ""; + public const string CameraRoll = ""; + public const string Cameraswitch = ""; + public const string Campaign = ""; + public const string Cancel = ""; + public const string CancelPresentation = ""; + public const string CancelScheduleSend = ""; + public const string CandlestickChart = ""; + public const string CarCrash = ""; + public const string CarRental = ""; + public const string CarRepair = ""; + public const string CardGiftcard = ""; + public const string CardMembership = ""; + public const string CardTravel = ""; + public const string Carpenter = ""; + public const string Cases = ""; + public const string Casino = ""; + public const string Cast = ""; + public const string CastConnected = ""; + public const string CastForEducation = ""; + public const string Castle = ""; + public const string CatchingPokemon = ""; + public const string Category = ""; + public const string Celebration = ""; + public const string CellTower = ""; + public const string CellWifi = ""; + public const string CenterFocusStrong = ""; + public const string CenterFocusWeak = ""; + public const string Chair = ""; + public const string ChairAlt = ""; + public const string Chalet = ""; + public const string ChangeCircle = ""; + public const string ChangeHistory = ""; + public const string ChargingStation = ""; + public const string Chat = ""; + public const string ChatBubble = ""; + public const string ChatBubbleOutline = ""; + public const string Check = ""; + public const string CheckBox = ""; + public const string CheckBoxOutlineBlank = ""; + public const string CheckCircle = ""; + public const string CheckCircleOutline = ""; + public const string Checklist = ""; + public const string ChecklistRtl = ""; + public const string Checkroom = ""; + public const string ChevronLeft = ""; + public const string ChevronRight = ""; + public const string ChildCare = ""; + public const string ChildFriendly = ""; + public const string ChromeReaderMode = ""; + public const string Church = ""; + public const string Circle = ""; + public const string CircleNotifications = ""; + public const string Class = ""; + public const string CleanHands = ""; + public const string CleaningServices = ""; + public const string Clear = ""; + public const string ClearAll = ""; + public const string Close = ""; + public const string CloseFullscreen = ""; + public const string ClosedCaption = ""; + public const string ClosedCaptionDisabled = ""; + public const string ClosedCaptionOff = ""; + public const string Cloud = ""; + public const string CloudCircle = ""; + public const string CloudDone = ""; + public const string CloudDownload = ""; + public const string CloudOff = ""; + public const string CloudQueue = ""; + public const string CloudSync = ""; + public const string CloudUpload = ""; + public const string Co2 = ""; + public const string CoPresent = ""; + public const string Code = ""; + public const string CodeOff = ""; + public const string Coffee = ""; + public const string CoffeeMaker = ""; + public const string Collections = ""; + public const string CollectionsBookmark = ""; + public const string ColorLens = ""; + public const string Colorize = ""; + public const string Comment = ""; + public const string CommentBank = ""; + public const string CommentsDisabled = ""; + public const string Commit = ""; + public const string Commute = ""; + public const string Compare = ""; + public const string CompareArrows = ""; + public const string CompassCalibration = ""; + public const string Compost = ""; + public const string Compress = ""; + public const string Computer = ""; + public const string ConfirmationNumber = ""; + public const string ConnectWithoutContact = ""; + public const string ConnectedTv = ""; + public const string ConnectingAirports = ""; + public const string Construction = ""; + public const string ContactMail = ""; + public const string ContactPage = ""; + public const string ContactPhone = ""; + public const string ContactSupport = ""; + public const string Contactless = ""; + public const string Contacts = ""; + public const string ContentCopy = ""; + public const string ContentCut = ""; + public const string ContentPaste = ""; + public const string ContentPasteGo = ""; + public const string ContentPasteOff = ""; + public const string ContentPasteSearch = ""; + public const string Contrast = ""; + public const string ControlCamera = ""; + public const string ControlPoint = ""; + public const string ControlPointDuplicate = ""; + public const string Cookie = ""; + public const string CopyAll = ""; + public const string Copyright = ""; + public const string Coronavirus = ""; + public const string CorporateFare = ""; + public const string Cottage = ""; + public const string Countertops = ""; + public const string Create = ""; + public const string CreateNewFolder = ""; + public const string CreditCard = ""; + public const string CreditCardOff = ""; + public const string CreditScore = ""; + public const string Crib = ""; + public const string CrisisAlert = ""; + public const string Crop = ""; + public const string Crop169 = ""; + public const string Crop32 = ""; + public const string Crop54 = ""; + public const string Crop75 = ""; + public const string CropDin = ""; + public const string CropFree = ""; + public const string CropLandscape = ""; + public const string CropOriginal = ""; + public const string CropPortrait = ""; + public const string CropRotate = ""; + public const string CropSquare = ""; + public const string CrueltyFree = ""; + public const string Css = ""; + public const string CurrencyBitcoin = ""; + public const string CurrencyExchange = ""; + public const string CurrencyFranc = ""; + public const string CurrencyLira = ""; + public const string CurrencyPound = ""; + public const string CurrencyRuble = ""; + public const string CurrencyRupee = ""; + public const string CurrencyYen = ""; + public const string CurrencyYuan = ""; + public const string Cyclone = ""; + public const string Dangerous = ""; + public const string DarkMode = ""; + public const string Dashboard = ""; + public const string DashboardCustomize = ""; + public const string DataArray = ""; + public const string DataExploration = ""; + public const string DataObject = ""; + public const string DataSaverOff = ""; + public const string DataSaverOn = ""; + public const string DataThresholding = ""; + public const string DataUsage = ""; + public const string DateRange = ""; + public const string Deblur = ""; + public const string Deck = ""; + public const string Dehaze = ""; + public const string Delete = ""; + public const string DeleteForever = ""; + public const string DeleteOutline = ""; + public const string DeleteSweep = ""; + public const string DeliveryDining = ""; + public const string DensityLarge = ""; + public const string DensityMedium = ""; + public const string DensitySmall = ""; + public const string DepartureBoard = ""; + public const string Description = ""; + public const string Deselect = ""; + public const string DesignServices = ""; + public const string DesktopAccessDisabled = ""; + public const string DesktopMac = ""; + public const string DesktopWindows = ""; + public const string Details = ""; + public const string DeveloperBoard = ""; + public const string DeveloperBoardOff = ""; + public const string DeveloperMode = ""; + public const string DeviceHub = ""; + public const string DeviceThermostat = ""; + public const string DeviceUnknown = ""; + public const string Devices = ""; + public const string DevicesFold = ""; + public const string DevicesOther = ""; + public const string DialerSip = ""; + public const string Dialpad = ""; + public const string Diamond = ""; + public const string Difference = ""; + public const string Dining = ""; + public const string DinnerDining = ""; + public const string Directions = ""; + public const string DirectionsBike = ""; + public const string DirectionsBoat = ""; + public const string DirectionsBoatFilled = ""; + public const string DirectionsBus = ""; + public const string DirectionsBusFilled = ""; + public const string DirectionsCar = ""; + public const string DirectionsCarFilled = ""; + public const string DirectionsOff = ""; + public const string DirectionsRailway = ""; + public const string DirectionsRailwayFilled = ""; + public const string DirectionsRun = ""; + public const string DirectionsSubway = ""; + public const string DirectionsSubwayFilled = ""; + public const string DirectionsTransit = ""; + public const string DirectionsTransitFilled = ""; + public const string DirectionsWalk = ""; + public const string DirtyLens = ""; + public const string DisabledByDefault = ""; + public const string DisabledVisible = ""; + public const string DiscFull = ""; + public const string Discount = ""; + public const string DisplaySettings = ""; + public const string Dns = ""; + public const string DoDisturb = ""; + public const string DoDisturbAlt = ""; + public const string DoDisturbOff = ""; + public const string DoDisturbOn = ""; + public const string DoNotDisturb = ""; + public const string DoNotDisturbAlt = ""; + public const string DoNotDisturbOff = ""; + public const string DoNotDisturbOn = ""; + public const string DoNotDisturbOnTotalSilence = ""; + public const string DoNotStep = ""; + public const string DoNotTouch = ""; + public const string Dock = ""; + public const string DocumentScanner = ""; + public const string Domain = ""; + public const string DomainAdd = ""; + public const string DomainDisabled = ""; + public const string DomainVerification = ""; + public const string Done = ""; + public const string DoneAll = ""; + public const string DoneOutline = ""; + public const string DonutLarge = ""; + public const string DonutSmall = ""; + public const string DoorBack = ""; + public const string DoorFront = ""; + public const string DoorSliding = ""; + public const string Doorbell = ""; + public const string DoubleArrow = ""; + public const string DownhillSkiing = ""; + public const string Download = ""; + public const string DownloadDone = ""; + public const string DownloadForOffline = ""; + public const string Downloading = ""; + public const string Drafts = ""; + public const string DragHandle = ""; + public const string DragIndicator = ""; + public const string Draw = ""; + public const string DriveEta = ""; + public const string DriveFileMove = ""; + public const string DriveFileMoveRtl = ""; + public const string DriveFileRenameOutline = ""; + public const string DriveFolderUpload = ""; + public const string Dry = ""; + public const string DryCleaning = ""; + public const string Duo = ""; + public const string Dvr = ""; + public const string DynamicFeed = ""; + public const string DynamicForm = ""; + public const string EMobiledata = ""; + public const string Earbuds = ""; + public const string EarbudsBattery = ""; + public const string East = ""; + public const string EdgesensorHigh = ""; + public const string EdgesensorLow = ""; + public const string Edit = ""; + public const string EditAttributes = ""; + public const string EditCalendar = ""; + public const string EditLocation = ""; + public const string EditLocationAlt = ""; + public const string EditNote = ""; + public const string EditNotifications = ""; + public const string EditOff = ""; + public const string EditRoad = ""; + public const string Egg = ""; + public const string EggAlt = ""; + public const string Eject = ""; + public const string Elderly = ""; + public const string ElderlyWoman = ""; + public const string ElectricBike = ""; + public const string ElectricCar = ""; + public const string ElectricMoped = ""; + public const string ElectricRickshaw = ""; + public const string ElectricScooter = ""; + public const string ElectricalServices = ""; + public const string Elevator = ""; + public const string Email = ""; + public const string Emergency = ""; + public const string EmergencyRecording = ""; + public const string EmergencyShare = ""; + public const string EmojiEmotions = ""; + public const string EmojiEvents = ""; + public const string EmojiFoodBeverage = ""; + public const string EmojiNature = ""; + public const string EmojiObjects = ""; + public const string EmojiPeople = ""; + public const string EmojiSymbols = ""; + public const string EmojiTransportation = ""; + public const string Engineering = ""; + public const string EnhancedEncryption = ""; + public const string Equalizer = ""; + public const string Error = ""; + public const string ErrorOutline = ""; + public const string Escalator = ""; + public const string EscalatorWarning = ""; + public const string Euro = ""; + public const string EuroSymbol = ""; + public const string EvStation = ""; + public const string Event = ""; + public const string EventAvailable = ""; + public const string EventBusy = ""; + public const string EventNote = ""; + public const string EventRepeat = ""; + public const string EventSeat = ""; + public const string ExitToApp = ""; + public const string Expand = ""; + public const string ExpandCircleDown = ""; + public const string ExpandLess = ""; + public const string ExpandMore = ""; + public const string Explicit = ""; + public const string Explore = ""; + public const string ExploreOff = ""; + public const string Exposure = ""; + public const string ExposureNeg1 = ""; + public const string ExposureNeg2 = ""; + public const string ExposurePlus1 = ""; + public const string ExposurePlus2 = ""; + public const string ExposureZero = ""; + public const string Extension = ""; + public const string ExtensionOff = ""; + public const string Face = ""; + public const string FaceRetouchingNatural = ""; + public const string FaceRetouchingOff = ""; + public const string FactCheck = ""; + public const string Factory = ""; + public const string FamilyRestroom = ""; + public const string FastForward = ""; + public const string FastRewind = ""; + public const string Fastfood = ""; + public const string Favorite = ""; + public const string FavoriteBorder = ""; + public const string Fax = ""; + public const string FeaturedPlayList = ""; + public const string FeaturedVideo = ""; + public const string Feed = ""; + public const string Feedback = ""; + public const string Female = ""; + public const string Fence = ""; + public const string Festival = ""; + public const string FiberDvr = ""; + public const string FiberManualRecord = ""; + public const string FiberNew = ""; + public const string FiberPin = ""; + public const string FiberSmartRecord = ""; + public const string FileCopy = ""; + public const string FileDownload = ""; + public const string FileDownloadDone = ""; + public const string FileDownloadOff = ""; + public const string FileOpen = ""; + public const string FilePresent = ""; + public const string FileUpload = ""; + public const string Filter = ""; + public const string Filter1 = ""; + public const string Filter2 = ""; + public const string Filter3 = ""; + public const string Filter4 = ""; + public const string Filter5 = ""; + public const string Filter6 = ""; + public const string Filter7 = ""; + public const string Filter8 = ""; + public const string Filter9 = ""; + public const string Filter9Plus = ""; + public const string FilterAlt = ""; + public const string FilterAltOff = ""; + public const string FilterBAndW = ""; + public const string FilterCenterFocus = ""; + public const string FilterDrama = ""; + public const string FilterFrames = ""; + public const string FilterHdr = ""; + public const string FilterList = ""; + public const string FilterListOff = ""; + public const string FilterNone = ""; + public const string FilterTiltShift = ""; + public const string FilterVintage = ""; + public const string FindInPage = ""; + public const string FindReplace = ""; + public const string Fingerprint = ""; + public const string FireExtinguisher = ""; + public const string Fireplace = ""; + public const string FirstPage = ""; + public const string FitScreen = ""; + public const string Fitbit = ""; + public const string FitnessCenter = ""; + public const string Flag = ""; + public const string FlagCircle = ""; + public const string Flaky = ""; + public const string Flare = ""; + public const string FlashAuto = ""; + public const string FlashOff = ""; + public const string FlashOn = ""; + public const string FlashlightOff = ""; + public const string FlashlightOn = ""; + public const string Flatware = ""; + public const string Flight = ""; + public const string FlightClass = ""; + public const string FlightLand = ""; + public const string FlightTakeoff = ""; + public const string Flip = ""; + public const string FlipCameraAndroid = ""; + public const string FlipCameraIos = ""; + public const string FlipToBack = ""; + public const string FlipToFront = ""; + public const string Flood = ""; + public const string Flourescent = ""; + public const string FlutterDash = ""; + public const string FmdBad = ""; + public const string FmdGood = ""; + public const string Folder = ""; + public const string FolderCopy = ""; + public const string FolderDelete = ""; + public const string FolderOff = ""; + public const string FolderOpen = ""; + public const string FolderShared = ""; + public const string FolderSpecial = ""; + public const string FolderZip = ""; + public const string FollowTheSigns = ""; + public const string FontDownload = ""; + public const string FontDownloadOff = ""; + public const string FoodBank = ""; + public const string Forest = ""; + public const string ForkLeft = ""; + public const string ForkRight = ""; + public const string FormatAlignCenter = ""; + public const string FormatAlignJustify = ""; + public const string FormatAlignLeft = ""; + public const string FormatAlignRight = ""; + public const string FormatBold = ""; + public const string FormatClear = ""; + public const string FormatColorFill = ""; + public const string FormatColorReset = ""; + public const string FormatColorText = ""; + public const string FormatIndentDecrease = ""; + public const string FormatIndentIncrease = ""; + public const string FormatItalic = ""; + public const string FormatLineSpacing = ""; + public const string FormatListBulleted = ""; + public const string FormatListNumbered = ""; + public const string FormatListNumberedRtl = ""; + public const string FormatOverline = ""; + public const string FormatPaint = ""; + public const string FormatQuote = ""; + public const string FormatShapes = ""; + public const string FormatSize = ""; + public const string FormatStrikethrough = ""; + public const string FormatTextdirectionLToR = ""; + public const string FormatTextdirectionRToL = ""; + public const string FormatUnderlined = ""; + public const string Fort = ""; + public const string Forum = ""; + public const string Forward = ""; + public const string Forward10 = ""; + public const string Forward30 = ""; + public const string Forward5 = ""; + public const string ForwardToInbox = ""; + public const string Foundation = ""; + public const string FreeBreakfast = ""; + public const string FreeCancellation = ""; + public const string FrontHand = ""; + public const string Fullscreen = ""; + public const string FullscreenExit = ""; + public const string Functions = ""; + public const string GMobiledata = ""; + public const string GTranslate = ""; + public const string Gamepad = ""; + public const string Games = ""; + public const string Garage = ""; + public const string Gavel = ""; + public const string GeneratingTokens = ""; + public const string Gesture = ""; + public const string GetApp = ""; + public const string Gif = ""; + public const string GifBox = ""; + public const string Girl = ""; + public const string Gite = ""; + public const string GolfCourse = ""; + public const string GppBad = ""; + public const string GppGood = ""; + public const string GppMaybe = ""; + public const string GpsFixed = ""; + public const string GpsNotFixed = ""; + public const string GpsOff = ""; + public const string Grade = ""; + public const string Gradient = ""; + public const string Grading = ""; + public const string Grain = ""; + public const string GraphicEq = ""; + public const string Grass = ""; + public const string Grid3x3 = ""; + public const string Grid4x4 = ""; + public const string GridGoldenratio = ""; + public const string GridOff = ""; + public const string GridOn = ""; + public const string GridView = ""; + public const string Group = ""; + public const string GroupAdd = ""; + public const string GroupOff = ""; + public const string GroupRemove = ""; + public const string GroupWork = ""; + public const string Groups = ""; + public const string HMobiledata = ""; + public const string HPlusMobiledata = ""; + public const string Hail = ""; + public const string Handshake = ""; + public const string Handyman = ""; + public const string Hardware = ""; + public const string Hd = ""; + public const string HdrAuto = ""; + public const string HdrAutoSelect = ""; + public const string HdrEnhancedSelect = ""; + public const string HdrOff = ""; + public const string HdrOffSelect = ""; + public const string HdrOn = ""; + public const string HdrOnSelect = ""; + public const string HdrPlus = ""; + public const string HdrStrong = ""; + public const string HdrWeak = ""; + public const string Headphones = ""; + public const string HeadphonesBattery = ""; + public const string Headset = ""; + public const string HeadsetMic = ""; + public const string HeadsetOff = ""; + public const string Healing = ""; + public const string HealthAndSafety = ""; + public const string Hearing = ""; + public const string HearingDisabled = ""; + public const string HeartBroken = ""; + public const string Height = ""; + public const string Help = ""; + public const string HelpCenter = ""; + public const string HelpOutline = ""; + public const string Hevc = ""; + public const string Hexagon = ""; + public const string HideImage = ""; + public const string HideSource = ""; + public const string HighQuality = ""; + public const string Highlight = ""; + public const string HighlightAlt = ""; + public const string HighlightOff = ""; + public const string Hiking = ""; + public const string History = ""; + public const string HistoryEdu = ""; + public const string HistoryToggleOff = ""; + public const string Hive = ""; + public const string Hls = ""; + public const string HlsOff = ""; + public const string HolidayVillage = ""; + public const string Home = ""; + public const string HomeMax = ""; + public const string HomeMini = ""; + public const string HomeRepairService = ""; + public const string HomeWork = ""; + public const string HorizontalDistribute = ""; + public const string HorizontalRule = ""; + public const string HorizontalSplit = ""; + public const string HotTub = ""; + public const string Hotel = ""; + public const string HotelClass = ""; + public const string HourglassBottom = ""; + public const string HourglassDisabled = ""; + public const string HourglassEmpty = ""; + public const string HourglassFull = ""; + public const string HourglassTop = ""; + public const string House = ""; + public const string HouseSiding = ""; + public const string Houseboat = ""; + public const string HowToReg = ""; + public const string HowToVote = ""; + public const string Html = ""; + public const string Http = ""; + public const string Https = ""; + public const string Hub = ""; + public const string Hvac = ""; + public const string IceSkating = ""; + public const string Icecream = ""; + public const string Image = ""; + public const string ImageAspectRatio = ""; + public const string ImageNotSupported = ""; + public const string ImageSearch = ""; + public const string ImagesearchRoller = ""; + public const string ImportContacts = ""; + public const string ImportExport = ""; + public const string ImportantDevices = ""; + public const string Inbox = ""; + public const string IncompleteCircle = ""; + public const string IndeterminateCheckBox = ""; + public const string Info = ""; + public const string Input = ""; + public const string InsertChart = ""; + public const string InsertChartOutlined = ""; + public const string InsertComment = ""; + public const string InsertDriveFile = ""; + public const string InsertEmoticon = ""; + public const string InsertInvitation = ""; + public const string InsertLink = ""; + public const string InsertPageBreak = ""; + public const string InsertPhoto = ""; + public const string Insights = ""; + public const string InstallDesktop = ""; + public const string InstallMobile = ""; + public const string IntegrationInstructions = ""; + public const string Interests = ""; + public const string InterpreterMode = ""; + public const string Inventory = ""; + public const string Inventory2 = ""; + public const string InvertColors = ""; + public const string InvertColorsOff = ""; + public const string IosShare = ""; + public const string Iron = ""; + public const string Iso = ""; + public const string Javascript = ""; + public const string JoinFull = ""; + public const string JoinInner = ""; + public const string JoinLeft = ""; + public const string JoinRight = ""; + public const string Kayaking = ""; + public const string KebabDining = ""; + public const string Key = ""; + public const string KeyOff = ""; + public const string Keyboard = ""; + public const string KeyboardAlt = ""; + public const string KeyboardArrowDown = ""; + public const string KeyboardArrowLeft = ""; + public const string KeyboardArrowRight = ""; + public const string KeyboardArrowUp = ""; + public const string KeyboardBackspace = ""; + public const string KeyboardCapslock = ""; + public const string KeyboardCommandKey = ""; + public const string KeyboardControlKey = ""; + public const string KeyboardDoubleArrowDown = ""; + public const string KeyboardDoubleArrowLeft = ""; + public const string KeyboardDoubleArrowRight = ""; + public const string KeyboardDoubleArrowUp = ""; + public const string KeyboardHide = ""; + public const string KeyboardOptionKey = ""; + public const string KeyboardReturn = ""; + public const string KeyboardTab = ""; + public const string KeyboardVoice = ""; + public const string KingBed = ""; + public const string Kitchen = ""; + public const string Kitesurfing = ""; + public const string Label = ""; + public const string LabelImportant = ""; + public const string LabelOff = ""; + public const string Lan = ""; + public const string Landscape = ""; + public const string Landslide = ""; + public const string Language = ""; + public const string Laptop = ""; + public const string LaptopChromebook = ""; + public const string LaptopMac = ""; + public const string LaptopWindows = ""; + public const string LastPage = ""; + public const string Launch = ""; + public const string Layers = ""; + public const string LayersClear = ""; + public const string Leaderboard = ""; + public const string LeakAdd = ""; + public const string LeakRemove = ""; + public const string LegendToggle = ""; + public const string Lens = ""; + public const string LensBlur = ""; + public const string LibraryAdd = ""; + public const string LibraryAddCheck = ""; + public const string LibraryBooks = ""; + public const string LibraryMusic = ""; + public const string Light = ""; + public const string LightMode = ""; + public const string Lightbulb = ""; + public const string LightbulbCircle = ""; + public const string LineAxis = ""; + public const string LineStyle = ""; + public const string LineWeight = ""; + public const string LinearScale = ""; + public const string Link = ""; + public const string LinkOff = ""; + public const string LinkedCamera = ""; + public const string Liquor = ""; + public const string List = ""; + public const string ListAlt = ""; + public const string LiveHelp = ""; + public const string LiveTv = ""; + public const string Living = ""; + public const string LocalActivity = ""; + public const string LocalAirport = ""; + public const string LocalAtm = ""; + public const string LocalBar = ""; + public const string LocalCafe = ""; + public const string LocalCarWash = ""; + public const string LocalConvenienceStore = ""; + public const string LocalDining = ""; + public const string LocalDrink = ""; + public const string LocalFireDepartment = ""; + public const string LocalFlorist = ""; + public const string LocalGasStation = ""; + public const string LocalGroceryStore = ""; + public const string LocalHospital = ""; + public const string LocalHotel = ""; + public const string LocalLaundryService = ""; + public const string LocalLibrary = ""; + public const string LocalMall = ""; + public const string LocalMovies = ""; + public const string LocalOffer = ""; + public const string LocalParking = ""; + public const string LocalPharmacy = ""; + public const string LocalPhone = ""; + public const string LocalPizza = ""; + public const string LocalPlay = ""; + public const string LocalPolice = ""; + public const string LocalPostOffice = ""; + public const string LocalPrintshop = ""; + public const string LocalSee = ""; + public const string LocalShipping = ""; + public const string LocalTaxi = ""; + public const string LocationCity = ""; + public const string LocationDisabled = ""; + public const string LocationOff = ""; + public const string LocationOn = ""; + public const string LocationSearching = ""; + public const string Lock = ""; + public const string LockClock = ""; + public const string LockOpen = ""; + public const string LockReset = ""; + public const string Login = ""; + public const string LogoDev = ""; + public const string Logout = ""; + public const string Looks = ""; + public const string Looks3 = ""; + public const string Looks4 = ""; + public const string Looks5 = ""; + public const string Looks6 = ""; + public const string LooksOne = ""; + public const string LooksTwo = ""; + public const string Loop = ""; + public const string Loupe = ""; + public const string LowPriority = ""; + public const string Loyalty = ""; + public const string LteMobiledata = ""; + public const string LtePlusMobiledata = ""; + public const string Luggage = ""; + public const string LunchDining = ""; + public const string Mail = ""; + public const string MailOutline = ""; + public const string Male = ""; + public const string Man = ""; + public const string ManageAccounts = ""; + public const string ManageHistory = ""; + public const string ManageSearch = ""; + public const string Map = ""; + public const string MapsHomeWork = ""; + public const string MapsUgc = ""; + public const string Margin = ""; + public const string MarkAsUnread = ""; + public const string MarkChatRead = ""; + public const string MarkChatUnread = ""; + public const string MarkEmailRead = ""; + public const string MarkEmailUnread = ""; + public const string MarkUnreadChatAlt = ""; + public const string Markunread = ""; + public const string MarkunreadMailbox = ""; + public const string Masks = ""; + public const string Maximize = ""; + public const string MediaBluetoothOff = ""; + public const string MediaBluetoothOn = ""; + public const string Mediation = ""; + public const string MedicalInformation = ""; + public const string MedicalServices = ""; + public const string Medication = ""; + public const string MedicationLiquid = ""; + public const string MeetingRoom = ""; + public const string Memory = ""; + public const string Menu = ""; + public const string MenuBook = ""; + public const string MenuOpen = ""; + public const string Merge = ""; + public const string MergeType = ""; + public const string Message = ""; + public const string Mic = ""; + public const string MicExternalOff = ""; + public const string MicExternalOn = ""; + public const string MicNone = ""; + public const string MicOff = ""; + public const string Microwave = ""; + public const string MilitaryTech = ""; + public const string Minimize = ""; + public const string MinorCrash = ""; + public const string MiscellaneousServices = ""; + public const string MissedVideoCall = ""; + public const string Mms = ""; + public const string MobileFriendly = ""; + public const string MobileOff = ""; + public const string MobileScreenShare = ""; + public const string MobiledataOff = ""; + public const string Mode = ""; + public const string ModeComment = ""; + public const string ModeEdit = ""; + public const string ModeEditOutline = ""; + public const string ModeNight = ""; + public const string ModeOfTravel = ""; + public const string ModeStandby = ""; + public const string ModelTraining = ""; + public const string MonetizationOn = ""; + public const string Money = ""; + public const string MoneyOff = ""; + public const string MoneyOffCsred = ""; + public const string Monitor = ""; + public const string MonitorHeart = ""; + public const string MonitorWeight = ""; + public const string MonochromePhotos = ""; + public const string Mood = ""; + public const string MoodBad = ""; + public const string Moped = ""; + public const string More = ""; + public const string MoreHoriz = ""; + public const string MoreTime = ""; + public const string MoreVert = ""; + public const string Mosque = ""; + public const string MotionPhotosAuto = ""; + public const string MotionPhotosOff = ""; + public const string MotionPhotosOn = ""; + public const string MotionPhotosPause = ""; + public const string MotionPhotosPaused = ""; + public const string Mouse = ""; + public const string MoveDown = ""; + public const string MoveToInbox = ""; + public const string MoveUp = ""; + public const string Movie = ""; + public const string MovieCreation = ""; + public const string MovieFilter = ""; + public const string Moving = ""; + public const string Mp = ""; + public const string MultilineChart = ""; + public const string MultipleStop = ""; + public const string Museum = ""; + public const string MusicNote = ""; + public const string MusicOff = ""; + public const string MusicVideo = ""; + public const string MyLocation = ""; + public const string Nat = ""; + public const string Nature = ""; + public const string NaturePeople = ""; + public const string NavigateBefore = ""; + public const string NavigateNext = ""; + public const string Navigation = ""; + public const string NearMe = ""; + public const string NearMeDisabled = ""; + public const string NearbyError = ""; + public const string NearbyOff = ""; + public const string NetworkCell = ""; + public const string NetworkCheck = ""; + public const string NetworkLocked = ""; + public const string NetworkPing = ""; + public const string NetworkWifi = ""; + public const string NetworkWifi1Bar = ""; + public const string NetworkWifi2Bar = ""; + public const string NetworkWifi3Bar = ""; + public const string NewLabel = ""; + public const string NewReleases = ""; + public const string Newspaper = ""; + public const string NextPlan = ""; + public const string NextWeek = ""; + public const string Nfc = ""; + public const string NightShelter = ""; + public const string Nightlife = ""; + public const string Nightlight = ""; + public const string NightlightRound = ""; + public const string NightsStay = ""; + public const string NoAccounts = ""; + public const string NoBackpack = ""; + public const string NoCell = ""; + public const string NoCrash = ""; + public const string NoDrinks = ""; + public const string NoEncryption = ""; + public const string NoEncryptionGmailerrorred = ""; + public const string NoFlash = ""; + public const string NoFood = ""; + public const string NoLuggage = ""; + public const string NoMeals = ""; + public const string NoMeetingRoom = ""; + public const string NoPhotography = ""; + public const string NoSim = ""; + public const string NoStroller = ""; + public const string NoTransfer = ""; + public const string NoiseAware = ""; + public const string NoiseControlOff = ""; + public const string NordicWalking = ""; + public const string North = ""; + public const string NorthEast = ""; + public const string NorthWest = ""; + public const string NotAccessible = ""; + public const string NotInterested = ""; + public const string NotListedLocation = ""; + public const string NotStarted = ""; + public const string Note = ""; + public const string NoteAdd = ""; + public const string NoteAlt = ""; + public const string Notes = ""; + public const string NotificationAdd = ""; + public const string NotificationImportant = ""; + public const string Notifications = ""; + public const string NotificationsActive = ""; + public const string NotificationsNone = ""; + public const string NotificationsOff = ""; + public const string NotificationsPaused = ""; + public const string Numbers = ""; + public const string OfflineBolt = ""; + public const string OfflinePin = ""; + public const string OfflineShare = ""; + public const string OnDeviceTraining = ""; + public const string OndemandVideo = ""; + public const string OnlinePrediction = ""; + public const string Opacity = ""; + public const string OpenInBrowser = ""; + public const string OpenInFull = ""; + public const string OpenInNew = ""; + public const string OpenInNewOff = ""; + public const string OpenWith = ""; + public const string OtherHouses = ""; + public const string Outbound = ""; + public const string Outbox = ""; + public const string OutdoorGrill = ""; + public const string Outlet = ""; + public const string OutlinedFlag = ""; + public const string Output = ""; + public const string Padding = ""; + public const string Pages = ""; + public const string Pageview = ""; + public const string Paid = ""; + public const string Palette = ""; + public const string PanTool = ""; + public const string PanToolAlt = ""; + public const string Panorama = ""; + public const string PanoramaFishEye = ""; + public const string PanoramaHorizontal = ""; + public const string PanoramaHorizontalSelect = ""; + public const string PanoramaPhotosphere = ""; + public const string PanoramaPhotosphereSelect = ""; + public const string PanoramaVertical = ""; + public const string PanoramaVerticalSelect = ""; + public const string PanoramaWideAngle = ""; + public const string PanoramaWideAngleSelect = ""; + public const string Paragliding = ""; + public const string Park = ""; + public const string PartyMode = ""; + public const string Password = ""; + public const string Pattern = ""; + public const string Pause = ""; + public const string PauseCircle = ""; + public const string PauseCircleFilled = ""; + public const string PauseCircleOutline = ""; + public const string PausePresentation = ""; + public const string Payment = ""; + public const string Payments = ""; + public const string PedalBike = ""; + public const string Pending = ""; + public const string PendingActions = ""; + public const string Pentagon = ""; + public const string People = ""; + public const string PeopleAlt = ""; + public const string PeopleOutline = ""; + public const string Percent = ""; + public const string PermCameraMic = ""; + public const string PermContactCalendar = ""; + public const string PermDataSetting = ""; + public const string PermDeviceInformation = ""; + public const string PermIdentity = ""; + public const string PermMedia = ""; + public const string PermPhoneMsg = ""; + public const string PermScanWifi = ""; + public const string Person = ""; + public const string PersonAdd = ""; + public const string PersonAddAlt = ""; + public const string PersonAddAlt1 = ""; + public const string PersonAddDisabled = ""; + public const string PersonOff = ""; + public const string PersonOutline = ""; + public const string PersonPin = ""; + public const string PersonPinCircle = ""; + public const string PersonRemove = ""; + public const string PersonRemoveAlt1 = ""; + public const string PersonSearch = ""; + public const string PersonalInjury = ""; + public const string PersonalVideo = ""; + public const string PestControl = ""; + public const string PestControlRodent = ""; + public const string Pets = ""; + public const string Phishing = ""; + public const string Phone = ""; + public const string PhoneAndroid = ""; + public const string PhoneBluetoothSpeaker = ""; + public const string PhoneCallback = ""; + public const string PhoneDisabled = ""; + public const string PhoneEnabled = ""; + public const string PhoneForwarded = ""; + public const string PhoneInTalk = ""; + public const string PhoneIphone = ""; + public const string PhoneLocked = ""; + public const string PhoneMissed = ""; + public const string PhonePaused = ""; + public const string Phonelink = ""; + public const string PhonelinkErase = ""; + public const string PhonelinkLock = ""; + public const string PhonelinkOff = ""; + public const string PhonelinkRing = ""; + public const string PhonelinkSetup = ""; + public const string Photo = ""; + public const string PhotoAlbum = ""; + public const string PhotoCamera = ""; + public const string PhotoCameraBack = ""; + public const string PhotoCameraFront = ""; + public const string PhotoFilter = ""; + public const string PhotoLibrary = ""; + public const string PhotoSizeSelectActual = ""; + public const string PhotoSizeSelectLarge = ""; + public const string PhotoSizeSelectSmall = ""; + public const string Php = ""; + public const string Piano = ""; + public const string PianoOff = ""; + public const string PictureAsPdf = ""; + public const string PictureInPicture = ""; + public const string PictureInPictureAlt = ""; + public const string PieChart = ""; + public const string PieChartOutline = ""; + public const string Pin = ""; + public const string PinDrop = ""; + public const string PinEnd = ""; + public const string PinInvoke = ""; + public const string Pinch = ""; + public const string PivotTableChart = ""; + public const string Pix = ""; + public const string Place = ""; + public const string Plagiarism = ""; + public const string PlayArrow = ""; + public const string PlayCircle = ""; + public const string PlayCircleFilled = ""; + public const string PlayCircleOutline = ""; + public const string PlayDisabled = ""; + public const string PlayForWork = ""; + public const string PlayLesson = ""; + public const string PlaylistAdd = ""; + public const string PlaylistAddCheck = ""; + public const string PlaylistAddCheckCircle = ""; + public const string PlaylistAddCircle = ""; + public const string PlaylistPlay = ""; + public const string PlaylistRemove = ""; + public const string Plumbing = ""; + public const string PlusOne = ""; + public const string Podcasts = ""; + public const string PointOfSale = ""; + public const string Policy = ""; + public const string Poll = ""; + public const string Polyline = ""; + public const string Polymer = ""; + public const string Pool = ""; + public const string PortableWifiOff = ""; + public const string Portrait = ""; + public const string PostAdd = ""; + public const string Power = ""; + public const string PowerInput = ""; + public const string PowerOff = ""; + public const string PowerSettingsNew = ""; + public const string PrecisionManufacturing = ""; + public const string PregnantWoman = ""; + public const string PresentToAll = ""; + public const string Preview = ""; + public const string PriceChange = ""; + public const string PriceCheck = ""; + public const string Print = ""; + public const string PrintDisabled = ""; + public const string PriorityHigh = ""; + public const string PrivacyTip = ""; + public const string PrivateConnectivity = ""; + public const string ProductionQuantityLimits = ""; + public const string Psychology = ""; + public const string Public = ""; + public const string PublicOff = ""; + public const string Publish = ""; + public const string PublishedWithChanges = ""; + public const string PunchClock = ""; + public const string PushPin = ""; + public const string QrCode = ""; + public const string QrCode2 = ""; + public const string QrCodeScanner = ""; + public const string QueryBuilder = ""; + public const string QueryStats = ""; + public const string QuestionAnswer = ""; + public const string QuestionMark = ""; + public const string Queue = ""; + public const string QueueMusic = ""; + public const string QueuePlayNext = ""; + public const string Quickreply = ""; + public const string Quiz = ""; + public const string RMobiledata = ""; + public const string Radar = ""; + public const string Radio = ""; + public const string RadioButtonChecked = ""; + public const string RadioButtonUnchecked = ""; + public const string RailwayAlert = ""; + public const string RamenDining = ""; + public const string RampLeft = ""; + public const string RampRight = ""; + public const string RateReview = ""; + public const string RawOff = ""; + public const string RawOn = ""; + public const string ReadMore = ""; + public const string RealEstateAgent = ""; + public const string Receipt = ""; + public const string ReceiptLong = ""; + public const string RecentActors = ""; + public const string Recommend = ""; + public const string RecordVoiceOver = ""; + public const string Rectangle = ""; + public const string Recycling = ""; + public const string Redeem = ""; + public const string Redo = ""; + public const string ReduceCapacity = ""; + public const string Refresh = ""; + public const string RememberMe = ""; + public const string Remove = ""; + public const string RemoveCircle = ""; + public const string RemoveCircleOutline = ""; + public const string RemoveDone = ""; + public const string RemoveFromQueue = ""; + public const string RemoveModerator = ""; + public const string RemoveRedEye = ""; + public const string RemoveRoad = ""; + public const string RemoveShoppingCart = ""; + public const string Reorder = ""; + public const string Repeat = ""; + public const string RepeatOn = ""; + public const string RepeatOne = ""; + public const string RepeatOneOn = ""; + public const string Replay = ""; + public const string Replay10 = ""; + public const string Replay30 = ""; + public const string Replay5 = ""; + public const string ReplayCircleFilled = ""; + public const string Reply = ""; + public const string ReplyAll = ""; + public const string Report = ""; + public const string ReportGmailerrorred = ""; + public const string ReportOff = ""; + public const string ReportProblem = ""; + public const string RequestPage = ""; + public const string RequestQuote = ""; + public const string ResetTv = ""; + public const string RestartAlt = ""; + public const string Restaurant = ""; + public const string RestaurantMenu = ""; + public const string Restore = ""; + public const string RestoreFromTrash = ""; + public const string RestorePage = ""; + public const string Reviews = ""; + public const string RiceBowl = ""; + public const string RingVolume = ""; + public const string Rocket = ""; + public const string RocketLaunch = ""; + public const string RollerSkating = ""; + public const string Roofing = ""; + public const string Room = ""; + public const string RoomPreferences = ""; + public const string RoomService = ""; + public const string Rotate90DegreesCcw = ""; + public const string Rotate90DegreesCw = ""; + public const string RotateLeft = ""; + public const string RotateRight = ""; + public const string RoundaboutLeft = ""; + public const string RoundaboutRight = ""; + public const string RoundedCorner = ""; + public const string Route = ""; + public const string Router = ""; + public const string Rowing = ""; + public const string RssFeed = ""; + public const string Rsvp = ""; + public const string Rtt = ""; + public const string Rule = ""; + public const string RuleFolder = ""; + public const string RunCircle = ""; + public const string RunningWithErrors = ""; + public const string RvHookup = ""; + public const string SafetyCheck = ""; + public const string SafetyDivider = ""; + public const string Sailing = ""; + public const string Sanitizer = ""; + public const string Satellite = ""; + public const string SatelliteAlt = ""; + public const string Save = ""; + public const string SaveAlt = ""; + public const string SaveAs = ""; + public const string SavedSearch = ""; + public const string Savings = ""; + public const string Scale = ""; + public const string Scanner = ""; + public const string ScatterPlot = ""; + public const string Schedule = ""; + public const string ScheduleSend = ""; + public const string Schema = ""; + public const string School = ""; + public const string Science = ""; + public const string Score = ""; + public const string Scoreboard = ""; + public const string ScreenLockLandscape = ""; + public const string ScreenLockPortrait = ""; + public const string ScreenLockRotation = ""; + public const string ScreenRotation = ""; + public const string ScreenRotationAlt = ""; + public const string ScreenSearchDesktop = ""; + public const string ScreenShare = ""; + public const string Screenshot = ""; + public const string ScubaDiving = ""; + public const string Sd = ""; + public const string SdCard = ""; + public const string SdCardAlert = ""; + public const string SdStorage = ""; + public const string Search = ""; + public const string SearchOff = ""; + public const string Security = ""; + public const string SecurityUpdate = ""; + public const string SecurityUpdateGood = ""; + public const string SecurityUpdateWarning = ""; + public const string Segment = ""; + public const string SelectAll = ""; + public const string SelfImprovement = ""; + public const string Sell = ""; + public const string Send = ""; + public const string SendAndArchive = ""; + public const string SendTimeExtension = ""; + public const string SendToMobile = ""; + public const string SensorDoor = ""; + public const string SensorWindow = ""; + public const string Sensors = ""; + public const string SensorsOff = ""; + public const string SentimentDissatisfied = ""; + public const string SentimentNeutral = ""; + public const string SentimentSatisfied = ""; + public const string SentimentSatisfiedAlt = ""; + public const string SentimentVeryDissatisfied = ""; + public const string SentimentVerySatisfied = ""; + public const string SetMeal = ""; + public const string Settings = ""; + public const string SettingsAccessibility = ""; + public const string SettingsApplications = ""; + public const string SettingsBackupRestore = ""; + public const string SettingsBluetooth = ""; + public const string SettingsBrightness = ""; + public const string SettingsCell = ""; + public const string SettingsEthernet = ""; + public const string SettingsInputAntenna = ""; + public const string SettingsInputComponent = ""; + public const string SettingsInputComposite = ""; + public const string SettingsInputHdmi = ""; + public const string SettingsInputSvideo = ""; + public const string SettingsOverscan = ""; + public const string SettingsPhone = ""; + public const string SettingsPower = ""; + public const string SettingsRemote = ""; + public const string SettingsSuggest = ""; + public const string SettingsSystemDaydream = ""; + public const string SettingsVoice = ""; + public const string SevereCold = ""; + public const string Share = ""; + public const string ShareLocation = ""; + public const string Shield = ""; + public const string ShieldMoon = ""; + public const string Shop = ""; + public const string Shop2 = ""; + public const string ShopTwo = ""; + public const string ShoppingBag = ""; + public const string ShoppingBasket = ""; + public const string ShoppingCart = ""; + public const string ShoppingCartCheckout = ""; + public const string ShortText = ""; + public const string Shortcut = ""; + public const string ShowChart = ""; + public const string Shower = ""; + public const string Shuffle = ""; + public const string ShuffleOn = ""; + public const string ShutterSpeed = ""; + public const string Sick = ""; + public const string SignLanguage = ""; + public const string SignalCellular0Bar = ""; + public const string SignalCellular4Bar = ""; + public const string SignalCellularAlt = ""; + public const string SignalCellularAlt1Bar = ""; + public const string SignalCellularAlt2Bar = ""; + public const string SignalCellularConnectedNoInternet0Bar = ""; + public const string SignalCellularConnectedNoInternet4Bar = ""; + public const string SignalCellularNoSim = ""; + public const string SignalCellularNodata = ""; + public const string SignalCellularNull = ""; + public const string SignalCellularOff = ""; + public const string SignalWifi0Bar = ""; + public const string SignalWifi4Bar = ""; + public const string SignalWifi4BarLock = ""; + public const string SignalWifiBad = ""; + public const string SignalWifiConnectedNoInternet4 = ""; + public const string SignalWifiOff = ""; + public const string SignalWifiStatusbar4Bar = ""; + public const string SignalWifiStatusbarConnectedNoInternet4 = ""; + public const string SignalWifiStatusbarNull = ""; + public const string Signpost = ""; + public const string SimCard = ""; + public const string SimCardAlert = ""; + public const string SimCardDownload = ""; + public const string SingleBed = ""; + public const string Sip = ""; + public const string Skateboarding = ""; + public const string SkipNext = ""; + public const string SkipPrevious = ""; + public const string Sledding = ""; + public const string Slideshow = ""; + public const string SlowMotionVideo = ""; + public const string SmartButton = ""; + public const string SmartDisplay = ""; + public const string SmartScreen = ""; + public const string SmartToy = ""; + public const string Smartphone = ""; + public const string SmokeFree = ""; + public const string SmokingRooms = ""; + public const string Sms = ""; + public const string SmsFailed = ""; + public const string SnippetFolder = ""; + public const string Snooze = ""; + public const string Snowboarding = ""; + public const string Snowmobile = ""; + public const string Snowshoeing = ""; + public const string Soap = ""; + public const string SocialDistance = ""; + public const string Sort = ""; + public const string SortByAlpha = ""; + public const string Sos = ""; + public const string SoupKitchen = ""; + public const string Source = ""; + public const string South = ""; + public const string SouthAmerica = ""; + public const string SouthEast = ""; + public const string SouthWest = ""; + public const string Spa = ""; + public const string SpaceBar = ""; + public const string SpaceDashboard = ""; + public const string SpatialAudio = ""; + public const string SpatialAudioOff = ""; + public const string SpatialTracking = ""; + public const string Speaker = ""; + public const string SpeakerGroup = ""; + public const string SpeakerNotes = ""; + public const string SpeakerNotesOff = ""; + public const string SpeakerPhone = ""; + public const string Speed = ""; + public const string Spellcheck = ""; + public const string Splitscreen = ""; + public const string Spoke = ""; + public const string Sports = ""; + public const string SportsBar = ""; + public const string SportsBaseball = ""; + public const string SportsBasketball = ""; + public const string SportsCricket = ""; + public const string SportsEsports = ""; + public const string SportsFootball = ""; + public const string SportsGolf = ""; + public const string SportsGymnastics = ""; + public const string SportsHandball = ""; + public const string SportsHockey = ""; + public const string SportsKabaddi = ""; + public const string SportsMartialArts = ""; + public const string SportsMma = ""; + public const string SportsMotorsports = ""; + public const string SportsRugby = ""; + public const string SportsScore = ""; + public const string SportsSoccer = ""; + public const string SportsTennis = ""; + public const string SportsVolleyball = ""; + public const string Square = ""; + public const string SquareFoot = ""; + public const string SsidChart = ""; + public const string StackedBarChart = ""; + public const string StackedLineChart = ""; + public const string Stadium = ""; + public const string Stairs = ""; + public const string Star = ""; + public const string StarBorder = ""; + public const string StarBorderPurple500 = ""; + public const string StarHalf = ""; + public const string StarOutline = ""; + public const string StarPurple500 = ""; + public const string StarRate = ""; + public const string Stars = ""; + public const string Start = ""; + public const string StayCurrentLandscape = ""; + public const string StayCurrentPortrait = ""; + public const string StayPrimaryLandscape = ""; + public const string StayPrimaryPortrait = ""; + public const string StickyNote2 = ""; + public const string Stop = ""; + public const string StopCircle = ""; + public const string StopScreenShare = ""; + public const string Storage = ""; + public const string Store = ""; + public const string StoreMallDirectory = ""; + public const string Storefront = ""; + public const string Storm = ""; + public const string Straight = ""; + public const string Straighten = ""; + public const string Stream = ""; + public const string Streetview = ""; + public const string StrikethroughS = ""; + public const string Stroller = ""; + public const string Style = ""; + public const string SubdirectoryArrowLeft = ""; + public const string SubdirectoryArrowRight = ""; + public const string Subject = ""; + public const string Subscript = ""; + public const string Subscriptions = ""; + public const string Subtitles = ""; + public const string SubtitlesOff = ""; + public const string Subway = ""; + public const string Summarize = ""; + public const string Superscript = ""; + public const string SupervisedUserCircle = ""; + public const string SupervisorAccount = ""; + public const string Support = ""; + public const string SupportAgent = ""; + public const string Surfing = ""; + public const string SurroundSound = ""; + public const string SwapCalls = ""; + public const string SwapHoriz = ""; + public const string SwapHorizontalCircle = ""; + public const string SwapVert = ""; + public const string SwapVerticalCircle = ""; + public const string Swipe = ""; + public const string SwipeDown = ""; + public const string SwipeDownAlt = ""; + public const string SwipeLeft = ""; + public const string SwipeLeftAlt = ""; + public const string SwipeRight = ""; + public const string SwipeRightAlt = ""; + public const string SwipeUp = ""; + public const string SwipeUpAlt = ""; + public const string SwipeVertical = ""; + public const string SwitchAccessShortcut = ""; + public const string SwitchAccessShortcutAdd = ""; + public const string SwitchAccount = ""; + public const string SwitchCamera = ""; + public const string SwitchLeft = ""; + public const string SwitchRight = ""; + public const string SwitchVideo = ""; + public const string Synagogue = ""; + public const string Sync = ""; + public const string SyncAlt = ""; + public const string SyncDisabled = ""; + public const string SyncLock = ""; + public const string SyncProblem = ""; + public const string SystemSecurityUpdate = ""; + public const string SystemSecurityUpdateGood = ""; + public const string SystemSecurityUpdateWarning = ""; + public const string SystemUpdate = ""; + public const string SystemUpdateAlt = ""; + public const string Tab = ""; + public const string TabUnselected = ""; + public const string TableBar = ""; + public const string TableChart = ""; + public const string TableRestaurant = ""; + public const string TableRows = ""; + public const string TableView = ""; + public const string Tablet = ""; + public const string TabletAndroid = ""; + public const string TabletMac = ""; + public const string Tag = ""; + public const string TagFaces = ""; + public const string TakeoutDining = ""; + public const string TapAndPlay = ""; + public const string Tapas = ""; + public const string Task = ""; + public const string TaskAlt = ""; + public const string TaxiAlert = ""; + public const string TempleBuddhist = ""; + public const string TempleHindu = ""; + public const string Terminal = ""; + public const string Terrain = ""; + public const string TextDecrease = ""; + public const string TextFields = ""; + public const string TextFormat = ""; + public const string TextIncrease = ""; + public const string TextRotateUp = ""; + public const string TextRotateVertical = ""; + public const string TextRotationAngledown = ""; + public const string TextRotationAngleup = ""; + public const string TextRotationDown = ""; + public const string TextRotationNone = ""; + public const string TextSnippet = ""; + public const string Textsms = ""; + public const string Texture = ""; + public const string TheaterComedy = ""; + public const string Theaters = ""; + public const string Thermostat = ""; + public const string ThermostatAuto = ""; + public const string ThumbDown = ""; + public const string ThumbDownAlt = ""; + public const string ThumbDownOffAlt = ""; + public const string ThumbUp = ""; + public const string ThumbUpAlt = ""; + public const string ThumbUpOffAlt = ""; + public const string ThumbsUpDown = ""; + public const string Thunderstorm = ""; + public const string TimeToLeave = ""; + public const string Timelapse = ""; + public const string Timeline = ""; + public const string Timer = ""; + public const string Timer10 = ""; + public const string Timer10Select = ""; + public const string Timer3 = ""; + public const string Timer3Select = ""; + public const string TimerOff = ""; + public const string TipsAndUpdates = ""; + public const string TireRepair = ""; + public const string Title = ""; + public const string Toc = ""; + public const string Today = ""; + public const string ToggleOff = ""; + public const string ToggleOn = ""; + public const string Token = ""; + public const string Toll = ""; + public const string Tonality = ""; + public const string Topic = ""; + public const string TouchApp = ""; + public const string Tour = ""; + public const string Toys = ""; + public const string TrackChanges = ""; + public const string Traffic = ""; + public const string Train = ""; + public const string Tram = ""; + public const string TransferWithinAStation = ""; + public const string Transform = ""; + public const string Transgender = ""; + public const string TransitEnterexit = ""; + public const string Translate = ""; + public const string TravelExplore = ""; + public const string TrendingDown = ""; + public const string TrendingFlat = ""; + public const string TrendingUp = ""; + public const string TripOrigin = ""; + public const string Try = ""; + public const string Tsunami = ""; + public const string Tty = ""; + public const string Tune = ""; + public const string Tungsten = ""; + public const string TurnLeft = ""; + public const string TurnRight = ""; + public const string TurnSharpLeft = ""; + public const string TurnSharpRight = ""; + public const string TurnSlightLeft = ""; + public const string TurnSlightRight = ""; + public const string TurnedIn = ""; + public const string TurnedInNot = ""; + public const string Tv = ""; + public const string TvOff = ""; + public const string TwoWheeler = ""; + public const string UTurnLeft = ""; + public const string UTurnRight = ""; + public const string Umbrella = ""; + public const string Unarchive = ""; + public const string Undo = ""; + public const string UnfoldLess = ""; + public const string UnfoldMore = ""; + public const string Unpublished = ""; + public const string Unsubscribe = ""; + public const string Upcoming = ""; + public const string Update = ""; + public const string UpdateDisabled = ""; + public const string Upgrade = ""; + public const string Upload = ""; + public const string UploadFile = ""; + public const string Usb = ""; + public const string UsbOff = ""; + public const string Vaccines = ""; + public const string VapeFree = ""; + public const string VapingRooms = ""; + public const string Verified = ""; + public const string VerifiedUser = ""; + public const string VerticalAlignBottom = ""; + public const string VerticalAlignCenter = ""; + public const string VerticalAlignTop = ""; + public const string VerticalDistribute = ""; + public const string VerticalSplit = ""; + public const string Vibration = ""; + public const string VideoCall = ""; + public const string VideoCameraBack = ""; + public const string VideoCameraFront = ""; + public const string VideoFile = ""; + public const string VideoLabel = ""; + public const string VideoLibrary = ""; + public const string VideoSettings = ""; + public const string VideoStable = ""; + public const string Videocam = ""; + public const string VideocamOff = ""; + public const string VideogameAsset = ""; + public const string VideogameAssetOff = ""; + public const string ViewAgenda = ""; + public const string ViewArray = ""; + public const string ViewCarousel = ""; + public const string ViewColumn = ""; + public const string ViewComfy = ""; + public const string ViewComfyAlt = ""; + public const string ViewCompact = ""; + public const string ViewCompactAlt = ""; + public const string ViewCozy = ""; + public const string ViewDay = ""; + public const string ViewHeadline = ""; + public const string ViewInAr = ""; + public const string ViewKanban = ""; + public const string ViewList = ""; + public const string ViewModule = ""; + public const string ViewQuilt = ""; + public const string ViewSidebar = ""; + public const string ViewStream = ""; + public const string ViewTimeline = ""; + public const string ViewWeek = ""; + public const string Vignette = ""; + public const string Villa = ""; + public const string Visibility = ""; + public const string VisibilityOff = ""; + public const string VoiceChat = ""; + public const string VoiceOverOff = ""; + public const string Voicemail = ""; + public const string Volcano = ""; + public const string VolumeDown = ""; + public const string VolumeMute = ""; + public const string VolumeOff = ""; + public const string VolumeUp = ""; + public const string VolunteerActivism = ""; + public const string VpnKey = ""; + public const string VpnKeyOff = ""; + public const string VpnLock = ""; + public const string Vrpano = ""; + public const string Wallpaper = ""; + public const string Warehouse = ""; + public const string Warning = ""; + public const string WarningAmber = ""; + public const string Wash = ""; + public const string Watch = ""; + public const string WatchLater = ""; + public const string WatchOff = ""; + public const string Water = ""; + public const string WaterDamage = ""; + public const string WaterDrop = ""; + public const string WaterfallChart = ""; + public const string Waves = ""; + public const string WavingHand = ""; + public const string WbAuto = ""; + public const string WbCloudy = ""; + public const string WbIncandescent = ""; + public const string WbIridescent = ""; + public const string WbShade = ""; + public const string WbSunny = ""; + public const string WbTwilight = ""; + public const string Wc = ""; + public const string Web = ""; + public const string WebAsset = ""; + public const string WebAssetOff = ""; + public const string Webhook = ""; + public const string Weekend = ""; + public const string West = ""; + public const string Whatsapp = ""; + public const string Whatshot = ""; + public const string WheelchairPickup = ""; + public const string WhereToVote = ""; + public const string Widgets = ""; + public const string Wifi = ""; + public const string Wifi1Bar = ""; + public const string Wifi2Bar = ""; + public const string WifiCalling = ""; + public const string WifiCalling3 = ""; + public const string WifiChannel = ""; + public const string WifiFind = ""; + public const string WifiLock = ""; + public const string WifiOff = ""; + public const string WifiPassword = ""; + public const string WifiProtectedSetup = ""; + public const string WifiTethering = ""; + public const string WifiTetheringError = ""; + public const string WifiTetheringOff = ""; + public const string Window = ""; + public const string WineBar = ""; + public const string Woman = ""; + public const string Work = ""; + public const string WorkOff = ""; + public const string WorkOutline = ""; + public const string WorkspacePremium = ""; + public const string Workspaces = ""; + public const string WrapText = ""; + public const string WrongLocation = ""; + public const string Wysiwyg = ""; + public const string Yard = ""; + public const string YoutubeSearchedFor = ""; + public const string ZoomIn = ""; + public const string ZoomInMap = ""; + public const string ZoomOut = ""; + public const string ZoomOutMap = ""; + } + } + } +} diff --git a/Icons/Material/_Obsolete.cs b/Icons/Material/_Obsolete.cs new file mode 100644 index 0000000..9a59b2a --- /dev/null +++ b/Icons/Material/_Obsolete.cs @@ -0,0 +1,197 @@ +using System; + +namespace Connected +{ + // These icons have been removed from the Google Material Design Icons set either + // due to typo corrections, improved consistency in naming or simply because they + // have been retired. They may be removed in a future version of MudBlazor so + // it is strongly recommended to remove or update any references to them. + public partial class Icons + { + public partial class Material + { + public partial class Filled + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string BlockFlipped = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string OutgoingMail = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string HomeFilled = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string AssistantNavigation = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string LocationPin = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Workspaces` icon.", true)] + public string WorkspacesFilled => Workspaces; + + [Obsolete("Removed from Material Design Icons. Replace with `FilterAlt` icon.", true)] + public string FilterListAlt => FilterAlt; + + [Obsolete("Removed from Material Design Icons. Replace with `AddIcCall` icon.", true)] + public string AddCall => AddIcCall; + + [Obsolete("Removed from Material Design Icons. Replace with `WbTwilight` icon.", true)] + public string WbTwighlight => WbTwilight; + + [Obsolete("Removed from Material Design Icons. Replace with `PieChartOutline` icon.", true)] + public string PieChartOutlined => PieChartOutline; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Workspaces` icon.", true)] + public string WorkspacesOutline => Outlined.Workspaces; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.DriveFileMove` icon.", true)] + public string DriveFileMoveOutline => Outlined.DriveFileMove; + + [Obsolete("Removed from Material Design Icons. Replace with `NoMeals` icon.", true)] + public string NoMealsOuline => NoMeals; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Filled.Flag` icon.", false)] + public string EmojiFlags => Filled.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Filled.Lock` icon.", false)] + public string LockOutline => Filled.Lock; + } + + public partial class Outlined + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Flag` icon.", false)] + public string EmojiFlags => Outlined.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + + public partial class Rounded + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Rounded.Flag` icon.", false)] + public string EmojiFlags => Rounded.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + + public partial class Sharp + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Sharp.Flag` icon.", false)] + public string EmojiFlags => Sharp.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + } + } +} diff --git a/Icons/Obsolete/Filled.cs b/Icons/Obsolete/Filled.cs new file mode 100644 index 0000000..8eb4822 --- /dev/null +++ b/Icons/Obsolete/Filled.cs @@ -0,0 +1,2066 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + [ExcludeFromCodeCoverage] + public partial class Filled + { + public const string _10k = Material.Filled._10k; + public const string _10mp = Material.Filled._10mp; + public const string _11mp = Material.Filled._11mp; + public const string _123 = Material.Filled._123; + public const string _12mp = Material.Filled._12mp; + public const string _13mp = Material.Filled._13mp; + public const string _14mp = Material.Filled._14mp; + public const string _15mp = Material.Filled._15mp; + public const string _16mp = Material.Filled._16mp; + public const string _17mp = Material.Filled._17mp; + public const string _18mp = Material.Filled._18mp; + public const string _19mp = Material.Filled._19mp; + public const string _1k = Material.Filled._1k; + public const string _1kPlus = Material.Filled._1kPlus; + public const string _1xMobiledata = Material.Filled._1xMobiledata; + public const string _20mp = Material.Filled._20mp; + public const string _21mp = Material.Filled._21mp; + public const string _22mp = Material.Filled._22mp; + public const string _23mp = Material.Filled._23mp; + public const string _24mp = Material.Filled._24mp; + public const string _2k = Material.Filled._2k; + public const string _2kPlus = Material.Filled._2kPlus; + public const string _2mp = Material.Filled._2mp; + public const string _30fps = Material.Filled._30fps; + public const string _30fpsSelect = Material.Filled._30fpsSelect; + public const string _360 = Material.Filled._360; + public const string _3dRotation = Material.Filled._3dRotation; + public const string _3gMobiledata = Material.Filled._3gMobiledata; + public const string _3k = Material.Filled._3k; + public const string _3kPlus = Material.Filled._3kPlus; + public const string _3mp = Material.Filled._3mp; + public const string _3p = Material.Filled._3p; + public const string _4gMobiledata = Material.Filled._4gMobiledata; + public const string _4gPlusMobiledata = Material.Filled._4gPlusMobiledata; + public const string _4k = Material.Filled._4k; + public const string _4kPlus = Material.Filled._4kPlus; + public const string _4mp = Material.Filled._4mp; + public const string _5g = Material.Filled._5g; + public const string _5k = Material.Filled._5k; + public const string _5kPlus = Material.Filled._5kPlus; + public const string _5mp = Material.Filled._5mp; + public const string _60fps = Material.Filled._60fps; + public const string _60fpsSelect = Material.Filled._60fpsSelect; + public const string _6FtApart = Material.Filled._6FtApart; + public const string _6k = Material.Filled._6k; + public const string _6kPlus = Material.Filled._6kPlus; + public const string _6mp = Material.Filled._6mp; + public const string _7k = Material.Filled._7k; + public const string _7kPlus = Material.Filled._7kPlus; + public const string _7mp = Material.Filled._7mp; + public const string _8k = Material.Filled._8k; + public const string _8kPlus = Material.Filled._8kPlus; + public const string _8mp = Material.Filled._8mp; + public const string _9k = Material.Filled._9k; + public const string _9kPlus = Material.Filled._9kPlus; + public const string _9mp = Material.Filled._9mp; + public const string Abc = Material.Filled.Abc; + public const string AcUnit = Material.Filled.AcUnit; + public const string AccessAlarm = Material.Filled.AccessAlarm; + public const string AccessAlarms = Material.Filled.AccessAlarms; + public const string AccessTime = Material.Filled.AccessTime; + public const string AccessTimeFilled = Material.Filled.AccessTimeFilled; + public const string Accessibility = Material.Filled.Accessibility; + public const string AccessibilityNew = Material.Filled.AccessibilityNew; + public const string Accessible = Material.Filled.Accessible; + public const string AccessibleForward = Material.Filled.AccessibleForward; + public const string AccountBalance = Material.Filled.AccountBalance; + public const string AccountBalanceWallet = Material.Filled.AccountBalanceWallet; + public const string AccountBox = Material.Filled.AccountBox; + public const string AccountCircle = Material.Filled.AccountCircle; + public const string AccountTree = Material.Filled.AccountTree; + public const string AdUnits = Material.Filled.AdUnits; + public const string Adb = Material.Filled.Adb; + public const string Add = Material.Filled.Add; + public const string AddAPhoto = Material.Filled.AddAPhoto; + public const string AddAlarm = Material.Filled.AddAlarm; + public const string AddAlert = Material.Filled.AddAlert; + public const string AddBox = Material.Filled.AddBox; + public const string AddBusiness = Material.Filled.AddBusiness; + public const string AddCard = Material.Filled.AddCard; + public const string AddChart = Material.Filled.AddChart; + public const string AddCircle = Material.Filled.AddCircle; + public const string AddCircleOutline = Material.Filled.AddCircleOutline; + public const string AddComment = Material.Filled.AddComment; + public const string AddIcCall = Material.Filled.AddIcCall; + public const string AddLink = Material.Filled.AddLink; + public const string AddLocation = Material.Filled.AddLocation; + public const string AddLocationAlt = Material.Filled.AddLocationAlt; + public const string AddModerator = Material.Filled.AddModerator; + public const string AddPhotoAlternate = Material.Filled.AddPhotoAlternate; + public const string AddReaction = Material.Filled.AddReaction; + public const string AddRoad = Material.Filled.AddRoad; + public const string AddShoppingCart = Material.Filled.AddShoppingCart; + public const string AddTask = Material.Filled.AddTask; + public const string AddToDrive = Material.Filled.AddToDrive; + public const string AddToHomeScreen = Material.Filled.AddToHomeScreen; + public const string AddToPhotos = Material.Filled.AddToPhotos; + public const string AddToQueue = Material.Filled.AddToQueue; + public const string Addchart = Material.Filled.Addchart; + public const string AdfScanner = Material.Filled.AdfScanner; + public const string Adjust = Material.Filled.Adjust; + public const string AdminPanelSettings = Material.Filled.AdminPanelSettings; + public const string AdsClick = Material.Filled.AdsClick; + public const string Agriculture = Material.Filled.Agriculture; + public const string Air = Material.Filled.Air; + public const string AirlineSeatFlat = Material.Filled.AirlineSeatFlat; + public const string AirlineSeatFlatAngled = Material.Filled.AirlineSeatFlatAngled; + public const string AirlineSeatIndividualSuite = Material.Filled.AirlineSeatIndividualSuite; + public const string AirlineSeatLegroomExtra = Material.Filled.AirlineSeatLegroomExtra; + public const string AirlineSeatLegroomNormal = Material.Filled.AirlineSeatLegroomNormal; + public const string AirlineSeatLegroomReduced = Material.Filled.AirlineSeatLegroomReduced; + public const string AirlineSeatReclineExtra = Material.Filled.AirlineSeatReclineExtra; + public const string AirlineSeatReclineNormal = Material.Filled.AirlineSeatReclineNormal; + public const string AirlineStops = Material.Filled.AirlineStops; + public const string Airlines = Material.Filled.Airlines; + public const string AirplaneTicket = Material.Filled.AirplaneTicket; + public const string AirplanemodeActive = Material.Filled.AirplanemodeActive; + public const string AirplanemodeInactive = Material.Filled.AirplanemodeInactive; + public const string Airplay = Material.Filled.Airplay; + public const string AirportShuttle = Material.Filled.AirportShuttle; + public const string Alarm = Material.Filled.Alarm; + public const string AlarmAdd = Material.Filled.AlarmAdd; + public const string AlarmOff = Material.Filled.AlarmOff; + public const string AlarmOn = Material.Filled.AlarmOn; + public const string Album = Material.Filled.Album; + public const string AlignHorizontalCenter = Material.Filled.AlignHorizontalCenter; + public const string AlignHorizontalLeft = Material.Filled.AlignHorizontalLeft; + public const string AlignHorizontalRight = Material.Filled.AlignHorizontalRight; + public const string AlignVerticalBottom = Material.Filled.AlignVerticalBottom; + public const string AlignVerticalCenter = Material.Filled.AlignVerticalCenter; + public const string AlignVerticalTop = Material.Filled.AlignVerticalTop; + public const string AllInbox = Material.Filled.AllInbox; + public const string AllInclusive = Material.Filled.AllInclusive; + public const string AllOut = Material.Filled.AllOut; + public const string AltRoute = Material.Filled.AltRoute; + public const string AlternateEmail = Material.Filled.AlternateEmail; + public const string Analytics = Material.Filled.Analytics; + public const string Anchor = Material.Filled.Anchor; + public const string Android = Material.Filled.Android; + public const string Animation = Material.Filled.Animation; + public const string Announcement = Material.Filled.Announcement; + public const string Aod = Material.Filled.Aod; + public const string Apartment = Material.Filled.Apartment; + public const string Api = Material.Filled.Api; + public const string AppBlocking = Material.Filled.AppBlocking; + public const string AppRegistration = Material.Filled.AppRegistration; + public const string AppSettingsAlt = Material.Filled.AppSettingsAlt; + public const string AppShortcut = Material.Filled.AppShortcut; + public const string Approval = Material.Filled.Approval; + public const string Apps = Material.Filled.Apps; + public const string AppsOutage = Material.Filled.AppsOutage; + public const string Architecture = Material.Filled.Architecture; + public const string Archive = Material.Filled.Archive; + public const string AreaChart = Material.Filled.AreaChart; + public const string ArrowBack = Material.Filled.ArrowBack; + public const string ArrowBackIos = Material.Filled.ArrowBackIos; + public const string ArrowBackIosNew = Material.Filled.ArrowBackIosNew; + public const string ArrowCircleDown = Material.Filled.ArrowCircleDown; + public const string ArrowCircleLeft = Material.Filled.ArrowCircleLeft; + public const string ArrowCircleRight = Material.Filled.ArrowCircleRight; + public const string ArrowCircleUp = Material.Filled.ArrowCircleUp; + public const string ArrowDownward = Material.Filled.ArrowDownward; + public const string ArrowDropDown = Material.Filled.ArrowDropDown; + public const string ArrowDropDownCircle = Material.Filled.ArrowDropDownCircle; + public const string ArrowDropUp = Material.Filled.ArrowDropUp; + public const string ArrowForward = Material.Filled.ArrowForward; + public const string ArrowForwardIos = Material.Filled.ArrowForwardIos; + public const string ArrowLeft = Material.Filled.ArrowLeft; + public const string ArrowRight = Material.Filled.ArrowRight; + public const string ArrowRightAlt = Material.Filled.ArrowRightAlt; + public const string ArrowUpward = Material.Filled.ArrowUpward; + public const string ArtTrack = Material.Filled.ArtTrack; + public const string Article = Material.Filled.Article; + public const string AspectRatio = Material.Filled.AspectRatio; + public const string Assessment = Material.Filled.Assessment; + public const string Assignment = Material.Filled.Assignment; + public const string AssignmentInd = Material.Filled.AssignmentInd; + public const string AssignmentLate = Material.Filled.AssignmentLate; + public const string AssignmentReturn = Material.Filled.AssignmentReturn; + public const string AssignmentReturned = Material.Filled.AssignmentReturned; + public const string AssignmentTurnedIn = Material.Filled.AssignmentTurnedIn; + public const string Assistant = Material.Filled.Assistant; + public const string AssistantDirection = Material.Filled.AssistantDirection; + public const string AssistantPhoto = Material.Filled.AssistantPhoto; + public const string AssuredWorkload = Material.Filled.AssuredWorkload; + public const string Atm = Material.Filled.Atm; + public const string AttachEmail = Material.Filled.AttachEmail; + public const string AttachFile = Material.Filled.AttachFile; + public const string AttachMoney = Material.Filled.AttachMoney; + public const string Attachment = Material.Filled.Attachment; + public const string Attractions = Material.Filled.Attractions; + public const string Attribution = Material.Filled.Attribution; + public const string AudioFile = Material.Filled.AudioFile; + public const string Audiotrack = Material.Filled.Audiotrack; + public const string AutoAwesome = Material.Filled.AutoAwesome; + public const string AutoAwesomeMosaic = Material.Filled.AutoAwesomeMosaic; + public const string AutoAwesomeMotion = Material.Filled.AutoAwesomeMotion; + public const string AutoDelete = Material.Filled.AutoDelete; + public const string AutoFixHigh = Material.Filled.AutoFixHigh; + public const string AutoFixNormal = Material.Filled.AutoFixNormal; + public const string AutoFixOff = Material.Filled.AutoFixOff; + public const string AutoGraph = Material.Filled.AutoGraph; + public const string AutoStories = Material.Filled.AutoStories; + public const string AutofpsSelect = Material.Filled.AutofpsSelect; + public const string Autorenew = Material.Filled.Autorenew; + public const string AvTimer = Material.Filled.AvTimer; + public const string BabyChangingStation = Material.Filled.BabyChangingStation; + public const string BackHand = Material.Filled.BackHand; + public const string Backpack = Material.Filled.Backpack; + public const string Backspace = Material.Filled.Backspace; + public const string Backup = Material.Filled.Backup; + public const string BackupTable = Material.Filled.BackupTable; + public const string Badge = Material.Filled.Badge; + public const string BakeryDining = Material.Filled.BakeryDining; + public const string Balance = Material.Filled.Balance; + public const string Balcony = Material.Filled.Balcony; + public const string Ballot = Material.Filled.Ballot; + public const string BarChart = Material.Filled.BarChart; + public const string BatchPrediction = Material.Filled.BatchPrediction; + public const string Bathroom = Material.Filled.Bathroom; + public const string Bathtub = Material.Filled.Bathtub; + public const string Battery0Bar = Material.Filled.Battery0Bar; + public const string Battery1Bar = Material.Filled.Battery1Bar; + public const string Battery2Bar = Material.Filled.Battery2Bar; + public const string Battery3Bar = Material.Filled.Battery3Bar; + public const string Battery4Bar = Material.Filled.Battery4Bar; + public const string Battery5Bar = Material.Filled.Battery5Bar; + public const string Battery6Bar = Material.Filled.Battery6Bar; + public const string BatteryAlert = Material.Filled.BatteryAlert; + public const string BatteryChargingFull = Material.Filled.BatteryChargingFull; + public const string BatteryFull = Material.Filled.BatteryFull; + public const string BatterySaver = Material.Filled.BatterySaver; + public const string BatteryStd = Material.Filled.BatteryStd; + public const string BatteryUnknown = Material.Filled.BatteryUnknown; + public const string BeachAccess = Material.Filled.BeachAccess; + public const string Bed = Material.Filled.Bed; + public const string BedroomBaby = Material.Filled.BedroomBaby; + public const string BedroomChild = Material.Filled.BedroomChild; + public const string BedroomParent = Material.Filled.BedroomParent; + public const string Bedtime = Material.Filled.Bedtime; + public const string BedtimeOff = Material.Filled.BedtimeOff; + public const string Beenhere = Material.Filled.Beenhere; + public const string Bento = Material.Filled.Bento; + public const string BikeScooter = Material.Filled.BikeScooter; + public const string Biotech = Material.Filled.Biotech; + public const string Blender = Material.Filled.Blender; + public const string Block = Material.Filled.Block; + public const string Bloodtype = Material.Filled.Bloodtype; + public const string Bluetooth = Material.Filled.Bluetooth; + public const string BluetoothAudio = Material.Filled.BluetoothAudio; + public const string BluetoothConnected = Material.Filled.BluetoothConnected; + public const string BluetoothDisabled = Material.Filled.BluetoothDisabled; + public const string BluetoothDrive = Material.Filled.BluetoothDrive; + public const string BluetoothSearching = Material.Filled.BluetoothSearching; + public const string BlurCircular = Material.Filled.BlurCircular; + public const string BlurLinear = Material.Filled.BlurLinear; + public const string BlurOff = Material.Filled.BlurOff; + public const string BlurOn = Material.Filled.BlurOn; + public const string Bolt = Material.Filled.Bolt; + public const string Book = Material.Filled.Book; + public const string BookOnline = Material.Filled.BookOnline; + public const string Bookmark = Material.Filled.Bookmark; + public const string BookmarkAdd = Material.Filled.BookmarkAdd; + public const string BookmarkAdded = Material.Filled.BookmarkAdded; + public const string BookmarkBorder = Material.Filled.BookmarkBorder; + public const string BookmarkRemove = Material.Filled.BookmarkRemove; + public const string Bookmarks = Material.Filled.Bookmarks; + public const string BorderAll = Material.Filled.BorderAll; + public const string BorderBottom = Material.Filled.BorderBottom; + public const string BorderClear = Material.Filled.BorderClear; + public const string BorderColor = Material.Filled.BorderColor; + public const string BorderHorizontal = Material.Filled.BorderHorizontal; + public const string BorderInner = Material.Filled.BorderInner; + public const string BorderLeft = Material.Filled.BorderLeft; + public const string BorderOuter = Material.Filled.BorderOuter; + public const string BorderRight = Material.Filled.BorderRight; + public const string BorderStyle = Material.Filled.BorderStyle; + public const string BorderTop = Material.Filled.BorderTop; + public const string BorderVertical = Material.Filled.BorderVertical; + public const string Boy = Material.Filled.Boy; + public const string BrandingWatermark = Material.Filled.BrandingWatermark; + public const string BreakfastDining = Material.Filled.BreakfastDining; + public const string Brightness1 = Material.Filled.Brightness1; + public const string Brightness2 = Material.Filled.Brightness2; + public const string Brightness3 = Material.Filled.Brightness3; + public const string Brightness4 = Material.Filled.Brightness4; + public const string Brightness5 = Material.Filled.Brightness5; + public const string Brightness6 = Material.Filled.Brightness6; + public const string Brightness7 = Material.Filled.Brightness7; + public const string BrightnessAuto = Material.Filled.BrightnessAuto; + public const string BrightnessHigh = Material.Filled.BrightnessHigh; + public const string BrightnessLow = Material.Filled.BrightnessLow; + public const string BrightnessMedium = Material.Filled.BrightnessMedium; + public const string BrokenImage = Material.Filled.BrokenImage; + public const string BrowseGallery = Material.Filled.BrowseGallery; + public const string BrowserNotSupported = Material.Filled.BrowserNotSupported; + public const string BrowserUpdated = Material.Filled.BrowserUpdated; + public const string BrunchDining = Material.Filled.BrunchDining; + public const string Brush = Material.Filled.Brush; + public const string BubbleChart = Material.Filled.BubbleChart; + public const string BugReport = Material.Filled.BugReport; + public const string Build = Material.Filled.Build; + public const string BuildCircle = Material.Filled.BuildCircle; + public const string Bungalow = Material.Filled.Bungalow; + public const string BurstMode = Material.Filled.BurstMode; + public const string BusAlert = Material.Filled.BusAlert; + public const string Business = Material.Filled.Business; + public const string BusinessCenter = Material.Filled.BusinessCenter; + public const string Cabin = Material.Filled.Cabin; + public const string Cable = Material.Filled.Cable; + public const string Cached = Material.Filled.Cached; + public const string Cake = Material.Filled.Cake; + public const string Calculate = Material.Filled.Calculate; + public const string CalendarMonth = Material.Filled.CalendarMonth; + public const string CalendarToday = Material.Filled.CalendarToday; + public const string CalendarViewDay = Material.Filled.CalendarViewDay; + public const string CalendarViewMonth = Material.Filled.CalendarViewMonth; + public const string CalendarViewWeek = Material.Filled.CalendarViewWeek; + public const string Call = Material.Filled.Call; + public const string CallEnd = Material.Filled.CallEnd; + public const string CallMade = Material.Filled.CallMade; + public const string CallMerge = Material.Filled.CallMerge; + public const string CallMissed = Material.Filled.CallMissed; + public const string CallMissedOutgoing = Material.Filled.CallMissedOutgoing; + public const string CallReceived = Material.Filled.CallReceived; + public const string CallSplit = Material.Filled.CallSplit; + public const string CallToAction = Material.Filled.CallToAction; + public const string Camera = Material.Filled.Camera; + public const string CameraAlt = Material.Filled.CameraAlt; + public const string CameraEnhance = Material.Filled.CameraEnhance; + public const string CameraFront = Material.Filled.CameraFront; + public const string CameraIndoor = Material.Filled.CameraIndoor; + public const string CameraOutdoor = Material.Filled.CameraOutdoor; + public const string CameraRear = Material.Filled.CameraRear; + public const string CameraRoll = Material.Filled.CameraRoll; + public const string Cameraswitch = Material.Filled.Cameraswitch; + public const string Campaign = Material.Filled.Campaign; + public const string Cancel = Material.Filled.Cancel; + public const string CancelPresentation = Material.Filled.CancelPresentation; + public const string CancelScheduleSend = Material.Filled.CancelScheduleSend; + public const string CandlestickChart = Material.Filled.CandlestickChart; + public const string CarCrash = Material.Filled.CarCrash; + public const string CarRental = Material.Filled.CarRental; + public const string CarRepair = Material.Filled.CarRepair; + public const string CardGiftcard = Material.Filled.CardGiftcard; + public const string CardMembership = Material.Filled.CardMembership; + public const string CardTravel = Material.Filled.CardTravel; + public const string Carpenter = Material.Filled.Carpenter; + public const string Cases = Material.Filled.Cases; + public const string Casino = Material.Filled.Casino; + public const string Cast = Material.Filled.Cast; + public const string CastConnected = Material.Filled.CastConnected; + public const string CastForEducation = Material.Filled.CastForEducation; + public const string Castle = Material.Filled.Castle; + public const string CatchingPokemon = Material.Filled.CatchingPokemon; + public const string Category = Material.Filled.Category; + public const string Celebration = Material.Filled.Celebration; + public const string CellTower = Material.Filled.CellTower; + public const string CellWifi = Material.Filled.CellWifi; + public const string CenterFocusStrong = Material.Filled.CenterFocusStrong; + public const string CenterFocusWeak = Material.Filled.CenterFocusWeak; + public const string Chair = Material.Filled.Chair; + public const string ChairAlt = Material.Filled.ChairAlt; + public const string Chalet = Material.Filled.Chalet; + public const string ChangeCircle = Material.Filled.ChangeCircle; + public const string ChangeHistory = Material.Filled.ChangeHistory; + public const string ChargingStation = Material.Filled.ChargingStation; + public const string Chat = Material.Filled.Chat; + public const string ChatBubble = Material.Filled.ChatBubble; + public const string ChatBubbleOutline = Material.Filled.ChatBubbleOutline; + public const string Check = Material.Filled.Check; + public const string CheckBox = Material.Filled.CheckBox; + public const string CheckBoxOutlineBlank = Material.Filled.CheckBoxOutlineBlank; + public const string CheckCircle = Material.Filled.CheckCircle; + public const string CheckCircleOutline = Material.Filled.CheckCircleOutline; + public const string Checklist = Material.Filled.Checklist; + public const string ChecklistRtl = Material.Filled.ChecklistRtl; + public const string Checkroom = Material.Filled.Checkroom; + public const string ChevronLeft = Material.Filled.ChevronLeft; + public const string ChevronRight = Material.Filled.ChevronRight; + public const string ChildCare = Material.Filled.ChildCare; + public const string ChildFriendly = Material.Filled.ChildFriendly; + public const string ChromeReaderMode = Material.Filled.ChromeReaderMode; + public const string Church = Material.Filled.Church; + public const string Circle = Material.Filled.Circle; + public const string CircleNotifications = Material.Filled.CircleNotifications; + public const string Class = Material.Filled.Class; + public const string CleanHands = Material.Filled.CleanHands; + public const string CleaningServices = Material.Filled.CleaningServices; + public const string Clear = Material.Filled.Clear; + public const string ClearAll = Material.Filled.ClearAll; + public const string Close = Material.Filled.Close; + public const string CloseFullscreen = Material.Filled.CloseFullscreen; + public const string ClosedCaption = Material.Filled.ClosedCaption; + public const string ClosedCaptionDisabled = Material.Filled.ClosedCaptionDisabled; + public const string ClosedCaptionOff = Material.Filled.ClosedCaptionOff; + public const string Cloud = Material.Filled.Cloud; + public const string CloudCircle = Material.Filled.CloudCircle; + public const string CloudDone = Material.Filled.CloudDone; + public const string CloudDownload = Material.Filled.CloudDownload; + public const string CloudOff = Material.Filled.CloudOff; + public const string CloudQueue = Material.Filled.CloudQueue; + public const string CloudSync = Material.Filled.CloudSync; + public const string CloudUpload = Material.Filled.CloudUpload; + public const string Co2 = Material.Filled.Co2; + public const string CoPresent = Material.Filled.CoPresent; + public const string Code = Material.Filled.Code; + public const string CodeOff = Material.Filled.CodeOff; + public const string Coffee = Material.Filled.Coffee; + public const string CoffeeMaker = Material.Filled.CoffeeMaker; + public const string Collections = Material.Filled.Collections; + public const string CollectionsBookmark = Material.Filled.CollectionsBookmark; + public const string ColorLens = Material.Filled.ColorLens; + public const string Colorize = Material.Filled.Colorize; + public const string Comment = Material.Filled.Comment; + public const string CommentBank = Material.Filled.CommentBank; + public const string CommentsDisabled = Material.Filled.CommentsDisabled; + public const string Commit = Material.Filled.Commit; + public const string Commute = Material.Filled.Commute; + public const string Compare = Material.Filled.Compare; + public const string CompareArrows = Material.Filled.CompareArrows; + public const string CompassCalibration = Material.Filled.CompassCalibration; + public const string Compost = Material.Filled.Compost; + public const string Compress = Material.Filled.Compress; + public const string Computer = Material.Filled.Computer; + public const string ConfirmationNumber = Material.Filled.ConfirmationNumber; + public const string ConnectWithoutContact = Material.Filled.ConnectWithoutContact; + public const string ConnectedTv = Material.Filled.ConnectedTv; + public const string ConnectingAirports = Material.Filled.ConnectingAirports; + public const string Construction = Material.Filled.Construction; + public const string ContactMail = Material.Filled.ContactMail; + public const string ContactPage = Material.Filled.ContactPage; + public const string ContactPhone = Material.Filled.ContactPhone; + public const string ContactSupport = Material.Filled.ContactSupport; + public const string Contactless = Material.Filled.Contactless; + public const string Contacts = Material.Filled.Contacts; + public const string ContentCopy = Material.Filled.ContentCopy; + public const string ContentCut = Material.Filled.ContentCut; + public const string ContentPaste = Material.Filled.ContentPaste; + public const string ContentPasteGo = Material.Filled.ContentPasteGo; + public const string ContentPasteOff = Material.Filled.ContentPasteOff; + public const string ContentPasteSearch = Material.Filled.ContentPasteSearch; + public const string Contrast = Material.Filled.Contrast; + public const string ControlCamera = Material.Filled.ControlCamera; + public const string ControlPoint = Material.Filled.ControlPoint; + public const string ControlPointDuplicate = Material.Filled.ControlPointDuplicate; + public const string Cookie = Material.Filled.Cookie; + public const string CopyAll = Material.Filled.CopyAll; + public const string Copyright = Material.Filled.Copyright; + public const string Coronavirus = Material.Filled.Coronavirus; + public const string CorporateFare = Material.Filled.CorporateFare; + public const string Cottage = Material.Filled.Cottage; + public const string Countertops = Material.Filled.Countertops; + public const string Create = Material.Filled.Create; + public const string CreateNewFolder = Material.Filled.CreateNewFolder; + public const string CreditCard = Material.Filled.CreditCard; + public const string CreditCardOff = Material.Filled.CreditCardOff; + public const string CreditScore = Material.Filled.CreditScore; + public const string Crib = Material.Filled.Crib; + public const string CrisisAlert = Material.Filled.CrisisAlert; + public const string Crop = Material.Filled.Crop; + public const string Crop169 = Material.Filled.Crop169; + public const string Crop32 = Material.Filled.Crop32; + public const string Crop54 = Material.Filled.Crop54; + public const string Crop75 = Material.Filled.Crop75; + public const string CropDin = Material.Filled.CropDin; + public const string CropFree = Material.Filled.CropFree; + public const string CropLandscape = Material.Filled.CropLandscape; + public const string CropOriginal = Material.Filled.CropOriginal; + public const string CropPortrait = Material.Filled.CropPortrait; + public const string CropRotate = Material.Filled.CropRotate; + public const string CropSquare = Material.Filled.CropSquare; + public const string CrueltyFree = Material.Filled.CrueltyFree; + public const string Css = Material.Filled.Css; + public const string CurrencyBitcoin = Material.Filled.CurrencyBitcoin; + public const string CurrencyExchange = Material.Filled.CurrencyExchange; + public const string CurrencyFranc = Material.Filled.CurrencyFranc; + public const string CurrencyLira = Material.Filled.CurrencyLira; + public const string CurrencyPound = Material.Filled.CurrencyPound; + public const string CurrencyRuble = Material.Filled.CurrencyRuble; + public const string CurrencyRupee = Material.Filled.CurrencyRupee; + public const string CurrencyYen = Material.Filled.CurrencyYen; + public const string CurrencyYuan = Material.Filled.CurrencyYuan; + public const string Cyclone = Material.Filled.Cyclone; + public const string Dangerous = Material.Filled.Dangerous; + public const string DarkMode = Material.Filled.DarkMode; + public const string Dashboard = Material.Filled.Dashboard; + public const string DashboardCustomize = Material.Filled.DashboardCustomize; + public const string DataArray = Material.Filled.DataArray; + public const string DataExploration = Material.Filled.DataExploration; + public const string DataObject = Material.Filled.DataObject; + public const string DataSaverOff = Material.Filled.DataSaverOff; + public const string DataSaverOn = Material.Filled.DataSaverOn; + public const string DataThresholding = Material.Filled.DataThresholding; + public const string DataUsage = Material.Filled.DataUsage; + public const string DateRange = Material.Filled.DateRange; + public const string Deblur = Material.Filled.Deblur; + public const string Deck = Material.Filled.Deck; + public const string Dehaze = Material.Filled.Dehaze; + public const string Delete = Material.Filled.Delete; + public const string DeleteForever = Material.Filled.DeleteForever; + public const string DeleteOutline = Material.Filled.DeleteOutline; + public const string DeleteSweep = Material.Filled.DeleteSweep; + public const string DeliveryDining = Material.Filled.DeliveryDining; + public const string DensityLarge = Material.Filled.DensityLarge; + public const string DensityMedium = Material.Filled.DensityMedium; + public const string DensitySmall = Material.Filled.DensitySmall; + public const string DepartureBoard = Material.Filled.DepartureBoard; + public const string Description = Material.Filled.Description; + public const string Deselect = Material.Filled.Deselect; + public const string DesignServices = Material.Filled.DesignServices; + public const string DesktopAccessDisabled = Material.Filled.DesktopAccessDisabled; + public const string DesktopMac = Material.Filled.DesktopMac; + public const string DesktopWindows = Material.Filled.DesktopWindows; + public const string Details = Material.Filled.Details; + public const string DeveloperBoard = Material.Filled.DeveloperBoard; + public const string DeveloperBoardOff = Material.Filled.DeveloperBoardOff; + public const string DeveloperMode = Material.Filled.DeveloperMode; + public const string DeviceHub = Material.Filled.DeviceHub; + public const string DeviceThermostat = Material.Filled.DeviceThermostat; + public const string DeviceUnknown = Material.Filled.DeviceUnknown; + public const string Devices = Material.Filled.Devices; + public const string DevicesFold = Material.Filled.DevicesFold; + public const string DevicesOther = Material.Filled.DevicesOther; + public const string DialerSip = Material.Filled.DialerSip; + public const string Dialpad = Material.Filled.Dialpad; + public const string Diamond = Material.Filled.Diamond; + public const string Difference = Material.Filled.Difference; + public const string Dining = Material.Filled.Dining; + public const string DinnerDining = Material.Filled.DinnerDining; + public const string Directions = Material.Filled.Directions; + public const string DirectionsBike = Material.Filled.DirectionsBike; + public const string DirectionsBoat = Material.Filled.DirectionsBoat; + public const string DirectionsBoatFilled = Material.Filled.DirectionsBoatFilled; + public const string DirectionsBus = Material.Filled.DirectionsBus; + public const string DirectionsBusFilled = Material.Filled.DirectionsBusFilled; + public const string DirectionsCar = Material.Filled.DirectionsCar; + public const string DirectionsCarFilled = Material.Filled.DirectionsCarFilled; + public const string DirectionsOff = Material.Filled.DirectionsOff; + public const string DirectionsRailway = Material.Filled.DirectionsRailway; + public const string DirectionsRailwayFilled = Material.Filled.DirectionsRailwayFilled; + public const string DirectionsRun = Material.Filled.DirectionsRun; + public const string DirectionsSubway = Material.Filled.DirectionsSubway; + public const string DirectionsSubwayFilled = Material.Filled.DirectionsSubwayFilled; + public const string DirectionsTransit = Material.Filled.DirectionsTransit; + public const string DirectionsTransitFilled = Material.Filled.DirectionsTransitFilled; + public const string DirectionsWalk = Material.Filled.DirectionsWalk; + public const string DirtyLens = Material.Filled.DirtyLens; + public const string DisabledByDefault = Material.Filled.DisabledByDefault; + public const string DisabledVisible = Material.Filled.DisabledVisible; + public const string DiscFull = Material.Filled.DiscFull; + public const string Discount = Material.Filled.Discount; + public const string DisplaySettings = Material.Filled.DisplaySettings; + public const string Dns = Material.Filled.Dns; + public const string DoDisturb = Material.Filled.DoDisturb; + public const string DoDisturbAlt = Material.Filled.DoDisturbAlt; + public const string DoDisturbOff = Material.Filled.DoDisturbOff; + public const string DoDisturbOn = Material.Filled.DoDisturbOn; + public const string DoNotDisturb = Material.Filled.DoNotDisturb; + public const string DoNotDisturbAlt = Material.Filled.DoNotDisturbAlt; + public const string DoNotDisturbOff = Material.Filled.DoNotDisturbOff; + public const string DoNotDisturbOn = Material.Filled.DoNotDisturbOn; + public const string DoNotDisturbOnTotalSilence = Material.Filled.DoNotDisturbOnTotalSilence; + public const string DoNotStep = Material.Filled.DoNotStep; + public const string DoNotTouch = Material.Filled.DoNotTouch; + public const string Dock = Material.Filled.Dock; + public const string DocumentScanner = Material.Filled.DocumentScanner; + public const string Domain = Material.Filled.Domain; + public const string DomainAdd = Material.Filled.DomainAdd; + public const string DomainDisabled = Material.Filled.DomainDisabled; + public const string DomainVerification = Material.Filled.DomainVerification; + public const string Done = Material.Filled.Done; + public const string DoneAll = Material.Filled.DoneAll; + public const string DoneOutline = Material.Filled.DoneOutline; + public const string DonutLarge = Material.Filled.DonutLarge; + public const string DonutSmall = Material.Filled.DonutSmall; + public const string DoorBack = Material.Filled.DoorBack; + public const string DoorFront = Material.Filled.DoorFront; + public const string DoorSliding = Material.Filled.DoorSliding; + public const string Doorbell = Material.Filled.Doorbell; + public const string DoubleArrow = Material.Filled.DoubleArrow; + public const string DownhillSkiing = Material.Filled.DownhillSkiing; + public const string Download = Material.Filled.Download; + public const string DownloadDone = Material.Filled.DownloadDone; + public const string DownloadForOffline = Material.Filled.DownloadForOffline; + public const string Downloading = Material.Filled.Downloading; + public const string Drafts = Material.Filled.Drafts; + public const string DragHandle = Material.Filled.DragHandle; + public const string DragIndicator = Material.Filled.DragIndicator; + public const string Draw = Material.Filled.Draw; + public const string DriveEta = Material.Filled.DriveEta; + public const string DriveFileMove = Material.Filled.DriveFileMove; + public const string DriveFileMoveRtl = Material.Filled.DriveFileMoveRtl; + public const string DriveFileRenameOutline = Material.Filled.DriveFileRenameOutline; + public const string DriveFolderUpload = Material.Filled.DriveFolderUpload; + public const string Dry = Material.Filled.Dry; + public const string DryCleaning = Material.Filled.DryCleaning; + public const string Duo = Material.Filled.Duo; + public const string Dvr = Material.Filled.Dvr; + public const string DynamicFeed = Material.Filled.DynamicFeed; + public const string DynamicForm = Material.Filled.DynamicForm; + public const string EMobiledata = Material.Filled.EMobiledata; + public const string Earbuds = Material.Filled.Earbuds; + public const string EarbudsBattery = Material.Filled.EarbudsBattery; + public const string East = Material.Filled.East; + public const string EdgesensorHigh = Material.Filled.EdgesensorHigh; + public const string EdgesensorLow = Material.Filled.EdgesensorLow; + public const string Edit = Material.Filled.Edit; + public const string EditAttributes = Material.Filled.EditAttributes; + public const string EditCalendar = Material.Filled.EditCalendar; + public const string EditLocation = Material.Filled.EditLocation; + public const string EditLocationAlt = Material.Filled.EditLocationAlt; + public const string EditNote = Material.Filled.EditNote; + public const string EditNotifications = Material.Filled.EditNotifications; + public const string EditOff = Material.Filled.EditOff; + public const string EditRoad = Material.Filled.EditRoad; + public const string Egg = Material.Filled.Egg; + public const string EggAlt = Material.Filled.EggAlt; + public const string Eject = Material.Filled.Eject; + public const string Elderly = Material.Filled.Elderly; + public const string ElderlyWoman = Material.Filled.ElderlyWoman; + public const string ElectricBike = Material.Filled.ElectricBike; + public const string ElectricCar = Material.Filled.ElectricCar; + public const string ElectricMoped = Material.Filled.ElectricMoped; + public const string ElectricRickshaw = Material.Filled.ElectricRickshaw; + public const string ElectricScooter = Material.Filled.ElectricScooter; + public const string ElectricalServices = Material.Filled.ElectricalServices; + public const string Elevator = Material.Filled.Elevator; + public const string Email = Material.Filled.Email; + public const string Emergency = Material.Filled.Emergency; + public const string EmergencyRecording = Material.Filled.EmergencyRecording; + public const string EmergencyShare = Material.Filled.EmergencyShare; + public const string EmojiEmotions = Material.Filled.EmojiEmotions; + public const string EmojiEvents = Material.Filled.EmojiEvents; + public const string EmojiFoodBeverage = Material.Filled.EmojiFoodBeverage; + public const string EmojiNature = Material.Filled.EmojiNature; + public const string EmojiObjects = Material.Filled.EmojiObjects; + public const string EmojiPeople = Material.Filled.EmojiPeople; + public const string EmojiSymbols = Material.Filled.EmojiSymbols; + public const string EmojiTransportation = Material.Filled.EmojiTransportation; + public const string Engineering = Material.Filled.Engineering; + public const string EnhancedEncryption = Material.Filled.EnhancedEncryption; + public const string Equalizer = Material.Filled.Equalizer; + public const string Error = Material.Filled.Error; + public const string ErrorOutline = Material.Filled.ErrorOutline; + public const string Escalator = Material.Filled.Escalator; + public const string EscalatorWarning = Material.Filled.EscalatorWarning; + public const string Euro = Material.Filled.Euro; + public const string EuroSymbol = Material.Filled.EuroSymbol; + public const string EvStation = Material.Filled.EvStation; + public const string Event = Material.Filled.Event; + public const string EventAvailable = Material.Filled.EventAvailable; + public const string EventBusy = Material.Filled.EventBusy; + public const string EventNote = Material.Filled.EventNote; + public const string EventRepeat = Material.Filled.EventRepeat; + public const string EventSeat = Material.Filled.EventSeat; + public const string ExitToApp = Material.Filled.ExitToApp; + public const string Expand = Material.Filled.Expand; + public const string ExpandCircleDown = Material.Filled.ExpandCircleDown; + public const string ExpandLess = Material.Filled.ExpandLess; + public const string ExpandMore = Material.Filled.ExpandMore; + public const string Explicit = Material.Filled.Explicit; + public const string Explore = Material.Filled.Explore; + public const string ExploreOff = Material.Filled.ExploreOff; + public const string Exposure = Material.Filled.Exposure; + public const string ExposureNeg1 = Material.Filled.ExposureNeg1; + public const string ExposureNeg2 = Material.Filled.ExposureNeg2; + public const string ExposurePlus1 = Material.Filled.ExposurePlus1; + public const string ExposurePlus2 = Material.Filled.ExposurePlus2; + public const string ExposureZero = Material.Filled.ExposureZero; + public const string Extension = Material.Filled.Extension; + public const string ExtensionOff = Material.Filled.ExtensionOff; + public const string Face = Material.Filled.Face; + public const string FaceRetouchingNatural = Material.Filled.FaceRetouchingNatural; + public const string FaceRetouchingOff = Material.Filled.FaceRetouchingOff; + public const string FactCheck = Material.Filled.FactCheck; + public const string Factory = Material.Filled.Factory; + public const string FamilyRestroom = Material.Filled.FamilyRestroom; + public const string FastForward = Material.Filled.FastForward; + public const string FastRewind = Material.Filled.FastRewind; + public const string Fastfood = Material.Filled.Fastfood; + public const string Favorite = Material.Filled.Favorite; + public const string FavoriteBorder = Material.Filled.FavoriteBorder; + public const string Fax = Material.Filled.Fax; + public const string FeaturedPlayList = Material.Filled.FeaturedPlayList; + public const string FeaturedVideo = Material.Filled.FeaturedVideo; + public const string Feed = Material.Filled.Feed; + public const string Feedback = Material.Filled.Feedback; + public const string Female = Material.Filled.Female; + public const string Fence = Material.Filled.Fence; + public const string Festival = Material.Filled.Festival; + public const string FiberDvr = Material.Filled.FiberDvr; + public const string FiberManualRecord = Material.Filled.FiberManualRecord; + public const string FiberNew = Material.Filled.FiberNew; + public const string FiberPin = Material.Filled.FiberPin; + public const string FiberSmartRecord = Material.Filled.FiberSmartRecord; + public const string FileCopy = Material.Filled.FileCopy; + public const string FileDownload = Material.Filled.FileDownload; + public const string FileDownloadDone = Material.Filled.FileDownloadDone; + public const string FileDownloadOff = Material.Filled.FileDownloadOff; + public const string FileOpen = Material.Filled.FileOpen; + public const string FilePresent = Material.Filled.FilePresent; + public const string FileUpload = Material.Filled.FileUpload; + public const string Filter = Material.Filled.Filter; + public const string Filter1 = Material.Filled.Filter1; + public const string Filter2 = Material.Filled.Filter2; + public const string Filter3 = Material.Filled.Filter3; + public const string Filter4 = Material.Filled.Filter4; + public const string Filter5 = Material.Filled.Filter5; + public const string Filter6 = Material.Filled.Filter6; + public const string Filter7 = Material.Filled.Filter7; + public const string Filter8 = Material.Filled.Filter8; + public const string Filter9 = Material.Filled.Filter9; + public const string Filter9Plus = Material.Filled.Filter9Plus; + public const string FilterAlt = Material.Filled.FilterAlt; + public const string FilterAltOff = Material.Filled.FilterAltOff; + public const string FilterBAndW = Material.Filled.FilterBAndW; + public const string FilterCenterFocus = Material.Filled.FilterCenterFocus; + public const string FilterDrama = Material.Filled.FilterDrama; + public const string FilterFrames = Material.Filled.FilterFrames; + public const string FilterHdr = Material.Filled.FilterHdr; + public const string FilterList = Material.Filled.FilterList; + public const string FilterListOff = Material.Filled.FilterListOff; + public const string FilterNone = Material.Filled.FilterNone; + public const string FilterTiltShift = Material.Filled.FilterTiltShift; + public const string FilterVintage = Material.Filled.FilterVintage; + public const string FindInPage = Material.Filled.FindInPage; + public const string FindReplace = Material.Filled.FindReplace; + public const string Fingerprint = Material.Filled.Fingerprint; + public const string FireExtinguisher = Material.Filled.FireExtinguisher; + public const string Fireplace = Material.Filled.Fireplace; + public const string FirstPage = Material.Filled.FirstPage; + public const string FitScreen = Material.Filled.FitScreen; + public const string Fitbit = Material.Filled.Fitbit; + public const string FitnessCenter = Material.Filled.FitnessCenter; + public const string Flag = Material.Filled.Flag; + public const string FlagCircle = Material.Filled.FlagCircle; + public const string Flaky = Material.Filled.Flaky; + public const string Flare = Material.Filled.Flare; + public const string FlashAuto = Material.Filled.FlashAuto; + public const string FlashOff = Material.Filled.FlashOff; + public const string FlashOn = Material.Filled.FlashOn; + public const string FlashlightOff = Material.Filled.FlashlightOff; + public const string FlashlightOn = Material.Filled.FlashlightOn; + public const string Flatware = Material.Filled.Flatware; + public const string Flight = Material.Filled.Flight; + public const string FlightClass = Material.Filled.FlightClass; + public const string FlightLand = Material.Filled.FlightLand; + public const string FlightTakeoff = Material.Filled.FlightTakeoff; + public const string Flip = Material.Filled.Flip; + public const string FlipCameraAndroid = Material.Filled.FlipCameraAndroid; + public const string FlipCameraIos = Material.Filled.FlipCameraIos; + public const string FlipToBack = Material.Filled.FlipToBack; + public const string FlipToFront = Material.Filled.FlipToFront; + public const string Flood = Material.Filled.Flood; + public const string Flourescent = Material.Filled.Flourescent; + public const string FlutterDash = Material.Filled.FlutterDash; + public const string FmdBad = Material.Filled.FmdBad; + public const string FmdGood = Material.Filled.FmdGood; + public const string Folder = Material.Filled.Folder; + public const string FolderCopy = Material.Filled.FolderCopy; + public const string FolderDelete = Material.Filled.FolderDelete; + public const string FolderOff = Material.Filled.FolderOff; + public const string FolderOpen = Material.Filled.FolderOpen; + public const string FolderShared = Material.Filled.FolderShared; + public const string FolderSpecial = Material.Filled.FolderSpecial; + public const string FolderZip = Material.Filled.FolderZip; + public const string FollowTheSigns = Material.Filled.FollowTheSigns; + public const string FontDownload = Material.Filled.FontDownload; + public const string FontDownloadOff = Material.Filled.FontDownloadOff; + public const string FoodBank = Material.Filled.FoodBank; + public const string Forest = Material.Filled.Forest; + public const string ForkLeft = Material.Filled.ForkLeft; + public const string ForkRight = Material.Filled.ForkRight; + public const string FormatAlignCenter = Material.Filled.FormatAlignCenter; + public const string FormatAlignJustify = Material.Filled.FormatAlignJustify; + public const string FormatAlignLeft = Material.Filled.FormatAlignLeft; + public const string FormatAlignRight = Material.Filled.FormatAlignRight; + public const string FormatBold = Material.Filled.FormatBold; + public const string FormatClear = Material.Filled.FormatClear; + public const string FormatColorFill = Material.Filled.FormatColorFill; + public const string FormatColorReset = Material.Filled.FormatColorReset; + public const string FormatColorText = Material.Filled.FormatColorText; + public const string FormatIndentDecrease = Material.Filled.FormatIndentDecrease; + public const string FormatIndentIncrease = Material.Filled.FormatIndentIncrease; + public const string FormatItalic = Material.Filled.FormatItalic; + public const string FormatLineSpacing = Material.Filled.FormatLineSpacing; + public const string FormatListBulleted = Material.Filled.FormatListBulleted; + public const string FormatListNumbered = Material.Filled.FormatListNumbered; + public const string FormatListNumberedRtl = Material.Filled.FormatListNumberedRtl; + public const string FormatOverline = Material.Filled.FormatOverline; + public const string FormatPaint = Material.Filled.FormatPaint; + public const string FormatQuote = Material.Filled.FormatQuote; + public const string FormatShapes = Material.Filled.FormatShapes; + public const string FormatSize = Material.Filled.FormatSize; + public const string FormatStrikethrough = Material.Filled.FormatStrikethrough; + public const string FormatTextdirectionLToR = Material.Filled.FormatTextdirectionLToR; + public const string FormatTextdirectionRToL = Material.Filled.FormatTextdirectionRToL; + public const string FormatUnderlined = Material.Filled.FormatUnderlined; + public const string Fort = Material.Filled.Fort; + public const string Forum = Material.Filled.Forum; + public const string Forward = Material.Filled.Forward; + public const string Forward10 = Material.Filled.Forward10; + public const string Forward30 = Material.Filled.Forward30; + public const string Forward5 = Material.Filled.Forward5; + public const string ForwardToInbox = Material.Filled.ForwardToInbox; + public const string Foundation = Material.Filled.Foundation; + public const string FreeBreakfast = Material.Filled.FreeBreakfast; + public const string FreeCancellation = Material.Filled.FreeCancellation; + public const string FrontHand = Material.Filled.FrontHand; + public const string Fullscreen = Material.Filled.Fullscreen; + public const string FullscreenExit = Material.Filled.FullscreenExit; + public const string Functions = Material.Filled.Functions; + public const string GMobiledata = Material.Filled.GMobiledata; + public const string GTranslate = Material.Filled.GTranslate; + public const string Gamepad = Material.Filled.Gamepad; + public const string Games = Material.Filled.Games; + public const string Garage = Material.Filled.Garage; + public const string Gavel = Material.Filled.Gavel; + public const string GeneratingTokens = Material.Filled.GeneratingTokens; + public const string Gesture = Material.Filled.Gesture; + public const string GetApp = Material.Filled.GetApp; + public const string Gif = Material.Filled.Gif; + public const string GifBox = Material.Filled.GifBox; + public const string Girl = Material.Filled.Girl; + public const string Gite = Material.Filled.Gite; + public const string GolfCourse = Material.Filled.GolfCourse; + public const string GppBad = Material.Filled.GppBad; + public const string GppGood = Material.Filled.GppGood; + public const string GppMaybe = Material.Filled.GppMaybe; + public const string GpsFixed = Material.Filled.GpsFixed; + public const string GpsNotFixed = Material.Filled.GpsNotFixed; + public const string GpsOff = Material.Filled.GpsOff; + public const string Grade = Material.Filled.Grade; + public const string Gradient = Material.Filled.Gradient; + public const string Grading = Material.Filled.Grading; + public const string Grain = Material.Filled.Grain; + public const string GraphicEq = Material.Filled.GraphicEq; + public const string Grass = Material.Filled.Grass; + public const string Grid3x3 = Material.Filled.Grid3x3; + public const string Grid4x4 = Material.Filled.Grid4x4; + public const string GridGoldenratio = Material.Filled.GridGoldenratio; + public const string GridOff = Material.Filled.GridOff; + public const string GridOn = Material.Filled.GridOn; + public const string GridView = Material.Filled.GridView; + public const string Group = Material.Filled.Group; + public const string GroupAdd = Material.Filled.GroupAdd; + public const string GroupOff = Material.Filled.GroupOff; + public const string GroupRemove = Material.Filled.GroupRemove; + public const string GroupWork = Material.Filled.GroupWork; + public const string Groups = Material.Filled.Groups; + public const string HMobiledata = Material.Filled.HMobiledata; + public const string HPlusMobiledata = Material.Filled.HPlusMobiledata; + public const string Hail = Material.Filled.Hail; + public const string Handshake = Material.Filled.Handshake; + public const string Handyman = Material.Filled.Handyman; + public const string Hardware = Material.Filled.Hardware; + public const string Hd = Material.Filled.Hd; + public const string HdrAuto = Material.Filled.HdrAuto; + public const string HdrAutoSelect = Material.Filled.HdrAutoSelect; + public const string HdrEnhancedSelect = Material.Filled.HdrEnhancedSelect; + public const string HdrOff = Material.Filled.HdrOff; + public const string HdrOffSelect = Material.Filled.HdrOffSelect; + public const string HdrOn = Material.Filled.HdrOn; + public const string HdrOnSelect = Material.Filled.HdrOnSelect; + public const string HdrPlus = Material.Filled.HdrPlus; + public const string HdrStrong = Material.Filled.HdrStrong; + public const string HdrWeak = Material.Filled.HdrWeak; + public const string Headphones = Material.Filled.Headphones; + public const string HeadphonesBattery = Material.Filled.HeadphonesBattery; + public const string Headset = Material.Filled.Headset; + public const string HeadsetMic = Material.Filled.HeadsetMic; + public const string HeadsetOff = Material.Filled.HeadsetOff; + public const string Healing = Material.Filled.Healing; + public const string HealthAndSafety = Material.Filled.HealthAndSafety; + public const string Hearing = Material.Filled.Hearing; + public const string HearingDisabled = Material.Filled.HearingDisabled; + public const string HeartBroken = Material.Filled.HeartBroken; + public const string Height = Material.Filled.Height; + public const string Help = Material.Filled.Help; + public const string HelpCenter = Material.Filled.HelpCenter; + public const string HelpOutline = Material.Filled.HelpOutline; + public const string Hevc = Material.Filled.Hevc; + public const string Hexagon = Material.Filled.Hexagon; + public const string HideImage = Material.Filled.HideImage; + public const string HideSource = Material.Filled.HideSource; + public const string HighQuality = Material.Filled.HighQuality; + public const string Highlight = Material.Filled.Highlight; + public const string HighlightAlt = Material.Filled.HighlightAlt; + public const string HighlightOff = Material.Filled.HighlightOff; + public const string Hiking = Material.Filled.Hiking; + public const string History = Material.Filled.History; + public const string HistoryEdu = Material.Filled.HistoryEdu; + public const string HistoryToggleOff = Material.Filled.HistoryToggleOff; + public const string Hive = Material.Filled.Hive; + public const string Hls = Material.Filled.Hls; + public const string HlsOff = Material.Filled.HlsOff; + public const string HolidayVillage = Material.Filled.HolidayVillage; + public const string Home = Material.Filled.Home; + public const string HomeMax = Material.Filled.HomeMax; + public const string HomeMini = Material.Filled.HomeMini; + public const string HomeRepairService = Material.Filled.HomeRepairService; + public const string HomeWork = Material.Filled.HomeWork; + public const string HorizontalDistribute = Material.Filled.HorizontalDistribute; + public const string HorizontalRule = Material.Filled.HorizontalRule; + public const string HorizontalSplit = Material.Filled.HorizontalSplit; + public const string HotTub = Material.Filled.HotTub; + public const string Hotel = Material.Filled.Hotel; + public const string HotelClass = Material.Filled.HotelClass; + public const string HourglassBottom = Material.Filled.HourglassBottom; + public const string HourglassDisabled = Material.Filled.HourglassDisabled; + public const string HourglassEmpty = Material.Filled.HourglassEmpty; + public const string HourglassFull = Material.Filled.HourglassFull; + public const string HourglassTop = Material.Filled.HourglassTop; + public const string House = Material.Filled.House; + public const string HouseSiding = Material.Filled.HouseSiding; + public const string Houseboat = Material.Filled.Houseboat; + public const string HowToReg = Material.Filled.HowToReg; + public const string HowToVote = Material.Filled.HowToVote; + public const string Html = Material.Filled.Html; + public const string Http = Material.Filled.Http; + public const string Https = Material.Filled.Https; + public const string Hub = Material.Filled.Hub; + public const string Hvac = Material.Filled.Hvac; + public const string IceSkating = Material.Filled.IceSkating; + public const string Icecream = Material.Filled.Icecream; + public const string Image = Material.Filled.Image; + public const string ImageAspectRatio = Material.Filled.ImageAspectRatio; + public const string ImageNotSupported = Material.Filled.ImageNotSupported; + public const string ImageSearch = Material.Filled.ImageSearch; + public const string ImagesearchRoller = Material.Filled.ImagesearchRoller; + public const string ImportContacts = Material.Filled.ImportContacts; + public const string ImportExport = Material.Filled.ImportExport; + public const string ImportantDevices = Material.Filled.ImportantDevices; + public const string Inbox = Material.Filled.Inbox; + public const string IncompleteCircle = Material.Filled.IncompleteCircle; + public const string IndeterminateCheckBox = Material.Filled.IndeterminateCheckBox; + public const string Info = Material.Filled.Info; + public const string Input = Material.Filled.Input; + public const string InsertChart = Material.Filled.InsertChart; + public const string InsertChartOutlined = Material.Filled.InsertChartOutlined; + public const string InsertComment = Material.Filled.InsertComment; + public const string InsertDriveFile = Material.Filled.InsertDriveFile; + public const string InsertEmoticon = Material.Filled.InsertEmoticon; + public const string InsertInvitation = Material.Filled.InsertInvitation; + public const string InsertLink = Material.Filled.InsertLink; + public const string InsertPageBreak = Material.Filled.InsertPageBreak; + public const string InsertPhoto = Material.Filled.InsertPhoto; + public const string Insights = Material.Filled.Insights; + public const string InstallDesktop = Material.Filled.InstallDesktop; + public const string InstallMobile = Material.Filled.InstallMobile; + public const string IntegrationInstructions = Material.Filled.IntegrationInstructions; + public const string Interests = Material.Filled.Interests; + public const string InterpreterMode = Material.Filled.InterpreterMode; + public const string Inventory = Material.Filled.Inventory; + public const string Inventory2 = Material.Filled.Inventory2; + public const string InvertColors = Material.Filled.InvertColors; + public const string InvertColorsOff = Material.Filled.InvertColorsOff; + public const string IosShare = Material.Filled.IosShare; + public const string Iron = Material.Filled.Iron; + public const string Iso = Material.Filled.Iso; + public const string Javascript = Material.Filled.Javascript; + public const string JoinFull = Material.Filled.JoinFull; + public const string JoinInner = Material.Filled.JoinInner; + public const string JoinLeft = Material.Filled.JoinLeft; + public const string JoinRight = Material.Filled.JoinRight; + public const string Kayaking = Material.Filled.Kayaking; + public const string KebabDining = Material.Filled.KebabDining; + public const string Key = Material.Filled.Key; + public const string KeyOff = Material.Filled.KeyOff; + public const string Keyboard = Material.Filled.Keyboard; + public const string KeyboardAlt = Material.Filled.KeyboardAlt; + public const string KeyboardArrowDown = Material.Filled.KeyboardArrowDown; + public const string KeyboardArrowLeft = Material.Filled.KeyboardArrowLeft; + public const string KeyboardArrowRight = Material.Filled.KeyboardArrowRight; + public const string KeyboardArrowUp = Material.Filled.KeyboardArrowUp; + public const string KeyboardBackspace = Material.Filled.KeyboardBackspace; + public const string KeyboardCapslock = Material.Filled.KeyboardCapslock; + public const string KeyboardCommandKey = Material.Filled.KeyboardCommandKey; + public const string KeyboardControlKey = Material.Filled.KeyboardControlKey; + public const string KeyboardDoubleArrowDown = Material.Filled.KeyboardDoubleArrowDown; + public const string KeyboardDoubleArrowLeft = Material.Filled.KeyboardDoubleArrowLeft; + public const string KeyboardDoubleArrowRight = Material.Filled.KeyboardDoubleArrowRight; + public const string KeyboardDoubleArrowUp = Material.Filled.KeyboardDoubleArrowUp; + public const string KeyboardHide = Material.Filled.KeyboardHide; + public const string KeyboardOptionKey = Material.Filled.KeyboardOptionKey; + public const string KeyboardReturn = Material.Filled.KeyboardReturn; + public const string KeyboardTab = Material.Filled.KeyboardTab; + public const string KeyboardVoice = Material.Filled.KeyboardVoice; + public const string KingBed = Material.Filled.KingBed; + public const string Kitchen = Material.Filled.Kitchen; + public const string Kitesurfing = Material.Filled.Kitesurfing; + public const string Label = Material.Filled.Label; + public const string LabelImportant = Material.Filled.LabelImportant; + public const string LabelOff = Material.Filled.LabelOff; + public const string Lan = Material.Filled.Lan; + public const string Landscape = Material.Filled.Landscape; + public const string Landslide = Material.Filled.Landslide; + public const string Language = Material.Filled.Language; + public const string Laptop = Material.Filled.Laptop; + public const string LaptopChromebook = Material.Filled.LaptopChromebook; + public const string LaptopMac = Material.Filled.LaptopMac; + public const string LaptopWindows = Material.Filled.LaptopWindows; + public const string LastPage = Material.Filled.LastPage; + public const string Launch = Material.Filled.Launch; + public const string Layers = Material.Filled.Layers; + public const string LayersClear = Material.Filled.LayersClear; + public const string Leaderboard = Material.Filled.Leaderboard; + public const string LeakAdd = Material.Filled.LeakAdd; + public const string LeakRemove = Material.Filled.LeakRemove; + public const string LegendToggle = Material.Filled.LegendToggle; + public const string Lens = Material.Filled.Lens; + public const string LensBlur = Material.Filled.LensBlur; + public const string LibraryAdd = Material.Filled.LibraryAdd; + public const string LibraryAddCheck = Material.Filled.LibraryAddCheck; + public const string LibraryBooks = Material.Filled.LibraryBooks; + public const string LibraryMusic = Material.Filled.LibraryMusic; + public const string Light = Material.Filled.Light; + public const string LightMode = Material.Filled.LightMode; + public const string Lightbulb = Material.Filled.Lightbulb; + public const string LightbulbCircle = Material.Filled.LightbulbCircle; + public const string LineAxis = Material.Filled.LineAxis; + public const string LineStyle = Material.Filled.LineStyle; + public const string LineWeight = Material.Filled.LineWeight; + public const string LinearScale = Material.Filled.LinearScale; + public const string Link = Material.Filled.Link; + public const string LinkOff = Material.Filled.LinkOff; + public const string LinkedCamera = Material.Filled.LinkedCamera; + public const string Liquor = Material.Filled.Liquor; + public const string List = Material.Filled.List; + public const string ListAlt = Material.Filled.ListAlt; + public const string LiveHelp = Material.Filled.LiveHelp; + public const string LiveTv = Material.Filled.LiveTv; + public const string Living = Material.Filled.Living; + public const string LocalActivity = Material.Filled.LocalActivity; + public const string LocalAirport = Material.Filled.LocalAirport; + public const string LocalAtm = Material.Filled.LocalAtm; + public const string LocalBar = Material.Filled.LocalBar; + public const string LocalCafe = Material.Filled.LocalCafe; + public const string LocalCarWash = Material.Filled.LocalCarWash; + public const string LocalConvenienceStore = Material.Filled.LocalConvenienceStore; + public const string LocalDining = Material.Filled.LocalDining; + public const string LocalDrink = Material.Filled.LocalDrink; + public const string LocalFireDepartment = Material.Filled.LocalFireDepartment; + public const string LocalFlorist = Material.Filled.LocalFlorist; + public const string LocalGasStation = Material.Filled.LocalGasStation; + public const string LocalGroceryStore = Material.Filled.LocalGroceryStore; + public const string LocalHospital = Material.Filled.LocalHospital; + public const string LocalHotel = Material.Filled.LocalHotel; + public const string LocalLaundryService = Material.Filled.LocalLaundryService; + public const string LocalLibrary = Material.Filled.LocalLibrary; + public const string LocalMall = Material.Filled.LocalMall; + public const string LocalMovies = Material.Filled.LocalMovies; + public const string LocalOffer = Material.Filled.LocalOffer; + public const string LocalParking = Material.Filled.LocalParking; + public const string LocalPharmacy = Material.Filled.LocalPharmacy; + public const string LocalPhone = Material.Filled.LocalPhone; + public const string LocalPizza = Material.Filled.LocalPizza; + public const string LocalPlay = Material.Filled.LocalPlay; + public const string LocalPolice = Material.Filled.LocalPolice; + public const string LocalPostOffice = Material.Filled.LocalPostOffice; + public const string LocalPrintshop = Material.Filled.LocalPrintshop; + public const string LocalSee = Material.Filled.LocalSee; + public const string LocalShipping = Material.Filled.LocalShipping; + public const string LocalTaxi = Material.Filled.LocalTaxi; + public const string LocationCity = Material.Filled.LocationCity; + public const string LocationDisabled = Material.Filled.LocationDisabled; + public const string LocationOff = Material.Filled.LocationOff; + public const string LocationOn = Material.Filled.LocationOn; + public const string LocationSearching = Material.Filled.LocationSearching; + public const string Lock = Material.Filled.Lock; + public const string LockClock = Material.Filled.LockClock; + public const string LockOpen = Material.Filled.LockOpen; + public const string LockReset = Material.Filled.LockReset; + public const string Login = Material.Filled.Login; + public const string LogoDev = Material.Filled.LogoDev; + public const string Logout = Material.Filled.Logout; + public const string Looks = Material.Filled.Looks; + public const string Looks3 = Material.Filled.Looks3; + public const string Looks4 = Material.Filled.Looks4; + public const string Looks5 = Material.Filled.Looks5; + public const string Looks6 = Material.Filled.Looks6; + public const string LooksOne = Material.Filled.LooksOne; + public const string LooksTwo = Material.Filled.LooksTwo; + public const string Loop = Material.Filled.Loop; + public const string Loupe = Material.Filled.Loupe; + public const string LowPriority = Material.Filled.LowPriority; + public const string Loyalty = Material.Filled.Loyalty; + public const string LteMobiledata = Material.Filled.LteMobiledata; + public const string LtePlusMobiledata = Material.Filled.LtePlusMobiledata; + public const string Luggage = Material.Filled.Luggage; + public const string LunchDining = Material.Filled.LunchDining; + public const string Mail = Material.Filled.Mail; + public const string MailOutline = Material.Filled.MailOutline; + public const string Male = Material.Filled.Male; + public const string Man = Material.Filled.Man; + public const string ManageAccounts = Material.Filled.ManageAccounts; + public const string ManageHistory = Material.Filled.ManageHistory; + public const string ManageSearch = Material.Filled.ManageSearch; + public const string Map = Material.Filled.Map; + public const string MapsHomeWork = Material.Filled.MapsHomeWork; + public const string MapsUgc = Material.Filled.MapsUgc; + public const string Margin = Material.Filled.Margin; + public const string MarkAsUnread = Material.Filled.MarkAsUnread; + public const string MarkChatRead = Material.Filled.MarkChatRead; + public const string MarkChatUnread = Material.Filled.MarkChatUnread; + public const string MarkEmailRead = Material.Filled.MarkEmailRead; + public const string MarkEmailUnread = Material.Filled.MarkEmailUnread; + public const string MarkUnreadChatAlt = Material.Filled.MarkUnreadChatAlt; + public const string Markunread = Material.Filled.Markunread; + public const string MarkunreadMailbox = Material.Filled.MarkunreadMailbox; + public const string Masks = Material.Filled.Masks; + public const string Maximize = Material.Filled.Maximize; + public const string MediaBluetoothOff = Material.Filled.MediaBluetoothOff; + public const string MediaBluetoothOn = Material.Filled.MediaBluetoothOn; + public const string Mediation = Material.Filled.Mediation; + public const string MedicalInformation = Material.Filled.MedicalInformation; + public const string MedicalServices = Material.Filled.MedicalServices; + public const string Medication = Material.Filled.Medication; + public const string MedicationLiquid = Material.Filled.MedicationLiquid; + public const string MeetingRoom = Material.Filled.MeetingRoom; + public const string Memory = Material.Filled.Memory; + public const string Menu = Material.Filled.Menu; + public const string MenuBook = Material.Filled.MenuBook; + public const string MenuOpen = Material.Filled.MenuOpen; + public const string Merge = Material.Filled.Merge; + public const string MergeType = Material.Filled.MergeType; + public const string Message = Material.Filled.Message; + public const string Mic = Material.Filled.Mic; + public const string MicExternalOff = Material.Filled.MicExternalOff; + public const string MicExternalOn = Material.Filled.MicExternalOn; + public const string MicNone = Material.Filled.MicNone; + public const string MicOff = Material.Filled.MicOff; + public const string Microwave = Material.Filled.Microwave; + public const string MilitaryTech = Material.Filled.MilitaryTech; + public const string Minimize = Material.Filled.Minimize; + public const string MinorCrash = Material.Filled.MinorCrash; + public const string MiscellaneousServices = Material.Filled.MiscellaneousServices; + public const string MissedVideoCall = Material.Filled.MissedVideoCall; + public const string Mms = Material.Filled.Mms; + public const string MobileFriendly = Material.Filled.MobileFriendly; + public const string MobileOff = Material.Filled.MobileOff; + public const string MobileScreenShare = Material.Filled.MobileScreenShare; + public const string MobiledataOff = Material.Filled.MobiledataOff; + public const string Mode = Material.Filled.Mode; + public const string ModeComment = Material.Filled.ModeComment; + public const string ModeEdit = Material.Filled.ModeEdit; + public const string ModeEditOutline = Material.Filled.ModeEditOutline; + public const string ModeNight = Material.Filled.ModeNight; + public const string ModeOfTravel = Material.Filled.ModeOfTravel; + public const string ModeStandby = Material.Filled.ModeStandby; + public const string ModelTraining = Material.Filled.ModelTraining; + public const string MonetizationOn = Material.Filled.MonetizationOn; + public const string Money = Material.Filled.Money; + public const string MoneyOff = Material.Filled.MoneyOff; + public const string MoneyOffCsred = Material.Filled.MoneyOffCsred; + public const string Monitor = Material.Filled.Monitor; + public const string MonitorHeart = Material.Filled.MonitorHeart; + public const string MonitorWeight = Material.Filled.MonitorWeight; + public const string MonochromePhotos = Material.Filled.MonochromePhotos; + public const string Mood = Material.Filled.Mood; + public const string MoodBad = Material.Filled.MoodBad; + public const string Moped = Material.Filled.Moped; + public const string More = Material.Filled.More; + public const string MoreHoriz = Material.Filled.MoreHoriz; + public const string MoreTime = Material.Filled.MoreTime; + public const string MoreVert = Material.Filled.MoreVert; + public const string Mosque = Material.Filled.Mosque; + public const string MotionPhotosAuto = Material.Filled.MotionPhotosAuto; + public const string MotionPhotosOff = Material.Filled.MotionPhotosOff; + public const string MotionPhotosOn = Material.Filled.MotionPhotosOn; + public const string MotionPhotosPause = Material.Filled.MotionPhotosPause; + public const string MotionPhotosPaused = Material.Filled.MotionPhotosPaused; + public const string Mouse = Material.Filled.Mouse; + public const string MoveDown = Material.Filled.MoveDown; + public const string MoveToInbox = Material.Filled.MoveToInbox; + public const string MoveUp = Material.Filled.MoveUp; + public const string Movie = Material.Filled.Movie; + public const string MovieCreation = Material.Filled.MovieCreation; + public const string MovieFilter = Material.Filled.MovieFilter; + public const string Moving = Material.Filled.Moving; + public const string Mp = Material.Filled.Mp; + public const string MultilineChart = Material.Filled.MultilineChart; + public const string MultipleStop = Material.Filled.MultipleStop; + public const string Museum = Material.Filled.Museum; + public const string MusicNote = Material.Filled.MusicNote; + public const string MusicOff = Material.Filled.MusicOff; + public const string MusicVideo = Material.Filled.MusicVideo; + public const string MyLocation = Material.Filled.MyLocation; + public const string Nat = Material.Filled.Nat; + public const string Nature = Material.Filled.Nature; + public const string NaturePeople = Material.Filled.NaturePeople; + public const string NavigateBefore = Material.Filled.NavigateBefore; + public const string NavigateNext = Material.Filled.NavigateNext; + public const string Navigation = Material.Filled.Navigation; + public const string NearMe = Material.Filled.NearMe; + public const string NearMeDisabled = Material.Filled.NearMeDisabled; + public const string NearbyError = Material.Filled.NearbyError; + public const string NearbyOff = Material.Filled.NearbyOff; + public const string NetworkCell = Material.Filled.NetworkCell; + public const string NetworkCheck = Material.Filled.NetworkCheck; + public const string NetworkLocked = Material.Filled.NetworkLocked; + public const string NetworkPing = Material.Filled.NetworkPing; + public const string NetworkWifi = Material.Filled.NetworkWifi; + public const string NetworkWifi1Bar = Material.Filled.NetworkWifi1Bar; + public const string NetworkWifi2Bar = Material.Filled.NetworkWifi2Bar; + public const string NetworkWifi3Bar = Material.Filled.NetworkWifi3Bar; + public const string NewLabel = Material.Filled.NewLabel; + public const string NewReleases = Material.Filled.NewReleases; + public const string Newspaper = Material.Filled.Newspaper; + public const string NextPlan = Material.Filled.NextPlan; + public const string NextWeek = Material.Filled.NextWeek; + public const string Nfc = Material.Filled.Nfc; + public const string NightShelter = Material.Filled.NightShelter; + public const string Nightlife = Material.Filled.Nightlife; + public const string Nightlight = Material.Filled.Nightlight; + public const string NightlightRound = Material.Filled.NightlightRound; + public const string NightsStay = Material.Filled.NightsStay; + public const string NoAccounts = Material.Filled.NoAccounts; + public const string NoBackpack = Material.Filled.NoBackpack; + public const string NoCell = Material.Filled.NoCell; + public const string NoCrash = Material.Filled.NoCrash; + public const string NoDrinks = Material.Filled.NoDrinks; + public const string NoEncryption = Material.Filled.NoEncryption; + public const string NoEncryptionGmailerrorred = Material.Filled.NoEncryptionGmailerrorred; + public const string NoFlash = Material.Filled.NoFlash; + public const string NoFood = Material.Filled.NoFood; + public const string NoLuggage = Material.Filled.NoLuggage; + public const string NoMeals = Material.Filled.NoMeals; + public const string NoMeetingRoom = Material.Filled.NoMeetingRoom; + public const string NoPhotography = Material.Filled.NoPhotography; + public const string NoSim = Material.Filled.NoSim; + public const string NoStroller = Material.Filled.NoStroller; + public const string NoTransfer = Material.Filled.NoTransfer; + public const string NoiseAware = Material.Filled.NoiseAware; + public const string NoiseControlOff = Material.Filled.NoiseControlOff; + public const string NordicWalking = Material.Filled.NordicWalking; + public const string North = Material.Filled.North; + public const string NorthEast = Material.Filled.NorthEast; + public const string NorthWest = Material.Filled.NorthWest; + public const string NotAccessible = Material.Filled.NotAccessible; + public const string NotInterested = Material.Filled.NotInterested; + public const string NotListedLocation = Material.Filled.NotListedLocation; + public const string NotStarted = Material.Filled.NotStarted; + public const string Note = Material.Filled.Note; + public const string NoteAdd = Material.Filled.NoteAdd; + public const string NoteAlt = Material.Filled.NoteAlt; + public const string Notes = Material.Filled.Notes; + public const string NotificationAdd = Material.Filled.NotificationAdd; + public const string NotificationImportant = Material.Filled.NotificationImportant; + public const string Notifications = Material.Filled.Notifications; + public const string NotificationsActive = Material.Filled.NotificationsActive; + public const string NotificationsNone = Material.Filled.NotificationsNone; + public const string NotificationsOff = Material.Filled.NotificationsOff; + public const string NotificationsPaused = Material.Filled.NotificationsPaused; + public const string Numbers = Material.Filled.Numbers; + public const string OfflineBolt = Material.Filled.OfflineBolt; + public const string OfflinePin = Material.Filled.OfflinePin; + public const string OfflineShare = Material.Filled.OfflineShare; + public const string OnDeviceTraining = Material.Filled.OnDeviceTraining; + public const string OndemandVideo = Material.Filled.OndemandVideo; + public const string OnlinePrediction = Material.Filled.OnlinePrediction; + public const string Opacity = Material.Filled.Opacity; + public const string OpenInBrowser = Material.Filled.OpenInBrowser; + public const string OpenInFull = Material.Filled.OpenInFull; + public const string OpenInNew = Material.Filled.OpenInNew; + public const string OpenInNewOff = Material.Filled.OpenInNewOff; + public const string OpenWith = Material.Filled.OpenWith; + public const string OtherHouses = Material.Filled.OtherHouses; + public const string Outbound = Material.Filled.Outbound; + public const string Outbox = Material.Filled.Outbox; + public const string OutdoorGrill = Material.Filled.OutdoorGrill; + public const string Outlet = Material.Filled.Outlet; + public const string OutlinedFlag = Material.Filled.OutlinedFlag; + public const string Output = Material.Filled.Output; + public const string Padding = Material.Filled.Padding; + public const string Pages = Material.Filled.Pages; + public const string Pageview = Material.Filled.Pageview; + public const string Paid = Material.Filled.Paid; + public const string Palette = Material.Filled.Palette; + public const string PanTool = Material.Filled.PanTool; + public const string PanToolAlt = Material.Filled.PanToolAlt; + public const string Panorama = Material.Filled.Panorama; + public const string PanoramaFishEye = Material.Filled.PanoramaFishEye; + public const string PanoramaHorizontal = Material.Filled.PanoramaHorizontal; + public const string PanoramaHorizontalSelect = Material.Filled.PanoramaHorizontalSelect; + public const string PanoramaPhotosphere = Material.Filled.PanoramaPhotosphere; + public const string PanoramaPhotosphereSelect = Material.Filled.PanoramaPhotosphereSelect; + public const string PanoramaVertical = Material.Filled.PanoramaVertical; + public const string PanoramaVerticalSelect = Material.Filled.PanoramaVerticalSelect; + public const string PanoramaWideAngle = Material.Filled.PanoramaWideAngle; + public const string PanoramaWideAngleSelect = Material.Filled.PanoramaWideAngleSelect; + public const string Paragliding = Material.Filled.Paragliding; + public const string Park = Material.Filled.Park; + public const string PartyMode = Material.Filled.PartyMode; + public const string Password = Material.Filled.Password; + public const string Pattern = Material.Filled.Pattern; + public const string Pause = Material.Filled.Pause; + public const string PauseCircle = Material.Filled.PauseCircle; + public const string PauseCircleFilled = Material.Filled.PauseCircleFilled; + public const string PauseCircleOutline = Material.Filled.PauseCircleOutline; + public const string PausePresentation = Material.Filled.PausePresentation; + public const string Payment = Material.Filled.Payment; + public const string Payments = Material.Filled.Payments; + public const string PedalBike = Material.Filled.PedalBike; + public const string Pending = Material.Filled.Pending; + public const string PendingActions = Material.Filled.PendingActions; + public const string Pentagon = Material.Filled.Pentagon; + public const string People = Material.Filled.People; + public const string PeopleAlt = Material.Filled.PeopleAlt; + public const string PeopleOutline = Material.Filled.PeopleOutline; + public const string Percent = Material.Filled.Percent; + public const string PermCameraMic = Material.Filled.PermCameraMic; + public const string PermContactCalendar = Material.Filled.PermContactCalendar; + public const string PermDataSetting = Material.Filled.PermDataSetting; + public const string PermDeviceInformation = Material.Filled.PermDeviceInformation; + public const string PermIdentity = Material.Filled.PermIdentity; + public const string PermMedia = Material.Filled.PermMedia; + public const string PermPhoneMsg = Material.Filled.PermPhoneMsg; + public const string PermScanWifi = Material.Filled.PermScanWifi; + public const string Person = Material.Filled.Person; + public const string PersonAdd = Material.Filled.PersonAdd; + public const string PersonAddAlt = Material.Filled.PersonAddAlt; + public const string PersonAddAlt1 = Material.Filled.PersonAddAlt1; + public const string PersonAddDisabled = Material.Filled.PersonAddDisabled; + public const string PersonOff = Material.Filled.PersonOff; + public const string PersonOutline = Material.Filled.PersonOutline; + public const string PersonPin = Material.Filled.PersonPin; + public const string PersonPinCircle = Material.Filled.PersonPinCircle; + public const string PersonRemove = Material.Filled.PersonRemove; + public const string PersonRemoveAlt1 = Material.Filled.PersonRemoveAlt1; + public const string PersonSearch = Material.Filled.PersonSearch; + public const string PersonalInjury = Material.Filled.PersonalInjury; + public const string PersonalVideo = Material.Filled.PersonalVideo; + public const string PestControl = Material.Filled.PestControl; + public const string PestControlRodent = Material.Filled.PestControlRodent; + public const string Pets = Material.Filled.Pets; + public const string Phishing = Material.Filled.Phishing; + public const string Phone = Material.Filled.Phone; + public const string PhoneAndroid = Material.Filled.PhoneAndroid; + public const string PhoneBluetoothSpeaker = Material.Filled.PhoneBluetoothSpeaker; + public const string PhoneCallback = Material.Filled.PhoneCallback; + public const string PhoneDisabled = Material.Filled.PhoneDisabled; + public const string PhoneEnabled = Material.Filled.PhoneEnabled; + public const string PhoneForwarded = Material.Filled.PhoneForwarded; + public const string PhoneInTalk = Material.Filled.PhoneInTalk; + public const string PhoneIphone = Material.Filled.PhoneIphone; + public const string PhoneLocked = Material.Filled.PhoneLocked; + public const string PhoneMissed = Material.Filled.PhoneMissed; + public const string PhonePaused = Material.Filled.PhonePaused; + public const string Phonelink = Material.Filled.Phonelink; + public const string PhonelinkErase = Material.Filled.PhonelinkErase; + public const string PhonelinkLock = Material.Filled.PhonelinkLock; + public const string PhonelinkOff = Material.Filled.PhonelinkOff; + public const string PhonelinkRing = Material.Filled.PhonelinkRing; + public const string PhonelinkSetup = Material.Filled.PhonelinkSetup; + public const string Photo = Material.Filled.Photo; + public const string PhotoAlbum = Material.Filled.PhotoAlbum; + public const string PhotoCamera = Material.Filled.PhotoCamera; + public const string PhotoCameraBack = Material.Filled.PhotoCameraBack; + public const string PhotoCameraFront = Material.Filled.PhotoCameraFront; + public const string PhotoFilter = Material.Filled.PhotoFilter; + public const string PhotoLibrary = Material.Filled.PhotoLibrary; + public const string PhotoSizeSelectActual = Material.Filled.PhotoSizeSelectActual; + public const string PhotoSizeSelectLarge = Material.Filled.PhotoSizeSelectLarge; + public const string PhotoSizeSelectSmall = Material.Filled.PhotoSizeSelectSmall; + public const string Php = Material.Filled.Php; + public const string Piano = Material.Filled.Piano; + public const string PianoOff = Material.Filled.PianoOff; + public const string PictureAsPdf = Material.Filled.PictureAsPdf; + public const string PictureInPicture = Material.Filled.PictureInPicture; + public const string PictureInPictureAlt = Material.Filled.PictureInPictureAlt; + public const string PieChart = Material.Filled.PieChart; + public const string PieChartOutline = Material.Filled.PieChartOutline; + public const string Pin = Material.Filled.Pin; + public const string PinDrop = Material.Filled.PinDrop; + public const string PinEnd = Material.Filled.PinEnd; + public const string PinInvoke = Material.Filled.PinInvoke; + public const string Pinch = Material.Filled.Pinch; + public const string PivotTableChart = Material.Filled.PivotTableChart; + public const string Pix = Material.Filled.Pix; + public const string Place = Material.Filled.Place; + public const string Plagiarism = Material.Filled.Plagiarism; + public const string PlayArrow = Material.Filled.PlayArrow; + public const string PlayCircle = Material.Filled.PlayCircle; + public const string PlayCircleFilled = Material.Filled.PlayCircleFilled; + public const string PlayCircleOutline = Material.Filled.PlayCircleOutline; + public const string PlayDisabled = Material.Filled.PlayDisabled; + public const string PlayForWork = Material.Filled.PlayForWork; + public const string PlayLesson = Material.Filled.PlayLesson; + public const string PlaylistAdd = Material.Filled.PlaylistAdd; + public const string PlaylistAddCheck = Material.Filled.PlaylistAddCheck; + public const string PlaylistAddCheckCircle = Material.Filled.PlaylistAddCheckCircle; + public const string PlaylistAddCircle = Material.Filled.PlaylistAddCircle; + public const string PlaylistPlay = Material.Filled.PlaylistPlay; + public const string PlaylistRemove = Material.Filled.PlaylistRemove; + public const string Plumbing = Material.Filled.Plumbing; + public const string PlusOne = Material.Filled.PlusOne; + public const string Podcasts = Material.Filled.Podcasts; + public const string PointOfSale = Material.Filled.PointOfSale; + public const string Policy = Material.Filled.Policy; + public const string Poll = Material.Filled.Poll; + public const string Polyline = Material.Filled.Polyline; + public const string Polymer = Material.Filled.Polymer; + public const string Pool = Material.Filled.Pool; + public const string PortableWifiOff = Material.Filled.PortableWifiOff; + public const string Portrait = Material.Filled.Portrait; + public const string PostAdd = Material.Filled.PostAdd; + public const string Power = Material.Filled.Power; + public const string PowerInput = Material.Filled.PowerInput; + public const string PowerOff = Material.Filled.PowerOff; + public const string PowerSettingsNew = Material.Filled.PowerSettingsNew; + public const string PrecisionManufacturing = Material.Filled.PrecisionManufacturing; + public const string PregnantWoman = Material.Filled.PregnantWoman; + public const string PresentToAll = Material.Filled.PresentToAll; + public const string Preview = Material.Filled.Preview; + public const string PriceChange = Material.Filled.PriceChange; + public const string PriceCheck = Material.Filled.PriceCheck; + public const string Print = Material.Filled.Print; + public const string PrintDisabled = Material.Filled.PrintDisabled; + public const string PriorityHigh = Material.Filled.PriorityHigh; + public const string PrivacyTip = Material.Filled.PrivacyTip; + public const string PrivateConnectivity = Material.Filled.PrivateConnectivity; + public const string ProductionQuantityLimits = Material.Filled.ProductionQuantityLimits; + public const string Psychology = Material.Filled.Psychology; + public const string Public = Material.Filled.Public; + public const string PublicOff = Material.Filled.PublicOff; + public const string Publish = Material.Filled.Publish; + public const string PublishedWithChanges = Material.Filled.PublishedWithChanges; + public const string PunchClock = Material.Filled.PunchClock; + public const string PushPin = Material.Filled.PushPin; + public const string QrCode = Material.Filled.QrCode; + public const string QrCode2 = Material.Filled.QrCode2; + public const string QrCodeScanner = Material.Filled.QrCodeScanner; + public const string QueryBuilder = Material.Filled.QueryBuilder; + public const string QueryStats = Material.Filled.QueryStats; + public const string QuestionAnswer = Material.Filled.QuestionAnswer; + public const string QuestionMark = Material.Filled.QuestionMark; + public const string Queue = Material.Filled.Queue; + public const string QueueMusic = Material.Filled.QueueMusic; + public const string QueuePlayNext = Material.Filled.QueuePlayNext; + public const string Quickreply = Material.Filled.Quickreply; + public const string Quiz = Material.Filled.Quiz; + public const string RMobiledata = Material.Filled.RMobiledata; + public const string Radar = Material.Filled.Radar; + public const string Radio = Material.Filled.Radio; + public const string RadioButtonChecked = Material.Filled.RadioButtonChecked; + public const string RadioButtonUnchecked = Material.Filled.RadioButtonUnchecked; + public const string RailwayAlert = Material.Filled.RailwayAlert; + public const string RamenDining = Material.Filled.RamenDining; + public const string RampLeft = Material.Filled.RampLeft; + public const string RampRight = Material.Filled.RampRight; + public const string RateReview = Material.Filled.RateReview; + public const string RawOff = Material.Filled.RawOff; + public const string RawOn = Material.Filled.RawOn; + public const string ReadMore = Material.Filled.ReadMore; + public const string RealEstateAgent = Material.Filled.RealEstateAgent; + public const string Receipt = Material.Filled.Receipt; + public const string ReceiptLong = Material.Filled.ReceiptLong; + public const string RecentActors = Material.Filled.RecentActors; + public const string Recommend = Material.Filled.Recommend; + public const string RecordVoiceOver = Material.Filled.RecordVoiceOver; + public const string Rectangle = Material.Filled.Rectangle; + public const string Recycling = Material.Filled.Recycling; + public const string Redeem = Material.Filled.Redeem; + public const string Redo = Material.Filled.Redo; + public const string ReduceCapacity = Material.Filled.ReduceCapacity; + public const string Refresh = Material.Filled.Refresh; + public const string RememberMe = Material.Filled.RememberMe; + public const string Remove = Material.Filled.Remove; + public const string RemoveCircle = Material.Filled.RemoveCircle; + public const string RemoveCircleOutline = Material.Filled.RemoveCircleOutline; + public const string RemoveDone = Material.Filled.RemoveDone; + public const string RemoveFromQueue = Material.Filled.RemoveFromQueue; + public const string RemoveModerator = Material.Filled.RemoveModerator; + public const string RemoveRedEye = Material.Filled.RemoveRedEye; + public const string RemoveRoad = Material.Filled.RemoveRoad; + public const string RemoveShoppingCart = Material.Filled.RemoveShoppingCart; + public const string Reorder = Material.Filled.Reorder; + public const string Repeat = Material.Filled.Repeat; + public const string RepeatOn = Material.Filled.RepeatOn; + public const string RepeatOne = Material.Filled.RepeatOne; + public const string RepeatOneOn = Material.Filled.RepeatOneOn; + public const string Replay = Material.Filled.Replay; + public const string Replay10 = Material.Filled.Replay10; + public const string Replay30 = Material.Filled.Replay30; + public const string Replay5 = Material.Filled.Replay5; + public const string ReplayCircleFilled = Material.Filled.ReplayCircleFilled; + public const string Reply = Material.Filled.Reply; + public const string ReplyAll = Material.Filled.ReplyAll; + public const string Report = Material.Filled.Report; + public const string ReportGmailerrorred = Material.Filled.ReportGmailerrorred; + public const string ReportOff = Material.Filled.ReportOff; + public const string ReportProblem = Material.Filled.ReportProblem; + public const string RequestPage = Material.Filled.RequestPage; + public const string RequestQuote = Material.Filled.RequestQuote; + public const string ResetTv = Material.Filled.ResetTv; + public const string RestartAlt = Material.Filled.RestartAlt; + public const string Restaurant = Material.Filled.Restaurant; + public const string RestaurantMenu = Material.Filled.RestaurantMenu; + public const string Restore = Material.Filled.Restore; + public const string RestoreFromTrash = Material.Filled.RestoreFromTrash; + public const string RestorePage = Material.Filled.RestorePage; + public const string Reviews = Material.Filled.Reviews; + public const string RiceBowl = Material.Filled.RiceBowl; + public const string RingVolume = Material.Filled.RingVolume; + public const string Rocket = Material.Filled.Rocket; + public const string RocketLaunch = Material.Filled.RocketLaunch; + public const string RollerSkating = Material.Filled.RollerSkating; + public const string Roofing = Material.Filled.Roofing; + public const string Room = Material.Filled.Room; + public const string RoomPreferences = Material.Filled.RoomPreferences; + public const string RoomService = Material.Filled.RoomService; + public const string Rotate90DegreesCcw = Material.Filled.Rotate90DegreesCcw; + public const string Rotate90DegreesCw = Material.Filled.Rotate90DegreesCw; + public const string RotateLeft = Material.Filled.RotateLeft; + public const string RotateRight = Material.Filled.RotateRight; + public const string RoundaboutLeft = Material.Filled.RoundaboutLeft; + public const string RoundaboutRight = Material.Filled.RoundaboutRight; + public const string RoundedCorner = Material.Filled.RoundedCorner; + public const string Route = Material.Filled.Route; + public const string Router = Material.Filled.Router; + public const string Rowing = Material.Filled.Rowing; + public const string RssFeed = Material.Filled.RssFeed; + public const string Rsvp = Material.Filled.Rsvp; + public const string Rtt = Material.Filled.Rtt; + public const string Rule = Material.Filled.Rule; + public const string RuleFolder = Material.Filled.RuleFolder; + public const string RunCircle = Material.Filled.RunCircle; + public const string RunningWithErrors = Material.Filled.RunningWithErrors; + public const string RvHookup = Material.Filled.RvHookup; + public const string SafetyCheck = Material.Filled.SafetyCheck; + public const string SafetyDivider = Material.Filled.SafetyDivider; + public const string Sailing = Material.Filled.Sailing; + public const string Sanitizer = Material.Filled.Sanitizer; + public const string Satellite = Material.Filled.Satellite; + public const string SatelliteAlt = Material.Filled.SatelliteAlt; + public const string Save = Material.Filled.Save; + public const string SaveAlt = Material.Filled.SaveAlt; + public const string SaveAs = Material.Filled.SaveAs; + public const string SavedSearch = Material.Filled.SavedSearch; + public const string Savings = Material.Filled.Savings; + public const string Scale = Material.Filled.Scale; + public const string Scanner = Material.Filled.Scanner; + public const string ScatterPlot = Material.Filled.ScatterPlot; + public const string Schedule = Material.Filled.Schedule; + public const string ScheduleSend = Material.Filled.ScheduleSend; + public const string Schema = Material.Filled.Schema; + public const string School = Material.Filled.School; + public const string Science = Material.Filled.Science; + public const string Score = Material.Filled.Score; + public const string Scoreboard = Material.Filled.Scoreboard; + public const string ScreenLockLandscape = Material.Filled.ScreenLockLandscape; + public const string ScreenLockPortrait = Material.Filled.ScreenLockPortrait; + public const string ScreenLockRotation = Material.Filled.ScreenLockRotation; + public const string ScreenRotation = Material.Filled.ScreenRotation; + public const string ScreenRotationAlt = Material.Filled.ScreenRotationAlt; + public const string ScreenSearchDesktop = Material.Filled.ScreenSearchDesktop; + public const string ScreenShare = Material.Filled.ScreenShare; + public const string Screenshot = Material.Filled.Screenshot; + public const string ScubaDiving = Material.Filled.ScubaDiving; + public const string Sd = Material.Filled.Sd; + public const string SdCard = Material.Filled.SdCard; + public const string SdCardAlert = Material.Filled.SdCardAlert; + public const string SdStorage = Material.Filled.SdStorage; + public const string Search = Material.Filled.Search; + public const string SearchOff = Material.Filled.SearchOff; + public const string Security = Material.Filled.Security; + public const string SecurityUpdate = Material.Filled.SecurityUpdate; + public const string SecurityUpdateGood = Material.Filled.SecurityUpdateGood; + public const string SecurityUpdateWarning = Material.Filled.SecurityUpdateWarning; + public const string Segment = Material.Filled.Segment; + public const string SelectAll = Material.Filled.SelectAll; + public const string SelfImprovement = Material.Filled.SelfImprovement; + public const string Sell = Material.Filled.Sell; + public const string Send = Material.Filled.Send; + public const string SendAndArchive = Material.Filled.SendAndArchive; + public const string SendTimeExtension = Material.Filled.SendTimeExtension; + public const string SendToMobile = Material.Filled.SendToMobile; + public const string SensorDoor = Material.Filled.SensorDoor; + public const string SensorWindow = Material.Filled.SensorWindow; + public const string Sensors = Material.Filled.Sensors; + public const string SensorsOff = Material.Filled.SensorsOff; + public const string SentimentDissatisfied = Material.Filled.SentimentDissatisfied; + public const string SentimentNeutral = Material.Filled.SentimentNeutral; + public const string SentimentSatisfied = Material.Filled.SentimentSatisfied; + public const string SentimentSatisfiedAlt = Material.Filled.SentimentSatisfiedAlt; + public const string SentimentVeryDissatisfied = Material.Filled.SentimentVeryDissatisfied; + public const string SentimentVerySatisfied = Material.Filled.SentimentVerySatisfied; + public const string SetMeal = Material.Filled.SetMeal; + public const string Settings = Material.Filled.Settings; + public const string SettingsAccessibility = Material.Filled.SettingsAccessibility; + public const string SettingsApplications = Material.Filled.SettingsApplications; + public const string SettingsBackupRestore = Material.Filled.SettingsBackupRestore; + public const string SettingsBluetooth = Material.Filled.SettingsBluetooth; + public const string SettingsBrightness = Material.Filled.SettingsBrightness; + public const string SettingsCell = Material.Filled.SettingsCell; + public const string SettingsEthernet = Material.Filled.SettingsEthernet; + public const string SettingsInputAntenna = Material.Filled.SettingsInputAntenna; + public const string SettingsInputComponent = Material.Filled.SettingsInputComponent; + public const string SettingsInputComposite = Material.Filled.SettingsInputComposite; + public const string SettingsInputHdmi = Material.Filled.SettingsInputHdmi; + public const string SettingsInputSvideo = Material.Filled.SettingsInputSvideo; + public const string SettingsOverscan = Material.Filled.SettingsOverscan; + public const string SettingsPhone = Material.Filled.SettingsPhone; + public const string SettingsPower = Material.Filled.SettingsPower; + public const string SettingsRemote = Material.Filled.SettingsRemote; + public const string SettingsSuggest = Material.Filled.SettingsSuggest; + public const string SettingsSystemDaydream = Material.Filled.SettingsSystemDaydream; + public const string SettingsVoice = Material.Filled.SettingsVoice; + public const string SevereCold = Material.Filled.SevereCold; + public const string Share = Material.Filled.Share; + public const string ShareLocation = Material.Filled.ShareLocation; + public const string Shield = Material.Filled.Shield; + public const string ShieldMoon = Material.Filled.ShieldMoon; + public const string Shop = Material.Filled.Shop; + public const string Shop2 = Material.Filled.Shop2; + public const string ShopTwo = Material.Filled.ShopTwo; + public const string ShoppingBag = Material.Filled.ShoppingBag; + public const string ShoppingBasket = Material.Filled.ShoppingBasket; + public const string ShoppingCart = Material.Filled.ShoppingCart; + public const string ShoppingCartCheckout = Material.Filled.ShoppingCartCheckout; + public const string ShortText = Material.Filled.ShortText; + public const string Shortcut = Material.Filled.Shortcut; + public const string ShowChart = Material.Filled.ShowChart; + public const string Shower = Material.Filled.Shower; + public const string Shuffle = Material.Filled.Shuffle; + public const string ShuffleOn = Material.Filled.ShuffleOn; + public const string ShutterSpeed = Material.Filled.ShutterSpeed; + public const string Sick = Material.Filled.Sick; + public const string SignLanguage = Material.Filled.SignLanguage; + public const string SignalCellular0Bar = Material.Filled.SignalCellular0Bar; + public const string SignalCellular4Bar = Material.Filled.SignalCellular4Bar; + public const string SignalCellularAlt = Material.Filled.SignalCellularAlt; + public const string SignalCellularAlt1Bar = Material.Filled.SignalCellularAlt1Bar; + public const string SignalCellularAlt2Bar = Material.Filled.SignalCellularAlt2Bar; + public const string SignalCellularConnectedNoInternet0Bar = Material.Filled.SignalCellularConnectedNoInternet0Bar; + public const string SignalCellularConnectedNoInternet4Bar = Material.Filled.SignalCellularConnectedNoInternet4Bar; + public const string SignalCellularNoSim = Material.Filled.SignalCellularNoSim; + public const string SignalCellularNodata = Material.Filled.SignalCellularNodata; + public const string SignalCellularNull = Material.Filled.SignalCellularNull; + public const string SignalCellularOff = Material.Filled.SignalCellularOff; + public const string SignalWifi0Bar = Material.Filled.SignalWifi0Bar; + public const string SignalWifi4Bar = Material.Filled.SignalWifi4Bar; + public const string SignalWifi4BarLock = Material.Filled.SignalWifi4BarLock; + public const string SignalWifiBad = Material.Filled.SignalWifiBad; + public const string SignalWifiConnectedNoInternet4 = Material.Filled.SignalWifiConnectedNoInternet4; + public const string SignalWifiOff = Material.Filled.SignalWifiOff; + public const string SignalWifiStatusbar4Bar = Material.Filled.SignalWifiStatusbar4Bar; + public const string SignalWifiStatusbarConnectedNoInternet4 = Material.Filled.SignalWifiStatusbarConnectedNoInternet4; + public const string SignalWifiStatusbarNull = Material.Filled.SignalWifiStatusbarNull; + public const string Signpost = Material.Filled.Signpost; + public const string SimCard = Material.Filled.SimCard; + public const string SimCardAlert = Material.Filled.SimCardAlert; + public const string SimCardDownload = Material.Filled.SimCardDownload; + public const string SingleBed = Material.Filled.SingleBed; + public const string Sip = Material.Filled.Sip; + public const string Skateboarding = Material.Filled.Skateboarding; + public const string SkipNext = Material.Filled.SkipNext; + public const string SkipPrevious = Material.Filled.SkipPrevious; + public const string Sledding = Material.Filled.Sledding; + public const string Slideshow = Material.Filled.Slideshow; + public const string SlowMotionVideo = Material.Filled.SlowMotionVideo; + public const string SmartButton = Material.Filled.SmartButton; + public const string SmartDisplay = Material.Filled.SmartDisplay; + public const string SmartScreen = Material.Filled.SmartScreen; + public const string SmartToy = Material.Filled.SmartToy; + public const string Smartphone = Material.Filled.Smartphone; + public const string SmokeFree = Material.Filled.SmokeFree; + public const string SmokingRooms = Material.Filled.SmokingRooms; + public const string Sms = Material.Filled.Sms; + public const string SmsFailed = Material.Filled.SmsFailed; + public const string SnippetFolder = Material.Filled.SnippetFolder; + public const string Snooze = Material.Filled.Snooze; + public const string Snowboarding = Material.Filled.Snowboarding; + public const string Snowmobile = Material.Filled.Snowmobile; + public const string Snowshoeing = Material.Filled.Snowshoeing; + public const string Soap = Material.Filled.Soap; + public const string SocialDistance = Material.Filled.SocialDistance; + public const string Sort = Material.Filled.Sort; + public const string SortByAlpha = Material.Filled.SortByAlpha; + public const string Sos = Material.Filled.Sos; + public const string SoupKitchen = Material.Filled.SoupKitchen; + public const string Source = Material.Filled.Source; + public const string South = Material.Filled.South; + public const string SouthAmerica = Material.Filled.SouthAmerica; + public const string SouthEast = Material.Filled.SouthEast; + public const string SouthWest = Material.Filled.SouthWest; + public const string Spa = Material.Filled.Spa; + public const string SpaceBar = Material.Filled.SpaceBar; + public const string SpaceDashboard = Material.Filled.SpaceDashboard; + public const string SpatialAudio = Material.Filled.SpatialAudio; + public const string SpatialAudioOff = Material.Filled.SpatialAudioOff; + public const string SpatialTracking = Material.Filled.SpatialTracking; + public const string Speaker = Material.Filled.Speaker; + public const string SpeakerGroup = Material.Filled.SpeakerGroup; + public const string SpeakerNotes = Material.Filled.SpeakerNotes; + public const string SpeakerNotesOff = Material.Filled.SpeakerNotesOff; + public const string SpeakerPhone = Material.Filled.SpeakerPhone; + public const string Speed = Material.Filled.Speed; + public const string Spellcheck = Material.Filled.Spellcheck; + public const string Splitscreen = Material.Filled.Splitscreen; + public const string Spoke = Material.Filled.Spoke; + public const string Sports = Material.Filled.Sports; + public const string SportsBar = Material.Filled.SportsBar; + public const string SportsBaseball = Material.Filled.SportsBaseball; + public const string SportsBasketball = Material.Filled.SportsBasketball; + public const string SportsCricket = Material.Filled.SportsCricket; + public const string SportsEsports = Material.Filled.SportsEsports; + public const string SportsFootball = Material.Filled.SportsFootball; + public const string SportsGolf = Material.Filled.SportsGolf; + public const string SportsGymnastics = Material.Filled.SportsGymnastics; + public const string SportsHandball = Material.Filled.SportsHandball; + public const string SportsHockey = Material.Filled.SportsHockey; + public const string SportsKabaddi = Material.Filled.SportsKabaddi; + public const string SportsMartialArts = Material.Filled.SportsMartialArts; + public const string SportsMma = Material.Filled.SportsMma; + public const string SportsMotorsports = Material.Filled.SportsMotorsports; + public const string SportsRugby = Material.Filled.SportsRugby; + public const string SportsScore = Material.Filled.SportsScore; + public const string SportsSoccer = Material.Filled.SportsSoccer; + public const string SportsTennis = Material.Filled.SportsTennis; + public const string SportsVolleyball = Material.Filled.SportsVolleyball; + public const string Square = Material.Filled.Square; + public const string SquareFoot = Material.Filled.SquareFoot; + public const string SsidChart = Material.Filled.SsidChart; + public const string StackedBarChart = Material.Filled.StackedBarChart; + public const string StackedLineChart = Material.Filled.StackedLineChart; + public const string Stadium = Material.Filled.Stadium; + public const string Stairs = Material.Filled.Stairs; + public const string Star = Material.Filled.Star; + public const string StarBorder = Material.Filled.StarBorder; + public const string StarBorderPurple500 = Material.Filled.StarBorderPurple500; + public const string StarHalf = Material.Filled.StarHalf; + public const string StarOutline = Material.Filled.StarOutline; + public const string StarPurple500 = Material.Filled.StarPurple500; + public const string StarRate = Material.Filled.StarRate; + public const string Stars = Material.Filled.Stars; + public const string Start = Material.Filled.Start; + public const string StayCurrentLandscape = Material.Filled.StayCurrentLandscape; + public const string StayCurrentPortrait = Material.Filled.StayCurrentPortrait; + public const string StayPrimaryLandscape = Material.Filled.StayPrimaryLandscape; + public const string StayPrimaryPortrait = Material.Filled.StayPrimaryPortrait; + public const string StickyNote2 = Material.Filled.StickyNote2; + public const string Stop = Material.Filled.Stop; + public const string StopCircle = Material.Filled.StopCircle; + public const string StopScreenShare = Material.Filled.StopScreenShare; + public const string Storage = Material.Filled.Storage; + public const string Store = Material.Filled.Store; + public const string StoreMallDirectory = Material.Filled.StoreMallDirectory; + public const string Storefront = Material.Filled.Storefront; + public const string Storm = Material.Filled.Storm; + public const string Straight = Material.Filled.Straight; + public const string Straighten = Material.Filled.Straighten; + public const string Stream = Material.Filled.Stream; + public const string Streetview = Material.Filled.Streetview; + public const string StrikethroughS = Material.Filled.StrikethroughS; + public const string Stroller = Material.Filled.Stroller; + public const string Style = Material.Filled.Style; + public const string SubdirectoryArrowLeft = Material.Filled.SubdirectoryArrowLeft; + public const string SubdirectoryArrowRight = Material.Filled.SubdirectoryArrowRight; + public const string Subject = Material.Filled.Subject; + public const string Subscript = Material.Filled.Subscript; + public const string Subscriptions = Material.Filled.Subscriptions; + public const string Subtitles = Material.Filled.Subtitles; + public const string SubtitlesOff = Material.Filled.SubtitlesOff; + public const string Subway = Material.Filled.Subway; + public const string Summarize = Material.Filled.Summarize; + public const string Superscript = Material.Filled.Superscript; + public const string SupervisedUserCircle = Material.Filled.SupervisedUserCircle; + public const string SupervisorAccount = Material.Filled.SupervisorAccount; + public const string Support = Material.Filled.Support; + public const string SupportAgent = Material.Filled.SupportAgent; + public const string Surfing = Material.Filled.Surfing; + public const string SurroundSound = Material.Filled.SurroundSound; + public const string SwapCalls = Material.Filled.SwapCalls; + public const string SwapHoriz = Material.Filled.SwapHoriz; + public const string SwapHorizontalCircle = Material.Filled.SwapHorizontalCircle; + public const string SwapVert = Material.Filled.SwapVert; + public const string SwapVerticalCircle = Material.Filled.SwapVerticalCircle; + public const string Swipe = Material.Filled.Swipe; + public const string SwipeDown = Material.Filled.SwipeDown; + public const string SwipeDownAlt = Material.Filled.SwipeDownAlt; + public const string SwipeLeft = Material.Filled.SwipeLeft; + public const string SwipeLeftAlt = Material.Filled.SwipeLeftAlt; + public const string SwipeRight = Material.Filled.SwipeRight; + public const string SwipeRightAlt = Material.Filled.SwipeRightAlt; + public const string SwipeUp = Material.Filled.SwipeUp; + public const string SwipeUpAlt = Material.Filled.SwipeUpAlt; + public const string SwipeVertical = Material.Filled.SwipeVertical; + public const string SwitchAccessShortcut = Material.Filled.SwitchAccessShortcut; + public const string SwitchAccessShortcutAdd = Material.Filled.SwitchAccessShortcutAdd; + public const string SwitchAccount = Material.Filled.SwitchAccount; + public const string SwitchCamera = Material.Filled.SwitchCamera; + public const string SwitchLeft = Material.Filled.SwitchLeft; + public const string SwitchRight = Material.Filled.SwitchRight; + public const string SwitchVideo = Material.Filled.SwitchVideo; + public const string Synagogue = Material.Filled.Synagogue; + public const string Sync = Material.Filled.Sync; + public const string SyncAlt = Material.Filled.SyncAlt; + public const string SyncDisabled = Material.Filled.SyncDisabled; + public const string SyncLock = Material.Filled.SyncLock; + public const string SyncProblem = Material.Filled.SyncProblem; + public const string SystemSecurityUpdate = Material.Filled.SystemSecurityUpdate; + public const string SystemSecurityUpdateGood = Material.Filled.SystemSecurityUpdateGood; + public const string SystemSecurityUpdateWarning = Material.Filled.SystemSecurityUpdateWarning; + public const string SystemUpdate = Material.Filled.SystemUpdate; + public const string SystemUpdateAlt = Material.Filled.SystemUpdateAlt; + public const string Tab = Material.Filled.Tab; + public const string TabUnselected = Material.Filled.TabUnselected; + public const string TableBar = Material.Filled.TableBar; + public const string TableChart = Material.Filled.TableChart; + public const string TableRestaurant = Material.Filled.TableRestaurant; + public const string TableRows = Material.Filled.TableRows; + public const string TableView = Material.Filled.TableView; + public const string Tablet = Material.Filled.Tablet; + public const string TabletAndroid = Material.Filled.TabletAndroid; + public const string TabletMac = Material.Filled.TabletMac; + public const string Tag = Material.Filled.Tag; + public const string TagFaces = Material.Filled.TagFaces; + public const string TakeoutDining = Material.Filled.TakeoutDining; + public const string TapAndPlay = Material.Filled.TapAndPlay; + public const string Tapas = Material.Filled.Tapas; + public const string Task = Material.Filled.Task; + public const string TaskAlt = Material.Filled.TaskAlt; + public const string TaxiAlert = Material.Filled.TaxiAlert; + public const string TempleBuddhist = Material.Filled.TempleBuddhist; + public const string TempleHindu = Material.Filled.TempleHindu; + public const string Terminal = Material.Filled.Terminal; + public const string Terrain = Material.Filled.Terrain; + public const string TextDecrease = Material.Filled.TextDecrease; + public const string TextFields = Material.Filled.TextFields; + public const string TextFormat = Material.Filled.TextFormat; + public const string TextIncrease = Material.Filled.TextIncrease; + public const string TextRotateUp = Material.Filled.TextRotateUp; + public const string TextRotateVertical = Material.Filled.TextRotateVertical; + public const string TextRotationAngledown = Material.Filled.TextRotationAngledown; + public const string TextRotationAngleup = Material.Filled.TextRotationAngleup; + public const string TextRotationDown = Material.Filled.TextRotationDown; + public const string TextRotationNone = Material.Filled.TextRotationNone; + public const string TextSnippet = Material.Filled.TextSnippet; + public const string Textsms = Material.Filled.Textsms; + public const string Texture = Material.Filled.Texture; + public const string TheaterComedy = Material.Filled.TheaterComedy; + public const string Theaters = Material.Filled.Theaters; + public const string Thermostat = Material.Filled.Thermostat; + public const string ThermostatAuto = Material.Filled.ThermostatAuto; + public const string ThumbDown = Material.Filled.ThumbDown; + public const string ThumbDownAlt = Material.Filled.ThumbDownAlt; + public const string ThumbDownOffAlt = Material.Filled.ThumbDownOffAlt; + public const string ThumbUp = Material.Filled.ThumbUp; + public const string ThumbUpAlt = Material.Filled.ThumbUpAlt; + public const string ThumbUpOffAlt = Material.Filled.ThumbUpOffAlt; + public const string ThumbsUpDown = Material.Filled.ThumbsUpDown; + public const string Thunderstorm = Material.Filled.Thunderstorm; + public const string TimeToLeave = Material.Filled.TimeToLeave; + public const string Timelapse = Material.Filled.Timelapse; + public const string Timeline = Material.Filled.Timeline; + public const string Timer = Material.Filled.Timer; + public const string Timer10 = Material.Filled.Timer10; + public const string Timer10Select = Material.Filled.Timer10Select; + public const string Timer3 = Material.Filled.Timer3; + public const string Timer3Select = Material.Filled.Timer3Select; + public const string TimerOff = Material.Filled.TimerOff; + public const string TipsAndUpdates = Material.Filled.TipsAndUpdates; + public const string TireRepair = Material.Filled.TireRepair; + public const string Title = Material.Filled.Title; + public const string Toc = Material.Filled.Toc; + public const string Today = Material.Filled.Today; + public const string ToggleOff = Material.Filled.ToggleOff; + public const string ToggleOn = Material.Filled.ToggleOn; + public const string Token = Material.Filled.Token; + public const string Toll = Material.Filled.Toll; + public const string Tonality = Material.Filled.Tonality; + public const string Topic = Material.Filled.Topic; + public const string TouchApp = Material.Filled.TouchApp; + public const string Tour = Material.Filled.Tour; + public const string Toys = Material.Filled.Toys; + public const string TrackChanges = Material.Filled.TrackChanges; + public const string Traffic = Material.Filled.Traffic; + public const string Train = Material.Filled.Train; + public const string Tram = Material.Filled.Tram; + public const string TransferWithinAStation = Material.Filled.TransferWithinAStation; + public const string Transform = Material.Filled.Transform; + public const string Transgender = Material.Filled.Transgender; + public const string TransitEnterexit = Material.Filled.TransitEnterexit; + public const string Translate = Material.Filled.Translate; + public const string TravelExplore = Material.Filled.TravelExplore; + public const string TrendingDown = Material.Filled.TrendingDown; + public const string TrendingFlat = Material.Filled.TrendingFlat; + public const string TrendingUp = Material.Filled.TrendingUp; + public const string TripOrigin = Material.Filled.TripOrigin; + public const string Try = Material.Filled.Try; + public const string Tsunami = Material.Filled.Tsunami; + public const string Tty = Material.Filled.Tty; + public const string Tune = Material.Filled.Tune; + public const string Tungsten = Material.Filled.Tungsten; + public const string TurnLeft = Material.Filled.TurnLeft; + public const string TurnRight = Material.Filled.TurnRight; + public const string TurnSharpLeft = Material.Filled.TurnSharpLeft; + public const string TurnSharpRight = Material.Filled.TurnSharpRight; + public const string TurnSlightLeft = Material.Filled.TurnSlightLeft; + public const string TurnSlightRight = Material.Filled.TurnSlightRight; + public const string TurnedIn = Material.Filled.TurnedIn; + public const string TurnedInNot = Material.Filled.TurnedInNot; + public const string Tv = Material.Filled.Tv; + public const string TvOff = Material.Filled.TvOff; + public const string TwoWheeler = Material.Filled.TwoWheeler; + public const string UTurnLeft = Material.Filled.UTurnLeft; + public const string UTurnRight = Material.Filled.UTurnRight; + public const string Umbrella = Material.Filled.Umbrella; + public const string Unarchive = Material.Filled.Unarchive; + public const string Undo = Material.Filled.Undo; + public const string UnfoldLess = Material.Filled.UnfoldLess; + public const string UnfoldMore = Material.Filled.UnfoldMore; + public const string Unpublished = Material.Filled.Unpublished; + public const string Unsubscribe = Material.Filled.Unsubscribe; + public const string Upcoming = Material.Filled.Upcoming; + public const string Update = Material.Filled.Update; + public const string UpdateDisabled = Material.Filled.UpdateDisabled; + public const string Upgrade = Material.Filled.Upgrade; + public const string Upload = Material.Filled.Upload; + public const string UploadFile = Material.Filled.UploadFile; + public const string Usb = Material.Filled.Usb; + public const string UsbOff = Material.Filled.UsbOff; + public const string Vaccines = Material.Filled.Vaccines; + public const string VapeFree = Material.Filled.VapeFree; + public const string VapingRooms = Material.Filled.VapingRooms; + public const string Verified = Material.Filled.Verified; + public const string VerifiedUser = Material.Filled.VerifiedUser; + public const string VerticalAlignBottom = Material.Filled.VerticalAlignBottom; + public const string VerticalAlignCenter = Material.Filled.VerticalAlignCenter; + public const string VerticalAlignTop = Material.Filled.VerticalAlignTop; + public const string VerticalDistribute = Material.Filled.VerticalDistribute; + public const string VerticalSplit = Material.Filled.VerticalSplit; + public const string Vibration = Material.Filled.Vibration; + public const string VideoCall = Material.Filled.VideoCall; + public const string VideoCameraBack = Material.Filled.VideoCameraBack; + public const string VideoCameraFront = Material.Filled.VideoCameraFront; + public const string VideoFile = Material.Filled.VideoFile; + public const string VideoLabel = Material.Filled.VideoLabel; + public const string VideoLibrary = Material.Filled.VideoLibrary; + public const string VideoSettings = Material.Filled.VideoSettings; + public const string VideoStable = Material.Filled.VideoStable; + public const string Videocam = Material.Filled.Videocam; + public const string VideocamOff = Material.Filled.VideocamOff; + public const string VideogameAsset = Material.Filled.VideogameAsset; + public const string VideogameAssetOff = Material.Filled.VideogameAssetOff; + public const string ViewAgenda = Material.Filled.ViewAgenda; + public const string ViewArray = Material.Filled.ViewArray; + public const string ViewCarousel = Material.Filled.ViewCarousel; + public const string ViewColumn = Material.Filled.ViewColumn; + public const string ViewComfy = Material.Filled.ViewComfy; + public const string ViewComfyAlt = Material.Filled.ViewComfyAlt; + public const string ViewCompact = Material.Filled.ViewCompact; + public const string ViewCompactAlt = Material.Filled.ViewCompactAlt; + public const string ViewCozy = Material.Filled.ViewCozy; + public const string ViewDay = Material.Filled.ViewDay; + public const string ViewHeadline = Material.Filled.ViewHeadline; + public const string ViewInAr = Material.Filled.ViewInAr; + public const string ViewKanban = Material.Filled.ViewKanban; + public const string ViewList = Material.Filled.ViewList; + public const string ViewModule = Material.Filled.ViewModule; + public const string ViewQuilt = Material.Filled.ViewQuilt; + public const string ViewSidebar = Material.Filled.ViewSidebar; + public const string ViewStream = Material.Filled.ViewStream; + public const string ViewTimeline = Material.Filled.ViewTimeline; + public const string ViewWeek = Material.Filled.ViewWeek; + public const string Vignette = Material.Filled.Vignette; + public const string Villa = Material.Filled.Villa; + public const string Visibility = Material.Filled.Visibility; + public const string VisibilityOff = Material.Filled.VisibilityOff; + public const string VoiceChat = Material.Filled.VoiceChat; + public const string VoiceOverOff = Material.Filled.VoiceOverOff; + public const string Voicemail = Material.Filled.Voicemail; + public const string Volcano = Material.Filled.Volcano; + public const string VolumeDown = Material.Filled.VolumeDown; + public const string VolumeMute = Material.Filled.VolumeMute; + public const string VolumeOff = Material.Filled.VolumeOff; + public const string VolumeUp = Material.Filled.VolumeUp; + public const string VolunteerActivism = Material.Filled.VolunteerActivism; + public const string VpnKey = Material.Filled.VpnKey; + public const string VpnKeyOff = Material.Filled.VpnKeyOff; + public const string VpnLock = Material.Filled.VpnLock; + public const string Vrpano = Material.Filled.Vrpano; + public const string Wallpaper = Material.Filled.Wallpaper; + public const string Warehouse = Material.Filled.Warehouse; + public const string Warning = Material.Filled.Warning; + public const string WarningAmber = Material.Filled.WarningAmber; + public const string Wash = Material.Filled.Wash; + public const string Watch = Material.Filled.Watch; + public const string WatchLater = Material.Filled.WatchLater; + public const string WatchOff = Material.Filled.WatchOff; + public const string Water = Material.Filled.Water; + public const string WaterDamage = Material.Filled.WaterDamage; + public const string WaterDrop = Material.Filled.WaterDrop; + public const string WaterfallChart = Material.Filled.WaterfallChart; + public const string Waves = Material.Filled.Waves; + public const string WavingHand = Material.Filled.WavingHand; + public const string WbAuto = Material.Filled.WbAuto; + public const string WbCloudy = Material.Filled.WbCloudy; + public const string WbIncandescent = Material.Filled.WbIncandescent; + public const string WbIridescent = Material.Filled.WbIridescent; + public const string WbShade = Material.Filled.WbShade; + public const string WbSunny = Material.Filled.WbSunny; + public const string WbTwilight = Material.Filled.WbTwilight; + public const string Wc = Material.Filled.Wc; + public const string Web = Material.Filled.Web; + public const string WebAsset = Material.Filled.WebAsset; + public const string WebAssetOff = Material.Filled.WebAssetOff; + public const string Webhook = Material.Filled.Webhook; + public const string Weekend = Material.Filled.Weekend; + public const string West = Material.Filled.West; + public const string Whatsapp = Material.Filled.Whatsapp; + public const string Whatshot = Material.Filled.Whatshot; + public const string WheelchairPickup = Material.Filled.WheelchairPickup; + public const string WhereToVote = Material.Filled.WhereToVote; + public const string Widgets = Material.Filled.Widgets; + public const string Wifi = Material.Filled.Wifi; + public const string Wifi1Bar = Material.Filled.Wifi1Bar; + public const string Wifi2Bar = Material.Filled.Wifi2Bar; + public const string WifiCalling = Material.Filled.WifiCalling; + public const string WifiCalling3 = Material.Filled.WifiCalling3; + public const string WifiChannel = Material.Filled.WifiChannel; + public const string WifiFind = Material.Filled.WifiFind; + public const string WifiLock = Material.Filled.WifiLock; + public const string WifiOff = Material.Filled.WifiOff; + public const string WifiPassword = Material.Filled.WifiPassword; + public const string WifiProtectedSetup = Material.Filled.WifiProtectedSetup; + public const string WifiTethering = Material.Filled.WifiTethering; + public const string WifiTetheringError = Material.Filled.WifiTetheringError; + public const string WifiTetheringOff = Material.Filled.WifiTetheringOff; + public const string Window = Material.Filled.Window; + public const string WineBar = Material.Filled.WineBar; + public const string Woman = Material.Filled.Woman; + public const string Work = Material.Filled.Work; + public const string WorkOff = Material.Filled.WorkOff; + public const string WorkOutline = Material.Filled.WorkOutline; + public const string WorkspacePremium = Material.Filled.WorkspacePremium; + public const string Workspaces = Material.Filled.Workspaces; + public const string WrapText = Material.Filled.WrapText; + public const string WrongLocation = Material.Filled.WrongLocation; + public const string Wysiwyg = Material.Filled.Wysiwyg; + public const string Yard = Material.Filled.Yard; + public const string YoutubeSearchedFor = Material.Filled.YoutubeSearchedFor; + public const string ZoomIn = Material.Filled.ZoomIn; + public const string ZoomInMap = Material.Filled.ZoomInMap; + public const string ZoomOut = Material.Filled.ZoomOut; + public const string ZoomOutMap = Material.Filled.ZoomOutMap; + } + } +} diff --git a/Icons/Obsolete/Outlined.cs b/Icons/Obsolete/Outlined.cs new file mode 100644 index 0000000..0f56fe0 --- /dev/null +++ b/Icons/Obsolete/Outlined.cs @@ -0,0 +1,2074 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + [ExcludeFromCodeCoverage] + public partial class Outlined + { + public const string _10k = Material.Outlined._10k; + public const string _10mp = Material.Outlined._10mp; + public const string _11mp = Material.Outlined._11mp; + public const string _123 = Material.Outlined._123; + public const string _12mp = Material.Outlined._12mp; + public const string _13mp = Material.Outlined._13mp; + public const string _14mp = Material.Outlined._14mp; + public const string _15mp = Material.Outlined._15mp; + public const string _16mp = Material.Outlined._16mp; + public const string _17mp = Material.Outlined._17mp; + public const string _18mp = Material.Outlined._18mp; + public const string _19mp = Material.Outlined._19mp; + public const string _1k = Material.Outlined._1k; + public const string _1kPlus = Material.Outlined._1kPlus; + public const string _1xMobiledata = Material.Outlined._1xMobiledata; + public const string _20mp = Material.Outlined._20mp; + public const string _21mp = Material.Outlined._21mp; + public const string _22mp = Material.Outlined._22mp; + public const string _23mp = Material.Outlined._23mp; + public const string _24mp = Material.Outlined._24mp; + public const string _2k = Material.Outlined._2k; + public const string _2kPlus = Material.Outlined._2kPlus; + public const string _2mp = Material.Outlined._2mp; + public const string _30fps = Material.Outlined._30fps; + public const string _30fpsSelect = Material.Outlined._30fpsSelect; + public const string _360 = Material.Outlined._360; + public const string _3dRotation = Material.Outlined._3dRotation; + public const string _3gMobiledata = Material.Outlined._3gMobiledata; + public const string _3k = Material.Outlined._3k; + public const string _3kPlus = Material.Outlined._3kPlus; + public const string _3mp = Material.Outlined._3mp; + public const string _3p = Material.Outlined._3p; + public const string _4gMobiledata = Material.Outlined._4gMobiledata; + public const string _4gPlusMobiledata = Material.Outlined._4gPlusMobiledata; + public const string _4k = Material.Outlined._4k; + public const string _4kPlus = Material.Outlined._4kPlus; + public const string _4mp = Material.Outlined._4mp; + public const string _5g = Material.Outlined._5g; + public const string _5k = Material.Outlined._5k; + public const string _5kPlus = Material.Outlined._5kPlus; + public const string _5mp = Material.Outlined._5mp; + public const string _60fps = Material.Outlined._60fps; + public const string _60fpsSelect = Material.Outlined._60fpsSelect; + public const string _6FtApart = Material.Outlined._6FtApart; + public const string _6k = Material.Outlined._6k; + public const string _6kPlus = Material.Outlined._6kPlus; + public const string _6mp = Material.Outlined._6mp; + public const string _7k = Material.Outlined._7k; + public const string _7kPlus = Material.Outlined._7kPlus; + public const string _7mp = Material.Outlined._7mp; + public const string _8k = Material.Outlined._8k; + public const string _8kPlus = Material.Outlined._8kPlus; + public const string _8mp = Material.Outlined._8mp; + public const string _9k = Material.Outlined._9k; + public const string _9kPlus = Material.Outlined._9kPlus; + public const string _9mp = Material.Outlined._9mp; + public const string Abc = Material.Outlined.Abc; + public const string AcUnit = Material.Outlined.AcUnit; + public const string AccessAlarm = Material.Outlined.AccessAlarm; + public const string AccessAlarms = Material.Outlined.AccessAlarms; + public const string AccessTime = Material.Outlined.AccessTime; + public const string AccessTimeFilled = Material.Outlined.AccessTimeFilled; + public const string Accessibility = Material.Outlined.Accessibility; + public const string AccessibilityNew = Material.Outlined.AccessibilityNew; + public const string Accessible = Material.Outlined.Accessible; + public const string AccessibleForward = Material.Outlined.AccessibleForward; + public const string AccountBalance = Material.Outlined.AccountBalance; + public const string AccountBalanceWallet = Material.Outlined.AccountBalanceWallet; + public const string AccountBox = Material.Outlined.AccountBox; + public const string AccountCircle = Material.Outlined.AccountCircle; + public const string AccountTree = Material.Outlined.AccountTree; + public const string AdUnits = Material.Outlined.AdUnits; + public const string Adb = Material.Outlined.Adb; + public const string Add = Material.Outlined.Add; + public const string AddAPhoto = Material.Outlined.AddAPhoto; + public const string AddAlarm = Material.Outlined.AddAlarm; + public const string AddAlert = Material.Outlined.AddAlert; + public const string AddBox = Material.Outlined.AddBox; + public const string AddBusiness = Material.Outlined.AddBusiness; + public const string AddCard = Material.Outlined.AddCard; + public const string AddChart = Material.Outlined.AddChart; + public const string AddCircle = Material.Outlined.AddCircle; + public const string AddCircleOutline = Material.Outlined.AddCircleOutline; + public const string AddComment = Material.Outlined.AddComment; + public const string AddIcCall = Material.Outlined.AddIcCall; + public const string AddLink = Material.Outlined.AddLink; + public const string AddLocation = Material.Outlined.AddLocation; + public const string AddLocationAlt = Material.Outlined.AddLocationAlt; + public const string AddModerator = Material.Outlined.AddModerator; + public const string AddPhotoAlternate = Material.Outlined.AddPhotoAlternate; + public const string AddReaction = Material.Outlined.AddReaction; + public const string AddRoad = Material.Outlined.AddRoad; + public const string AddShoppingCart = Material.Outlined.AddShoppingCart; + public const string AddTask = Material.Outlined.AddTask; + public const string AddToDrive = Material.Outlined.AddToDrive; + public const string AddToHomeScreen = Material.Outlined.AddToHomeScreen; + public const string AddToPhotos = Material.Outlined.AddToPhotos; + public const string AddToQueue = Material.Outlined.AddToQueue; + public const string Addchart = Material.Outlined.Addchart; + public const string AdfScanner = Material.Outlined.AdfScanner; + public const string Adjust = Material.Outlined.Adjust; + public const string AdminPanelSettings = Material.Outlined.AdminPanelSettings; + public const string AdsClick = Material.Outlined.AdsClick; + public const string Agriculture = Material.Outlined.Agriculture; + public const string Air = Material.Outlined.Air; + public const string AirlineSeatFlat = Material.Outlined.AirlineSeatFlat; + public const string AirlineSeatFlatAngled = Material.Outlined.AirlineSeatFlatAngled; + public const string AirlineSeatIndividualSuite = Material.Outlined.AirlineSeatIndividualSuite; + public const string AirlineSeatLegroomExtra = Material.Outlined.AirlineSeatLegroomExtra; + public const string AirlineSeatLegroomNormal = Material.Outlined.AirlineSeatLegroomNormal; + public const string AirlineSeatLegroomReduced = Material.Outlined.AirlineSeatLegroomReduced; + public const string AirlineSeatReclineExtra = Material.Outlined.AirlineSeatReclineExtra; + public const string AirlineSeatReclineNormal = Material.Outlined.AirlineSeatReclineNormal; + public const string AirlineStops = Material.Outlined.AirlineStops; + public const string Airlines = Material.Outlined.Airlines; + public const string AirplaneTicket = Material.Outlined.AirplaneTicket; + public const string AirplanemodeActive = Material.Outlined.AirplanemodeActive; + public const string AirplanemodeInactive = Material.Outlined.AirplanemodeInactive; + public const string Airplay = Material.Outlined.Airplay; + public const string AirportShuttle = Material.Outlined.AirportShuttle; + public const string Alarm = Material.Outlined.Alarm; + public const string AlarmAdd = Material.Outlined.AlarmAdd; + public const string AlarmOff = Material.Outlined.AlarmOff; + public const string AlarmOn = Material.Outlined.AlarmOn; + public const string Album = Material.Outlined.Album; + public const string AlignHorizontalCenter = Material.Outlined.AlignHorizontalCenter; + public const string AlignHorizontalLeft = Material.Outlined.AlignHorizontalLeft; + public const string AlignHorizontalRight = Material.Outlined.AlignHorizontalRight; + public const string AlignVerticalBottom = Material.Outlined.AlignVerticalBottom; + public const string AlignVerticalCenter = Material.Outlined.AlignVerticalCenter; + public const string AlignVerticalTop = Material.Outlined.AlignVerticalTop; + public const string AllInbox = Material.Outlined.AllInbox; + public const string AllInclusive = Material.Outlined.AllInclusive; + public const string AllOut = Material.Outlined.AllOut; + public const string AltRoute = Material.Outlined.AltRoute; + public const string AlternateEmail = Material.Outlined.AlternateEmail; + public const string Analytics = Material.Outlined.Analytics; + public const string Anchor = Material.Outlined.Anchor; + public const string Android = Material.Outlined.Android; + public const string Animation = Material.Outlined.Animation; + public const string Announcement = Material.Outlined.Announcement; + public const string Aod = Material.Outlined.Aod; + public const string Apartment = Material.Outlined.Apartment; + public const string Api = Material.Outlined.Api; + public const string AppBlocking = Material.Outlined.AppBlocking; + public const string AppRegistration = Material.Outlined.AppRegistration; + public const string AppSettingsAlt = Material.Outlined.AppSettingsAlt; + public const string AppShortcut = Material.Outlined.AppShortcut; + public const string Approval = Material.Outlined.Approval; + public const string Apps = Material.Outlined.Apps; + public const string AppsOutage = Material.Outlined.AppsOutage; + public const string Architecture = Material.Outlined.Architecture; + public const string Archive = Material.Outlined.Archive; + public const string AreaChart = Material.Outlined.AreaChart; + public const string ArrowBack = Material.Outlined.ArrowBack; + public const string ArrowBackIos = Material.Outlined.ArrowBackIos; + public const string ArrowBackIosNew = Material.Outlined.ArrowBackIosNew; + public const string ArrowCircleDown = Material.Outlined.ArrowCircleDown; + public const string ArrowCircleLeft = Material.Outlined.ArrowCircleLeft; + public const string ArrowCircleRight = Material.Outlined.ArrowCircleRight; + public const string ArrowCircleUp = Material.Outlined.ArrowCircleUp; + public const string ArrowDownward = Material.Outlined.ArrowDownward; + public const string ArrowDropDown = Material.Outlined.ArrowDropDown; + public const string ArrowDropDownCircle = Material.Outlined.ArrowDropDownCircle; + public const string ArrowDropUp = Material.Outlined.ArrowDropUp; + public const string ArrowForward = Material.Outlined.ArrowForward; + public const string ArrowForwardIos = Material.Outlined.ArrowForwardIos; + public const string ArrowLeft = Material.Outlined.ArrowLeft; + public const string ArrowRight = Material.Outlined.ArrowRight; + public const string ArrowRightAlt = Material.Outlined.ArrowRightAlt; + public const string ArrowUpward = Material.Outlined.ArrowUpward; + public const string ArtTrack = Material.Outlined.ArtTrack; + public const string Article = Material.Outlined.Article; + public const string AspectRatio = Material.Outlined.AspectRatio; + public const string Assessment = Material.Outlined.Assessment; + public const string Assignment = Material.Outlined.Assignment; + public const string AssignmentInd = Material.Outlined.AssignmentInd; + public const string AssignmentLate = Material.Outlined.AssignmentLate; + public const string AssignmentReturn = Material.Outlined.AssignmentReturn; + public const string AssignmentReturned = Material.Outlined.AssignmentReturned; + public const string AssignmentTurnedIn = Material.Outlined.AssignmentTurnedIn; + public const string Assistant = Material.Outlined.Assistant; + public const string AssistantDirection = Material.Outlined.AssistantDirection; + public const string AssistantPhoto = Material.Outlined.AssistantPhoto; + public const string AssuredWorkload = Material.Outlined.AssuredWorkload; + public const string Atm = Material.Outlined.Atm; + public const string AttachEmail = Material.Outlined.AttachEmail; + public const string AttachFile = Material.Outlined.AttachFile; + public const string AttachMoney = Material.Outlined.AttachMoney; + public const string Attachment = Material.Outlined.Attachment; + public const string Attractions = Material.Outlined.Attractions; + public const string Attribution = Material.Outlined.Attribution; + public const string AudioFile = Material.Outlined.AudioFile; + public const string Audiotrack = Material.Outlined.Audiotrack; + public const string AutoAwesome = Material.Outlined.AutoAwesome; + public const string AutoAwesomeMosaic = Material.Outlined.AutoAwesomeMosaic; + public const string AutoAwesomeMotion = Material.Outlined.AutoAwesomeMotion; + public const string AutoDelete = Material.Outlined.AutoDelete; + public const string AutoFixHigh = Material.Outlined.AutoFixHigh; + public const string AutoFixNormal = Material.Outlined.AutoFixNormal; + public const string AutoFixOff = Material.Outlined.AutoFixOff; + public const string AutoGraph = Material.Outlined.AutoGraph; + public const string AutoStories = Material.Outlined.AutoStories; + public const string AutofpsSelect = Material.Outlined.AutofpsSelect; + public const string Autorenew = Material.Outlined.Autorenew; + public const string AvTimer = Material.Outlined.AvTimer; + public const string BabyChangingStation = Material.Outlined.BabyChangingStation; + public const string BackHand = Material.Outlined.BackHand; + public const string Backpack = Material.Outlined.Backpack; + public const string Backspace = Material.Outlined.Backspace; + public const string Backup = Material.Outlined.Backup; + public const string BackupTable = Material.Outlined.BackupTable; + public const string Badge = Material.Outlined.Badge; + public const string BakeryDining = Material.Outlined.BakeryDining; + public const string Balance = Material.Outlined.Balance; + public const string Balcony = Material.Outlined.Balcony; + public const string Ballot = Material.Outlined.Ballot; + public const string BarChart = Material.Outlined.BarChart; + public const string BatchPrediction = Material.Outlined.BatchPrediction; + public const string Bathroom = Material.Outlined.Bathroom; + public const string Bathtub = Material.Outlined.Bathtub; + public const string Battery0Bar = Material.Outlined.Battery0Bar; + public const string Battery1Bar = Material.Outlined.Battery1Bar; + public const string Battery2Bar = Material.Outlined.Battery2Bar; + public const string Battery3Bar = Material.Outlined.Battery3Bar; + public const string Battery4Bar = Material.Outlined.Battery4Bar; + public const string Battery5Bar = Material.Outlined.Battery5Bar; + public const string Battery6Bar = Material.Outlined.Battery6Bar; + public const string BatteryAlert = Material.Outlined.BatteryAlert; + public const string BatteryChargingFull = Material.Outlined.BatteryChargingFull; + public const string BatteryFull = Material.Outlined.BatteryFull; + public const string BatterySaver = Material.Outlined.BatterySaver; + public const string BatteryStd = Material.Outlined.BatteryStd; + public const string BatteryUnknown = Material.Outlined.BatteryUnknown; + public const string BeachAccess = Material.Outlined.BeachAccess; + public const string Bed = Material.Outlined.Bed; + public const string BedroomBaby = Material.Outlined.BedroomBaby; + public const string BedroomChild = Material.Outlined.BedroomChild; + public const string BedroomParent = Material.Outlined.BedroomParent; + public const string Bedtime = Material.Outlined.Bedtime; + public const string BedtimeOff = Material.Outlined.BedtimeOff; + public const string Beenhere = Material.Outlined.Beenhere; + public const string Bento = Material.Outlined.Bento; + public const string BikeScooter = Material.Outlined.BikeScooter; + public const string Biotech = Material.Outlined.Biotech; + public const string Blender = Material.Outlined.Blender; + public const string Block = Material.Outlined.Block; + public const string Bloodtype = Material.Outlined.Bloodtype; + public const string Bluetooth = Material.Outlined.Bluetooth; + public const string BluetoothAudio = Material.Outlined.BluetoothAudio; + public const string BluetoothConnected = Material.Outlined.BluetoothConnected; + public const string BluetoothDisabled = Material.Outlined.BluetoothDisabled; + public const string BluetoothDrive = Material.Outlined.BluetoothDrive; + public const string BluetoothSearching = Material.Outlined.BluetoothSearching; + public const string BlurCircular = Material.Outlined.BlurCircular; + public const string BlurLinear = Material.Outlined.BlurLinear; + public const string BlurOff = Material.Outlined.BlurOff; + public const string BlurOn = Material.Outlined.BlurOn; + public const string Bolt = Material.Outlined.Bolt; + public const string Book = Material.Outlined.Book; + public const string BookOnline = Material.Outlined.BookOnline; + public const string Bookmark = Material.Outlined.Bookmark; + public const string BookmarkAdd = Material.Outlined.BookmarkAdd; + public const string BookmarkAdded = Material.Outlined.BookmarkAdded; + public const string BookmarkBorder = Material.Outlined.BookmarkBorder; + public const string BookmarkRemove = Material.Outlined.BookmarkRemove; + public const string Bookmarks = Material.Outlined.Bookmarks; + public const string BorderAll = Material.Outlined.BorderAll; + public const string BorderBottom = Material.Outlined.BorderBottom; + public const string BorderClear = Material.Outlined.BorderClear; + public const string BorderColor = Material.Outlined.BorderColor; + public const string BorderHorizontal = Material.Outlined.BorderHorizontal; + public const string BorderInner = Material.Outlined.BorderInner; + public const string BorderLeft = Material.Outlined.BorderLeft; + public const string BorderOuter = Material.Outlined.BorderOuter; + public const string BorderRight = Material.Outlined.BorderRight; + public const string BorderStyle = Material.Outlined.BorderStyle; + public const string BorderTop = Material.Outlined.BorderTop; + public const string BorderVertical = Material.Outlined.BorderVertical; + public const string Boy = Material.Outlined.Boy; + public const string BrandingWatermark = Material.Outlined.BrandingWatermark; + public const string BreakfastDining = Material.Outlined.BreakfastDining; + public const string Brightness1 = Material.Outlined.Brightness1; + public const string Brightness2 = Material.Outlined.Brightness2; + public const string Brightness3 = Material.Outlined.Brightness3; + public const string Brightness4 = Material.Outlined.Brightness4; + public const string Brightness5 = Material.Outlined.Brightness5; + public const string Brightness6 = Material.Outlined.Brightness6; + public const string Brightness7 = Material.Outlined.Brightness7; + public const string BrightnessAuto = Material.Outlined.BrightnessAuto; + public const string BrightnessHigh = Material.Outlined.BrightnessHigh; + public const string BrightnessLow = Material.Outlined.BrightnessLow; + public const string BrightnessMedium = Material.Outlined.BrightnessMedium; + public const string BrokenImage = Material.Outlined.BrokenImage; + public const string BrowseGallery = Material.Outlined.BrowseGallery; + public const string BrowserNotSupported = Material.Outlined.BrowserNotSupported; + public const string BrowserUpdated = Material.Outlined.BrowserUpdated; + public const string BrunchDining = Material.Outlined.BrunchDining; + public const string Brush = Material.Outlined.Brush; + public const string BubbleChart = Material.Outlined.BubbleChart; + public const string BugReport = Material.Outlined.BugReport; + public const string Build = Material.Outlined.Build; + public const string BuildCircle = Material.Outlined.BuildCircle; + public const string Bungalow = Material.Outlined.Bungalow; + public const string BurstMode = Material.Outlined.BurstMode; + public const string BusAlert = Material.Outlined.BusAlert; + public const string Business = Material.Outlined.Business; + public const string BusinessCenter = Material.Outlined.BusinessCenter; + public const string Cabin = Material.Outlined.Cabin; + public const string Cable = Material.Outlined.Cable; + public const string Cached = Material.Outlined.Cached; + public const string Cake = Material.Outlined.Cake; + public const string Calculate = Material.Outlined.Calculate; + public const string CalendarMonth = Material.Outlined.CalendarMonth; + public const string CalendarToday = Material.Outlined.CalendarToday; + public const string CalendarViewDay = Material.Outlined.CalendarViewDay; + public const string CalendarViewMonth = Material.Outlined.CalendarViewMonth; + public const string CalendarViewWeek = Material.Outlined.CalendarViewWeek; + public const string Call = Material.Outlined.Call; + public const string CallEnd = Material.Outlined.CallEnd; + public const string CallMade = Material.Outlined.CallMade; + public const string CallMerge = Material.Outlined.CallMerge; + public const string CallMissed = Material.Outlined.CallMissed; + public const string CallMissedOutgoing = Material.Outlined.CallMissedOutgoing; + public const string CallReceived = Material.Outlined.CallReceived; + public const string CallSplit = Material.Outlined.CallSplit; + public const string CallToAction = Material.Outlined.CallToAction; + public const string Camera = Material.Outlined.Camera; + public const string CameraAlt = Material.Outlined.CameraAlt; + public const string CameraEnhance = Material.Outlined.CameraEnhance; + public const string CameraFront = Material.Outlined.CameraFront; + public const string CameraIndoor = Material.Outlined.CameraIndoor; + public const string CameraOutdoor = Material.Outlined.CameraOutdoor; + public const string CameraRear = Material.Outlined.CameraRear; + public const string CameraRoll = Material.Outlined.CameraRoll; + public const string Cameraswitch = Material.Outlined.Cameraswitch; + public const string Campaign = Material.Outlined.Campaign; + public const string Cancel = Material.Outlined.Cancel; + public const string CancelPresentation = Material.Outlined.CancelPresentation; + public const string CancelScheduleSend = Material.Outlined.CancelScheduleSend; + public const string CandlestickChart = Material.Outlined.CandlestickChart; + public const string CarCrash = Material.Outlined.CarCrash; + public const string CarRental = Material.Outlined.CarRental; + public const string CarRepair = Material.Outlined.CarRepair; + public const string CardGiftcard = Material.Outlined.CardGiftcard; + public const string CardMembership = Material.Outlined.CardMembership; + public const string CardTravel = Material.Outlined.CardTravel; + public const string Carpenter = Material.Outlined.Carpenter; + public const string Cases = Material.Outlined.Cases; + public const string Casino = Material.Outlined.Casino; + public const string Cast = Material.Outlined.Cast; + public const string CastConnected = Material.Outlined.CastConnected; + public const string CastForEducation = Material.Outlined.CastForEducation; + public const string Castle = Material.Outlined.Castle; + public const string CatchingPokemon = Material.Outlined.CatchingPokemon; + public const string Category = Material.Outlined.Category; + public const string Celebration = Material.Outlined.Celebration; + public const string CellTower = Material.Outlined.CellTower; + public const string CellWifi = Material.Outlined.CellWifi; + public const string CenterFocusStrong = Material.Outlined.CenterFocusStrong; + public const string CenterFocusWeak = Material.Outlined.CenterFocusWeak; + public const string Chair = Material.Outlined.Chair; + public const string ChairAlt = Material.Outlined.ChairAlt; + public const string Chalet = Material.Outlined.Chalet; + public const string ChangeCircle = Material.Outlined.ChangeCircle; + public const string ChangeHistory = Material.Outlined.ChangeHistory; + public const string ChargingStation = Material.Outlined.ChargingStation; + public const string Chat = Material.Outlined.Chat; + public const string ChatBubble = Material.Outlined.ChatBubble; + public const string ChatBubbleOutline = Material.Outlined.ChatBubbleOutline; + public const string Check = Material.Outlined.Check; + public const string CheckBox = Material.Outlined.CheckBox; + public const string CheckBoxOutlineBlank = Material.Outlined.CheckBoxOutlineBlank; + public const string CheckCircle = Material.Outlined.CheckCircle; + public const string CheckCircleOutline = Material.Outlined.CheckCircleOutline; + public const string Checklist = Material.Outlined.Checklist; + public const string ChecklistRtl = Material.Outlined.ChecklistRtl; + public const string Checkroom = Material.Outlined.Checkroom; + public const string ChevronLeft = Material.Outlined.ChevronLeft; + public const string ChevronRight = Material.Outlined.ChevronRight; + public const string ChildCare = Material.Outlined.ChildCare; + public const string ChildFriendly = Material.Outlined.ChildFriendly; + public const string ChromeReaderMode = Material.Outlined.ChromeReaderMode; + public const string Church = Material.Outlined.Church; + public const string Circle = Material.Outlined.Circle; + public const string CircleNotifications = Material.Outlined.CircleNotifications; + public const string Class = Material.Outlined.Class; + public const string CleanHands = Material.Outlined.CleanHands; + public const string CleaningServices = Material.Outlined.CleaningServices; + public const string Clear = Material.Outlined.Clear; + public const string ClearAll = Material.Outlined.ClearAll; + public const string Close = Material.Outlined.Close; + public const string CloseFullscreen = Material.Outlined.CloseFullscreen; + public const string ClosedCaption = Material.Outlined.ClosedCaption; + public const string ClosedCaptionDisabled = Material.Outlined.ClosedCaptionDisabled; + public const string ClosedCaptionOff = Material.Outlined.ClosedCaptionOff; + public const string Cloud = Material.Outlined.Cloud; + public const string CloudCircle = Material.Outlined.CloudCircle; + public const string CloudDone = Material.Outlined.CloudDone; + public const string CloudDownload = Material.Outlined.CloudDownload; + public const string CloudOff = Material.Outlined.CloudOff; + public const string CloudQueue = Material.Outlined.CloudQueue; + public const string CloudSync = Material.Outlined.CloudSync; + public const string CloudUpload = Material.Outlined.CloudUpload; + public const string Co2 = Material.Outlined.Co2; + public const string CoPresent = Material.Outlined.CoPresent; + public const string Code = Material.Outlined.Code; + public const string CodeOff = Material.Outlined.CodeOff; + public const string Coffee = Material.Outlined.Coffee; + public const string CoffeeMaker = Material.Outlined.CoffeeMaker; + public const string Collections = Material.Outlined.Collections; + public const string CollectionsBookmark = Material.Outlined.CollectionsBookmark; + public const string ColorLens = Material.Outlined.ColorLens; + public const string Colorize = Material.Outlined.Colorize; + public const string Comment = Material.Outlined.Comment; + public const string CommentBank = Material.Outlined.CommentBank; + public const string CommentsDisabled = Material.Outlined.CommentsDisabled; + public const string Commit = Material.Outlined.Commit; + public const string Commute = Material.Outlined.Commute; + public const string Compare = Material.Outlined.Compare; + public const string CompareArrows = Material.Outlined.CompareArrows; + public const string CompassCalibration = Material.Outlined.CompassCalibration; + public const string Compost = Material.Outlined.Compost; + public const string Compress = Material.Outlined.Compress; + public const string Computer = Material.Outlined.Computer; + public const string ConfirmationNumber = Material.Outlined.ConfirmationNumber; + public const string ConnectWithoutContact = Material.Outlined.ConnectWithoutContact; + public const string ConnectedTv = Material.Outlined.ConnectedTv; + public const string ConnectingAirports = Material.Outlined.ConnectingAirports; + public const string Construction = Material.Outlined.Construction; + public const string ContactMail = Material.Outlined.ContactMail; + public const string ContactPage = Material.Outlined.ContactPage; + public const string ContactPhone = Material.Outlined.ContactPhone; + public const string ContactSupport = Material.Outlined.ContactSupport; + public const string Contactless = Material.Outlined.Contactless; + public const string Contacts = Material.Outlined.Contacts; + public const string ContentCopy = Material.Outlined.ContentCopy; + public const string ContentCut = Material.Outlined.ContentCut; + public const string ContentPaste = Material.Outlined.ContentPaste; + public const string ContentPasteGo = Material.Outlined.ContentPasteGo; + public const string ContentPasteOff = Material.Outlined.ContentPasteOff; + public const string ContentPasteSearch = Material.Outlined.ContentPasteSearch; + public const string Contrast = Material.Outlined.Contrast; + public const string ControlCamera = Material.Outlined.ControlCamera; + public const string ControlPoint = Material.Outlined.ControlPoint; + public const string ControlPointDuplicate = Material.Outlined.ControlPointDuplicate; + public const string Cookie = Material.Outlined.Cookie; + public const string CopyAll = Material.Outlined.CopyAll; + public const string Copyright = Material.Outlined.Copyright; + public const string Coronavirus = Material.Outlined.Coronavirus; + public const string CorporateFare = Material.Outlined.CorporateFare; + public const string Cottage = Material.Outlined.Cottage; + public const string Countertops = Material.Outlined.Countertops; + public const string Create = Material.Outlined.Create; + public const string CreateNewFolder = Material.Outlined.CreateNewFolder; + public const string CreditCard = Material.Outlined.CreditCard; + public const string CreditCardOff = Material.Outlined.CreditCardOff; + public const string CreditScore = Material.Outlined.CreditScore; + public const string Crib = Material.Outlined.Crib; + public const string CrisisAlert = Material.Outlined.CrisisAlert; + public const string Crop = Material.Outlined.Crop; + public const string Crop169 = Material.Outlined.Crop169; + public const string Crop32 = Material.Outlined.Crop32; + public const string Crop54 = Material.Outlined.Crop54; + public const string Crop75 = Material.Outlined.Crop75; + public const string CropDin = Material.Outlined.CropDin; + public const string CropFree = Material.Outlined.CropFree; + public const string CropLandscape = Material.Outlined.CropLandscape; + public const string CropOriginal = Material.Outlined.CropOriginal; + public const string CropPortrait = Material.Outlined.CropPortrait; + public const string CropRotate = Material.Outlined.CropRotate; + public const string CropSquare = Material.Outlined.CropSquare; + public const string CrueltyFree = Material.Outlined.CrueltyFree; + public const string Css = Material.Outlined.Css; + public const string CurrencyBitcoin = Material.Outlined.CurrencyBitcoin; + public const string CurrencyExchange = Material.Outlined.CurrencyExchange; + public const string CurrencyFranc = Material.Outlined.CurrencyFranc; + public const string CurrencyLira = Material.Outlined.CurrencyLira; + public const string CurrencyPound = Material.Outlined.CurrencyPound; + public const string CurrencyRuble = Material.Outlined.CurrencyRuble; + public const string CurrencyRupee = Material.Outlined.CurrencyRupee; + public const string CurrencyYen = Material.Outlined.CurrencyYen; + public const string CurrencyYuan = Material.Outlined.CurrencyYuan; + public const string Cyclone = Material.Outlined.Cyclone; + public const string Dangerous = Material.Outlined.Dangerous; + public const string DarkMode = Material.Outlined.DarkMode; + public const string Dashboard = Material.Outlined.Dashboard; + public const string DashboardCustomize = Material.Outlined.DashboardCustomize; + public const string DataArray = Material.Outlined.DataArray; + public const string DataExploration = Material.Outlined.DataExploration; + public const string DataObject = Material.Outlined.DataObject; + public const string DataSaverOff = Material.Outlined.DataSaverOff; + public const string DataSaverOn = Material.Outlined.DataSaverOn; + public const string DataThresholding = Material.Outlined.DataThresholding; + public const string DataUsage = Material.Outlined.DataUsage; + public const string DateRange = Material.Outlined.DateRange; + public const string Deblur = Material.Outlined.Deblur; + public const string Deck = Material.Outlined.Deck; + public const string Dehaze = Material.Outlined.Dehaze; + public const string Delete = Material.Outlined.Delete; + public const string DeleteForever = Material.Outlined.DeleteForever; + public const string DeleteOutline = Material.Outlined.DeleteOutline; + public const string DeleteSweep = Material.Outlined.DeleteSweep; + public const string DeliveryDining = Material.Outlined.DeliveryDining; + public const string DensityLarge = Material.Outlined.DensityLarge; + public const string DensityMedium = Material.Outlined.DensityMedium; + public const string DensitySmall = Material.Outlined.DensitySmall; + public const string DepartureBoard = Material.Outlined.DepartureBoard; + public const string Description = Material.Outlined.Description; + public const string Deselect = Material.Outlined.Deselect; + public const string DesignServices = Material.Outlined.DesignServices; + public const string DesktopAccessDisabled = Material.Outlined.DesktopAccessDisabled; + public const string DesktopMac = Material.Outlined.DesktopMac; + public const string DesktopWindows = Material.Outlined.DesktopWindows; + public const string Details = Material.Outlined.Details; + public const string DeveloperBoard = Material.Outlined.DeveloperBoard; + public const string DeveloperBoardOff = Material.Outlined.DeveloperBoardOff; + public const string DeveloperMode = Material.Outlined.DeveloperMode; + public const string DeviceHub = Material.Outlined.DeviceHub; + public const string DeviceThermostat = Material.Outlined.DeviceThermostat; + public const string DeviceUnknown = Material.Outlined.DeviceUnknown; + public const string Devices = Material.Outlined.Devices; + public const string DevicesFold = Material.Outlined.DevicesFold; + public const string DevicesOther = Material.Outlined.DevicesOther; + public const string DialerSip = Material.Outlined.DialerSip; + public const string Dialpad = Material.Outlined.Dialpad; + public const string Diamond = Material.Outlined.Diamond; + public const string Difference = Material.Outlined.Difference; + public const string Dining = Material.Outlined.Dining; + public const string DinnerDining = Material.Outlined.DinnerDining; + public const string Directions = Material.Outlined.Directions; + public const string DirectionsBike = Material.Outlined.DirectionsBike; + public const string DirectionsBoat = Material.Outlined.DirectionsBoat; + public const string DirectionsBoatFilled = Material.Outlined.DirectionsBoatFilled; + public const string DirectionsBus = Material.Outlined.DirectionsBus; + public const string DirectionsBusFilled = Material.Outlined.DirectionsBusFilled; + public const string DirectionsCar = Material.Outlined.DirectionsCar; + public const string DirectionsCarFilled = Material.Outlined.DirectionsCarFilled; + public const string DirectionsOff = Material.Outlined.DirectionsOff; + public const string DirectionsRailway = Material.Outlined.DirectionsRailway; + public const string DirectionsRailwayFilled = Material.Outlined.DirectionsRailwayFilled; + public const string DirectionsRun = Material.Outlined.DirectionsRun; + public const string DirectionsSubway = Material.Outlined.DirectionsSubway; + public const string DirectionsSubwayFilled = Material.Outlined.DirectionsSubwayFilled; + public const string DirectionsTransit = Material.Outlined.DirectionsTransit; + public const string DirectionsTransitFilled = Material.Outlined.DirectionsTransitFilled; + public const string DirectionsWalk = Material.Outlined.DirectionsWalk; + public const string DirtyLens = Material.Outlined.DirtyLens; + public const string DisabledByDefault = Material.Outlined.DisabledByDefault; + public const string DisabledVisible = Material.Outlined.DisabledVisible; + public const string DiscFull = Material.Outlined.DiscFull; + public const string Discount = Material.Outlined.Discount; + public const string DisplaySettings = Material.Outlined.DisplaySettings; + public const string Dns = Material.Outlined.Dns; + public const string DoDisturb = Material.Outlined.DoDisturb; + public const string DoDisturbAlt = Material.Outlined.DoDisturbAlt; + public const string DoDisturbOff = Material.Outlined.DoDisturbOff; + public const string DoDisturbOn = Material.Outlined.DoDisturbOn; + public const string DoNotDisturb = Material.Outlined.DoNotDisturb; + public const string DoNotDisturbAlt = Material.Outlined.DoNotDisturbAlt; + public const string DoNotDisturbOff = Material.Outlined.DoNotDisturbOff; + public const string DoNotDisturbOn = Material.Outlined.DoNotDisturbOn; + public const string DoNotDisturbOnTotalSilence = Material.Outlined.DoNotDisturbOnTotalSilence; + public const string DoNotStep = Material.Outlined.DoNotStep; + public const string DoNotTouch = Material.Outlined.DoNotTouch; + public const string Dock = Material.Outlined.Dock; + public const string DocumentScanner = Material.Outlined.DocumentScanner; + public const string Domain = Material.Outlined.Domain; + public const string DomainAdd = Material.Outlined.DomainAdd; + public const string DomainDisabled = Material.Outlined.DomainDisabled; + public const string DomainVerification = Material.Outlined.DomainVerification; + public const string Done = Material.Outlined.Done; + public const string DoneAll = Material.Outlined.DoneAll; + public const string DoneOutline = Material.Outlined.DoneOutline; + public const string DonutLarge = Material.Outlined.DonutLarge; + public const string DonutSmall = Material.Outlined.DonutSmall; + public const string DoorBack = Material.Outlined.DoorBack; + public const string DoorFront = Material.Outlined.DoorFront; + public const string DoorSliding = Material.Outlined.DoorSliding; + public const string Doorbell = Material.Outlined.Doorbell; + public const string DoubleArrow = Material.Outlined.DoubleArrow; + public const string DownhillSkiing = Material.Outlined.DownhillSkiing; + public const string Download = Material.Outlined.Download; + public const string DownloadDone = Material.Outlined.DownloadDone; + public const string DownloadForOffline = Material.Outlined.DownloadForOffline; + public const string Downloading = Material.Outlined.Downloading; + public const string Drafts = Material.Outlined.Drafts; + public const string DragHandle = Material.Outlined.DragHandle; + public const string DragIndicator = Material.Outlined.DragIndicator; + public const string Draw = Material.Outlined.Draw; + public const string DriveEta = Material.Outlined.DriveEta; + public const string DriveFileMove = Material.Outlined.DriveFileMove; + public const string DriveFileMoveRtl = Material.Outlined.DriveFileMoveRtl; + public const string DriveFileRenameOutline = Material.Outlined.DriveFileRenameOutline; + public const string DriveFolderUpload = Material.Outlined.DriveFolderUpload; + public const string Dry = Material.Outlined.Dry; + public const string DryCleaning = Material.Outlined.DryCleaning; + public const string Duo = Material.Outlined.Duo; + public const string Dvr = Material.Outlined.Dvr; + public const string DynamicFeed = Material.Outlined.DynamicFeed; + public const string DynamicForm = Material.Outlined.DynamicForm; + public const string EMobiledata = Material.Outlined.EMobiledata; + public const string Earbuds = Material.Outlined.Earbuds; + public const string EarbudsBattery = Material.Outlined.EarbudsBattery; + public const string East = Material.Outlined.East; + public const string EdgesensorHigh = Material.Outlined.EdgesensorHigh; + public const string EdgesensorLow = Material.Outlined.EdgesensorLow; + public const string Edit = Material.Outlined.Edit; + public const string EditAttributes = Material.Outlined.EditAttributes; + public const string EditCalendar = Material.Outlined.EditCalendar; + public const string EditLocation = Material.Outlined.EditLocation; + public const string EditLocationAlt = Material.Outlined.EditLocationAlt; + public const string EditNote = Material.Outlined.EditNote; + public const string EditNotifications = Material.Outlined.EditNotifications; + public const string EditOff = Material.Outlined.EditOff; + public const string EditRoad = Material.Outlined.EditRoad; + public const string Egg = Material.Outlined.Egg; + public const string EggAlt = Material.Outlined.EggAlt; + public const string Eject = Material.Outlined.Eject; + public const string Elderly = Material.Outlined.Elderly; + public const string ElderlyWoman = Material.Outlined.ElderlyWoman; + public const string ElectricBike = Material.Outlined.ElectricBike; + public const string ElectricCar = Material.Outlined.ElectricCar; + public const string ElectricMoped = Material.Outlined.ElectricMoped; + public const string ElectricRickshaw = Material.Outlined.ElectricRickshaw; + public const string ElectricScooter = Material.Outlined.ElectricScooter; + public const string ElectricalServices = Material.Outlined.ElectricalServices; + public const string Elevator = Material.Outlined.Elevator; + public const string Email = Material.Outlined.Email; + public const string Emergency = Material.Outlined.Emergency; + public const string EmergencyRecording = Material.Outlined.EmergencyRecording; + public const string EmergencyShare = Material.Outlined.EmergencyShare; + public const string EmojiEmotions = Material.Outlined.EmojiEmotions; + public const string EmojiEvents = Material.Outlined.EmojiEvents; + public const string EmojiFoodBeverage = Material.Outlined.EmojiFoodBeverage; + public const string EmojiNature = Material.Outlined.EmojiNature; + public const string EmojiObjects = Material.Outlined.EmojiObjects; + public const string EmojiPeople = Material.Outlined.EmojiPeople; + public const string EmojiSymbols = Material.Outlined.EmojiSymbols; + public const string EmojiTransportation = Material.Outlined.EmojiTransportation; + public const string Engineering = Material.Outlined.Engineering; + public const string EnhancedEncryption = Material.Outlined.EnhancedEncryption; + public const string Equalizer = Material.Outlined.Equalizer; + public const string Error = Material.Outlined.Error; + public const string ErrorOutline = Material.Outlined.ErrorOutline; + public const string Escalator = Material.Outlined.Escalator; + public const string EscalatorWarning = Material.Outlined.EscalatorWarning; + public const string Euro = Material.Outlined.Euro; + public const string EuroSymbol = Material.Outlined.EuroSymbol; + public const string EvStation = Material.Outlined.EvStation; + public const string Event = Material.Outlined.Event; + public const string EventAvailable = Material.Outlined.EventAvailable; + public const string EventBusy = Material.Outlined.EventBusy; + public const string EventNote = Material.Outlined.EventNote; + public const string EventRepeat = Material.Outlined.EventRepeat; + public const string EventSeat = Material.Outlined.EventSeat; + public const string ExitToApp = Material.Outlined.ExitToApp; + public const string Expand = Material.Outlined.Expand; + public const string ExpandCircleDown = Material.Outlined.ExpandCircleDown; + public const string ExpandLess = Material.Outlined.ExpandLess; + public const string ExpandMore = Material.Outlined.ExpandMore; + public const string Explicit = Material.Outlined.Explicit; + public const string Explore = Material.Outlined.Explore; + public const string ExploreOff = Material.Outlined.ExploreOff; + public const string Exposure = Material.Outlined.Exposure; + public const string ExposureNeg1 = Material.Outlined.ExposureNeg1; + public const string ExposureNeg2 = Material.Outlined.ExposureNeg2; + public const string ExposurePlus1 = Material.Outlined.ExposurePlus1; + public const string ExposurePlus2 = Material.Outlined.ExposurePlus2; + public const string ExposureZero = Material.Outlined.ExposureZero; + public const string Extension = Material.Outlined.Extension; + public const string ExtensionOff = Material.Outlined.ExtensionOff; + public const string Face = Material.Outlined.Face; + public const string FaceRetouchingNatural = Material.Outlined.FaceRetouchingNatural; + public const string FaceRetouchingOff = Material.Outlined.FaceRetouchingOff; + public const string FactCheck = Material.Outlined.FactCheck; + public const string Factory = Material.Outlined.Factory; + public const string FamilyRestroom = Material.Outlined.FamilyRestroom; + public const string FastForward = Material.Outlined.FastForward; + public const string FastRewind = Material.Outlined.FastRewind; + public const string Fastfood = Material.Outlined.Fastfood; + public const string Favorite = Material.Outlined.Favorite; + public const string FavoriteBorder = Material.Outlined.FavoriteBorder; + public const string Fax = Material.Outlined.Fax; + public const string FeaturedPlayList = Material.Outlined.FeaturedPlayList; + public const string FeaturedVideo = Material.Outlined.FeaturedVideo; + public const string Feed = Material.Outlined.Feed; + public const string Feedback = Material.Outlined.Feedback; + public const string Female = Material.Outlined.Female; + public const string Fence = Material.Outlined.Fence; + public const string Festival = Material.Outlined.Festival; + public const string FiberDvr = Material.Outlined.FiberDvr; + public const string FiberManualRecord = Material.Outlined.FiberManualRecord; + public const string FiberNew = Material.Outlined.FiberNew; + public const string FiberPin = Material.Outlined.FiberPin; + public const string FiberSmartRecord = Material.Outlined.FiberSmartRecord; + public const string FileCopy = Material.Outlined.FileCopy; + public const string FileDownload = Material.Outlined.FileDownload; + public const string FileDownloadDone = Material.Outlined.FileDownloadDone; + public const string FileDownloadOff = Material.Outlined.FileDownloadOff; + public const string FileOpen = Material.Outlined.FileOpen; + public const string FilePresent = Material.Outlined.FilePresent; + public const string FileUpload = Material.Outlined.FileUpload; + public const string Filter = Material.Outlined.Filter; + public const string Filter1 = Material.Outlined.Filter1; + public const string Filter2 = Material.Outlined.Filter2; + public const string Filter3 = Material.Outlined.Filter3; + public const string Filter4 = Material.Outlined.Filter4; + public const string Filter5 = Material.Outlined.Filter5; + public const string Filter6 = Material.Outlined.Filter6; + public const string Filter7 = Material.Outlined.Filter7; + public const string Filter8 = Material.Outlined.Filter8; + public const string Filter9 = Material.Outlined.Filter9; + public const string Filter9Plus = Material.Outlined.Filter9Plus; + public const string FilterAlt = Material.Outlined.FilterAlt; + public const string FilterAltOff = Material.Outlined.FilterAltOff; + public const string FilterBAndW = Material.Outlined.FilterBAndW; + public const string FilterCenterFocus = Material.Outlined.FilterCenterFocus; + public const string FilterDrama = Material.Outlined.FilterDrama; + public const string FilterFrames = Material.Outlined.FilterFrames; + public const string FilterHdr = Material.Outlined.FilterHdr; + public const string FilterList = Material.Outlined.FilterList; + public const string FilterListOff = Material.Outlined.FilterListOff; + public const string FilterNone = Material.Outlined.FilterNone; + public const string FilterTiltShift = Material.Outlined.FilterTiltShift; + public const string FilterVintage = Material.Outlined.FilterVintage; + public const string FindInPage = Material.Outlined.FindInPage; + public const string FindReplace = Material.Outlined.FindReplace; + public const string Fingerprint = Material.Outlined.Fingerprint; + public const string FireExtinguisher = Material.Outlined.FireExtinguisher; + public const string Fireplace = Material.Outlined.Fireplace; + public const string FirstPage = Material.Outlined.FirstPage; + public const string FitScreen = Material.Outlined.FitScreen; + public const string Fitbit = Material.Outlined.Fitbit; + public const string FitnessCenter = Material.Outlined.FitnessCenter; + public const string Flag = Material.Outlined.Flag; + public const string FlagCircle = Material.Outlined.FlagCircle; + public const string Flaky = Material.Outlined.Flaky; + public const string Flare = Material.Outlined.Flare; + public const string FlashAuto = Material.Outlined.FlashAuto; + public const string FlashOff = Material.Outlined.FlashOff; + public const string FlashOn = Material.Outlined.FlashOn; + public const string FlashlightOff = Material.Outlined.FlashlightOff; + public const string FlashlightOn = Material.Outlined.FlashlightOn; + public const string Flatware = Material.Outlined.Flatware; + public const string Flight = Material.Outlined.Flight; + public const string FlightClass = Material.Outlined.FlightClass; + public const string FlightLand = Material.Outlined.FlightLand; + public const string FlightTakeoff = Material.Outlined.FlightTakeoff; + public const string Flip = Material.Outlined.Flip; + public const string FlipCameraAndroid = Material.Outlined.FlipCameraAndroid; + public const string FlipCameraIos = Material.Outlined.FlipCameraIos; + public const string FlipToBack = Material.Outlined.FlipToBack; + public const string FlipToFront = Material.Outlined.FlipToFront; + public const string Flood = Material.Outlined.Flood; + public const string Flourescent = Material.Outlined.Flourescent; + public const string FlutterDash = Material.Outlined.FlutterDash; + public const string FmdBad = Material.Outlined.FmdBad; + public const string FmdGood = Material.Outlined.FmdGood; + public const string Folder = Material.Outlined.Folder; + public const string FolderCopy = Material.Outlined.FolderCopy; + public const string FolderDelete = Material.Outlined.FolderDelete; + public const string FolderOff = Material.Outlined.FolderOff; + public const string FolderOpen = Material.Outlined.FolderOpen; + public const string FolderShared = Material.Outlined.FolderShared; + public const string FolderSpecial = Material.Outlined.FolderSpecial; + public const string FolderZip = Material.Outlined.FolderZip; + public const string FollowTheSigns = Material.Outlined.FollowTheSigns; + public const string FontDownload = Material.Outlined.FontDownload; + public const string FontDownloadOff = Material.Outlined.FontDownloadOff; + public const string FoodBank = Material.Outlined.FoodBank; + public const string Forest = Material.Outlined.Forest; + public const string ForkLeft = Material.Outlined.ForkLeft; + public const string ForkRight = Material.Outlined.ForkRight; + public const string FormatAlignCenter = Material.Outlined.FormatAlignCenter; + public const string FormatAlignJustify = Material.Outlined.FormatAlignJustify; + public const string FormatAlignLeft = Material.Outlined.FormatAlignLeft; + public const string FormatAlignRight = Material.Outlined.FormatAlignRight; + public const string FormatBold = Material.Outlined.FormatBold; + public const string FormatClear = Material.Outlined.FormatClear; + public const string FormatColorFill = Material.Outlined.FormatColorFill; + public const string FormatColorReset = Material.Outlined.FormatColorReset; + public const string FormatColorText = Material.Outlined.FormatColorText; + public const string FormatIndentDecrease = Material.Outlined.FormatIndentDecrease; + public const string FormatIndentIncrease = Material.Outlined.FormatIndentIncrease; + public const string FormatItalic = Material.Outlined.FormatItalic; + public const string FormatLineSpacing = Material.Outlined.FormatLineSpacing; + public const string FormatListBulleted = Material.Outlined.FormatListBulleted; + public const string FormatListNumbered = Material.Outlined.FormatListNumbered; + public const string FormatListNumberedRtl = Material.Outlined.FormatListNumberedRtl; + public const string FormatOverline = Material.Outlined.FormatOverline; + public const string FormatPaint = Material.Outlined.FormatPaint; + public const string FormatQuote = Material.Outlined.FormatQuote; + public const string FormatShapes = Material.Outlined.FormatShapes; + public const string FormatSize = Material.Outlined.FormatSize; + public const string FormatStrikethrough = Material.Outlined.FormatStrikethrough; + public const string FormatTextdirectionLToR = Material.Outlined.FormatTextdirectionLToR; + public const string FormatTextdirectionRToL = Material.Outlined.FormatTextdirectionRToL; + public const string FormatUnderlined = Material.Outlined.FormatUnderlined; + public const string Fort = Material.Outlined.Fort; + public const string Forum = Material.Outlined.Forum; + public const string Forward = Material.Outlined.Forward; + public const string Forward10 = Material.Outlined.Forward10; + public const string Forward30 = Material.Outlined.Forward30; + public const string Forward5 = Material.Outlined.Forward5; + public const string ForwardToInbox = Material.Outlined.ForwardToInbox; + public const string Foundation = Material.Outlined.Foundation; + public const string FreeBreakfast = Material.Outlined.FreeBreakfast; + public const string FreeCancellation = Material.Outlined.FreeCancellation; + public const string FrontHand = Material.Outlined.FrontHand; + public const string Fullscreen = Material.Outlined.Fullscreen; + public const string FullscreenExit = Material.Outlined.FullscreenExit; + public const string Functions = Material.Outlined.Functions; + public const string GMobiledata = Material.Outlined.GMobiledata; + public const string GTranslate = Material.Outlined.GTranslate; + public const string Gamepad = Material.Outlined.Gamepad; + public const string Games = Material.Outlined.Games; + public const string Garage = Material.Outlined.Garage; + public const string Gavel = Material.Outlined.Gavel; + public const string GeneratingTokens = Material.Outlined.GeneratingTokens; + public const string Gesture = Material.Outlined.Gesture; + public const string GetApp = Material.Outlined.GetApp; + public const string Gif = Material.Outlined.Gif; + public const string GifBox = Material.Outlined.GifBox; + public const string Girl = Material.Outlined.Girl; + public const string Gite = Material.Outlined.Gite; + public const string GolfCourse = Material.Outlined.GolfCourse; + public const string GppBad = Material.Outlined.GppBad; + public const string GppGood = Material.Outlined.GppGood; + public const string GppMaybe = Material.Outlined.GppMaybe; + public const string GpsFixed = Material.Outlined.GpsFixed; + public const string GpsNotFixed = Material.Outlined.GpsNotFixed; + public const string GpsOff = Material.Outlined.GpsOff; + public const string Grade = Material.Outlined.Grade; + public const string Gradient = Material.Outlined.Gradient; + public const string Grading = Material.Outlined.Grading; + public const string Grain = Material.Outlined.Grain; + public const string GraphicEq = Material.Outlined.GraphicEq; + public const string Grass = Material.Outlined.Grass; + public const string Grid3x3 = Material.Outlined.Grid3x3; + public const string Grid4x4 = Material.Outlined.Grid4x4; + public const string GridGoldenratio = Material.Outlined.GridGoldenratio; + public const string GridOff = Material.Outlined.GridOff; + public const string GridOn = Material.Outlined.GridOn; + public const string GridView = Material.Outlined.GridView; + public const string Group = Material.Outlined.Group; + public const string GroupAdd = Material.Outlined.GroupAdd; + public const string GroupOff = Material.Outlined.GroupOff; + public const string GroupRemove = Material.Outlined.GroupRemove; + public const string GroupWork = Material.Outlined.GroupWork; + public const string Groups = Material.Outlined.Groups; + public const string HMobiledata = Material.Outlined.HMobiledata; + public const string HPlusMobiledata = Material.Outlined.HPlusMobiledata; + public const string Hail = Material.Outlined.Hail; + public const string Handshake = Material.Outlined.Handshake; + public const string Handyman = Material.Outlined.Handyman; + public const string Hardware = Material.Outlined.Hardware; + public const string Hd = Material.Outlined.Hd; + public const string HdrAuto = Material.Outlined.HdrAuto; + public const string HdrAutoSelect = Material.Outlined.HdrAutoSelect; + public const string HdrEnhancedSelect = Material.Outlined.HdrEnhancedSelect; + public const string HdrOff = Material.Outlined.HdrOff; + public const string HdrOffSelect = Material.Outlined.HdrOffSelect; + public const string HdrOn = Material.Outlined.HdrOn; + public const string HdrOnSelect = Material.Outlined.HdrOnSelect; + public const string HdrPlus = Material.Outlined.HdrPlus; + public const string HdrStrong = Material.Outlined.HdrStrong; + public const string HdrWeak = Material.Outlined.HdrWeak; + public const string Headphones = Material.Outlined.Headphones; + public const string HeadphonesBattery = Material.Outlined.HeadphonesBattery; + public const string Headset = Material.Outlined.Headset; + public const string HeadsetMic = Material.Outlined.HeadsetMic; + public const string HeadsetOff = Material.Outlined.HeadsetOff; + public const string Healing = Material.Outlined.Healing; + public const string HealthAndSafety = Material.Outlined.HealthAndSafety; + public const string Hearing = Material.Outlined.Hearing; + public const string HearingDisabled = Material.Outlined.HearingDisabled; + public const string HeartBroken = Material.Outlined.HeartBroken; + public const string Height = Material.Outlined.Height; + public const string Help = Material.Outlined.Help; + public const string HelpCenter = Material.Outlined.HelpCenter; + public const string HelpOutline = Material.Outlined.HelpOutline; + public const string Hevc = Material.Outlined.Hevc; + public const string Hexagon = Material.Outlined.Hexagon; + public const string HideImage = Material.Outlined.HideImage; + public const string HideSource = Material.Outlined.HideSource; + public const string HighQuality = Material.Outlined.HighQuality; + public const string Highlight = Material.Outlined.Highlight; + public const string HighlightAlt = Material.Outlined.HighlightAlt; + public const string HighlightOff = Material.Outlined.HighlightOff; + public const string Hiking = Material.Outlined.Hiking; + public const string History = Material.Outlined.History; + public const string HistoryEdu = Material.Outlined.HistoryEdu; + public const string HistoryToggleOff = Material.Outlined.HistoryToggleOff; + public const string Hive = Material.Outlined.Hive; + public const string Hls = Material.Outlined.Hls; + public const string HlsOff = Material.Outlined.HlsOff; + public const string HolidayVillage = Material.Outlined.HolidayVillage; + public const string Home = Material.Outlined.Home; + public const string HomeMax = Material.Outlined.HomeMax; + public const string HomeMini = Material.Outlined.HomeMini; + public const string HomeRepairService = Material.Outlined.HomeRepairService; + public const string HomeWork = Material.Outlined.HomeWork; + public const string HorizontalDistribute = Material.Outlined.HorizontalDistribute; + public const string HorizontalRule = Material.Outlined.HorizontalRule; + public const string HorizontalSplit = Material.Outlined.HorizontalSplit; + public const string HotTub = Material.Outlined.HotTub; + public const string Hotel = Material.Outlined.Hotel; + public const string HotelClass = Material.Outlined.HotelClass; + public const string HourglassBottom = Material.Outlined.HourglassBottom; + public const string HourglassDisabled = Material.Outlined.HourglassDisabled; + public const string HourglassEmpty = Material.Outlined.HourglassEmpty; + public const string HourglassFull = Material.Outlined.HourglassFull; + public const string HourglassTop = Material.Outlined.HourglassTop; + public const string House = Material.Outlined.House; + public const string HouseSiding = Material.Outlined.HouseSiding; + public const string Houseboat = Material.Outlined.Houseboat; + public const string HowToReg = Material.Outlined.HowToReg; + public const string HowToVote = Material.Outlined.HowToVote; + public const string Html = Material.Outlined.Html; + public const string Http = Material.Outlined.Http; + public const string Https = Material.Outlined.Https; + public const string Hub = Material.Outlined.Hub; + public const string Hvac = Material.Outlined.Hvac; + public const string IceSkating = Material.Outlined.IceSkating; + public const string Icecream = Material.Outlined.Icecream; + public const string Image = Material.Outlined.Image; + public const string ImageAspectRatio = Material.Outlined.ImageAspectRatio; + public const string ImageNotSupported = Material.Outlined.ImageNotSupported; + public const string ImageSearch = Material.Outlined.ImageSearch; + public const string ImagesearchRoller = Material.Outlined.ImagesearchRoller; + public const string ImportContacts = Material.Outlined.ImportContacts; + public const string ImportExport = Material.Outlined.ImportExport; + public const string ImportantDevices = Material.Outlined.ImportantDevices; + public const string Inbox = Material.Outlined.Inbox; + public const string IncompleteCircle = Material.Outlined.IncompleteCircle; + public const string IndeterminateCheckBox = Material.Outlined.IndeterminateCheckBox; + public const string Info = Material.Outlined.Info; + public const string Input = Material.Outlined.Input; + public const string InsertChart = Material.Outlined.InsertChart; + public const string InsertChartOutlined = Material.Outlined.InsertChartOutlined; + public const string InsertComment = Material.Outlined.InsertComment; + public const string InsertDriveFile = Material.Outlined.InsertDriveFile; + public const string InsertEmoticon = Material.Outlined.InsertEmoticon; + public const string InsertInvitation = Material.Outlined.InsertInvitation; + public const string InsertLink = Material.Outlined.InsertLink; + public const string InsertPageBreak = Material.Outlined.InsertPageBreak; + public const string InsertPhoto = Material.Outlined.InsertPhoto; + public const string Insights = Material.Outlined.Insights; + public const string InstallDesktop = Material.Outlined.InstallDesktop; + public const string InstallMobile = Material.Outlined.InstallMobile; + public const string IntegrationInstructions = Material.Outlined.IntegrationInstructions; + public const string Interests = Material.Outlined.Interests; + public const string InterpreterMode = Material.Outlined.InterpreterMode; + public const string Inventory = Material.Outlined.Inventory; + public const string Inventory2 = Material.Outlined.Inventory2; + public const string InvertColors = Material.Outlined.InvertColors; + public const string InvertColorsOff = Material.Outlined.InvertColorsOff; + public const string IosShare = Material.Outlined.IosShare; + public const string Iron = Material.Outlined.Iron; + public const string Iso = Material.Outlined.Iso; + public const string Javascript = Material.Outlined.Javascript; + public const string JoinFull = Material.Outlined.JoinFull; + public const string JoinInner = Material.Outlined.JoinInner; + public const string JoinLeft = Material.Outlined.JoinLeft; + public const string JoinRight = Material.Outlined.JoinRight; + public const string Kayaking = Material.Outlined.Kayaking; + public const string KebabDining = Material.Outlined.KebabDining; + public const string Key = Material.Outlined.Key; + public const string KeyOff = Material.Outlined.KeyOff; + public const string Keyboard = Material.Outlined.Keyboard; + public const string KeyboardAlt = Material.Outlined.KeyboardAlt; + public const string KeyboardArrowDown = Material.Outlined.KeyboardArrowDown; + public const string KeyboardArrowLeft = Material.Outlined.KeyboardArrowLeft; + public const string KeyboardArrowRight = Material.Outlined.KeyboardArrowRight; + public const string KeyboardArrowUp = Material.Outlined.KeyboardArrowUp; + public const string KeyboardBackspace = Material.Outlined.KeyboardBackspace; + public const string KeyboardCapslock = Material.Outlined.KeyboardCapslock; + public const string KeyboardCommandKey = Material.Outlined.KeyboardCommandKey; + public const string KeyboardControlKey = Material.Outlined.KeyboardControlKey; + public const string KeyboardDoubleArrowDown = Material.Outlined.KeyboardDoubleArrowDown; + public const string KeyboardDoubleArrowLeft = Material.Outlined.KeyboardDoubleArrowLeft; + public const string KeyboardDoubleArrowRight = Material.Outlined.KeyboardDoubleArrowRight; + public const string KeyboardDoubleArrowUp = Material.Outlined.KeyboardDoubleArrowUp; + public const string KeyboardHide = Material.Outlined.KeyboardHide; + public const string KeyboardOptionKey = Material.Outlined.KeyboardOptionKey; + public const string KeyboardReturn = Material.Outlined.KeyboardReturn; + public const string KeyboardTab = Material.Outlined.KeyboardTab; + public const string KeyboardVoice = Material.Outlined.KeyboardVoice; + public const string KingBed = Material.Outlined.KingBed; + public const string Kitchen = Material.Outlined.Kitchen; + public const string Kitesurfing = Material.Outlined.Kitesurfing; + public const string Label = Material.Outlined.Label; + public const string LabelImportant = Material.Outlined.LabelImportant; + public const string LabelOff = Material.Outlined.LabelOff; + public const string Lan = Material.Outlined.Lan; + public const string Landscape = Material.Outlined.Landscape; + public const string Landslide = Material.Outlined.Landslide; + public const string Language = Material.Outlined.Language; + public const string Laptop = Material.Outlined.Laptop; + public const string LaptopChromebook = Material.Outlined.LaptopChromebook; + public const string LaptopMac = Material.Outlined.LaptopMac; + public const string LaptopWindows = Material.Outlined.LaptopWindows; + public const string LastPage = Material.Outlined.LastPage; + public const string Launch = Material.Outlined.Launch; + public const string Layers = Material.Outlined.Layers; + public const string LayersClear = Material.Outlined.LayersClear; + public const string Leaderboard = Material.Outlined.Leaderboard; + public const string LeakAdd = Material.Outlined.LeakAdd; + public const string LeakRemove = Material.Outlined.LeakRemove; + public const string LegendToggle = Material.Outlined.LegendToggle; + public const string Lens = Material.Outlined.Lens; + public const string LensBlur = Material.Outlined.LensBlur; + public const string LibraryAdd = Material.Outlined.LibraryAdd; + public const string LibraryAddCheck = Material.Outlined.LibraryAddCheck; + public const string LibraryBooks = Material.Outlined.LibraryBooks; + public const string LibraryMusic = Material.Outlined.LibraryMusic; + public const string Light = Material.Outlined.Light; + public const string LightMode = Material.Outlined.LightMode; + public const string Lightbulb = Material.Outlined.Lightbulb; + public const string LightbulbCircle = Material.Outlined.LightbulbCircle; + public const string LineAxis = Material.Outlined.LineAxis; + public const string LineStyle = Material.Outlined.LineStyle; + public const string LineWeight = Material.Outlined.LineWeight; + public const string LinearScale = Material.Outlined.LinearScale; + public const string Link = Material.Outlined.Link; + public const string LinkOff = Material.Outlined.LinkOff; + public const string LinkedCamera = Material.Outlined.LinkedCamera; + public const string Liquor = Material.Outlined.Liquor; + public const string List = Material.Outlined.List; + public const string ListAlt = Material.Outlined.ListAlt; + public const string LiveHelp = Material.Outlined.LiveHelp; + public const string LiveTv = Material.Outlined.LiveTv; + public const string Living = Material.Outlined.Living; + public const string LocalActivity = Material.Outlined.LocalActivity; + public const string LocalAirport = Material.Outlined.LocalAirport; + public const string LocalAtm = Material.Outlined.LocalAtm; + public const string LocalBar = Material.Outlined.LocalBar; + public const string LocalCafe = Material.Outlined.LocalCafe; + public const string LocalCarWash = Material.Outlined.LocalCarWash; + public const string LocalConvenienceStore = Material.Outlined.LocalConvenienceStore; + public const string LocalDining = Material.Outlined.LocalDining; + public const string LocalDrink = Material.Outlined.LocalDrink; + public const string LocalFireDepartment = Material.Outlined.LocalFireDepartment; + public const string LocalFlorist = Material.Outlined.LocalFlorist; + public const string LocalGasStation = Material.Outlined.LocalGasStation; + public const string LocalGroceryStore = Material.Outlined.LocalGroceryStore; + public const string LocalHospital = Material.Outlined.LocalHospital; + public const string LocalHotel = Material.Outlined.LocalHotel; + public const string LocalLaundryService = Material.Outlined.LocalLaundryService; + public const string LocalLibrary = Material.Outlined.LocalLibrary; + public const string LocalMall = Material.Outlined.LocalMall; + public const string LocalMovies = Material.Outlined.LocalMovies; + public const string LocalOffer = Material.Outlined.LocalOffer; + public const string LocalParking = Material.Outlined.LocalParking; + public const string LocalPharmacy = Material.Outlined.LocalPharmacy; + public const string LocalPhone = Material.Outlined.LocalPhone; + public const string LocalPizza = Material.Outlined.LocalPizza; + public const string LocalPlay = Material.Outlined.LocalPlay; + public const string LocalPolice = Material.Outlined.LocalPolice; + public const string LocalPostOffice = Material.Outlined.LocalPostOffice; + public const string LocalPrintshop = Material.Outlined.LocalPrintshop; + public const string LocalSee = Material.Outlined.LocalSee; + public const string LocalShipping = Material.Outlined.LocalShipping; + public const string LocalTaxi = Material.Outlined.LocalTaxi; + public const string LocationCity = Material.Outlined.LocationCity; + public const string LocationDisabled = Material.Outlined.LocationDisabled; + public const string LocationOff = Material.Outlined.LocationOff; + public const string LocationOn = Material.Outlined.LocationOn; + public const string LocationSearching = Material.Outlined.LocationSearching; + public const string Lock = Material.Outlined.Lock; + public const string LockClock = Material.Outlined.LockClock; + public const string LockOpen = Material.Outlined.LockOpen; + public const string LockReset = Material.Outlined.LockReset; + public const string Login = Material.Outlined.Login; + public const string LogoDev = Material.Outlined.LogoDev; + public const string Logout = Material.Outlined.Logout; + public const string Looks = Material.Outlined.Looks; + public const string Looks3 = Material.Outlined.Looks3; + public const string Looks4 = Material.Outlined.Looks4; + public const string Looks5 = Material.Outlined.Looks5; + public const string Looks6 = Material.Outlined.Looks6; + public const string LooksOne = Material.Outlined.LooksOne; + public const string LooksTwo = Material.Outlined.LooksTwo; + public const string Loop = Material.Outlined.Loop; + public const string Loupe = Material.Outlined.Loupe; + public const string LowPriority = Material.Outlined.LowPriority; + public const string Loyalty = Material.Outlined.Loyalty; + public const string LteMobiledata = Material.Outlined.LteMobiledata; + public const string LtePlusMobiledata = Material.Outlined.LtePlusMobiledata; + public const string Luggage = Material.Outlined.Luggage; + public const string LunchDining = Material.Outlined.LunchDining; + public const string Mail = Material.Outlined.Mail; + public const string MailOutline = Material.Outlined.MailOutline; + public const string Male = Material.Outlined.Male; + public const string Man = Material.Outlined.Man; + public const string ManageAccounts = Material.Outlined.ManageAccounts; + public const string ManageHistory = Material.Outlined.ManageHistory; + public const string ManageSearch = Material.Outlined.ManageSearch; + public const string Map = Material.Outlined.Map; + public const string MapsHomeWork = Material.Outlined.MapsHomeWork; + public const string MapsUgc = Material.Outlined.MapsUgc; + public const string Margin = Material.Outlined.Margin; + public const string MarkAsUnread = Material.Outlined.MarkAsUnread; + public const string MarkChatRead = Material.Outlined.MarkChatRead; + public const string MarkChatUnread = Material.Outlined.MarkChatUnread; + public const string MarkEmailRead = Material.Outlined.MarkEmailRead; + public const string MarkEmailUnread = Material.Outlined.MarkEmailUnread; + public const string MarkUnreadChatAlt = Material.Outlined.MarkUnreadChatAlt; + public const string Markunread = Material.Outlined.Markunread; + public const string MarkunreadMailbox = Material.Outlined.MarkunreadMailbox; + public const string Masks = Material.Outlined.Masks; + public const string Maximize = Material.Outlined.Maximize; + public const string MediaBluetoothOff = Material.Outlined.MediaBluetoothOff; + public const string MediaBluetoothOn = Material.Outlined.MediaBluetoothOn; + public const string Mediation = Material.Outlined.Mediation; + public const string MedicalInformation = Material.Outlined.MedicalInformation; + public const string MedicalServices = Material.Outlined.MedicalServices; + public const string Medication = Material.Outlined.Medication; + public const string MedicationLiquid = Material.Outlined.MedicationLiquid; + public const string MeetingRoom = Material.Outlined.MeetingRoom; + public const string Memory = Material.Outlined.Memory; + public const string Menu = Material.Outlined.Menu; + public const string MenuBook = Material.Outlined.MenuBook; + public const string MenuOpen = Material.Outlined.MenuOpen; + public const string Merge = Material.Outlined.Merge; + public const string MergeType = Material.Outlined.MergeType; + public const string Message = Material.Outlined.Message; + public const string Mic = Material.Outlined.Mic; + public const string MicExternalOff = Material.Outlined.MicExternalOff; + public const string MicExternalOn = Material.Outlined.MicExternalOn; + public const string MicNone = Material.Outlined.MicNone; + public const string MicOff = Material.Outlined.MicOff; + public const string Microwave = Material.Outlined.Microwave; + public const string MilitaryTech = Material.Outlined.MilitaryTech; + public const string Minimize = Material.Outlined.Minimize; + public const string MinorCrash = Material.Outlined.MinorCrash; + public const string MiscellaneousServices = Material.Outlined.MiscellaneousServices; + public const string MissedVideoCall = Material.Outlined.MissedVideoCall; + public const string Mms = Material.Outlined.Mms; + public const string MobileFriendly = Material.Outlined.MobileFriendly; + public const string MobileOff = Material.Outlined.MobileOff; + public const string MobileScreenShare = Material.Outlined.MobileScreenShare; + public const string MobiledataOff = Material.Outlined.MobiledataOff; + public const string Mode = Material.Outlined.Mode; + public const string ModeComment = Material.Outlined.ModeComment; + public const string ModeEdit = Material.Outlined.ModeEdit; + public const string ModeEditOutline = Material.Outlined.ModeEditOutline; + public const string ModeNight = Material.Outlined.ModeNight; + public const string ModeOfTravel = Material.Outlined.ModeOfTravel; + public const string ModeStandby = Material.Outlined.ModeStandby; + public const string ModelTraining = Material.Outlined.ModelTraining; + public const string MonetizationOn = Material.Outlined.MonetizationOn; + public const string Money = Material.Outlined.Money; + public const string MoneyOff = Material.Outlined.MoneyOff; + public const string MoneyOffCsred = Material.Outlined.MoneyOffCsred; + public const string Monitor = Material.Outlined.Monitor; + public const string MonitorHeart = Material.Outlined.MonitorHeart; + public const string MonitorWeight = Material.Outlined.MonitorWeight; + public const string MonochromePhotos = Material.Outlined.MonochromePhotos; + public const string Mood = Material.Outlined.Mood; + public const string MoodBad = Material.Outlined.MoodBad; + public const string Moped = Material.Outlined.Moped; + public const string More = Material.Outlined.More; + public const string MoreHoriz = Material.Outlined.MoreHoriz; + public const string MoreTime = Material.Outlined.MoreTime; + public const string MoreVert = Material.Outlined.MoreVert; + public const string Mosque = Material.Outlined.Mosque; + public const string MotionPhotosAuto = Material.Outlined.MotionPhotosAuto; + public const string MotionPhotosOff = Material.Outlined.MotionPhotosOff; + public const string MotionPhotosOn = Material.Outlined.MotionPhotosOn; + public const string MotionPhotosPause = Material.Outlined.MotionPhotosPause; + public const string MotionPhotosPaused = Material.Outlined.MotionPhotosPaused; + public const string Mouse = Material.Outlined.Mouse; + public const string MoveDown = Material.Outlined.MoveDown; + public const string MoveToInbox = Material.Outlined.MoveToInbox; + public const string MoveUp = Material.Outlined.MoveUp; + public const string Movie = Material.Outlined.Movie; + public const string MovieCreation = Material.Outlined.MovieCreation; + public const string MovieFilter = Material.Outlined.MovieFilter; + public const string Moving = Material.Outlined.Moving; + public const string Mp = Material.Outlined.Mp; + public const string MultilineChart = Material.Outlined.MultilineChart; + public const string MultipleStop = Material.Outlined.MultipleStop; + public const string Museum = Material.Outlined.Museum; + public const string MusicNote = Material.Outlined.MusicNote; + public const string MusicOff = Material.Outlined.MusicOff; + public const string MusicVideo = Material.Outlined.MusicVideo; + public const string MyLocation = Material.Outlined.MyLocation; + public const string Nat = Material.Outlined.Nat; + public const string Nature = Material.Outlined.Nature; + public const string NaturePeople = Material.Outlined.NaturePeople; + public const string NavigateBefore = Material.Outlined.NavigateBefore; + public const string NavigateNext = Material.Outlined.NavigateNext; + public const string Navigation = Material.Outlined.Navigation; + public const string NearMe = Material.Outlined.NearMe; + public const string NearMeDisabled = Material.Outlined.NearMeDisabled; + public const string NearbyError = Material.Outlined.NearbyError; + public const string NearbyOff = Material.Outlined.NearbyOff; + public const string NetworkCell = Material.Outlined.NetworkCell; + public const string NetworkCheck = Material.Outlined.NetworkCheck; + public const string NetworkLocked = Material.Outlined.NetworkLocked; + public const string NetworkPing = Material.Outlined.NetworkPing; + public const string NetworkWifi = Material.Outlined.NetworkWifi; + public const string NetworkWifi1Bar = Material.Outlined.NetworkWifi1Bar; + public const string NetworkWifi2Bar = Material.Outlined.NetworkWifi2Bar; + public const string NetworkWifi3Bar = Material.Outlined.NetworkWifi3Bar; + public const string NewLabel = Material.Outlined.NewLabel; + public const string NewReleases = Material.Outlined.NewReleases; + public const string Newspaper = Material.Outlined.Newspaper; + public const string NextPlan = Material.Outlined.NextPlan; + public const string NextWeek = Material.Outlined.NextWeek; + public const string Nfc = Material.Outlined.Nfc; + public const string NightShelter = Material.Outlined.NightShelter; + public const string Nightlife = Material.Outlined.Nightlife; + public const string Nightlight = Material.Outlined.Nightlight; + public const string NightlightRound = Material.Outlined.NightlightRound; + public const string NightsStay = Material.Outlined.NightsStay; + public const string NoAccounts = Material.Outlined.NoAccounts; + public const string NoBackpack = Material.Outlined.NoBackpack; + public const string NoCell = Material.Outlined.NoCell; + public const string NoCrash = Material.Outlined.NoCrash; + public const string NoDrinks = Material.Outlined.NoDrinks; + public const string NoEncryption = Material.Outlined.NoEncryption; + public const string NoEncryptionGmailerrorred = Material.Outlined.NoEncryptionGmailerrorred; + public const string NoFlash = Material.Outlined.NoFlash; + public const string NoFood = Material.Outlined.NoFood; + public const string NoLuggage = Material.Outlined.NoLuggage; + public const string NoMeals = Material.Outlined.NoMeals; + public const string NoMeetingRoom = Material.Outlined.NoMeetingRoom; + public const string NoPhotography = Material.Outlined.NoPhotography; + public const string NoSim = Material.Outlined.NoSim; + public const string NoStroller = Material.Outlined.NoStroller; + public const string NoTransfer = Material.Outlined.NoTransfer; + public const string NoiseAware = Material.Outlined.NoiseAware; + public const string NoiseControlOff = Material.Outlined.NoiseControlOff; + public const string NordicWalking = Material.Outlined.NordicWalking; + public const string North = Material.Outlined.North; + public const string NorthEast = Material.Outlined.NorthEast; + public const string NorthWest = Material.Outlined.NorthWest; + public const string NotAccessible = Material.Outlined.NotAccessible; + public const string NotInterested = Material.Outlined.NotInterested; + public const string NotListedLocation = Material.Outlined.NotListedLocation; + public const string NotStarted = Material.Outlined.NotStarted; + public const string Note = Material.Outlined.Note; + public const string NoteAdd = Material.Outlined.NoteAdd; + public const string NoteAlt = Material.Outlined.NoteAlt; + public const string Notes = Material.Outlined.Notes; + public const string NotificationAdd = Material.Outlined.NotificationAdd; + public const string NotificationImportant = Material.Outlined.NotificationImportant; + public const string Notifications = Material.Outlined.Notifications; + public const string NotificationsActive = Material.Outlined.NotificationsActive; + public const string NotificationsNone = Material.Outlined.NotificationsNone; + public const string NotificationsOff = Material.Outlined.NotificationsOff; + public const string NotificationsPaused = Material.Outlined.NotificationsPaused; + public const string Numbers = Material.Outlined.Numbers; + public const string OfflineBolt = Material.Outlined.OfflineBolt; + public const string OfflinePin = Material.Outlined.OfflinePin; + public const string OfflineShare = Material.Outlined.OfflineShare; + public const string OnDeviceTraining = Material.Outlined.OnDeviceTraining; + public const string OndemandVideo = Material.Outlined.OndemandVideo; + public const string OnlinePrediction = Material.Outlined.OnlinePrediction; + public const string Opacity = Material.Outlined.Opacity; + public const string OpenInBrowser = Material.Outlined.OpenInBrowser; + public const string OpenInFull = Material.Outlined.OpenInFull; + public const string OpenInNew = Material.Outlined.OpenInNew; + public const string OpenInNewOff = Material.Outlined.OpenInNewOff; + public const string OpenWith = Material.Outlined.OpenWith; + public const string OtherHouses = Material.Outlined.OtherHouses; + public const string Outbound = Material.Outlined.Outbound; + public const string Outbox = Material.Outlined.Outbox; + public const string OutdoorGrill = Material.Outlined.OutdoorGrill; + public const string Outlet = Material.Outlined.Outlet; + public const string OutlinedFlag = Material.Outlined.OutlinedFlag; + public const string Output = Material.Outlined.Output; + public const string Padding = Material.Outlined.Padding; + public const string Pages = Material.Outlined.Pages; + public const string Pageview = Material.Outlined.Pageview; + public const string Paid = Material.Outlined.Paid; + public const string Palette = Material.Outlined.Palette; + public const string PanTool = Material.Outlined.PanTool; + public const string PanToolAlt = Material.Outlined.PanToolAlt; + public const string Panorama = Material.Outlined.Panorama; + public const string PanoramaFishEye = Material.Outlined.PanoramaFishEye; + public const string PanoramaHorizontal = Material.Outlined.PanoramaHorizontal; + public const string PanoramaHorizontalSelect = Material.Outlined.PanoramaHorizontalSelect; + public const string PanoramaPhotosphere = Material.Outlined.PanoramaPhotosphere; + public const string PanoramaPhotosphereSelect = Material.Outlined.PanoramaPhotosphereSelect; + public const string PanoramaVertical = Material.Outlined.PanoramaVertical; + public const string PanoramaVerticalSelect = Material.Outlined.PanoramaVerticalSelect; + public const string PanoramaWideAngle = Material.Outlined.PanoramaWideAngle; + public const string PanoramaWideAngleSelect = Material.Outlined.PanoramaWideAngleSelect; + public const string Paragliding = Material.Outlined.Paragliding; + public const string Park = Material.Outlined.Park; + public const string PartyMode = Material.Outlined.PartyMode; + public const string Password = Material.Outlined.Password; + public const string Pattern = Material.Outlined.Pattern; + public const string Pause = Material.Outlined.Pause; + public const string PauseCircle = Material.Outlined.PauseCircle; + public const string PauseCircleFilled = Material.Outlined.PauseCircleFilled; + public const string PauseCircleOutline = Material.Outlined.PauseCircleOutline; + public const string PausePresentation = Material.Outlined.PausePresentation; + public const string Payment = Material.Outlined.Payment; + public const string Payments = Material.Outlined.Payments; + public const string PedalBike = Material.Outlined.PedalBike; + public const string Pending = Material.Outlined.Pending; + public const string PendingActions = Material.Outlined.PendingActions; + public const string Pentagon = Material.Outlined.Pentagon; + public const string People = Material.Outlined.People; + public const string PeopleAlt = Material.Outlined.PeopleAlt; + public const string PeopleOutline = Material.Outlined.PeopleOutline; + public const string Percent = Material.Outlined.Percent; + public const string PermCameraMic = Material.Outlined.PermCameraMic; + public const string PermContactCalendar = Material.Outlined.PermContactCalendar; + public const string PermDataSetting = Material.Outlined.PermDataSetting; + public const string PermDeviceInformation = Material.Outlined.PermDeviceInformation; + public const string PermIdentity = Material.Outlined.PermIdentity; + public const string PermMedia = Material.Outlined.PermMedia; + public const string PermPhoneMsg = Material.Outlined.PermPhoneMsg; + public const string PermScanWifi = Material.Outlined.PermScanWifi; + public const string Person = Material.Outlined.Person; + public const string PersonAdd = Material.Outlined.PersonAdd; + public const string PersonAddAlt = Material.Outlined.PersonAddAlt; + public const string PersonAddAlt1 = Material.Outlined.PersonAddAlt1; + public const string PersonAddDisabled = Material.Outlined.PersonAddDisabled; + public const string PersonOff = Material.Outlined.PersonOff; + public const string PersonOutline = Material.Outlined.PersonOutline; + public const string PersonPin = Material.Outlined.PersonPin; + public const string PersonPinCircle = Material.Outlined.PersonPinCircle; + public const string PersonRemove = Material.Outlined.PersonRemove; + public const string PersonRemoveAlt1 = Material.Outlined.PersonRemoveAlt1; + public const string PersonSearch = Material.Outlined.PersonSearch; + public const string PersonalInjury = Material.Outlined.PersonalInjury; + public const string PersonalVideo = Material.Outlined.PersonalVideo; + public const string PestControl = Material.Outlined.PestControl; + public const string PestControlRodent = Material.Outlined.PestControlRodent; + public const string Pets = Material.Outlined.Pets; + public const string Phishing = Material.Outlined.Phishing; + public const string Phone = Material.Outlined.Phone; + public const string PhoneAndroid = Material.Outlined.PhoneAndroid; + public const string PhoneBluetoothSpeaker = Material.Outlined.PhoneBluetoothSpeaker; + public const string PhoneCallback = Material.Outlined.PhoneCallback; + public const string PhoneDisabled = Material.Outlined.PhoneDisabled; + public const string PhoneEnabled = Material.Outlined.PhoneEnabled; + public const string PhoneForwarded = Material.Outlined.PhoneForwarded; + public const string PhoneInTalk = Material.Outlined.PhoneInTalk; + public const string PhoneIphone = Material.Outlined.PhoneIphone; + public const string PhoneLocked = Material.Outlined.PhoneLocked; + public const string PhoneMissed = Material.Outlined.PhoneMissed; + public const string PhonePaused = Material.Outlined.PhonePaused; + public const string Phonelink = Material.Outlined.Phonelink; + public const string PhonelinkErase = Material.Outlined.PhonelinkErase; + public const string PhonelinkLock = Material.Outlined.PhonelinkLock; + public const string PhonelinkOff = Material.Outlined.PhonelinkOff; + public const string PhonelinkRing = Material.Outlined.PhonelinkRing; + public const string PhonelinkSetup = Material.Outlined.PhonelinkSetup; + public const string Photo = Material.Outlined.Photo; + public const string PhotoAlbum = Material.Outlined.PhotoAlbum; + public const string PhotoCamera = Material.Outlined.PhotoCamera; + public const string PhotoCameraBack = Material.Outlined.PhotoCameraBack; + public const string PhotoCameraFront = Material.Outlined.PhotoCameraFront; + public const string PhotoFilter = Material.Outlined.PhotoFilter; + public const string PhotoLibrary = Material.Outlined.PhotoLibrary; + public const string PhotoSizeSelectActual = Material.Outlined.PhotoSizeSelectActual; + public const string PhotoSizeSelectLarge = Material.Outlined.PhotoSizeSelectLarge; + public const string PhotoSizeSelectSmall = Material.Outlined.PhotoSizeSelectSmall; + public const string Php = Material.Outlined.Php; + public const string Piano = Material.Outlined.Piano; + public const string PianoOff = Material.Outlined.PianoOff; + public const string PictureAsPdf = Material.Outlined.PictureAsPdf; + public const string PictureInPicture = Material.Outlined.PictureInPicture; + public const string PictureInPictureAlt = Material.Outlined.PictureInPictureAlt; + public const string PieChart = Material.Outlined.PieChart; + public const string PieChartOutline = Material.Outlined.PieChartOutline; + public const string Pin = Material.Outlined.Pin; + public const string PinDrop = Material.Outlined.PinDrop; + public const string PinEnd = Material.Outlined.PinEnd; + public const string PinInvoke = Material.Outlined.PinInvoke; + public const string Pinch = Material.Outlined.Pinch; + public const string PivotTableChart = Material.Outlined.PivotTableChart; + public const string Pix = Material.Outlined.Pix; + public const string Place = Material.Outlined.Place; + public const string Plagiarism = Material.Outlined.Plagiarism; + public const string PlayArrow = Material.Outlined.PlayArrow; + public const string PlayCircle = Material.Outlined.PlayCircle; + public const string PlayCircleFilled = Material.Outlined.PlayCircleFilled; + public const string PlayCircleOutline = Material.Outlined.PlayCircleOutline; + public const string PlayDisabled = Material.Outlined.PlayDisabled; + public const string PlayForWork = Material.Outlined.PlayForWork; + public const string PlayLesson = Material.Outlined.PlayLesson; + public const string PlaylistAdd = Material.Outlined.PlaylistAdd; + public const string PlaylistAddCheck = Material.Outlined.PlaylistAddCheck; + public const string PlaylistAddCheckCircle = Material.Outlined.PlaylistAddCheckCircle; + public const string PlaylistAddCircle = Material.Outlined.PlaylistAddCircle; + public const string PlaylistPlay = Material.Outlined.PlaylistPlay; + public const string PlaylistRemove = Material.Outlined.PlaylistRemove; + public const string Plumbing = Material.Outlined.Plumbing; + public const string PlusOne = Material.Outlined.PlusOne; + public const string Podcasts = Material.Outlined.Podcasts; + public const string PointOfSale = Material.Outlined.PointOfSale; + public const string Policy = Material.Outlined.Policy; + public const string Poll = Material.Outlined.Poll; + public const string Polyline = Material.Outlined.Polyline; + public const string Polymer = Material.Outlined.Polymer; + public const string Pool = Material.Outlined.Pool; + public const string PortableWifiOff = Material.Outlined.PortableWifiOff; + public const string Portrait = Material.Outlined.Portrait; + public const string PostAdd = Material.Outlined.PostAdd; + public const string Power = Material.Outlined.Power; + public const string PowerInput = Material.Outlined.PowerInput; + public const string PowerOff = Material.Outlined.PowerOff; + public const string PowerSettingsNew = Material.Outlined.PowerSettingsNew; + public const string PrecisionManufacturing = Material.Outlined.PrecisionManufacturing; + public const string PregnantWoman = Material.Outlined.PregnantWoman; + public const string PresentToAll = Material.Outlined.PresentToAll; + public const string Preview = Material.Outlined.Preview; + public const string PriceChange = Material.Outlined.PriceChange; + public const string PriceCheck = Material.Outlined.PriceCheck; + public const string Print = Material.Outlined.Print; + public const string PrintDisabled = Material.Outlined.PrintDisabled; + public const string PriorityHigh = Material.Outlined.PriorityHigh; + public const string PrivacyTip = Material.Outlined.PrivacyTip; + public const string PrivateConnectivity = Material.Outlined.PrivateConnectivity; + public const string ProductionQuantityLimits = Material.Outlined.ProductionQuantityLimits; + public const string Psychology = Material.Outlined.Psychology; + public const string Public = Material.Outlined.Public; + public const string PublicOff = Material.Outlined.PublicOff; + public const string Publish = Material.Outlined.Publish; + public const string PublishedWithChanges = Material.Outlined.PublishedWithChanges; + public const string PunchClock = Material.Outlined.PunchClock; + public const string PushPin = Material.Outlined.PushPin; + public const string QrCode = Material.Outlined.QrCode; + public const string QrCode2 = Material.Outlined.QrCode2; + public const string QrCodeScanner = Material.Outlined.QrCodeScanner; + public const string QueryBuilder = Material.Outlined.QueryBuilder; + public const string QueryStats = Material.Outlined.QueryStats; + public const string QuestionAnswer = Material.Outlined.QuestionAnswer; + public const string QuestionMark = Material.Outlined.QuestionMark; + public const string Queue = Material.Outlined.Queue; + public const string QueueMusic = Material.Outlined.QueueMusic; + public const string QueuePlayNext = Material.Outlined.QueuePlayNext; + public const string Quickreply = Material.Outlined.Quickreply; + public const string Quiz = Material.Outlined.Quiz; + public const string RMobiledata = Material.Outlined.RMobiledata; + public const string Radar = Material.Outlined.Radar; + public const string Radio = Material.Outlined.Radio; + public const string RadioButtonChecked = Material.Outlined.RadioButtonChecked; + public const string RadioButtonUnchecked = Material.Outlined.RadioButtonUnchecked; + public const string RailwayAlert = Material.Outlined.RailwayAlert; + public const string RamenDining = Material.Outlined.RamenDining; + public const string RampLeft = Material.Outlined.RampLeft; + public const string RampRight = Material.Outlined.RampRight; + public const string RateReview = Material.Outlined.RateReview; + public const string RawOff = Material.Outlined.RawOff; + public const string RawOn = Material.Outlined.RawOn; + public const string ReadMore = Material.Outlined.ReadMore; + public const string RealEstateAgent = Material.Outlined.RealEstateAgent; + public const string Receipt = Material.Outlined.Receipt; + public const string ReceiptLong = Material.Outlined.ReceiptLong; + public const string RecentActors = Material.Outlined.RecentActors; + public const string Recommend = Material.Outlined.Recommend; + public const string RecordVoiceOver = Material.Outlined.RecordVoiceOver; + public const string Rectangle = Material.Outlined.Rectangle; + public const string Recycling = Material.Outlined.Recycling; + public const string Redeem = Material.Outlined.Redeem; + public const string Redo = Material.Outlined.Redo; + public const string ReduceCapacity = Material.Outlined.ReduceCapacity; + public const string Refresh = Material.Outlined.Refresh; + public const string RememberMe = Material.Outlined.RememberMe; + public const string Remove = Material.Outlined.Remove; + public const string RemoveCircle = Material.Outlined.RemoveCircle; + public const string RemoveCircleOutline = Material.Outlined.RemoveCircleOutline; + public const string RemoveDone = Material.Outlined.RemoveDone; + public const string RemoveFromQueue = Material.Outlined.RemoveFromQueue; + public const string RemoveModerator = Material.Outlined.RemoveModerator; + public const string RemoveRedEye = Material.Outlined.RemoveRedEye; + public const string RemoveRoad = Material.Outlined.RemoveRoad; + public const string RemoveShoppingCart = Material.Outlined.RemoveShoppingCart; + public const string Reorder = Material.Outlined.Reorder; + public const string Repeat = Material.Outlined.Repeat; + public const string RepeatOn = Material.Outlined.RepeatOn; + public const string RepeatOne = Material.Outlined.RepeatOne; + public const string RepeatOneOn = Material.Outlined.RepeatOneOn; + public const string Replay = Material.Outlined.Replay; + public const string Replay10 = Material.Outlined.Replay10; + public const string Replay30 = Material.Outlined.Replay30; + public const string Replay5 = Material.Outlined.Replay5; + public const string ReplayCircleFilled = Material.Outlined.ReplayCircleFilled; + public const string Reply = Material.Outlined.Reply; + public const string ReplyAll = Material.Outlined.ReplyAll; + public const string Report = Material.Outlined.Report; + public const string ReportGmailerrorred = Material.Outlined.ReportGmailerrorred; + public const string ReportOff = Material.Outlined.ReportOff; + public const string ReportProblem = Material.Outlined.ReportProblem; + public const string RequestPage = Material.Outlined.RequestPage; + public const string RequestQuote = Material.Outlined.RequestQuote; + public const string ResetTv = Material.Outlined.ResetTv; + public const string RestartAlt = Material.Outlined.RestartAlt; + public const string Restaurant = Material.Outlined.Restaurant; + public const string RestaurantMenu = Material.Outlined.RestaurantMenu; + public const string Restore = Material.Outlined.Restore; + public const string RestoreFromTrash = Material.Outlined.RestoreFromTrash; + public const string RestorePage = Material.Outlined.RestorePage; + public const string Reviews = Material.Outlined.Reviews; + public const string RiceBowl = Material.Outlined.RiceBowl; + public const string RingVolume = Material.Outlined.RingVolume; + public const string Rocket = Material.Outlined.Rocket; + public const string RocketLaunch = Material.Outlined.RocketLaunch; + public const string RollerSkating = Material.Outlined.RollerSkating; + public const string Roofing = Material.Outlined.Roofing; + public const string Room = Material.Outlined.Room; + public const string RoomPreferences = Material.Outlined.RoomPreferences; + public const string RoomService = Material.Outlined.RoomService; + public const string Rotate90DegreesCcw = Material.Outlined.Rotate90DegreesCcw; + public const string Rotate90DegreesCw = Material.Outlined.Rotate90DegreesCw; + public const string RotateLeft = Material.Outlined.RotateLeft; + public const string RotateRight = Material.Outlined.RotateRight; + public const string RoundaboutLeft = Material.Outlined.RoundaboutLeft; + public const string RoundaboutRight = Material.Outlined.RoundaboutRight; + public const string RoundedCorner = Material.Outlined.RoundedCorner; + public const string Route = Material.Outlined.Route; + public const string Router = Material.Outlined.Router; + public const string Rowing = Material.Outlined.Rowing; + public const string RssFeed = Material.Outlined.RssFeed; + public const string Rsvp = Material.Outlined.Rsvp; + public const string Rtt = Material.Outlined.Rtt; + public const string Rule = Material.Outlined.Rule; + public const string RuleFolder = Material.Outlined.RuleFolder; + public const string RunCircle = Material.Outlined.RunCircle; + public const string RunningWithErrors = Material.Outlined.RunningWithErrors; + public const string RvHookup = Material.Outlined.RvHookup; + public const string SafetyCheck = Material.Outlined.SafetyCheck; + public const string SafetyDivider = Material.Outlined.SafetyDivider; + public const string Sailing = Material.Outlined.Sailing; + public const string Sanitizer = Material.Outlined.Sanitizer; + public const string Satellite = Material.Outlined.Satellite; + public const string SatelliteAlt = Material.Outlined.SatelliteAlt; + public const string Save = Material.Outlined.Save; + public const string SaveAlt = Material.Outlined.SaveAlt; + public const string SaveAs = Material.Outlined.SaveAs; + public const string SavedSearch = Material.Outlined.SavedSearch; + public const string Savings = Material.Outlined.Savings; + public const string Scale = Material.Outlined.Scale; + public const string Scanner = Material.Outlined.Scanner; + public const string ScatterPlot = Material.Outlined.ScatterPlot; + public const string Schedule = Material.Outlined.Schedule; + public const string ScheduleSend = Material.Outlined.ScheduleSend; + public const string Schema = Material.Outlined.Schema; + public const string School = Material.Outlined.School; + public const string Science = Material.Outlined.Science; + public const string Score = Material.Outlined.Score; + public const string Scoreboard = Material.Outlined.Scoreboard; + public const string ScreenLockLandscape = Material.Outlined.ScreenLockLandscape; + public const string ScreenLockPortrait = Material.Outlined.ScreenLockPortrait; + public const string ScreenLockRotation = Material.Outlined.ScreenLockRotation; + public const string ScreenRotation = Material.Outlined.ScreenRotation; + public const string ScreenRotationAlt = Material.Outlined.ScreenRotationAlt; + public const string ScreenSearchDesktop = Material.Outlined.ScreenSearchDesktop; + public const string ScreenShare = Material.Outlined.ScreenShare; + public const string Screenshot = Material.Outlined.Screenshot; + public const string ScubaDiving = Material.Outlined.ScubaDiving; + public const string Sd = Material.Outlined.Sd; + public const string SdCard = Material.Outlined.SdCard; + public const string SdCardAlert = Material.Outlined.SdCardAlert; + public const string SdStorage = Material.Outlined.SdStorage; + public const string Search = Material.Outlined.Search; + public const string SearchOff = Material.Outlined.SearchOff; + public const string Security = Material.Outlined.Security; + public const string SecurityUpdate = Material.Outlined.SecurityUpdate; + public const string SecurityUpdateGood = Material.Outlined.SecurityUpdateGood; + public const string SecurityUpdateWarning = Material.Outlined.SecurityUpdateWarning; + public const string Segment = Material.Outlined.Segment; + public const string SelectAll = Material.Outlined.SelectAll; + public const string SelfImprovement = Material.Outlined.SelfImprovement; + public const string Sell = Material.Outlined.Sell; + public const string Send = Material.Outlined.Send; + public const string SendAndArchive = Material.Outlined.SendAndArchive; + public const string SendTimeExtension = Material.Outlined.SendTimeExtension; + public const string SendToMobile = Material.Outlined.SendToMobile; + public const string SensorDoor = Material.Outlined.SensorDoor; + public const string SensorWindow = Material.Outlined.SensorWindow; + public const string Sensors = Material.Outlined.Sensors; + public const string SensorsOff = Material.Outlined.SensorsOff; + public const string SentimentDissatisfied = Material.Outlined.SentimentDissatisfied; + public const string SentimentNeutral = Material.Outlined.SentimentNeutral; + public const string SentimentSatisfied = Material.Outlined.SentimentSatisfied; + public const string SentimentSatisfiedAlt = Material.Outlined.SentimentSatisfiedAlt; + public const string SentimentVeryDissatisfied = Material.Outlined.SentimentVeryDissatisfied; + public const string SentimentVerySatisfied = Material.Outlined.SentimentVerySatisfied; + public const string SetMeal = Material.Outlined.SetMeal; + public const string Settings = Material.Outlined.Settings; + public const string SettingsAccessibility = Material.Outlined.SettingsAccessibility; + public const string SettingsApplications = Material.Outlined.SettingsApplications; + public const string SettingsBackupRestore = Material.Outlined.SettingsBackupRestore; + public const string SettingsBluetooth = Material.Outlined.SettingsBluetooth; + public const string SettingsBrightness = Material.Outlined.SettingsBrightness; + public const string SettingsCell = Material.Outlined.SettingsCell; + public const string SettingsEthernet = Material.Outlined.SettingsEthernet; + public const string SettingsInputAntenna = Material.Outlined.SettingsInputAntenna; + public const string SettingsInputComponent = Material.Outlined.SettingsInputComponent; + public const string SettingsInputComposite = Material.Outlined.SettingsInputComposite; + public const string SettingsInputHdmi = Material.Outlined.SettingsInputHdmi; + public const string SettingsInputSvideo = Material.Outlined.SettingsInputSvideo; + public const string SettingsOverscan = Material.Outlined.SettingsOverscan; + public const string SettingsPhone = Material.Outlined.SettingsPhone; + public const string SettingsPower = Material.Outlined.SettingsPower; + public const string SettingsRemote = Material.Outlined.SettingsRemote; + public const string SettingsSuggest = Material.Outlined.SettingsSuggest; + public const string SettingsSystemDaydream = Material.Outlined.SettingsSystemDaydream; + public const string SettingsVoice = Material.Outlined.SettingsVoice; + public const string SevereCold = Material.Outlined.SevereCold; + public const string Share = Material.Outlined.Share; + public const string ShareLocation = Material.Outlined.ShareLocation; + public const string Shield = Material.Outlined.Shield; + public const string ShieldMoon = Material.Outlined.ShieldMoon; + public const string Shop = Material.Outlined.Shop; + public const string Shop2 = Material.Outlined.Shop2; + public const string ShopTwo = Material.Outlined.ShopTwo; + public const string ShoppingBag = Material.Outlined.ShoppingBag; + public const string ShoppingBasket = Material.Outlined.ShoppingBasket; + public const string ShoppingCart = Material.Outlined.ShoppingCart; + public const string ShoppingCartCheckout = Material.Outlined.ShoppingCartCheckout; + public const string ShortText = Material.Outlined.ShortText; + public const string Shortcut = Material.Outlined.Shortcut; + public const string ShowChart = Material.Outlined.ShowChart; + public const string Shower = Material.Outlined.Shower; + public const string Shuffle = Material.Outlined.Shuffle; + public const string ShuffleOn = Material.Outlined.ShuffleOn; + public const string ShutterSpeed = Material.Outlined.ShutterSpeed; + public const string Sick = Material.Outlined.Sick; + public const string SignLanguage = Material.Outlined.SignLanguage; + public const string SignalCellular0Bar = Material.Outlined.SignalCellular0Bar; + public const string SignalCellular4Bar = Material.Outlined.SignalCellular4Bar; + public const string SignalCellularAlt = Material.Outlined.SignalCellularAlt; + public const string SignalCellularAlt1Bar = Material.Outlined.SignalCellularAlt1Bar; + public const string SignalCellularAlt2Bar = Material.Outlined.SignalCellularAlt2Bar; + + public const string SignalCellularConnectedNoInternet0Bar = + Material.Outlined.SignalCellularConnectedNoInternet0Bar; + + public const string SignalCellularConnectedNoInternet4Bar = + Material.Outlined.SignalCellularConnectedNoInternet4Bar; + + public const string SignalCellularNoSim = Material.Outlined.SignalCellularNoSim; + public const string SignalCellularNodata = Material.Outlined.SignalCellularNodata; + public const string SignalCellularNull = Material.Outlined.SignalCellularNull; + public const string SignalCellularOff = Material.Outlined.SignalCellularOff; + public const string SignalWifi0Bar = Material.Outlined.SignalWifi0Bar; + public const string SignalWifi4Bar = Material.Outlined.SignalWifi4Bar; + public const string SignalWifi4BarLock = Material.Outlined.SignalWifi4BarLock; + public const string SignalWifiBad = Material.Outlined.SignalWifiBad; + public const string SignalWifiConnectedNoInternet4 = Material.Outlined.SignalWifiConnectedNoInternet4; + public const string SignalWifiOff = Material.Outlined.SignalWifiOff; + public const string SignalWifiStatusbar4Bar = Material.Outlined.SignalWifiStatusbar4Bar; + + public const string SignalWifiStatusbarConnectedNoInternet4 = + Material.Outlined.SignalWifiStatusbarConnectedNoInternet4; + + public const string SignalWifiStatusbarNull = Material.Outlined.SignalWifiStatusbarNull; + public const string Signpost = Material.Outlined.Signpost; + public const string SimCard = Material.Outlined.SimCard; + public const string SimCardAlert = Material.Outlined.SimCardAlert; + public const string SimCardDownload = Material.Outlined.SimCardDownload; + public const string SingleBed = Material.Outlined.SingleBed; + public const string Sip = Material.Outlined.Sip; + public const string Skateboarding = Material.Outlined.Skateboarding; + public const string SkipNext = Material.Outlined.SkipNext; + public const string SkipPrevious = Material.Outlined.SkipPrevious; + public const string Sledding = Material.Outlined.Sledding; + public const string Slideshow = Material.Outlined.Slideshow; + public const string SlowMotionVideo = Material.Outlined.SlowMotionVideo; + public const string SmartButton = Material.Outlined.SmartButton; + public const string SmartDisplay = Material.Outlined.SmartDisplay; + public const string SmartScreen = Material.Outlined.SmartScreen; + public const string SmartToy = Material.Outlined.SmartToy; + public const string Smartphone = Material.Outlined.Smartphone; + public const string SmokeFree = Material.Outlined.SmokeFree; + public const string SmokingRooms = Material.Outlined.SmokingRooms; + public const string Sms = Material.Outlined.Sms; + public const string SmsFailed = Material.Outlined.SmsFailed; + public const string SnippetFolder = Material.Outlined.SnippetFolder; + public const string Snooze = Material.Outlined.Snooze; + public const string Snowboarding = Material.Outlined.Snowboarding; + public const string Snowmobile = Material.Outlined.Snowmobile; + public const string Snowshoeing = Material.Outlined.Snowshoeing; + public const string Soap = Material.Outlined.Soap; + public const string SocialDistance = Material.Outlined.SocialDistance; + public const string Sort = Material.Outlined.Sort; + public const string SortByAlpha = Material.Outlined.SortByAlpha; + public const string Sos = Material.Outlined.Sos; + public const string SoupKitchen = Material.Outlined.SoupKitchen; + public const string Source = Material.Outlined.Source; + public const string South = Material.Outlined.South; + public const string SouthAmerica = Material.Outlined.SouthAmerica; + public const string SouthEast = Material.Outlined.SouthEast; + public const string SouthWest = Material.Outlined.SouthWest; + public const string Spa = Material.Outlined.Spa; + public const string SpaceBar = Material.Outlined.SpaceBar; + public const string SpaceDashboard = Material.Outlined.SpaceDashboard; + public const string SpatialAudio = Material.Outlined.SpatialAudio; + public const string SpatialAudioOff = Material.Outlined.SpatialAudioOff; + public const string SpatialTracking = Material.Outlined.SpatialTracking; + public const string Speaker = Material.Outlined.Speaker; + public const string SpeakerGroup = Material.Outlined.SpeakerGroup; + public const string SpeakerNotes = Material.Outlined.SpeakerNotes; + public const string SpeakerNotesOff = Material.Outlined.SpeakerNotesOff; + public const string SpeakerPhone = Material.Outlined.SpeakerPhone; + public const string Speed = Material.Outlined.Speed; + public const string Spellcheck = Material.Outlined.Spellcheck; + public const string Splitscreen = Material.Outlined.Splitscreen; + public const string Spoke = Material.Outlined.Spoke; + public const string Sports = Material.Outlined.Sports; + public const string SportsBar = Material.Outlined.SportsBar; + public const string SportsBaseball = Material.Outlined.SportsBaseball; + public const string SportsBasketball = Material.Outlined.SportsBasketball; + public const string SportsCricket = Material.Outlined.SportsCricket; + public const string SportsEsports = Material.Outlined.SportsEsports; + public const string SportsFootball = Material.Outlined.SportsFootball; + public const string SportsGolf = Material.Outlined.SportsGolf; + public const string SportsGymnastics = Material.Outlined.SportsGymnastics; + public const string SportsHandball = Material.Outlined.SportsHandball; + public const string SportsHockey = Material.Outlined.SportsHockey; + public const string SportsKabaddi = Material.Outlined.SportsKabaddi; + public const string SportsMartialArts = Material.Outlined.SportsMartialArts; + public const string SportsMma = Material.Outlined.SportsMma; + public const string SportsMotorsports = Material.Outlined.SportsMotorsports; + public const string SportsRugby = Material.Outlined.SportsRugby; + public const string SportsScore = Material.Outlined.SportsScore; + public const string SportsSoccer = Material.Outlined.SportsSoccer; + public const string SportsTennis = Material.Outlined.SportsTennis; + public const string SportsVolleyball = Material.Outlined.SportsVolleyball; + public const string Square = Material.Outlined.Square; + public const string SquareFoot = Material.Outlined.SquareFoot; + public const string SsidChart = Material.Outlined.SsidChart; + public const string StackedBarChart = Material.Outlined.StackedBarChart; + public const string StackedLineChart = Material.Outlined.StackedLineChart; + public const string Stadium = Material.Outlined.Stadium; + public const string Stairs = Material.Outlined.Stairs; + public const string Star = Material.Outlined.Star; + public const string StarBorder = Material.Outlined.StarBorder; + public const string StarBorderPurple500 = Material.Outlined.StarBorderPurple500; + public const string StarHalf = Material.Outlined.StarHalf; + public const string StarOutline = Material.Outlined.StarOutline; + public const string StarPurple500 = Material.Outlined.StarPurple500; + public const string StarRate = Material.Outlined.StarRate; + public const string Stars = Material.Outlined.Stars; + public const string Start = Material.Outlined.Start; + public const string StayCurrentLandscape = Material.Outlined.StayCurrentLandscape; + public const string StayCurrentPortrait = Material.Outlined.StayCurrentPortrait; + public const string StayPrimaryLandscape = Material.Outlined.StayPrimaryLandscape; + public const string StayPrimaryPortrait = Material.Outlined.StayPrimaryPortrait; + public const string StickyNote2 = Material.Outlined.StickyNote2; + public const string Stop = Material.Outlined.Stop; + public const string StopCircle = Material.Outlined.StopCircle; + public const string StopScreenShare = Material.Outlined.StopScreenShare; + public const string Storage = Material.Outlined.Storage; + public const string Store = Material.Outlined.Store; + public const string StoreMallDirectory = Material.Outlined.StoreMallDirectory; + public const string Storefront = Material.Outlined.Storefront; + public const string Storm = Material.Outlined.Storm; + public const string Straight = Material.Outlined.Straight; + public const string Straighten = Material.Outlined.Straighten; + public const string Stream = Material.Outlined.Stream; + public const string Streetview = Material.Outlined.Streetview; + public const string StrikethroughS = Material.Outlined.StrikethroughS; + public const string Stroller = Material.Outlined.Stroller; + public const string Style = Material.Outlined.Style; + public const string SubdirectoryArrowLeft = Material.Outlined.SubdirectoryArrowLeft; + public const string SubdirectoryArrowRight = Material.Outlined.SubdirectoryArrowRight; + public const string Subject = Material.Outlined.Subject; + public const string Subscript = Material.Outlined.Subscript; + public const string Subscriptions = Material.Outlined.Subscriptions; + public const string Subtitles = Material.Outlined.Subtitles; + public const string SubtitlesOff = Material.Outlined.SubtitlesOff; + public const string Subway = Material.Outlined.Subway; + public const string Summarize = Material.Outlined.Summarize; + public const string Superscript = Material.Outlined.Superscript; + public const string SupervisedUserCircle = Material.Outlined.SupervisedUserCircle; + public const string SupervisorAccount = Material.Outlined.SupervisorAccount; + public const string Support = Material.Outlined.Support; + public const string SupportAgent = Material.Outlined.SupportAgent; + public const string Surfing = Material.Outlined.Surfing; + public const string SurroundSound = Material.Outlined.SurroundSound; + public const string SwapCalls = Material.Outlined.SwapCalls; + public const string SwapHoriz = Material.Outlined.SwapHoriz; + public const string SwapHorizontalCircle = Material.Outlined.SwapHorizontalCircle; + public const string SwapVert = Material.Outlined.SwapVert; + public const string SwapVerticalCircle = Material.Outlined.SwapVerticalCircle; + public const string Swipe = Material.Outlined.Swipe; + public const string SwipeDown = Material.Outlined.SwipeDown; + public const string SwipeDownAlt = Material.Outlined.SwipeDownAlt; + public const string SwipeLeft = Material.Outlined.SwipeLeft; + public const string SwipeLeftAlt = Material.Outlined.SwipeLeftAlt; + public const string SwipeRight = Material.Outlined.SwipeRight; + public const string SwipeRightAlt = Material.Outlined.SwipeRightAlt; + public const string SwipeUp = Material.Outlined.SwipeUp; + public const string SwipeUpAlt = Material.Outlined.SwipeUpAlt; + public const string SwipeVertical = Material.Outlined.SwipeVertical; + public const string SwitchAccessShortcut = Material.Outlined.SwitchAccessShortcut; + public const string SwitchAccessShortcutAdd = Material.Outlined.SwitchAccessShortcutAdd; + public const string SwitchAccount = Material.Outlined.SwitchAccount; + public const string SwitchCamera = Material.Outlined.SwitchCamera; + public const string SwitchLeft = Material.Outlined.SwitchLeft; + public const string SwitchRight = Material.Outlined.SwitchRight; + public const string SwitchVideo = Material.Outlined.SwitchVideo; + public const string Synagogue = Material.Outlined.Synagogue; + public const string Sync = Material.Outlined.Sync; + public const string SyncAlt = Material.Outlined.SyncAlt; + public const string SyncDisabled = Material.Outlined.SyncDisabled; + public const string SyncLock = Material.Outlined.SyncLock; + public const string SyncProblem = Material.Outlined.SyncProblem; + public const string SystemSecurityUpdate = Material.Outlined.SystemSecurityUpdate; + public const string SystemSecurityUpdateGood = Material.Outlined.SystemSecurityUpdateGood; + public const string SystemSecurityUpdateWarning = Material.Outlined.SystemSecurityUpdateWarning; + public const string SystemUpdate = Material.Outlined.SystemUpdate; + public const string SystemUpdateAlt = Material.Outlined.SystemUpdateAlt; + public const string Tab = Material.Outlined.Tab; + public const string TabUnselected = Material.Outlined.TabUnselected; + public const string TableBar = Material.Outlined.TableBar; + public const string TableChart = Material.Outlined.TableChart; + public const string TableRestaurant = Material.Outlined.TableRestaurant; + public const string TableRows = Material.Outlined.TableRows; + public const string TableView = Material.Outlined.TableView; + public const string Tablet = Material.Outlined.Tablet; + public const string TabletAndroid = Material.Outlined.TabletAndroid; + public const string TabletMac = Material.Outlined.TabletMac; + public const string Tag = Material.Outlined.Tag; + public const string TagFaces = Material.Outlined.TagFaces; + public const string TakeoutDining = Material.Outlined.TakeoutDining; + public const string TapAndPlay = Material.Outlined.TapAndPlay; + public const string Tapas = Material.Outlined.Tapas; + public const string Task = Material.Outlined.Task; + public const string TaskAlt = Material.Outlined.TaskAlt; + public const string TaxiAlert = Material.Outlined.TaxiAlert; + public const string TempleBuddhist = Material.Outlined.TempleBuddhist; + public const string TempleHindu = Material.Outlined.TempleHindu; + public const string Terminal = Material.Outlined.Terminal; + public const string Terrain = Material.Outlined.Terrain; + public const string TextDecrease = Material.Outlined.TextDecrease; + public const string TextFields = Material.Outlined.TextFields; + public const string TextFormat = Material.Outlined.TextFormat; + public const string TextIncrease = Material.Outlined.TextIncrease; + public const string TextRotateUp = Material.Outlined.TextRotateUp; + public const string TextRotateVertical = Material.Outlined.TextRotateVertical; + public const string TextRotationAngledown = Material.Outlined.TextRotationAngledown; + public const string TextRotationAngleup = Material.Outlined.TextRotationAngleup; + public const string TextRotationDown = Material.Outlined.TextRotationDown; + public const string TextRotationNone = Material.Outlined.TextRotationNone; + public const string TextSnippet = Material.Outlined.TextSnippet; + public const string Textsms = Material.Outlined.Textsms; + public const string Texture = Material.Outlined.Texture; + public const string TheaterComedy = Material.Outlined.TheaterComedy; + public const string Theaters = Material.Outlined.Theaters; + public const string Thermostat = Material.Outlined.Thermostat; + public const string ThermostatAuto = Material.Outlined.ThermostatAuto; + public const string ThumbDown = Material.Outlined.ThumbDown; + public const string ThumbDownAlt = Material.Outlined.ThumbDownAlt; + public const string ThumbDownOffAlt = Material.Outlined.ThumbDownOffAlt; + public const string ThumbUp = Material.Outlined.ThumbUp; + public const string ThumbUpAlt = Material.Outlined.ThumbUpAlt; + public const string ThumbUpOffAlt = Material.Outlined.ThumbUpOffAlt; + public const string ThumbsUpDown = Material.Outlined.ThumbsUpDown; + public const string Thunderstorm = Material.Outlined.Thunderstorm; + public const string TimeToLeave = Material.Outlined.TimeToLeave; + public const string Timelapse = Material.Outlined.Timelapse; + public const string Timeline = Material.Outlined.Timeline; + public const string Timer = Material.Outlined.Timer; + public const string Timer10 = Material.Outlined.Timer10; + public const string Timer10Select = Material.Outlined.Timer10Select; + public const string Timer3 = Material.Outlined.Timer3; + public const string Timer3Select = Material.Outlined.Timer3Select; + public const string TimerOff = Material.Outlined.TimerOff; + public const string TipsAndUpdates = Material.Outlined.TipsAndUpdates; + public const string TireRepair = Material.Outlined.TireRepair; + public const string Title = Material.Outlined.Title; + public const string Toc = Material.Outlined.Toc; + public const string Today = Material.Outlined.Today; + public const string ToggleOff = Material.Outlined.ToggleOff; + public const string ToggleOn = Material.Outlined.ToggleOn; + public const string Token = Material.Outlined.Token; + public const string Toll = Material.Outlined.Toll; + public const string Tonality = Material.Outlined.Tonality; + public const string Topic = Material.Outlined.Topic; + public const string TouchApp = Material.Outlined.TouchApp; + public const string Tour = Material.Outlined.Tour; + public const string Toys = Material.Outlined.Toys; + public const string TrackChanges = Material.Outlined.TrackChanges; + public const string Traffic = Material.Outlined.Traffic; + public const string Train = Material.Outlined.Train; + public const string Tram = Material.Outlined.Tram; + public const string TransferWithinAStation = Material.Outlined.TransferWithinAStation; + public const string Transform = Material.Outlined.Transform; + public const string Transgender = Material.Outlined.Transgender; + public const string TransitEnterexit = Material.Outlined.TransitEnterexit; + public const string Translate = Material.Outlined.Translate; + public const string TravelExplore = Material.Outlined.TravelExplore; + public const string TrendingDown = Material.Outlined.TrendingDown; + public const string TrendingFlat = Material.Outlined.TrendingFlat; + public const string TrendingUp = Material.Outlined.TrendingUp; + public const string TripOrigin = Material.Outlined.TripOrigin; + public const string Try = Material.Outlined.Try; + public const string Tsunami = Material.Outlined.Tsunami; + public const string Tty = Material.Outlined.Tty; + public const string Tune = Material.Outlined.Tune; + public const string Tungsten = Material.Outlined.Tungsten; + public const string TurnLeft = Material.Outlined.TurnLeft; + public const string TurnRight = Material.Outlined.TurnRight; + public const string TurnSharpLeft = Material.Outlined.TurnSharpLeft; + public const string TurnSharpRight = Material.Outlined.TurnSharpRight; + public const string TurnSlightLeft = Material.Outlined.TurnSlightLeft; + public const string TurnSlightRight = Material.Outlined.TurnSlightRight; + public const string TurnedIn = Material.Outlined.TurnedIn; + public const string TurnedInNot = Material.Outlined.TurnedInNot; + public const string Tv = Material.Outlined.Tv; + public const string TvOff = Material.Outlined.TvOff; + public const string TwoWheeler = Material.Outlined.TwoWheeler; + public const string UTurnLeft = Material.Outlined.UTurnLeft; + public const string UTurnRight = Material.Outlined.UTurnRight; + public const string Umbrella = Material.Outlined.Umbrella; + public const string Unarchive = Material.Outlined.Unarchive; + public const string Undo = Material.Outlined.Undo; + public const string UnfoldLess = Material.Outlined.UnfoldLess; + public const string UnfoldMore = Material.Outlined.UnfoldMore; + public const string Unpublished = Material.Outlined.Unpublished; + public const string Unsubscribe = Material.Outlined.Unsubscribe; + public const string Upcoming = Material.Outlined.Upcoming; + public const string Update = Material.Outlined.Update; + public const string UpdateDisabled = Material.Outlined.UpdateDisabled; + public const string Upgrade = Material.Outlined.Upgrade; + public const string Upload = Material.Outlined.Upload; + public const string UploadFile = Material.Outlined.UploadFile; + public const string Usb = Material.Outlined.Usb; + public const string UsbOff = Material.Outlined.UsbOff; + public const string Vaccines = Material.Outlined.Vaccines; + public const string VapeFree = Material.Outlined.VapeFree; + public const string VapingRooms = Material.Outlined.VapingRooms; + public const string Verified = Material.Outlined.Verified; + public const string VerifiedUser = Material.Outlined.VerifiedUser; + public const string VerticalAlignBottom = Material.Outlined.VerticalAlignBottom; + public const string VerticalAlignCenter = Material.Outlined.VerticalAlignCenter; + public const string VerticalAlignTop = Material.Outlined.VerticalAlignTop; + public const string VerticalDistribute = Material.Outlined.VerticalDistribute; + public const string VerticalSplit = Material.Outlined.VerticalSplit; + public const string Vibration = Material.Outlined.Vibration; + public const string VideoCall = Material.Outlined.VideoCall; + public const string VideoCameraBack = Material.Outlined.VideoCameraBack; + public const string VideoCameraFront = Material.Outlined.VideoCameraFront; + public const string VideoFile = Material.Outlined.VideoFile; + public const string VideoLabel = Material.Outlined.VideoLabel; + public const string VideoLibrary = Material.Outlined.VideoLibrary; + public const string VideoSettings = Material.Outlined.VideoSettings; + public const string VideoStable = Material.Outlined.VideoStable; + public const string Videocam = Material.Outlined.Videocam; + public const string VideocamOff = Material.Outlined.VideocamOff; + public const string VideogameAsset = Material.Outlined.VideogameAsset; + public const string VideogameAssetOff = Material.Outlined.VideogameAssetOff; + public const string ViewAgenda = Material.Outlined.ViewAgenda; + public const string ViewArray = Material.Outlined.ViewArray; + public const string ViewCarousel = Material.Outlined.ViewCarousel; + public const string ViewColumn = Material.Outlined.ViewColumn; + public const string ViewComfy = Material.Outlined.ViewComfy; + public const string ViewComfyAlt = Material.Outlined.ViewComfyAlt; + public const string ViewCompact = Material.Outlined.ViewCompact; + public const string ViewCompactAlt = Material.Outlined.ViewCompactAlt; + public const string ViewCozy = Material.Outlined.ViewCozy; + public const string ViewDay = Material.Outlined.ViewDay; + public const string ViewHeadline = Material.Outlined.ViewHeadline; + public const string ViewInAr = Material.Outlined.ViewInAr; + public const string ViewKanban = Material.Outlined.ViewKanban; + public const string ViewList = Material.Outlined.ViewList; + public const string ViewModule = Material.Outlined.ViewModule; + public const string ViewQuilt = Material.Outlined.ViewQuilt; + public const string ViewSidebar = Material.Outlined.ViewSidebar; + public const string ViewStream = Material.Outlined.ViewStream; + public const string ViewTimeline = Material.Outlined.ViewTimeline; + public const string ViewWeek = Material.Outlined.ViewWeek; + public const string Vignette = Material.Outlined.Vignette; + public const string Villa = Material.Outlined.Villa; + public const string Visibility = Material.Outlined.Visibility; + public const string VisibilityOff = Material.Outlined.VisibilityOff; + public const string VoiceChat = Material.Outlined.VoiceChat; + public const string VoiceOverOff = Material.Outlined.VoiceOverOff; + public const string Voicemail = Material.Outlined.Voicemail; + public const string Volcano = Material.Outlined.Volcano; + public const string VolumeDown = Material.Outlined.VolumeDown; + public const string VolumeMute = Material.Outlined.VolumeMute; + public const string VolumeOff = Material.Outlined.VolumeOff; + public const string VolumeUp = Material.Outlined.VolumeUp; + public const string VolunteerActivism = Material.Outlined.VolunteerActivism; + public const string VpnKey = Material.Outlined.VpnKey; + public const string VpnKeyOff = Material.Outlined.VpnKeyOff; + public const string VpnLock = Material.Outlined.VpnLock; + public const string Vrpano = Material.Outlined.Vrpano; + public const string Wallpaper = Material.Outlined.Wallpaper; + public const string Warehouse = Material.Outlined.Warehouse; + public const string Warning = Material.Outlined.Warning; + public const string WarningAmber = Material.Outlined.WarningAmber; + public const string Wash = Material.Outlined.Wash; + public const string Watch = Material.Outlined.Watch; + public const string WatchLater = Material.Outlined.WatchLater; + public const string WatchOff = Material.Outlined.WatchOff; + public const string Water = Material.Outlined.Water; + public const string WaterDamage = Material.Outlined.WaterDamage; + public const string WaterDrop = Material.Outlined.WaterDrop; + public const string WaterfallChart = Material.Outlined.WaterfallChart; + public const string Waves = Material.Outlined.Waves; + public const string WavingHand = Material.Outlined.WavingHand; + public const string WbAuto = Material.Outlined.WbAuto; + public const string WbCloudy = Material.Outlined.WbCloudy; + public const string WbIncandescent = Material.Outlined.WbIncandescent; + public const string WbIridescent = Material.Outlined.WbIridescent; + public const string WbShade = Material.Outlined.WbShade; + public const string WbSunny = Material.Outlined.WbSunny; + public const string WbTwilight = Material.Outlined.WbTwilight; + public const string Wc = Material.Outlined.Wc; + public const string Web = Material.Outlined.Web; + public const string WebAsset = Material.Outlined.WebAsset; + public const string WebAssetOff = Material.Outlined.WebAssetOff; + public const string Webhook = Material.Outlined.Webhook; + public const string Weekend = Material.Outlined.Weekend; + public const string West = Material.Outlined.West; + public const string Whatsapp = Material.Outlined.Whatsapp; + public const string Whatshot = Material.Outlined.Whatshot; + public const string WheelchairPickup = Material.Outlined.WheelchairPickup; + public const string WhereToVote = Material.Outlined.WhereToVote; + public const string Widgets = Material.Outlined.Widgets; + public const string Wifi = Material.Outlined.Wifi; + public const string Wifi1Bar = Material.Outlined.Wifi1Bar; + public const string Wifi2Bar = Material.Outlined.Wifi2Bar; + public const string WifiCalling = Material.Outlined.WifiCalling; + public const string WifiCalling3 = Material.Outlined.WifiCalling3; + public const string WifiChannel = Material.Outlined.WifiChannel; + public const string WifiFind = Material.Outlined.WifiFind; + public const string WifiLock = Material.Outlined.WifiLock; + public const string WifiOff = Material.Outlined.WifiOff; + public const string WifiPassword = Material.Outlined.WifiPassword; + public const string WifiProtectedSetup = Material.Outlined.WifiProtectedSetup; + public const string WifiTethering = Material.Outlined.WifiTethering; + public const string WifiTetheringError = Material.Outlined.WifiTetheringError; + public const string WifiTetheringOff = Material.Outlined.WifiTetheringOff; + public const string Window = Material.Outlined.Window; + public const string WineBar = Material.Outlined.WineBar; + public const string Woman = Material.Outlined.Woman; + public const string Work = Material.Outlined.Work; + public const string WorkOff = Material.Outlined.WorkOff; + public const string WorkOutline = Material.Outlined.WorkOutline; + public const string WorkspacePremium = Material.Outlined.WorkspacePremium; + public const string Workspaces = Material.Outlined.Workspaces; + public const string WrapText = Material.Outlined.WrapText; + public const string WrongLocation = Material.Outlined.WrongLocation; + public const string Wysiwyg = Material.Outlined.Wysiwyg; + public const string Yard = Material.Outlined.Yard; + public const string YoutubeSearchedFor = Material.Outlined.YoutubeSearchedFor; + public const string ZoomIn = Material.Outlined.ZoomIn; + public const string ZoomInMap = Material.Outlined.ZoomInMap; + public const string ZoomOut = Material.Outlined.ZoomOut; + public const string ZoomOutMap = Material.Outlined.ZoomOutMap; + } + } +} diff --git a/Icons/Obsolete/Rounded.cs b/Icons/Obsolete/Rounded.cs new file mode 100644 index 0000000..d49f31c --- /dev/null +++ b/Icons/Obsolete/Rounded.cs @@ -0,0 +1,2074 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + [ExcludeFromCodeCoverage] + public partial class Rounded + { + public const string _10k = Material.Rounded._10k; + public const string _10mp = Material.Rounded._10mp; + public const string _11mp = Material.Rounded._11mp; + public const string _123 = Material.Rounded._123; + public const string _12mp = Material.Rounded._12mp; + public const string _13mp = Material.Rounded._13mp; + public const string _14mp = Material.Rounded._14mp; + public const string _15mp = Material.Rounded._15mp; + public const string _16mp = Material.Rounded._16mp; + public const string _17mp = Material.Rounded._17mp; + public const string _18mp = Material.Rounded._18mp; + public const string _19mp = Material.Rounded._19mp; + public const string _1k = Material.Rounded._1k; + public const string _1kPlus = Material.Rounded._1kPlus; + public const string _1xMobiledata = Material.Rounded._1xMobiledata; + public const string _20mp = Material.Rounded._20mp; + public const string _21mp = Material.Rounded._21mp; + public const string _22mp = Material.Rounded._22mp; + public const string _23mp = Material.Rounded._23mp; + public const string _24mp = Material.Rounded._24mp; + public const string _2k = Material.Rounded._2k; + public const string _2kPlus = Material.Rounded._2kPlus; + public const string _2mp = Material.Rounded._2mp; + public const string _30fps = Material.Rounded._30fps; + public const string _30fpsSelect = Material.Rounded._30fpsSelect; + public const string _360 = Material.Rounded._360; + public const string _3dRotation = Material.Rounded._3dRotation; + public const string _3gMobiledata = Material.Rounded._3gMobiledata; + public const string _3k = Material.Rounded._3k; + public const string _3kPlus = Material.Rounded._3kPlus; + public const string _3mp = Material.Rounded._3mp; + public const string _3p = Material.Rounded._3p; + public const string _4gMobiledata = Material.Rounded._4gMobiledata; + public const string _4gPlusMobiledata = Material.Rounded._4gPlusMobiledata; + public const string _4k = Material.Rounded._4k; + public const string _4kPlus = Material.Rounded._4kPlus; + public const string _4mp = Material.Rounded._4mp; + public const string _5g = Material.Rounded._5g; + public const string _5k = Material.Rounded._5k; + public const string _5kPlus = Material.Rounded._5kPlus; + public const string _5mp = Material.Rounded._5mp; + public const string _60fps = Material.Rounded._60fps; + public const string _60fpsSelect = Material.Rounded._60fpsSelect; + public const string _6FtApart = Material.Rounded._6FtApart; + public const string _6k = Material.Rounded._6k; + public const string _6kPlus = Material.Rounded._6kPlus; + public const string _6mp = Material.Rounded._6mp; + public const string _7k = Material.Rounded._7k; + public const string _7kPlus = Material.Rounded._7kPlus; + public const string _7mp = Material.Rounded._7mp; + public const string _8k = Material.Rounded._8k; + public const string _8kPlus = Material.Rounded._8kPlus; + public const string _8mp = Material.Rounded._8mp; + public const string _9k = Material.Rounded._9k; + public const string _9kPlus = Material.Rounded._9kPlus; + public const string _9mp = Material.Rounded._9mp; + public const string Abc = Material.Rounded.Abc; + public const string AcUnit = Material.Rounded.AcUnit; + public const string AccessAlarm = Material.Rounded.AccessAlarm; + public const string AccessAlarms = Material.Rounded.AccessAlarms; + public const string AccessTime = Material.Rounded.AccessTime; + public const string AccessTimeFilled = Material.Rounded.AccessTimeFilled; + public const string Accessibility = Material.Rounded.Accessibility; + public const string AccessibilityNew = Material.Rounded.AccessibilityNew; + public const string Accessible = Material.Rounded.Accessible; + public const string AccessibleForward = Material.Rounded.AccessibleForward; + public const string AccountBalance = Material.Rounded.AccountBalance; + public const string AccountBalanceWallet = Material.Rounded.AccountBalanceWallet; + public const string AccountBox = Material.Rounded.AccountBox; + public const string AccountCircle = Material.Rounded.AccountCircle; + public const string AccountTree = Material.Rounded.AccountTree; + public const string AdUnits = Material.Rounded.AdUnits; + public const string Adb = Material.Rounded.Adb; + public const string Add = Material.Rounded.Add; + public const string AddAPhoto = Material.Rounded.AddAPhoto; + public const string AddAlarm = Material.Rounded.AddAlarm; + public const string AddAlert = Material.Rounded.AddAlert; + public const string AddBox = Material.Rounded.AddBox; + public const string AddBusiness = Material.Rounded.AddBusiness; + public const string AddCard = Material.Rounded.AddCard; + public const string AddChart = Material.Rounded.AddChart; + public const string AddCircle = Material.Rounded.AddCircle; + public const string AddCircleOutline = Material.Rounded.AddCircleOutline; + public const string AddComment = Material.Rounded.AddComment; + public const string AddIcCall = Material.Rounded.AddIcCall; + public const string AddLink = Material.Rounded.AddLink; + public const string AddLocation = Material.Rounded.AddLocation; + public const string AddLocationAlt = Material.Rounded.AddLocationAlt; + public const string AddModerator = Material.Rounded.AddModerator; + public const string AddPhotoAlternate = Material.Rounded.AddPhotoAlternate; + public const string AddReaction = Material.Rounded.AddReaction; + public const string AddRoad = Material.Rounded.AddRoad; + public const string AddShoppingCart = Material.Rounded.AddShoppingCart; + public const string AddTask = Material.Rounded.AddTask; + public const string AddToDrive = Material.Rounded.AddToDrive; + public const string AddToHomeScreen = Material.Rounded.AddToHomeScreen; + public const string AddToPhotos = Material.Rounded.AddToPhotos; + public const string AddToQueue = Material.Rounded.AddToQueue; + public const string Addchart = Material.Rounded.Addchart; + public const string AdfScanner = Material.Rounded.AdfScanner; + public const string Adjust = Material.Rounded.Adjust; + public const string AdminPanelSettings = Material.Rounded.AdminPanelSettings; + public const string AdsClick = Material.Rounded.AdsClick; + public const string Agriculture = Material.Rounded.Agriculture; + public const string Air = Material.Rounded.Air; + public const string AirlineSeatFlat = Material.Rounded.AirlineSeatFlat; + public const string AirlineSeatFlatAngled = Material.Rounded.AirlineSeatFlatAngled; + public const string AirlineSeatIndividualSuite = Material.Rounded.AirlineSeatIndividualSuite; + public const string AirlineSeatLegroomExtra = Material.Rounded.AirlineSeatLegroomExtra; + public const string AirlineSeatLegroomNormal = Material.Rounded.AirlineSeatLegroomNormal; + public const string AirlineSeatLegroomReduced = Material.Rounded.AirlineSeatLegroomReduced; + public const string AirlineSeatReclineExtra = Material.Rounded.AirlineSeatReclineExtra; + public const string AirlineSeatReclineNormal = Material.Rounded.AirlineSeatReclineNormal; + public const string AirlineStops = Material.Rounded.AirlineStops; + public const string Airlines = Material.Rounded.Airlines; + public const string AirplaneTicket = Material.Rounded.AirplaneTicket; + public const string AirplanemodeActive = Material.Rounded.AirplanemodeActive; + public const string AirplanemodeInactive = Material.Rounded.AirplanemodeInactive; + public const string Airplay = Material.Rounded.Airplay; + public const string AirportShuttle = Material.Rounded.AirportShuttle; + public const string Alarm = Material.Rounded.Alarm; + public const string AlarmAdd = Material.Rounded.AlarmAdd; + public const string AlarmOff = Material.Rounded.AlarmOff; + public const string AlarmOn = Material.Rounded.AlarmOn; + public const string Album = Material.Rounded.Album; + public const string AlignHorizontalCenter = Material.Rounded.AlignHorizontalCenter; + public const string AlignHorizontalLeft = Material.Rounded.AlignHorizontalLeft; + public const string AlignHorizontalRight = Material.Rounded.AlignHorizontalRight; + public const string AlignVerticalBottom = Material.Rounded.AlignVerticalBottom; + public const string AlignVerticalCenter = Material.Rounded.AlignVerticalCenter; + public const string AlignVerticalTop = Material.Rounded.AlignVerticalTop; + public const string AllInbox = Material.Rounded.AllInbox; + public const string AllInclusive = Material.Rounded.AllInclusive; + public const string AllOut = Material.Rounded.AllOut; + public const string AltRoute = Material.Rounded.AltRoute; + public const string AlternateEmail = Material.Rounded.AlternateEmail; + public const string Analytics = Material.Rounded.Analytics; + public const string Anchor = Material.Rounded.Anchor; + public const string Android = Material.Rounded.Android; + public const string Animation = Material.Rounded.Animation; + public const string Announcement = Material.Rounded.Announcement; + public const string Aod = Material.Rounded.Aod; + public const string Apartment = Material.Rounded.Apartment; + public const string Api = Material.Rounded.Api; + public const string AppBlocking = Material.Rounded.AppBlocking; + public const string AppRegistration = Material.Rounded.AppRegistration; + public const string AppSettingsAlt = Material.Rounded.AppSettingsAlt; + public const string AppShortcut = Material.Rounded.AppShortcut; + public const string Approval = Material.Rounded.Approval; + public const string Apps = Material.Rounded.Apps; + public const string AppsOutage = Material.Rounded.AppsOutage; + public const string Architecture = Material.Rounded.Architecture; + public const string Archive = Material.Rounded.Archive; + public const string AreaChart = Material.Rounded.AreaChart; + public const string ArrowBack = Material.Rounded.ArrowBack; + public const string ArrowBackIos = Material.Rounded.ArrowBackIos; + public const string ArrowBackIosNew = Material.Rounded.ArrowBackIosNew; + public const string ArrowCircleDown = Material.Rounded.ArrowCircleDown; + public const string ArrowCircleLeft = Material.Rounded.ArrowCircleLeft; + public const string ArrowCircleRight = Material.Rounded.ArrowCircleRight; + public const string ArrowCircleUp = Material.Rounded.ArrowCircleUp; + public const string ArrowDownward = Material.Rounded.ArrowDownward; + public const string ArrowDropDown = Material.Rounded.ArrowDropDown; + public const string ArrowDropDownCircle = Material.Rounded.ArrowDropDownCircle; + public const string ArrowDropUp = Material.Rounded.ArrowDropUp; + public const string ArrowForward = Material.Rounded.ArrowForward; + public const string ArrowForwardIos = Material.Rounded.ArrowForwardIos; + public const string ArrowLeft = Material.Rounded.ArrowLeft; + public const string ArrowRight = Material.Rounded.ArrowRight; + public const string ArrowRightAlt = Material.Rounded.ArrowRightAlt; + public const string ArrowUpward = Material.Rounded.ArrowUpward; + public const string ArtTrack = Material.Rounded.ArtTrack; + public const string Article = Material.Rounded.Article; + public const string AspectRatio = Material.Rounded.AspectRatio; + public const string Assessment = Material.Rounded.Assessment; + public const string Assignment = Material.Rounded.Assignment; + public const string AssignmentInd = Material.Rounded.AssignmentInd; + public const string AssignmentLate = Material.Rounded.AssignmentLate; + public const string AssignmentReturn = Material.Rounded.AssignmentReturn; + public const string AssignmentReturned = Material.Rounded.AssignmentReturned; + public const string AssignmentTurnedIn = Material.Rounded.AssignmentTurnedIn; + public const string Assistant = Material.Rounded.Assistant; + public const string AssistantDirection = Material.Rounded.AssistantDirection; + public const string AssistantPhoto = Material.Rounded.AssistantPhoto; + public const string AssuredWorkload = Material.Rounded.AssuredWorkload; + public const string Atm = Material.Rounded.Atm; + public const string AttachEmail = Material.Rounded.AttachEmail; + public const string AttachFile = Material.Rounded.AttachFile; + public const string AttachMoney = Material.Rounded.AttachMoney; + public const string Attachment = Material.Rounded.Attachment; + public const string Attractions = Material.Rounded.Attractions; + public const string Attribution = Material.Rounded.Attribution; + public const string AudioFile = Material.Rounded.AudioFile; + public const string Audiotrack = Material.Rounded.Audiotrack; + public const string AutoAwesome = Material.Rounded.AutoAwesome; + public const string AutoAwesomeMosaic = Material.Rounded.AutoAwesomeMosaic; + public const string AutoAwesomeMotion = Material.Rounded.AutoAwesomeMotion; + public const string AutoDelete = Material.Rounded.AutoDelete; + public const string AutoFixHigh = Material.Rounded.AutoFixHigh; + public const string AutoFixNormal = Material.Rounded.AutoFixNormal; + public const string AutoFixOff = Material.Rounded.AutoFixOff; + public const string AutoGraph = Material.Rounded.AutoGraph; + public const string AutoStories = Material.Rounded.AutoStories; + public const string AutofpsSelect = Material.Rounded.AutofpsSelect; + public const string Autorenew = Material.Rounded.Autorenew; + public const string AvTimer = Material.Rounded.AvTimer; + public const string BabyChangingStation = Material.Rounded.BabyChangingStation; + public const string BackHand = Material.Rounded.BackHand; + public const string Backpack = Material.Rounded.Backpack; + public const string Backspace = Material.Rounded.Backspace; + public const string Backup = Material.Rounded.Backup; + public const string BackupTable = Material.Rounded.BackupTable; + public const string Badge = Material.Rounded.Badge; + public const string BakeryDining = Material.Rounded.BakeryDining; + public const string Balance = Material.Rounded.Balance; + public const string Balcony = Material.Rounded.Balcony; + public const string Ballot = Material.Rounded.Ballot; + public const string BarChart = Material.Rounded.BarChart; + public const string BatchPrediction = Material.Rounded.BatchPrediction; + public const string Bathroom = Material.Rounded.Bathroom; + public const string Bathtub = Material.Rounded.Bathtub; + public const string Battery0Bar = Material.Rounded.Battery0Bar; + public const string Battery1Bar = Material.Rounded.Battery1Bar; + public const string Battery2Bar = Material.Rounded.Battery2Bar; + public const string Battery3Bar = Material.Rounded.Battery3Bar; + public const string Battery4Bar = Material.Rounded.Battery4Bar; + public const string Battery5Bar = Material.Rounded.Battery5Bar; + public const string Battery6Bar = Material.Rounded.Battery6Bar; + public const string BatteryAlert = Material.Rounded.BatteryAlert; + public const string BatteryChargingFull = Material.Rounded.BatteryChargingFull; + public const string BatteryFull = Material.Rounded.BatteryFull; + public const string BatterySaver = Material.Rounded.BatterySaver; + public const string BatteryStd = Material.Rounded.BatteryStd; + public const string BatteryUnknown = Material.Rounded.BatteryUnknown; + public const string BeachAccess = Material.Rounded.BeachAccess; + public const string Bed = Material.Rounded.Bed; + public const string BedroomBaby = Material.Rounded.BedroomBaby; + public const string BedroomChild = Material.Rounded.BedroomChild; + public const string BedroomParent = Material.Rounded.BedroomParent; + public const string Bedtime = Material.Rounded.Bedtime; + public const string BedtimeOff = Material.Rounded.BedtimeOff; + public const string Beenhere = Material.Rounded.Beenhere; + public const string Bento = Material.Rounded.Bento; + public const string BikeScooter = Material.Rounded.BikeScooter; + public const string Biotech = Material.Rounded.Biotech; + public const string Blender = Material.Rounded.Blender; + public const string Block = Material.Rounded.Block; + public const string Bloodtype = Material.Rounded.Bloodtype; + public const string Bluetooth = Material.Rounded.Bluetooth; + public const string BluetoothAudio = Material.Rounded.BluetoothAudio; + public const string BluetoothConnected = Material.Rounded.BluetoothConnected; + public const string BluetoothDisabled = Material.Rounded.BluetoothDisabled; + public const string BluetoothDrive = Material.Rounded.BluetoothDrive; + public const string BluetoothSearching = Material.Rounded.BluetoothSearching; + public const string BlurCircular = Material.Rounded.BlurCircular; + public const string BlurLinear = Material.Rounded.BlurLinear; + public const string BlurOff = Material.Rounded.BlurOff; + public const string BlurOn = Material.Rounded.BlurOn; + public const string Bolt = Material.Rounded.Bolt; + public const string Book = Material.Rounded.Book; + public const string BookOnline = Material.Rounded.BookOnline; + public const string Bookmark = Material.Rounded.Bookmark; + public const string BookmarkAdd = Material.Rounded.BookmarkAdd; + public const string BookmarkAdded = Material.Rounded.BookmarkAdded; + public const string BookmarkBorder = Material.Rounded.BookmarkBorder; + public const string BookmarkRemove = Material.Rounded.BookmarkRemove; + public const string Bookmarks = Material.Rounded.Bookmarks; + public const string BorderAll = Material.Rounded.BorderAll; + public const string BorderBottom = Material.Rounded.BorderBottom; + public const string BorderClear = Material.Rounded.BorderClear; + public const string BorderColor = Material.Rounded.BorderColor; + public const string BorderHorizontal = Material.Rounded.BorderHorizontal; + public const string BorderInner = Material.Rounded.BorderInner; + public const string BorderLeft = Material.Rounded.BorderLeft; + public const string BorderOuter = Material.Rounded.BorderOuter; + public const string BorderRight = Material.Rounded.BorderRight; + public const string BorderStyle = Material.Rounded.BorderStyle; + public const string BorderTop = Material.Rounded.BorderTop; + public const string BorderVertical = Material.Rounded.BorderVertical; + public const string Boy = Material.Rounded.Boy; + public const string BrandingWatermark = Material.Rounded.BrandingWatermark; + public const string BreakfastDining = Material.Rounded.BreakfastDining; + public const string Brightness1 = Material.Rounded.Brightness1; + public const string Brightness2 = Material.Rounded.Brightness2; + public const string Brightness3 = Material.Rounded.Brightness3; + public const string Brightness4 = Material.Rounded.Brightness4; + public const string Brightness5 = Material.Rounded.Brightness5; + public const string Brightness6 = Material.Rounded.Brightness6; + public const string Brightness7 = Material.Rounded.Brightness7; + public const string BrightnessAuto = Material.Rounded.BrightnessAuto; + public const string BrightnessHigh = Material.Rounded.BrightnessHigh; + public const string BrightnessLow = Material.Rounded.BrightnessLow; + public const string BrightnessMedium = Material.Rounded.BrightnessMedium; + public const string BrokenImage = Material.Rounded.BrokenImage; + public const string BrowseGallery = Material.Rounded.BrowseGallery; + public const string BrowserNotSupported = Material.Rounded.BrowserNotSupported; + public const string BrowserUpdated = Material.Rounded.BrowserUpdated; + public const string BrunchDining = Material.Rounded.BrunchDining; + public const string Brush = Material.Rounded.Brush; + public const string BubbleChart = Material.Rounded.BubbleChart; + public const string BugReport = Material.Rounded.BugReport; + public const string Build = Material.Rounded.Build; + public const string BuildCircle = Material.Rounded.BuildCircle; + public const string Bungalow = Material.Rounded.Bungalow; + public const string BurstMode = Material.Rounded.BurstMode; + public const string BusAlert = Material.Rounded.BusAlert; + public const string Business = Material.Rounded.Business; + public const string BusinessCenter = Material.Rounded.BusinessCenter; + public const string Cabin = Material.Rounded.Cabin; + public const string Cable = Material.Rounded.Cable; + public const string Cached = Material.Rounded.Cached; + public const string Cake = Material.Rounded.Cake; + public const string Calculate = Material.Rounded.Calculate; + public const string CalendarMonth = Material.Rounded.CalendarMonth; + public const string CalendarToday = Material.Rounded.CalendarToday; + public const string CalendarViewDay = Material.Rounded.CalendarViewDay; + public const string CalendarViewMonth = Material.Rounded.CalendarViewMonth; + public const string CalendarViewWeek = Material.Rounded.CalendarViewWeek; + public const string Call = Material.Rounded.Call; + public const string CallEnd = Material.Rounded.CallEnd; + public const string CallMade = Material.Rounded.CallMade; + public const string CallMerge = Material.Rounded.CallMerge; + public const string CallMissed = Material.Rounded.CallMissed; + public const string CallMissedOutgoing = Material.Rounded.CallMissedOutgoing; + public const string CallReceived = Material.Rounded.CallReceived; + public const string CallSplit = Material.Rounded.CallSplit; + public const string CallToAction = Material.Rounded.CallToAction; + public const string Camera = Material.Rounded.Camera; + public const string CameraAlt = Material.Rounded.CameraAlt; + public const string CameraEnhance = Material.Rounded.CameraEnhance; + public const string CameraFront = Material.Rounded.CameraFront; + public const string CameraIndoor = Material.Rounded.CameraIndoor; + public const string CameraOutdoor = Material.Rounded.CameraOutdoor; + public const string CameraRear = Material.Rounded.CameraRear; + public const string CameraRoll = Material.Rounded.CameraRoll; + public const string Cameraswitch = Material.Rounded.Cameraswitch; + public const string Campaign = Material.Rounded.Campaign; + public const string Cancel = Material.Rounded.Cancel; + public const string CancelPresentation = Material.Rounded.CancelPresentation; + public const string CancelScheduleSend = Material.Rounded.CancelScheduleSend; + public const string CandlestickChart = Material.Rounded.CandlestickChart; + public const string CarCrash = Material.Rounded.CarCrash; + public const string CarRental = Material.Rounded.CarRental; + public const string CarRepair = Material.Rounded.CarRepair; + public const string CardGiftcard = Material.Rounded.CardGiftcard; + public const string CardMembership = Material.Rounded.CardMembership; + public const string CardTravel = Material.Rounded.CardTravel; + public const string Carpenter = Material.Rounded.Carpenter; + public const string Cases = Material.Rounded.Cases; + public const string Casino = Material.Rounded.Casino; + public const string Cast = Material.Rounded.Cast; + public const string CastConnected = Material.Rounded.CastConnected; + public const string CastForEducation = Material.Rounded.CastForEducation; + public const string Castle = Material.Rounded.Castle; + public const string CatchingPokemon = Material.Rounded.CatchingPokemon; + public const string Category = Material.Rounded.Category; + public const string Celebration = Material.Rounded.Celebration; + public const string CellTower = Material.Rounded.CellTower; + public const string CellWifi = Material.Rounded.CellWifi; + public const string CenterFocusStrong = Material.Rounded.CenterFocusStrong; + public const string CenterFocusWeak = Material.Rounded.CenterFocusWeak; + public const string Chair = Material.Rounded.Chair; + public const string ChairAlt = Material.Rounded.ChairAlt; + public const string Chalet = Material.Rounded.Chalet; + public const string ChangeCircle = Material.Rounded.ChangeCircle; + public const string ChangeHistory = Material.Rounded.ChangeHistory; + public const string ChargingStation = Material.Rounded.ChargingStation; + public const string Chat = Material.Rounded.Chat; + public const string ChatBubble = Material.Rounded.ChatBubble; + public const string ChatBubbleOutline = Material.Rounded.ChatBubbleOutline; + public const string Check = Material.Rounded.Check; + public const string CheckBox = Material.Rounded.CheckBox; + public const string CheckBoxOutlineBlank = Material.Rounded.CheckBoxOutlineBlank; + public const string CheckCircle = Material.Rounded.CheckCircle; + public const string CheckCircleOutline = Material.Rounded.CheckCircleOutline; + public const string Checklist = Material.Rounded.Checklist; + public const string ChecklistRtl = Material.Rounded.ChecklistRtl; + public const string Checkroom = Material.Rounded.Checkroom; + public const string ChevronLeft = Material.Rounded.ChevronLeft; + public const string ChevronRight = Material.Rounded.ChevronRight; + public const string ChildCare = Material.Rounded.ChildCare; + public const string ChildFriendly = Material.Rounded.ChildFriendly; + public const string ChromeReaderMode = Material.Rounded.ChromeReaderMode; + public const string Church = Material.Rounded.Church; + public const string Circle = Material.Rounded.Circle; + public const string CircleNotifications = Material.Rounded.CircleNotifications; + public const string Class = Material.Rounded.Class; + public const string CleanHands = Material.Rounded.CleanHands; + public const string CleaningServices = Material.Rounded.CleaningServices; + public const string Clear = Material.Rounded.Clear; + public const string ClearAll = Material.Rounded.ClearAll; + public const string Close = Material.Rounded.Close; + public const string CloseFullscreen = Material.Rounded.CloseFullscreen; + public const string ClosedCaption = Material.Rounded.ClosedCaption; + public const string ClosedCaptionDisabled = Material.Rounded.ClosedCaptionDisabled; + public const string ClosedCaptionOff = Material.Rounded.ClosedCaptionOff; + public const string Cloud = Material.Rounded.Cloud; + public const string CloudCircle = Material.Rounded.CloudCircle; + public const string CloudDone = Material.Rounded.CloudDone; + public const string CloudDownload = Material.Rounded.CloudDownload; + public const string CloudOff = Material.Rounded.CloudOff; + public const string CloudQueue = Material.Rounded.CloudQueue; + public const string CloudSync = Material.Rounded.CloudSync; + public const string CloudUpload = Material.Rounded.CloudUpload; + public const string Co2 = Material.Rounded.Co2; + public const string CoPresent = Material.Rounded.CoPresent; + public const string Code = Material.Rounded.Code; + public const string CodeOff = Material.Rounded.CodeOff; + public const string Coffee = Material.Rounded.Coffee; + public const string CoffeeMaker = Material.Rounded.CoffeeMaker; + public const string Collections = Material.Rounded.Collections; + public const string CollectionsBookmark = Material.Rounded.CollectionsBookmark; + public const string ColorLens = Material.Rounded.ColorLens; + public const string Colorize = Material.Rounded.Colorize; + public const string Comment = Material.Rounded.Comment; + public const string CommentBank = Material.Rounded.CommentBank; + public const string CommentsDisabled = Material.Rounded.CommentsDisabled; + public const string Commit = Material.Rounded.Commit; + public const string Commute = Material.Rounded.Commute; + public const string Compare = Material.Rounded.Compare; + public const string CompareArrows = Material.Rounded.CompareArrows; + public const string CompassCalibration = Material.Rounded.CompassCalibration; + public const string Compost = Material.Rounded.Compost; + public const string Compress = Material.Rounded.Compress; + public const string Computer = Material.Rounded.Computer; + public const string ConfirmationNumber = Material.Rounded.ConfirmationNumber; + public const string ConnectWithoutContact = Material.Rounded.ConnectWithoutContact; + public const string ConnectedTv = Material.Rounded.ConnectedTv; + public const string ConnectingAirports = Material.Rounded.ConnectingAirports; + public const string Construction = Material.Rounded.Construction; + public const string ContactMail = Material.Rounded.ContactMail; + public const string ContactPage = Material.Rounded.ContactPage; + public const string ContactPhone = Material.Rounded.ContactPhone; + public const string ContactSupport = Material.Rounded.ContactSupport; + public const string Contactless = Material.Rounded.Contactless; + public const string Contacts = Material.Rounded.Contacts; + public const string ContentCopy = Material.Rounded.ContentCopy; + public const string ContentCut = Material.Rounded.ContentCut; + public const string ContentPaste = Material.Rounded.ContentPaste; + public const string ContentPasteGo = Material.Rounded.ContentPasteGo; + public const string ContentPasteOff = Material.Rounded.ContentPasteOff; + public const string ContentPasteSearch = Material.Rounded.ContentPasteSearch; + public const string Contrast = Material.Rounded.Contrast; + public const string ControlCamera = Material.Rounded.ControlCamera; + public const string ControlPoint = Material.Rounded.ControlPoint; + public const string ControlPointDuplicate = Material.Rounded.ControlPointDuplicate; + public const string Cookie = Material.Rounded.Cookie; + public const string CopyAll = Material.Rounded.CopyAll; + public const string Copyright = Material.Rounded.Copyright; + public const string Coronavirus = Material.Rounded.Coronavirus; + public const string CorporateFare = Material.Rounded.CorporateFare; + public const string Cottage = Material.Rounded.Cottage; + public const string Countertops = Material.Rounded.Countertops; + public const string Create = Material.Rounded.Create; + public const string CreateNewFolder = Material.Rounded.CreateNewFolder; + public const string CreditCard = Material.Rounded.CreditCard; + public const string CreditCardOff = Material.Rounded.CreditCardOff; + public const string CreditScore = Material.Rounded.CreditScore; + public const string Crib = Material.Rounded.Crib; + public const string CrisisAlert = Material.Rounded.CrisisAlert; + public const string Crop = Material.Rounded.Crop; + public const string Crop169 = Material.Rounded.Crop169; + public const string Crop32 = Material.Rounded.Crop32; + public const string Crop54 = Material.Rounded.Crop54; + public const string Crop75 = Material.Rounded.Crop75; + public const string CropDin = Material.Rounded.CropDin; + public const string CropFree = Material.Rounded.CropFree; + public const string CropLandscape = Material.Rounded.CropLandscape; + public const string CropOriginal = Material.Rounded.CropOriginal; + public const string CropPortrait = Material.Rounded.CropPortrait; + public const string CropRotate = Material.Rounded.CropRotate; + public const string CropSquare = Material.Rounded.CropSquare; + public const string CrueltyFree = Material.Rounded.CrueltyFree; + public const string Css = Material.Rounded.Css; + public const string CurrencyBitcoin = Material.Rounded.CurrencyBitcoin; + public const string CurrencyExchange = Material.Rounded.CurrencyExchange; + public const string CurrencyFranc = Material.Rounded.CurrencyFranc; + public const string CurrencyLira = Material.Rounded.CurrencyLira; + public const string CurrencyPound = Material.Rounded.CurrencyPound; + public const string CurrencyRuble = Material.Rounded.CurrencyRuble; + public const string CurrencyRupee = Material.Rounded.CurrencyRupee; + public const string CurrencyYen = Material.Rounded.CurrencyYen; + public const string CurrencyYuan = Material.Rounded.CurrencyYuan; + public const string Cyclone = Material.Rounded.Cyclone; + public const string Dangerous = Material.Rounded.Dangerous; + public const string DarkMode = Material.Rounded.DarkMode; + public const string Dashboard = Material.Rounded.Dashboard; + public const string DashboardCustomize = Material.Rounded.DashboardCustomize; + public const string DataArray = Material.Rounded.DataArray; + public const string DataExploration = Material.Rounded.DataExploration; + public const string DataObject = Material.Rounded.DataObject; + public const string DataSaverOff = Material.Rounded.DataSaverOff; + public const string DataSaverOn = Material.Rounded.DataSaverOn; + public const string DataThresholding = Material.Rounded.DataThresholding; + public const string DataUsage = Material.Rounded.DataUsage; + public const string DateRange = Material.Rounded.DateRange; + public const string Deblur = Material.Rounded.Deblur; + public const string Deck = Material.Rounded.Deck; + public const string Dehaze = Material.Rounded.Dehaze; + public const string Delete = Material.Rounded.Delete; + public const string DeleteForever = Material.Rounded.DeleteForever; + public const string DeleteOutline = Material.Rounded.DeleteOutline; + public const string DeleteSweep = Material.Rounded.DeleteSweep; + public const string DeliveryDining = Material.Rounded.DeliveryDining; + public const string DensityLarge = Material.Rounded.DensityLarge; + public const string DensityMedium = Material.Rounded.DensityMedium; + public const string DensitySmall = Material.Rounded.DensitySmall; + public const string DepartureBoard = Material.Rounded.DepartureBoard; + public const string Description = Material.Rounded.Description; + public const string Deselect = Material.Rounded.Deselect; + public const string DesignServices = Material.Rounded.DesignServices; + public const string DesktopAccessDisabled = Material.Rounded.DesktopAccessDisabled; + public const string DesktopMac = Material.Rounded.DesktopMac; + public const string DesktopWindows = Material.Rounded.DesktopWindows; + public const string Details = Material.Rounded.Details; + public const string DeveloperBoard = Material.Rounded.DeveloperBoard; + public const string DeveloperBoardOff = Material.Rounded.DeveloperBoardOff; + public const string DeveloperMode = Material.Rounded.DeveloperMode; + public const string DeviceHub = Material.Rounded.DeviceHub; + public const string DeviceThermostat = Material.Rounded.DeviceThermostat; + public const string DeviceUnknown = Material.Rounded.DeviceUnknown; + public const string Devices = Material.Rounded.Devices; + public const string DevicesFold = Material.Rounded.DevicesFold; + public const string DevicesOther = Material.Rounded.DevicesOther; + public const string DialerSip = Material.Rounded.DialerSip; + public const string Dialpad = Material.Rounded.Dialpad; + public const string Diamond = Material.Rounded.Diamond; + public const string Difference = Material.Rounded.Difference; + public const string Dining = Material.Rounded.Dining; + public const string DinnerDining = Material.Rounded.DinnerDining; + public const string Directions = Material.Rounded.Directions; + public const string DirectionsBike = Material.Rounded.DirectionsBike; + public const string DirectionsBoat = Material.Rounded.DirectionsBoat; + public const string DirectionsBoatFilled = Material.Rounded.DirectionsBoatFilled; + public const string DirectionsBus = Material.Rounded.DirectionsBus; + public const string DirectionsBusFilled = Material.Rounded.DirectionsBusFilled; + public const string DirectionsCar = Material.Rounded.DirectionsCar; + public const string DirectionsCarFilled = Material.Rounded.DirectionsCarFilled; + public const string DirectionsOff = Material.Rounded.DirectionsOff; + public const string DirectionsRailway = Material.Rounded.DirectionsRailway; + public const string DirectionsRailwayFilled = Material.Rounded.DirectionsRailwayFilled; + public const string DirectionsRun = Material.Rounded.DirectionsRun; + public const string DirectionsSubway = Material.Rounded.DirectionsSubway; + public const string DirectionsSubwayFilled = Material.Rounded.DirectionsSubwayFilled; + public const string DirectionsTransit = Material.Rounded.DirectionsTransit; + public const string DirectionsTransitFilled = Material.Rounded.DirectionsTransitFilled; + public const string DirectionsWalk = Material.Rounded.DirectionsWalk; + public const string DirtyLens = Material.Rounded.DirtyLens; + public const string DisabledByDefault = Material.Rounded.DisabledByDefault; + public const string DisabledVisible = Material.Rounded.DisabledVisible; + public const string DiscFull = Material.Rounded.DiscFull; + public const string Discount = Material.Rounded.Discount; + public const string DisplaySettings = Material.Rounded.DisplaySettings; + public const string Dns = Material.Rounded.Dns; + public const string DoDisturb = Material.Rounded.DoDisturb; + public const string DoDisturbAlt = Material.Rounded.DoDisturbAlt; + public const string DoDisturbOff = Material.Rounded.DoDisturbOff; + public const string DoDisturbOn = Material.Rounded.DoDisturbOn; + public const string DoNotDisturb = Material.Rounded.DoNotDisturb; + public const string DoNotDisturbAlt = Material.Rounded.DoNotDisturbAlt; + public const string DoNotDisturbOff = Material.Rounded.DoNotDisturbOff; + public const string DoNotDisturbOn = Material.Rounded.DoNotDisturbOn; + public const string DoNotDisturbOnTotalSilence = Material.Rounded.DoNotDisturbOnTotalSilence; + public const string DoNotStep = Material.Rounded.DoNotStep; + public const string DoNotTouch = Material.Rounded.DoNotTouch; + public const string Dock = Material.Rounded.Dock; + public const string DocumentScanner = Material.Rounded.DocumentScanner; + public const string Domain = Material.Rounded.Domain; + public const string DomainAdd = Material.Rounded.DomainAdd; + public const string DomainDisabled = Material.Rounded.DomainDisabled; + public const string DomainVerification = Material.Rounded.DomainVerification; + public const string Done = Material.Rounded.Done; + public const string DoneAll = Material.Rounded.DoneAll; + public const string DoneOutline = Material.Rounded.DoneOutline; + public const string DonutLarge = Material.Rounded.DonutLarge; + public const string DonutSmall = Material.Rounded.DonutSmall; + public const string DoorBack = Material.Rounded.DoorBack; + public const string DoorFront = Material.Rounded.DoorFront; + public const string DoorSliding = Material.Rounded.DoorSliding; + public const string Doorbell = Material.Rounded.Doorbell; + public const string DoubleArrow = Material.Rounded.DoubleArrow; + public const string DownhillSkiing = Material.Rounded.DownhillSkiing; + public const string Download = Material.Rounded.Download; + public const string DownloadDone = Material.Rounded.DownloadDone; + public const string DownloadForOffline = Material.Rounded.DownloadForOffline; + public const string Downloading = Material.Rounded.Downloading; + public const string Drafts = Material.Rounded.Drafts; + public const string DragHandle = Material.Rounded.DragHandle; + public const string DragIndicator = Material.Rounded.DragIndicator; + public const string Draw = Material.Rounded.Draw; + public const string DriveEta = Material.Rounded.DriveEta; + public const string DriveFileMove = Material.Rounded.DriveFileMove; + public const string DriveFileMoveRtl = Material.Rounded.DriveFileMoveRtl; + public const string DriveFileRenameOutline = Material.Rounded.DriveFileRenameOutline; + public const string DriveFolderUpload = Material.Rounded.DriveFolderUpload; + public const string Dry = Material.Rounded.Dry; + public const string DryCleaning = Material.Rounded.DryCleaning; + public const string Duo = Material.Rounded.Duo; + public const string Dvr = Material.Rounded.Dvr; + public const string DynamicFeed = Material.Rounded.DynamicFeed; + public const string DynamicForm = Material.Rounded.DynamicForm; + public const string EMobiledata = Material.Rounded.EMobiledata; + public const string Earbuds = Material.Rounded.Earbuds; + public const string EarbudsBattery = Material.Rounded.EarbudsBattery; + public const string East = Material.Rounded.East; + public const string EdgesensorHigh = Material.Rounded.EdgesensorHigh; + public const string EdgesensorLow = Material.Rounded.EdgesensorLow; + public const string Edit = Material.Rounded.Edit; + public const string EditAttributes = Material.Rounded.EditAttributes; + public const string EditCalendar = Material.Rounded.EditCalendar; + public const string EditLocation = Material.Rounded.EditLocation; + public const string EditLocationAlt = Material.Rounded.EditLocationAlt; + public const string EditNote = Material.Rounded.EditNote; + public const string EditNotifications = Material.Rounded.EditNotifications; + public const string EditOff = Material.Rounded.EditOff; + public const string EditRoad = Material.Rounded.EditRoad; + public const string Egg = Material.Rounded.Egg; + public const string EggAlt = Material.Rounded.EggAlt; + public const string Eject = Material.Rounded.Eject; + public const string Elderly = Material.Rounded.Elderly; + public const string ElderlyWoman = Material.Rounded.ElderlyWoman; + public const string ElectricBike = Material.Rounded.ElectricBike; + public const string ElectricCar = Material.Rounded.ElectricCar; + public const string ElectricMoped = Material.Rounded.ElectricMoped; + public const string ElectricRickshaw = Material.Rounded.ElectricRickshaw; + public const string ElectricScooter = Material.Rounded.ElectricScooter; + public const string ElectricalServices = Material.Rounded.ElectricalServices; + public const string Elevator = Material.Rounded.Elevator; + public const string Email = Material.Rounded.Email; + public const string Emergency = Material.Rounded.Emergency; + public const string EmergencyRecording = Material.Rounded.EmergencyRecording; + public const string EmergencyShare = Material.Rounded.EmergencyShare; + public const string EmojiEmotions = Material.Rounded.EmojiEmotions; + public const string EmojiEvents = Material.Rounded.EmojiEvents; + public const string EmojiFoodBeverage = Material.Rounded.EmojiFoodBeverage; + public const string EmojiNature = Material.Rounded.EmojiNature; + public const string EmojiObjects = Material.Rounded.EmojiObjects; + public const string EmojiPeople = Material.Rounded.EmojiPeople; + public const string EmojiSymbols = Material.Rounded.EmojiSymbols; + public const string EmojiTransportation = Material.Rounded.EmojiTransportation; + public const string Engineering = Material.Rounded.Engineering; + public const string EnhancedEncryption = Material.Rounded.EnhancedEncryption; + public const string Equalizer = Material.Rounded.Equalizer; + public const string Error = Material.Rounded.Error; + public const string ErrorOutline = Material.Rounded.ErrorOutline; + public const string Escalator = Material.Rounded.Escalator; + public const string EscalatorWarning = Material.Rounded.EscalatorWarning; + public const string Euro = Material.Rounded.Euro; + public const string EuroSymbol = Material.Rounded.EuroSymbol; + public const string EvStation = Material.Rounded.EvStation; + public const string Event = Material.Rounded.Event; + public const string EventAvailable = Material.Rounded.EventAvailable; + public const string EventBusy = Material.Rounded.EventBusy; + public const string EventNote = Material.Rounded.EventNote; + public const string EventRepeat = Material.Rounded.EventRepeat; + public const string EventSeat = Material.Rounded.EventSeat; + public const string ExitToApp = Material.Rounded.ExitToApp; + public const string Expand = Material.Rounded.Expand; + public const string ExpandCircleDown = Material.Rounded.ExpandCircleDown; + public const string ExpandLess = Material.Rounded.ExpandLess; + public const string ExpandMore = Material.Rounded.ExpandMore; + public const string Explicit = Material.Rounded.Explicit; + public const string Explore = Material.Rounded.Explore; + public const string ExploreOff = Material.Rounded.ExploreOff; + public const string Exposure = Material.Rounded.Exposure; + public const string ExposureNeg1 = Material.Rounded.ExposureNeg1; + public const string ExposureNeg2 = Material.Rounded.ExposureNeg2; + public const string ExposurePlus1 = Material.Rounded.ExposurePlus1; + public const string ExposurePlus2 = Material.Rounded.ExposurePlus2; + public const string ExposureZero = Material.Rounded.ExposureZero; + public const string Extension = Material.Rounded.Extension; + public const string ExtensionOff = Material.Rounded.ExtensionOff; + public const string Face = Material.Rounded.Face; + public const string FaceRetouchingNatural = Material.Rounded.FaceRetouchingNatural; + public const string FaceRetouchingOff = Material.Rounded.FaceRetouchingOff; + public const string FactCheck = Material.Rounded.FactCheck; + public const string Factory = Material.Rounded.Factory; + public const string FamilyRestroom = Material.Rounded.FamilyRestroom; + public const string FastForward = Material.Rounded.FastForward; + public const string FastRewind = Material.Rounded.FastRewind; + public const string Fastfood = Material.Rounded.Fastfood; + public const string Favorite = Material.Rounded.Favorite; + public const string FavoriteBorder = Material.Rounded.FavoriteBorder; + public const string Fax = Material.Rounded.Fax; + public const string FeaturedPlayList = Material.Rounded.FeaturedPlayList; + public const string FeaturedVideo = Material.Rounded.FeaturedVideo; + public const string Feed = Material.Rounded.Feed; + public const string Feedback = Material.Rounded.Feedback; + public const string Female = Material.Rounded.Female; + public const string Fence = Material.Rounded.Fence; + public const string Festival = Material.Rounded.Festival; + public const string FiberDvr = Material.Rounded.FiberDvr; + public const string FiberManualRecord = Material.Rounded.FiberManualRecord; + public const string FiberNew = Material.Rounded.FiberNew; + public const string FiberPin = Material.Rounded.FiberPin; + public const string FiberSmartRecord = Material.Rounded.FiberSmartRecord; + public const string FileCopy = Material.Rounded.FileCopy; + public const string FileDownload = Material.Rounded.FileDownload; + public const string FileDownloadDone = Material.Rounded.FileDownloadDone; + public const string FileDownloadOff = Material.Rounded.FileDownloadOff; + public const string FileOpen = Material.Rounded.FileOpen; + public const string FilePresent = Material.Rounded.FilePresent; + public const string FileUpload = Material.Rounded.FileUpload; + public const string Filter = Material.Rounded.Filter; + public const string Filter1 = Material.Rounded.Filter1; + public const string Filter2 = Material.Rounded.Filter2; + public const string Filter3 = Material.Rounded.Filter3; + public const string Filter4 = Material.Rounded.Filter4; + public const string Filter5 = Material.Rounded.Filter5; + public const string Filter6 = Material.Rounded.Filter6; + public const string Filter7 = Material.Rounded.Filter7; + public const string Filter8 = Material.Rounded.Filter8; + public const string Filter9 = Material.Rounded.Filter9; + public const string Filter9Plus = Material.Rounded.Filter9Plus; + public const string FilterAlt = Material.Rounded.FilterAlt; + public const string FilterAltOff = Material.Rounded.FilterAltOff; + public const string FilterBAndW = Material.Rounded.FilterBAndW; + public const string FilterCenterFocus = Material.Rounded.FilterCenterFocus; + public const string FilterDrama = Material.Rounded.FilterDrama; + public const string FilterFrames = Material.Rounded.FilterFrames; + public const string FilterHdr = Material.Rounded.FilterHdr; + public const string FilterList = Material.Rounded.FilterList; + public const string FilterListOff = Material.Rounded.FilterListOff; + public const string FilterNone = Material.Rounded.FilterNone; + public const string FilterTiltShift = Material.Rounded.FilterTiltShift; + public const string FilterVintage = Material.Rounded.FilterVintage; + public const string FindInPage = Material.Rounded.FindInPage; + public const string FindReplace = Material.Rounded.FindReplace; + public const string Fingerprint = Material.Rounded.Fingerprint; + public const string FireExtinguisher = Material.Rounded.FireExtinguisher; + public const string Fireplace = Material.Rounded.Fireplace; + public const string FirstPage = Material.Rounded.FirstPage; + public const string FitScreen = Material.Rounded.FitScreen; + public const string Fitbit = Material.Rounded.Fitbit; + public const string FitnessCenter = Material.Rounded.FitnessCenter; + public const string Flag = Material.Rounded.Flag; + public const string FlagCircle = Material.Rounded.FlagCircle; + public const string Flaky = Material.Rounded.Flaky; + public const string Flare = Material.Rounded.Flare; + public const string FlashAuto = Material.Rounded.FlashAuto; + public const string FlashOff = Material.Rounded.FlashOff; + public const string FlashOn = Material.Rounded.FlashOn; + public const string FlashlightOff = Material.Rounded.FlashlightOff; + public const string FlashlightOn = Material.Rounded.FlashlightOn; + public const string Flatware = Material.Rounded.Flatware; + public const string Flight = Material.Rounded.Flight; + public const string FlightClass = Material.Rounded.FlightClass; + public const string FlightLand = Material.Rounded.FlightLand; + public const string FlightTakeoff = Material.Rounded.FlightTakeoff; + public const string Flip = Material.Rounded.Flip; + public const string FlipCameraAndroid = Material.Rounded.FlipCameraAndroid; + public const string FlipCameraIos = Material.Rounded.FlipCameraIos; + public const string FlipToBack = Material.Rounded.FlipToBack; + public const string FlipToFront = Material.Rounded.FlipToFront; + public const string Flood = Material.Rounded.Flood; + public const string Flourescent = Material.Rounded.Flourescent; + public const string FlutterDash = Material.Rounded.FlutterDash; + public const string FmdBad = Material.Rounded.FmdBad; + public const string FmdGood = Material.Rounded.FmdGood; + public const string Folder = Material.Rounded.Folder; + public const string FolderCopy = Material.Rounded.FolderCopy; + public const string FolderDelete = Material.Rounded.FolderDelete; + public const string FolderOff = Material.Rounded.FolderOff; + public const string FolderOpen = Material.Rounded.FolderOpen; + public const string FolderShared = Material.Rounded.FolderShared; + public const string FolderSpecial = Material.Rounded.FolderSpecial; + public const string FolderZip = Material.Rounded.FolderZip; + public const string FollowTheSigns = Material.Rounded.FollowTheSigns; + public const string FontDownload = Material.Rounded.FontDownload; + public const string FontDownloadOff = Material.Rounded.FontDownloadOff; + public const string FoodBank = Material.Rounded.FoodBank; + public const string Forest = Material.Rounded.Forest; + public const string ForkLeft = Material.Rounded.ForkLeft; + public const string ForkRight = Material.Rounded.ForkRight; + public const string FormatAlignCenter = Material.Rounded.FormatAlignCenter; + public const string FormatAlignJustify = Material.Rounded.FormatAlignJustify; + public const string FormatAlignLeft = Material.Rounded.FormatAlignLeft; + public const string FormatAlignRight = Material.Rounded.FormatAlignRight; + public const string FormatBold = Material.Rounded.FormatBold; + public const string FormatClear = Material.Rounded.FormatClear; + public const string FormatColorFill = Material.Rounded.FormatColorFill; + public const string FormatColorReset = Material.Rounded.FormatColorReset; + public const string FormatColorText = Material.Rounded.FormatColorText; + public const string FormatIndentDecrease = Material.Rounded.FormatIndentDecrease; + public const string FormatIndentIncrease = Material.Rounded.FormatIndentIncrease; + public const string FormatItalic = Material.Rounded.FormatItalic; + public const string FormatLineSpacing = Material.Rounded.FormatLineSpacing; + public const string FormatListBulleted = Material.Rounded.FormatListBulleted; + public const string FormatListNumbered = Material.Rounded.FormatListNumbered; + public const string FormatListNumberedRtl = Material.Rounded.FormatListNumberedRtl; + public const string FormatOverline = Material.Rounded.FormatOverline; + public const string FormatPaint = Material.Rounded.FormatPaint; + public const string FormatQuote = Material.Rounded.FormatQuote; + public const string FormatShapes = Material.Rounded.FormatShapes; + public const string FormatSize = Material.Rounded.FormatSize; + public const string FormatStrikethrough = Material.Rounded.FormatStrikethrough; + public const string FormatTextdirectionLToR = Material.Rounded.FormatTextdirectionLToR; + public const string FormatTextdirectionRToL = Material.Rounded.FormatTextdirectionRToL; + public const string FormatUnderlined = Material.Rounded.FormatUnderlined; + public const string Fort = Material.Rounded.Fort; + public const string Forum = Material.Rounded.Forum; + public const string Forward = Material.Rounded.Forward; + public const string Forward10 = Material.Rounded.Forward10; + public const string Forward30 = Material.Rounded.Forward30; + public const string Forward5 = Material.Rounded.Forward5; + public const string ForwardToInbox = Material.Rounded.ForwardToInbox; + public const string Foundation = Material.Rounded.Foundation; + public const string FreeBreakfast = Material.Rounded.FreeBreakfast; + public const string FreeCancellation = Material.Rounded.FreeCancellation; + public const string FrontHand = Material.Rounded.FrontHand; + public const string Fullscreen = Material.Rounded.Fullscreen; + public const string FullscreenExit = Material.Rounded.FullscreenExit; + public const string Functions = Material.Rounded.Functions; + public const string GMobiledata = Material.Rounded.GMobiledata; + public const string GTranslate = Material.Rounded.GTranslate; + public const string Gamepad = Material.Rounded.Gamepad; + public const string Games = Material.Rounded.Games; + public const string Garage = Material.Rounded.Garage; + public const string Gavel = Material.Rounded.Gavel; + public const string GeneratingTokens = Material.Rounded.GeneratingTokens; + public const string Gesture = Material.Rounded.Gesture; + public const string GetApp = Material.Rounded.GetApp; + public const string Gif = Material.Rounded.Gif; + public const string GifBox = Material.Rounded.GifBox; + public const string Girl = Material.Rounded.Girl; + public const string Gite = Material.Rounded.Gite; + public const string GolfCourse = Material.Rounded.GolfCourse; + public const string GppBad = Material.Rounded.GppBad; + public const string GppGood = Material.Rounded.GppGood; + public const string GppMaybe = Material.Rounded.GppMaybe; + public const string GpsFixed = Material.Rounded.GpsFixed; + public const string GpsNotFixed = Material.Rounded.GpsNotFixed; + public const string GpsOff = Material.Rounded.GpsOff; + public const string Grade = Material.Rounded.Grade; + public const string Gradient = Material.Rounded.Gradient; + public const string Grading = Material.Rounded.Grading; + public const string Grain = Material.Rounded.Grain; + public const string GraphicEq = Material.Rounded.GraphicEq; + public const string Grass = Material.Rounded.Grass; + public const string Grid3x3 = Material.Rounded.Grid3x3; + public const string Grid4x4 = Material.Rounded.Grid4x4; + public const string GridGoldenratio = Material.Rounded.GridGoldenratio; + public const string GridOff = Material.Rounded.GridOff; + public const string GridOn = Material.Rounded.GridOn; + public const string GridView = Material.Rounded.GridView; + public const string Group = Material.Rounded.Group; + public const string GroupAdd = Material.Rounded.GroupAdd; + public const string GroupOff = Material.Rounded.GroupOff; + public const string GroupRemove = Material.Rounded.GroupRemove; + public const string GroupWork = Material.Rounded.GroupWork; + public const string Groups = Material.Rounded.Groups; + public const string HMobiledata = Material.Rounded.HMobiledata; + public const string HPlusMobiledata = Material.Rounded.HPlusMobiledata; + public const string Hail = Material.Rounded.Hail; + public const string Handshake = Material.Rounded.Handshake; + public const string Handyman = Material.Rounded.Handyman; + public const string Hardware = Material.Rounded.Hardware; + public const string Hd = Material.Rounded.Hd; + public const string HdrAuto = Material.Rounded.HdrAuto; + public const string HdrAutoSelect = Material.Rounded.HdrAutoSelect; + public const string HdrEnhancedSelect = Material.Rounded.HdrEnhancedSelect; + public const string HdrOff = Material.Rounded.HdrOff; + public const string HdrOffSelect = Material.Rounded.HdrOffSelect; + public const string HdrOn = Material.Rounded.HdrOn; + public const string HdrOnSelect = Material.Rounded.HdrOnSelect; + public const string HdrPlus = Material.Rounded.HdrPlus; + public const string HdrStrong = Material.Rounded.HdrStrong; + public const string HdrWeak = Material.Rounded.HdrWeak; + public const string Headphones = Material.Rounded.Headphones; + public const string HeadphonesBattery = Material.Rounded.HeadphonesBattery; + public const string Headset = Material.Rounded.Headset; + public const string HeadsetMic = Material.Rounded.HeadsetMic; + public const string HeadsetOff = Material.Rounded.HeadsetOff; + public const string Healing = Material.Rounded.Healing; + public const string HealthAndSafety = Material.Rounded.HealthAndSafety; + public const string Hearing = Material.Rounded.Hearing; + public const string HearingDisabled = Material.Rounded.HearingDisabled; + public const string HeartBroken = Material.Rounded.HeartBroken; + public const string Height = Material.Rounded.Height; + public const string Help = Material.Rounded.Help; + public const string HelpCenter = Material.Rounded.HelpCenter; + public const string HelpOutline = Material.Rounded.HelpOutline; + public const string Hevc = Material.Rounded.Hevc; + public const string Hexagon = Material.Rounded.Hexagon; + public const string HideImage = Material.Rounded.HideImage; + public const string HideSource = Material.Rounded.HideSource; + public const string HighQuality = Material.Rounded.HighQuality; + public const string Highlight = Material.Rounded.Highlight; + public const string HighlightAlt = Material.Rounded.HighlightAlt; + public const string HighlightOff = Material.Rounded.HighlightOff; + public const string Hiking = Material.Rounded.Hiking; + public const string History = Material.Rounded.History; + public const string HistoryEdu = Material.Rounded.HistoryEdu; + public const string HistoryToggleOff = Material.Rounded.HistoryToggleOff; + public const string Hive = Material.Rounded.Hive; + public const string Hls = Material.Rounded.Hls; + public const string HlsOff = Material.Rounded.HlsOff; + public const string HolidayVillage = Material.Rounded.HolidayVillage; + public const string Home = Material.Rounded.Home; + public const string HomeMax = Material.Rounded.HomeMax; + public const string HomeMini = Material.Rounded.HomeMini; + public const string HomeRepairService = Material.Rounded.HomeRepairService; + public const string HomeWork = Material.Rounded.HomeWork; + public const string HorizontalDistribute = Material.Rounded.HorizontalDistribute; + public const string HorizontalRule = Material.Rounded.HorizontalRule; + public const string HorizontalSplit = Material.Rounded.HorizontalSplit; + public const string HotTub = Material.Rounded.HotTub; + public const string Hotel = Material.Rounded.Hotel; + public const string HotelClass = Material.Rounded.HotelClass; + public const string HourglassBottom = Material.Rounded.HourglassBottom; + public const string HourglassDisabled = Material.Rounded.HourglassDisabled; + public const string HourglassEmpty = Material.Rounded.HourglassEmpty; + public const string HourglassFull = Material.Rounded.HourglassFull; + public const string HourglassTop = Material.Rounded.HourglassTop; + public const string House = Material.Rounded.House; + public const string HouseSiding = Material.Rounded.HouseSiding; + public const string Houseboat = Material.Rounded.Houseboat; + public const string HowToReg = Material.Rounded.HowToReg; + public const string HowToVote = Material.Rounded.HowToVote; + public const string Html = Material.Rounded.Html; + public const string Http = Material.Rounded.Http; + public const string Https = Material.Rounded.Https; + public const string Hub = Material.Rounded.Hub; + public const string Hvac = Material.Rounded.Hvac; + public const string IceSkating = Material.Rounded.IceSkating; + public const string Icecream = Material.Rounded.Icecream; + public const string Image = Material.Rounded.Image; + public const string ImageAspectRatio = Material.Rounded.ImageAspectRatio; + public const string ImageNotSupported = Material.Rounded.ImageNotSupported; + public const string ImageSearch = Material.Rounded.ImageSearch; + public const string ImagesearchRoller = Material.Rounded.ImagesearchRoller; + public const string ImportContacts = Material.Rounded.ImportContacts; + public const string ImportExport = Material.Rounded.ImportExport; + public const string ImportantDevices = Material.Rounded.ImportantDevices; + public const string Inbox = Material.Rounded.Inbox; + public const string IncompleteCircle = Material.Rounded.IncompleteCircle; + public const string IndeterminateCheckBox = Material.Rounded.IndeterminateCheckBox; + public const string Info = Material.Rounded.Info; + public const string Input = Material.Rounded.Input; + public const string InsertChart = Material.Rounded.InsertChart; + public const string InsertChartOutlined = Material.Rounded.InsertChartOutlined; + public const string InsertComment = Material.Rounded.InsertComment; + public const string InsertDriveFile = Material.Rounded.InsertDriveFile; + public const string InsertEmoticon = Material.Rounded.InsertEmoticon; + public const string InsertInvitation = Material.Rounded.InsertInvitation; + public const string InsertLink = Material.Rounded.InsertLink; + public const string InsertPageBreak = Material.Rounded.InsertPageBreak; + public const string InsertPhoto = Material.Rounded.InsertPhoto; + public const string Insights = Material.Rounded.Insights; + public const string InstallDesktop = Material.Rounded.InstallDesktop; + public const string InstallMobile = Material.Rounded.InstallMobile; + public const string IntegrationInstructions = Material.Rounded.IntegrationInstructions; + public const string Interests = Material.Rounded.Interests; + public const string InterpreterMode = Material.Rounded.InterpreterMode; + public const string Inventory = Material.Rounded.Inventory; + public const string Inventory2 = Material.Rounded.Inventory2; + public const string InvertColors = Material.Rounded.InvertColors; + public const string InvertColorsOff = Material.Rounded.InvertColorsOff; + public const string IosShare = Material.Rounded.IosShare; + public const string Iron = Material.Rounded.Iron; + public const string Iso = Material.Rounded.Iso; + public const string Javascript = Material.Rounded.Javascript; + public const string JoinFull = Material.Rounded.JoinFull; + public const string JoinInner = Material.Rounded.JoinInner; + public const string JoinLeft = Material.Rounded.JoinLeft; + public const string JoinRight = Material.Rounded.JoinRight; + public const string Kayaking = Material.Rounded.Kayaking; + public const string KebabDining = Material.Rounded.KebabDining; + public const string Key = Material.Rounded.Key; + public const string KeyOff = Material.Rounded.KeyOff; + public const string Keyboard = Material.Rounded.Keyboard; + public const string KeyboardAlt = Material.Rounded.KeyboardAlt; + public const string KeyboardArrowDown = Material.Rounded.KeyboardArrowDown; + public const string KeyboardArrowLeft = Material.Rounded.KeyboardArrowLeft; + public const string KeyboardArrowRight = Material.Rounded.KeyboardArrowRight; + public const string KeyboardArrowUp = Material.Rounded.KeyboardArrowUp; + public const string KeyboardBackspace = Material.Rounded.KeyboardBackspace; + public const string KeyboardCapslock = Material.Rounded.KeyboardCapslock; + public const string KeyboardCommandKey = Material.Rounded.KeyboardCommandKey; + public const string KeyboardControlKey = Material.Rounded.KeyboardControlKey; + public const string KeyboardDoubleArrowDown = Material.Rounded.KeyboardDoubleArrowDown; + public const string KeyboardDoubleArrowLeft = Material.Rounded.KeyboardDoubleArrowLeft; + public const string KeyboardDoubleArrowRight = Material.Rounded.KeyboardDoubleArrowRight; + public const string KeyboardDoubleArrowUp = Material.Rounded.KeyboardDoubleArrowUp; + public const string KeyboardHide = Material.Rounded.KeyboardHide; + public const string KeyboardOptionKey = Material.Rounded.KeyboardOptionKey; + public const string KeyboardReturn = Material.Rounded.KeyboardReturn; + public const string KeyboardTab = Material.Rounded.KeyboardTab; + public const string KeyboardVoice = Material.Rounded.KeyboardVoice; + public const string KingBed = Material.Rounded.KingBed; + public const string Kitchen = Material.Rounded.Kitchen; + public const string Kitesurfing = Material.Rounded.Kitesurfing; + public const string Label = Material.Rounded.Label; + public const string LabelImportant = Material.Rounded.LabelImportant; + public const string LabelOff = Material.Rounded.LabelOff; + public const string Lan = Material.Rounded.Lan; + public const string Landscape = Material.Rounded.Landscape; + public const string Landslide = Material.Rounded.Landslide; + public const string Language = Material.Rounded.Language; + public const string Laptop = Material.Rounded.Laptop; + public const string LaptopChromebook = Material.Rounded.LaptopChromebook; + public const string LaptopMac = Material.Rounded.LaptopMac; + public const string LaptopWindows = Material.Rounded.LaptopWindows; + public const string LastPage = Material.Rounded.LastPage; + public const string Launch = Material.Rounded.Launch; + public const string Layers = Material.Rounded.Layers; + public const string LayersClear = Material.Rounded.LayersClear; + public const string Leaderboard = Material.Rounded.Leaderboard; + public const string LeakAdd = Material.Rounded.LeakAdd; + public const string LeakRemove = Material.Rounded.LeakRemove; + public const string LegendToggle = Material.Rounded.LegendToggle; + public const string Lens = Material.Rounded.Lens; + public const string LensBlur = Material.Rounded.LensBlur; + public const string LibraryAdd = Material.Rounded.LibraryAdd; + public const string LibraryAddCheck = Material.Rounded.LibraryAddCheck; + public const string LibraryBooks = Material.Rounded.LibraryBooks; + public const string LibraryMusic = Material.Rounded.LibraryMusic; + public const string Light = Material.Rounded.Light; + public const string LightMode = Material.Rounded.LightMode; + public const string Lightbulb = Material.Rounded.Lightbulb; + public const string LightbulbCircle = Material.Rounded.LightbulbCircle; + public const string LineAxis = Material.Rounded.LineAxis; + public const string LineStyle = Material.Rounded.LineStyle; + public const string LineWeight = Material.Rounded.LineWeight; + public const string LinearScale = Material.Rounded.LinearScale; + public const string Link = Material.Rounded.Link; + public const string LinkOff = Material.Rounded.LinkOff; + public const string LinkedCamera = Material.Rounded.LinkedCamera; + public const string Liquor = Material.Rounded.Liquor; + public const string List = Material.Rounded.List; + public const string ListAlt = Material.Rounded.ListAlt; + public const string LiveHelp = Material.Rounded.LiveHelp; + public const string LiveTv = Material.Rounded.LiveTv; + public const string Living = Material.Rounded.Living; + public const string LocalActivity = Material.Rounded.LocalActivity; + public const string LocalAirport = Material.Rounded.LocalAirport; + public const string LocalAtm = Material.Rounded.LocalAtm; + public const string LocalBar = Material.Rounded.LocalBar; + public const string LocalCafe = Material.Rounded.LocalCafe; + public const string LocalCarWash = Material.Rounded.LocalCarWash; + public const string LocalConvenienceStore = Material.Rounded.LocalConvenienceStore; + public const string LocalDining = Material.Rounded.LocalDining; + public const string LocalDrink = Material.Rounded.LocalDrink; + public const string LocalFireDepartment = Material.Rounded.LocalFireDepartment; + public const string LocalFlorist = Material.Rounded.LocalFlorist; + public const string LocalGasStation = Material.Rounded.LocalGasStation; + public const string LocalGroceryStore = Material.Rounded.LocalGroceryStore; + public const string LocalHospital = Material.Rounded.LocalHospital; + public const string LocalHotel = Material.Rounded.LocalHotel; + public const string LocalLaundryService = Material.Rounded.LocalLaundryService; + public const string LocalLibrary = Material.Rounded.LocalLibrary; + public const string LocalMall = Material.Rounded.LocalMall; + public const string LocalMovies = Material.Rounded.LocalMovies; + public const string LocalOffer = Material.Rounded.LocalOffer; + public const string LocalParking = Material.Rounded.LocalParking; + public const string LocalPharmacy = Material.Rounded.LocalPharmacy; + public const string LocalPhone = Material.Rounded.LocalPhone; + public const string LocalPizza = Material.Rounded.LocalPizza; + public const string LocalPlay = Material.Rounded.LocalPlay; + public const string LocalPolice = Material.Rounded.LocalPolice; + public const string LocalPostOffice = Material.Rounded.LocalPostOffice; + public const string LocalPrintshop = Material.Rounded.LocalPrintshop; + public const string LocalSee = Material.Rounded.LocalSee; + public const string LocalShipping = Material.Rounded.LocalShipping; + public const string LocalTaxi = Material.Rounded.LocalTaxi; + public const string LocationCity = Material.Rounded.LocationCity; + public const string LocationDisabled = Material.Rounded.LocationDisabled; + public const string LocationOff = Material.Rounded.LocationOff; + public const string LocationOn = Material.Rounded.LocationOn; + public const string LocationSearching = Material.Rounded.LocationSearching; + public const string Lock = Material.Rounded.Lock; + public const string LockClock = Material.Rounded.LockClock; + public const string LockOpen = Material.Rounded.LockOpen; + public const string LockReset = Material.Rounded.LockReset; + public const string Login = Material.Rounded.Login; + public const string LogoDev = Material.Rounded.LogoDev; + public const string Logout = Material.Rounded.Logout; + public const string Looks = Material.Rounded.Looks; + public const string Looks3 = Material.Rounded.Looks3; + public const string Looks4 = Material.Rounded.Looks4; + public const string Looks5 = Material.Rounded.Looks5; + public const string Looks6 = Material.Rounded.Looks6; + public const string LooksOne = Material.Rounded.LooksOne; + public const string LooksTwo = Material.Rounded.LooksTwo; + public const string Loop = Material.Rounded.Loop; + public const string Loupe = Material.Rounded.Loupe; + public const string LowPriority = Material.Rounded.LowPriority; + public const string Loyalty = Material.Rounded.Loyalty; + public const string LteMobiledata = Material.Rounded.LteMobiledata; + public const string LtePlusMobiledata = Material.Rounded.LtePlusMobiledata; + public const string Luggage = Material.Rounded.Luggage; + public const string LunchDining = Material.Rounded.LunchDining; + public const string Mail = Material.Rounded.Mail; + public const string MailOutline = Material.Rounded.MailOutline; + public const string Male = Material.Rounded.Male; + public const string Man = Material.Rounded.Man; + public const string ManageAccounts = Material.Rounded.ManageAccounts; + public const string ManageHistory = Material.Rounded.ManageHistory; + public const string ManageSearch = Material.Rounded.ManageSearch; + public const string Map = Material.Rounded.Map; + public const string MapsHomeWork = Material.Rounded.MapsHomeWork; + public const string MapsUgc = Material.Rounded.MapsUgc; + public const string Margin = Material.Rounded.Margin; + public const string MarkAsUnread = Material.Rounded.MarkAsUnread; + public const string MarkChatRead = Material.Rounded.MarkChatRead; + public const string MarkChatUnread = Material.Rounded.MarkChatUnread; + public const string MarkEmailRead = Material.Rounded.MarkEmailRead; + public const string MarkEmailUnread = Material.Rounded.MarkEmailUnread; + public const string MarkUnreadChatAlt = Material.Rounded.MarkUnreadChatAlt; + public const string Markunread = Material.Rounded.Markunread; + public const string MarkunreadMailbox = Material.Rounded.MarkunreadMailbox; + public const string Masks = Material.Rounded.Masks; + public const string Maximize = Material.Rounded.Maximize; + public const string MediaBluetoothOff = Material.Rounded.MediaBluetoothOff; + public const string MediaBluetoothOn = Material.Rounded.MediaBluetoothOn; + public const string Mediation = Material.Rounded.Mediation; + public const string MedicalInformation = Material.Rounded.MedicalInformation; + public const string MedicalServices = Material.Rounded.MedicalServices; + public const string Medication = Material.Rounded.Medication; + public const string MedicationLiquid = Material.Rounded.MedicationLiquid; + public const string MeetingRoom = Material.Rounded.MeetingRoom; + public const string Memory = Material.Rounded.Memory; + public const string Menu = Material.Rounded.Menu; + public const string MenuBook = Material.Rounded.MenuBook; + public const string MenuOpen = Material.Rounded.MenuOpen; + public const string Merge = Material.Rounded.Merge; + public const string MergeType = Material.Rounded.MergeType; + public const string Message = Material.Rounded.Message; + public const string Mic = Material.Rounded.Mic; + public const string MicExternalOff = Material.Rounded.MicExternalOff; + public const string MicExternalOn = Material.Rounded.MicExternalOn; + public const string MicNone = Material.Rounded.MicNone; + public const string MicOff = Material.Rounded.MicOff; + public const string Microwave = Material.Rounded.Microwave; + public const string MilitaryTech = Material.Rounded.MilitaryTech; + public const string Minimize = Material.Rounded.Minimize; + public const string MinorCrash = Material.Rounded.MinorCrash; + public const string MiscellaneousServices = Material.Rounded.MiscellaneousServices; + public const string MissedVideoCall = Material.Rounded.MissedVideoCall; + public const string Mms = Material.Rounded.Mms; + public const string MobileFriendly = Material.Rounded.MobileFriendly; + public const string MobileOff = Material.Rounded.MobileOff; + public const string MobileScreenShare = Material.Rounded.MobileScreenShare; + public const string MobiledataOff = Material.Rounded.MobiledataOff; + public const string Mode = Material.Rounded.Mode; + public const string ModeComment = Material.Rounded.ModeComment; + public const string ModeEdit = Material.Rounded.ModeEdit; + public const string ModeEditOutline = Material.Rounded.ModeEditOutline; + public const string ModeNight = Material.Rounded.ModeNight; + public const string ModeOfTravel = Material.Rounded.ModeOfTravel; + public const string ModeStandby = Material.Rounded.ModeStandby; + public const string ModelTraining = Material.Rounded.ModelTraining; + public const string MonetizationOn = Material.Rounded.MonetizationOn; + public const string Money = Material.Rounded.Money; + public const string MoneyOff = Material.Rounded.MoneyOff; + public const string MoneyOffCsred = Material.Rounded.MoneyOffCsred; + public const string Monitor = Material.Rounded.Monitor; + public const string MonitorHeart = Material.Rounded.MonitorHeart; + public const string MonitorWeight = Material.Rounded.MonitorWeight; + public const string MonochromePhotos = Material.Rounded.MonochromePhotos; + public const string Mood = Material.Rounded.Mood; + public const string MoodBad = Material.Rounded.MoodBad; + public const string Moped = Material.Rounded.Moped; + public const string More = Material.Rounded.More; + public const string MoreHoriz = Material.Rounded.MoreHoriz; + public const string MoreTime = Material.Rounded.MoreTime; + public const string MoreVert = Material.Rounded.MoreVert; + public const string Mosque = Material.Rounded.Mosque; + public const string MotionPhotosAuto = Material.Rounded.MotionPhotosAuto; + public const string MotionPhotosOff = Material.Rounded.MotionPhotosOff; + public const string MotionPhotosOn = Material.Rounded.MotionPhotosOn; + public const string MotionPhotosPause = Material.Rounded.MotionPhotosPause; + public const string MotionPhotosPaused = Material.Rounded.MotionPhotosPaused; + public const string Mouse = Material.Rounded.Mouse; + public const string MoveDown = Material.Rounded.MoveDown; + public const string MoveToInbox = Material.Rounded.MoveToInbox; + public const string MoveUp = Material.Rounded.MoveUp; + public const string Movie = Material.Rounded.Movie; + public const string MovieCreation = Material.Rounded.MovieCreation; + public const string MovieFilter = Material.Rounded.MovieFilter; + public const string Moving = Material.Rounded.Moving; + public const string Mp = Material.Rounded.Mp; + public const string MultilineChart = Material.Rounded.MultilineChart; + public const string MultipleStop = Material.Rounded.MultipleStop; + public const string Museum = Material.Rounded.Museum; + public const string MusicNote = Material.Rounded.MusicNote; + public const string MusicOff = Material.Rounded.MusicOff; + public const string MusicVideo = Material.Rounded.MusicVideo; + public const string MyLocation = Material.Rounded.MyLocation; + public const string Nat = Material.Rounded.Nat; + public const string Nature = Material.Rounded.Nature; + public const string NaturePeople = Material.Rounded.NaturePeople; + public const string NavigateBefore = Material.Rounded.NavigateBefore; + public const string NavigateNext = Material.Rounded.NavigateNext; + public const string Navigation = Material.Rounded.Navigation; + public const string NearMe = Material.Rounded.NearMe; + public const string NearMeDisabled = Material.Rounded.NearMeDisabled; + public const string NearbyError = Material.Rounded.NearbyError; + public const string NearbyOff = Material.Rounded.NearbyOff; + public const string NetworkCell = Material.Rounded.NetworkCell; + public const string NetworkCheck = Material.Rounded.NetworkCheck; + public const string NetworkLocked = Material.Rounded.NetworkLocked; + public const string NetworkPing = Material.Rounded.NetworkPing; + public const string NetworkWifi = Material.Rounded.NetworkWifi; + public const string NetworkWifi1Bar = Material.Rounded.NetworkWifi1Bar; + public const string NetworkWifi2Bar = Material.Rounded.NetworkWifi2Bar; + public const string NetworkWifi3Bar = Material.Rounded.NetworkWifi3Bar; + public const string NewLabel = Material.Rounded.NewLabel; + public const string NewReleases = Material.Rounded.NewReleases; + public const string Newspaper = Material.Rounded.Newspaper; + public const string NextPlan = Material.Rounded.NextPlan; + public const string NextWeek = Material.Rounded.NextWeek; + public const string Nfc = Material.Rounded.Nfc; + public const string NightShelter = Material.Rounded.NightShelter; + public const string Nightlife = Material.Rounded.Nightlife; + public const string Nightlight = Material.Rounded.Nightlight; + public const string NightlightRound = Material.Rounded.NightlightRound; + public const string NightsStay = Material.Rounded.NightsStay; + public const string NoAccounts = Material.Rounded.NoAccounts; + public const string NoBackpack = Material.Rounded.NoBackpack; + public const string NoCell = Material.Rounded.NoCell; + public const string NoCrash = Material.Rounded.NoCrash; + public const string NoDrinks = Material.Rounded.NoDrinks; + public const string NoEncryption = Material.Rounded.NoEncryption; + public const string NoEncryptionGmailerrorred = Material.Rounded.NoEncryptionGmailerrorred; + public const string NoFlash = Material.Rounded.NoFlash; + public const string NoFood = Material.Rounded.NoFood; + public const string NoLuggage = Material.Rounded.NoLuggage; + public const string NoMeals = Material.Rounded.NoMeals; + public const string NoMeetingRoom = Material.Rounded.NoMeetingRoom; + public const string NoPhotography = Material.Rounded.NoPhotography; + public const string NoSim = Material.Rounded.NoSim; + public const string NoStroller = Material.Rounded.NoStroller; + public const string NoTransfer = Material.Rounded.NoTransfer; + public const string NoiseAware = Material.Rounded.NoiseAware; + public const string NoiseControlOff = Material.Rounded.NoiseControlOff; + public const string NordicWalking = Material.Rounded.NordicWalking; + public const string North = Material.Rounded.North; + public const string NorthEast = Material.Rounded.NorthEast; + public const string NorthWest = Material.Rounded.NorthWest; + public const string NotAccessible = Material.Rounded.NotAccessible; + public const string NotInterested = Material.Rounded.NotInterested; + public const string NotListedLocation = Material.Rounded.NotListedLocation; + public const string NotStarted = Material.Rounded.NotStarted; + public const string Note = Material.Rounded.Note; + public const string NoteAdd = Material.Rounded.NoteAdd; + public const string NoteAlt = Material.Rounded.NoteAlt; + public const string Notes = Material.Rounded.Notes; + public const string NotificationAdd = Material.Rounded.NotificationAdd; + public const string NotificationImportant = Material.Rounded.NotificationImportant; + public const string Notifications = Material.Rounded.Notifications; + public const string NotificationsActive = Material.Rounded.NotificationsActive; + public const string NotificationsNone = Material.Rounded.NotificationsNone; + public const string NotificationsOff = Material.Rounded.NotificationsOff; + public const string NotificationsPaused = Material.Rounded.NotificationsPaused; + public const string Numbers = Material.Rounded.Numbers; + public const string OfflineBolt = Material.Rounded.OfflineBolt; + public const string OfflinePin = Material.Rounded.OfflinePin; + public const string OfflineShare = Material.Rounded.OfflineShare; + public const string OnDeviceTraining = Material.Rounded.OnDeviceTraining; + public const string OndemandVideo = Material.Rounded.OndemandVideo; + public const string OnlinePrediction = Material.Rounded.OnlinePrediction; + public const string Opacity = Material.Rounded.Opacity; + public const string OpenInBrowser = Material.Rounded.OpenInBrowser; + public const string OpenInFull = Material.Rounded.OpenInFull; + public const string OpenInNew = Material.Rounded.OpenInNew; + public const string OpenInNewOff = Material.Rounded.OpenInNewOff; + public const string OpenWith = Material.Rounded.OpenWith; + public const string OtherHouses = Material.Rounded.OtherHouses; + public const string Outbound = Material.Rounded.Outbound; + public const string Outbox = Material.Rounded.Outbox; + public const string OutdoorGrill = Material.Rounded.OutdoorGrill; + public const string Outlet = Material.Rounded.Outlet; + public const string OutlinedFlag = Material.Rounded.OutlinedFlag; + public const string Output = Material.Rounded.Output; + public const string Padding = Material.Rounded.Padding; + public const string Pages = Material.Rounded.Pages; + public const string Pageview = Material.Rounded.Pageview; + public const string Paid = Material.Rounded.Paid; + public const string Palette = Material.Rounded.Palette; + public const string PanTool = Material.Rounded.PanTool; + public const string PanToolAlt = Material.Rounded.PanToolAlt; + public const string Panorama = Material.Rounded.Panorama; + public const string PanoramaFishEye = Material.Rounded.PanoramaFishEye; + public const string PanoramaHorizontal = Material.Rounded.PanoramaHorizontal; + public const string PanoramaHorizontalSelect = Material.Rounded.PanoramaHorizontalSelect; + public const string PanoramaPhotosphere = Material.Rounded.PanoramaPhotosphere; + public const string PanoramaPhotosphereSelect = Material.Rounded.PanoramaPhotosphereSelect; + public const string PanoramaVertical = Material.Rounded.PanoramaVertical; + public const string PanoramaVerticalSelect = Material.Rounded.PanoramaVerticalSelect; + public const string PanoramaWideAngle = Material.Rounded.PanoramaWideAngle; + public const string PanoramaWideAngleSelect = Material.Rounded.PanoramaWideAngleSelect; + public const string Paragliding = Material.Rounded.Paragliding; + public const string Park = Material.Rounded.Park; + public const string PartyMode = Material.Rounded.PartyMode; + public const string Password = Material.Rounded.Password; + public const string Pattern = Material.Rounded.Pattern; + public const string Pause = Material.Rounded.Pause; + public const string PauseCircle = Material.Rounded.PauseCircle; + public const string PauseCircleFilled = Material.Rounded.PauseCircleFilled; + public const string PauseCircleOutline = Material.Rounded.PauseCircleOutline; + public const string PausePresentation = Material.Rounded.PausePresentation; + public const string Payment = Material.Rounded.Payment; + public const string Payments = Material.Rounded.Payments; + public const string PedalBike = Material.Rounded.PedalBike; + public const string Pending = Material.Rounded.Pending; + public const string PendingActions = Material.Rounded.PendingActions; + public const string Pentagon = Material.Rounded.Pentagon; + public const string People = Material.Rounded.People; + public const string PeopleAlt = Material.Rounded.PeopleAlt; + public const string PeopleOutline = Material.Rounded.PeopleOutline; + public const string Percent = Material.Rounded.Percent; + public const string PermCameraMic = Material.Rounded.PermCameraMic; + public const string PermContactCalendar = Material.Rounded.PermContactCalendar; + public const string PermDataSetting = Material.Rounded.PermDataSetting; + public const string PermDeviceInformation = Material.Rounded.PermDeviceInformation; + public const string PermIdentity = Material.Rounded.PermIdentity; + public const string PermMedia = Material.Rounded.PermMedia; + public const string PermPhoneMsg = Material.Rounded.PermPhoneMsg; + public const string PermScanWifi = Material.Rounded.PermScanWifi; + public const string Person = Material.Rounded.Person; + public const string PersonAdd = Material.Rounded.PersonAdd; + public const string PersonAddAlt = Material.Rounded.PersonAddAlt; + public const string PersonAddAlt1 = Material.Rounded.PersonAddAlt1; + public const string PersonAddDisabled = Material.Rounded.PersonAddDisabled; + public const string PersonOff = Material.Rounded.PersonOff; + public const string PersonOutline = Material.Rounded.PersonOutline; + public const string PersonPin = Material.Rounded.PersonPin; + public const string PersonPinCircle = Material.Rounded.PersonPinCircle; + public const string PersonRemove = Material.Rounded.PersonRemove; + public const string PersonRemoveAlt1 = Material.Rounded.PersonRemoveAlt1; + public const string PersonSearch = Material.Rounded.PersonSearch; + public const string PersonalInjury = Material.Rounded.PersonalInjury; + public const string PersonalVideo = Material.Rounded.PersonalVideo; + public const string PestControl = Material.Rounded.PestControl; + public const string PestControlRodent = Material.Rounded.PestControlRodent; + public const string Pets = Material.Rounded.Pets; + public const string Phishing = Material.Rounded.Phishing; + public const string Phone = Material.Rounded.Phone; + public const string PhoneAndroid = Material.Rounded.PhoneAndroid; + public const string PhoneBluetoothSpeaker = Material.Rounded.PhoneBluetoothSpeaker; + public const string PhoneCallback = Material.Rounded.PhoneCallback; + public const string PhoneDisabled = Material.Rounded.PhoneDisabled; + public const string PhoneEnabled = Material.Rounded.PhoneEnabled; + public const string PhoneForwarded = Material.Rounded.PhoneForwarded; + public const string PhoneInTalk = Material.Rounded.PhoneInTalk; + public const string PhoneIphone = Material.Rounded.PhoneIphone; + public const string PhoneLocked = Material.Rounded.PhoneLocked; + public const string PhoneMissed = Material.Rounded.PhoneMissed; + public const string PhonePaused = Material.Rounded.PhonePaused; + public const string Phonelink = Material.Rounded.Phonelink; + public const string PhonelinkErase = Material.Rounded.PhonelinkErase; + public const string PhonelinkLock = Material.Rounded.PhonelinkLock; + public const string PhonelinkOff = Material.Rounded.PhonelinkOff; + public const string PhonelinkRing = Material.Rounded.PhonelinkRing; + public const string PhonelinkSetup = Material.Rounded.PhonelinkSetup; + public const string Photo = Material.Rounded.Photo; + public const string PhotoAlbum = Material.Rounded.PhotoAlbum; + public const string PhotoCamera = Material.Rounded.PhotoCamera; + public const string PhotoCameraBack = Material.Rounded.PhotoCameraBack; + public const string PhotoCameraFront = Material.Rounded.PhotoCameraFront; + public const string PhotoFilter = Material.Rounded.PhotoFilter; + public const string PhotoLibrary = Material.Rounded.PhotoLibrary; + public const string PhotoSizeSelectActual = Material.Rounded.PhotoSizeSelectActual; + public const string PhotoSizeSelectLarge = Material.Rounded.PhotoSizeSelectLarge; + public const string PhotoSizeSelectSmall = Material.Rounded.PhotoSizeSelectSmall; + public const string Php = Material.Rounded.Php; + public const string Piano = Material.Rounded.Piano; + public const string PianoOff = Material.Rounded.PianoOff; + public const string PictureAsPdf = Material.Rounded.PictureAsPdf; + public const string PictureInPicture = Material.Rounded.PictureInPicture; + public const string PictureInPictureAlt = Material.Rounded.PictureInPictureAlt; + public const string PieChart = Material.Rounded.PieChart; + public const string PieChartOutline = Material.Rounded.PieChartOutline; + public const string Pin = Material.Rounded.Pin; + public const string PinDrop = Material.Rounded.PinDrop; + public const string PinEnd = Material.Rounded.PinEnd; + public const string PinInvoke = Material.Rounded.PinInvoke; + public const string Pinch = Material.Rounded.Pinch; + public const string PivotTableChart = Material.Rounded.PivotTableChart; + public const string Pix = Material.Rounded.Pix; + public const string Place = Material.Rounded.Place; + public const string Plagiarism = Material.Rounded.Plagiarism; + public const string PlayArrow = Material.Rounded.PlayArrow; + public const string PlayCircle = Material.Rounded.PlayCircle; + public const string PlayCircleFilled = Material.Rounded.PlayCircleFilled; + public const string PlayCircleOutline = Material.Rounded.PlayCircleOutline; + public const string PlayDisabled = Material.Rounded.PlayDisabled; + public const string PlayForWork = Material.Rounded.PlayForWork; + public const string PlayLesson = Material.Rounded.PlayLesson; + public const string PlaylistAdd = Material.Rounded.PlaylistAdd; + public const string PlaylistAddCheck = Material.Rounded.PlaylistAddCheck; + public const string PlaylistAddCheckCircle = Material.Rounded.PlaylistAddCheckCircle; + public const string PlaylistAddCircle = Material.Rounded.PlaylistAddCircle; + public const string PlaylistPlay = Material.Rounded.PlaylistPlay; + public const string PlaylistRemove = Material.Rounded.PlaylistRemove; + public const string Plumbing = Material.Rounded.Plumbing; + public const string PlusOne = Material.Rounded.PlusOne; + public const string Podcasts = Material.Rounded.Podcasts; + public const string PointOfSale = Material.Rounded.PointOfSale; + public const string Policy = Material.Rounded.Policy; + public const string Poll = Material.Rounded.Poll; + public const string Polyline = Material.Rounded.Polyline; + public const string Polymer = Material.Rounded.Polymer; + public const string Pool = Material.Rounded.Pool; + public const string PortableWifiOff = Material.Rounded.PortableWifiOff; + public const string Portrait = Material.Rounded.Portrait; + public const string PostAdd = Material.Rounded.PostAdd; + public const string Power = Material.Rounded.Power; + public const string PowerInput = Material.Rounded.PowerInput; + public const string PowerOff = Material.Rounded.PowerOff; + public const string PowerSettingsNew = Material.Rounded.PowerSettingsNew; + public const string PrecisionManufacturing = Material.Rounded.PrecisionManufacturing; + public const string PregnantWoman = Material.Rounded.PregnantWoman; + public const string PresentToAll = Material.Rounded.PresentToAll; + public const string Preview = Material.Rounded.Preview; + public const string PriceChange = Material.Rounded.PriceChange; + public const string PriceCheck = Material.Rounded.PriceCheck; + public const string Print = Material.Rounded.Print; + public const string PrintDisabled = Material.Rounded.PrintDisabled; + public const string PriorityHigh = Material.Rounded.PriorityHigh; + public const string PrivacyTip = Material.Rounded.PrivacyTip; + public const string PrivateConnectivity = Material.Rounded.PrivateConnectivity; + public const string ProductionQuantityLimits = Material.Rounded.ProductionQuantityLimits; + public const string Psychology = Material.Rounded.Psychology; + public const string Public = Material.Rounded.Public; + public const string PublicOff = Material.Rounded.PublicOff; + public const string Publish = Material.Rounded.Publish; + public const string PublishedWithChanges = Material.Rounded.PublishedWithChanges; + public const string PunchClock = Material.Rounded.PunchClock; + public const string PushPin = Material.Rounded.PushPin; + public const string QrCode = Material.Rounded.QrCode; + public const string QrCode2 = Material.Rounded.QrCode2; + public const string QrCodeScanner = Material.Rounded.QrCodeScanner; + public const string QueryBuilder = Material.Rounded.QueryBuilder; + public const string QueryStats = Material.Rounded.QueryStats; + public const string QuestionAnswer = Material.Rounded.QuestionAnswer; + public const string QuestionMark = Material.Rounded.QuestionMark; + public const string Queue = Material.Rounded.Queue; + public const string QueueMusic = Material.Rounded.QueueMusic; + public const string QueuePlayNext = Material.Rounded.QueuePlayNext; + public const string Quickreply = Material.Rounded.Quickreply; + public const string Quiz = Material.Rounded.Quiz; + public const string RMobiledata = Material.Rounded.RMobiledata; + public const string Radar = Material.Rounded.Radar; + public const string Radio = Material.Rounded.Radio; + public const string RadioButtonChecked = Material.Rounded.RadioButtonChecked; + public const string RadioButtonUnchecked = Material.Rounded.RadioButtonUnchecked; + public const string RailwayAlert = Material.Rounded.RailwayAlert; + public const string RamenDining = Material.Rounded.RamenDining; + public const string RampLeft = Material.Rounded.RampLeft; + public const string RampRight = Material.Rounded.RampRight; + public const string RateReview = Material.Rounded.RateReview; + public const string RawOff = Material.Rounded.RawOff; + public const string RawOn = Material.Rounded.RawOn; + public const string ReadMore = Material.Rounded.ReadMore; + public const string RealEstateAgent = Material.Rounded.RealEstateAgent; + public const string Receipt = Material.Rounded.Receipt; + public const string ReceiptLong = Material.Rounded.ReceiptLong; + public const string RecentActors = Material.Rounded.RecentActors; + public const string Recommend = Material.Rounded.Recommend; + public const string RecordVoiceOver = Material.Rounded.RecordVoiceOver; + public const string Rectangle = Material.Rounded.Rectangle; + public const string Recycling = Material.Rounded.Recycling; + public const string Redeem = Material.Rounded.Redeem; + public const string Redo = Material.Rounded.Redo; + public const string ReduceCapacity = Material.Rounded.ReduceCapacity; + public const string Refresh = Material.Rounded.Refresh; + public const string RememberMe = Material.Rounded.RememberMe; + public const string Remove = Material.Rounded.Remove; + public const string RemoveCircle = Material.Rounded.RemoveCircle; + public const string RemoveCircleOutline = Material.Rounded.RemoveCircleOutline; + public const string RemoveDone = Material.Rounded.RemoveDone; + public const string RemoveFromQueue = Material.Rounded.RemoveFromQueue; + public const string RemoveModerator = Material.Rounded.RemoveModerator; + public const string RemoveRedEye = Material.Rounded.RemoveRedEye; + public const string RemoveRoad = Material.Rounded.RemoveRoad; + public const string RemoveShoppingCart = Material.Rounded.RemoveShoppingCart; + public const string Reorder = Material.Rounded.Reorder; + public const string Repeat = Material.Rounded.Repeat; + public const string RepeatOn = Material.Rounded.RepeatOn; + public const string RepeatOne = Material.Rounded.RepeatOne; + public const string RepeatOneOn = Material.Rounded.RepeatOneOn; + public const string Replay = Material.Rounded.Replay; + public const string Replay10 = Material.Rounded.Replay10; + public const string Replay30 = Material.Rounded.Replay30; + public const string Replay5 = Material.Rounded.Replay5; + public const string ReplayCircleFilled = Material.Rounded.ReplayCircleFilled; + public const string Reply = Material.Rounded.Reply; + public const string ReplyAll = Material.Rounded.ReplyAll; + public const string Report = Material.Rounded.Report; + public const string ReportGmailerrorred = Material.Rounded.ReportGmailerrorred; + public const string ReportOff = Material.Rounded.ReportOff; + public const string ReportProblem = Material.Rounded.ReportProblem; + public const string RequestPage = Material.Rounded.RequestPage; + public const string RequestQuote = Material.Rounded.RequestQuote; + public const string ResetTv = Material.Rounded.ResetTv; + public const string RestartAlt = Material.Rounded.RestartAlt; + public const string Restaurant = Material.Rounded.Restaurant; + public const string RestaurantMenu = Material.Rounded.RestaurantMenu; + public const string Restore = Material.Rounded.Restore; + public const string RestoreFromTrash = Material.Rounded.RestoreFromTrash; + public const string RestorePage = Material.Rounded.RestorePage; + public const string Reviews = Material.Rounded.Reviews; + public const string RiceBowl = Material.Rounded.RiceBowl; + public const string RingVolume = Material.Rounded.RingVolume; + public const string Rocket = Material.Rounded.Rocket; + public const string RocketLaunch = Material.Rounded.RocketLaunch; + public const string RollerSkating = Material.Rounded.RollerSkating; + public const string Roofing = Material.Rounded.Roofing; + public const string Room = Material.Rounded.Room; + public const string RoomPreferences = Material.Rounded.RoomPreferences; + public const string RoomService = Material.Rounded.RoomService; + public const string Rotate90DegreesCcw = Material.Rounded.Rotate90DegreesCcw; + public const string Rotate90DegreesCw = Material.Rounded.Rotate90DegreesCw; + public const string RotateLeft = Material.Rounded.RotateLeft; + public const string RotateRight = Material.Rounded.RotateRight; + public const string RoundaboutLeft = Material.Rounded.RoundaboutLeft; + public const string RoundaboutRight = Material.Rounded.RoundaboutRight; + public const string RoundedCorner = Material.Rounded.RoundedCorner; + public const string Route = Material.Rounded.Route; + public const string Router = Material.Rounded.Router; + public const string Rowing = Material.Rounded.Rowing; + public const string RssFeed = Material.Rounded.RssFeed; + public const string Rsvp = Material.Rounded.Rsvp; + public const string Rtt = Material.Rounded.Rtt; + public const string Rule = Material.Rounded.Rule; + public const string RuleFolder = Material.Rounded.RuleFolder; + public const string RunCircle = Material.Rounded.RunCircle; + public const string RunningWithErrors = Material.Rounded.RunningWithErrors; + public const string RvHookup = Material.Rounded.RvHookup; + public const string SafetyCheck = Material.Rounded.SafetyCheck; + public const string SafetyDivider = Material.Rounded.SafetyDivider; + public const string Sailing = Material.Rounded.Sailing; + public const string Sanitizer = Material.Rounded.Sanitizer; + public const string Satellite = Material.Rounded.Satellite; + public const string SatelliteAlt = Material.Rounded.SatelliteAlt; + public const string Save = Material.Rounded.Save; + public const string SaveAlt = Material.Rounded.SaveAlt; + public const string SaveAs = Material.Rounded.SaveAs; + public const string SavedSearch = Material.Rounded.SavedSearch; + public const string Savings = Material.Rounded.Savings; + public const string Scale = Material.Rounded.Scale; + public const string Scanner = Material.Rounded.Scanner; + public const string ScatterPlot = Material.Rounded.ScatterPlot; + public const string Schedule = Material.Rounded.Schedule; + public const string ScheduleSend = Material.Rounded.ScheduleSend; + public const string Schema = Material.Rounded.Schema; + public const string School = Material.Rounded.School; + public const string Science = Material.Rounded.Science; + public const string Score = Material.Rounded.Score; + public const string Scoreboard = Material.Rounded.Scoreboard; + public const string ScreenLockLandscape = Material.Rounded.ScreenLockLandscape; + public const string ScreenLockPortrait = Material.Rounded.ScreenLockPortrait; + public const string ScreenLockRotation = Material.Rounded.ScreenLockRotation; + public const string ScreenRotation = Material.Rounded.ScreenRotation; + public const string ScreenRotationAlt = Material.Rounded.ScreenRotationAlt; + public const string ScreenSearchDesktop = Material.Rounded.ScreenSearchDesktop; + public const string ScreenShare = Material.Rounded.ScreenShare; + public const string Screenshot = Material.Rounded.Screenshot; + public const string ScubaDiving = Material.Rounded.ScubaDiving; + public const string Sd = Material.Rounded.Sd; + public const string SdCard = Material.Rounded.SdCard; + public const string SdCardAlert = Material.Rounded.SdCardAlert; + public const string SdStorage = Material.Rounded.SdStorage; + public const string Search = Material.Rounded.Search; + public const string SearchOff = Material.Rounded.SearchOff; + public const string Security = Material.Rounded.Security; + public const string SecurityUpdate = Material.Rounded.SecurityUpdate; + public const string SecurityUpdateGood = Material.Rounded.SecurityUpdateGood; + public const string SecurityUpdateWarning = Material.Rounded.SecurityUpdateWarning; + public const string Segment = Material.Rounded.Segment; + public const string SelectAll = Material.Rounded.SelectAll; + public const string SelfImprovement = Material.Rounded.SelfImprovement; + public const string Sell = Material.Rounded.Sell; + public const string Send = Material.Rounded.Send; + public const string SendAndArchive = Material.Rounded.SendAndArchive; + public const string SendTimeExtension = Material.Rounded.SendTimeExtension; + public const string SendToMobile = Material.Rounded.SendToMobile; + public const string SensorDoor = Material.Rounded.SensorDoor; + public const string SensorWindow = Material.Rounded.SensorWindow; + public const string Sensors = Material.Rounded.Sensors; + public const string SensorsOff = Material.Rounded.SensorsOff; + public const string SentimentDissatisfied = Material.Rounded.SentimentDissatisfied; + public const string SentimentNeutral = Material.Rounded.SentimentNeutral; + public const string SentimentSatisfied = Material.Rounded.SentimentSatisfied; + public const string SentimentSatisfiedAlt = Material.Rounded.SentimentSatisfiedAlt; + public const string SentimentVeryDissatisfied = Material.Rounded.SentimentVeryDissatisfied; + public const string SentimentVerySatisfied = Material.Rounded.SentimentVerySatisfied; + public const string SetMeal = Material.Rounded.SetMeal; + public const string Settings = Material.Rounded.Settings; + public const string SettingsAccessibility = Material.Rounded.SettingsAccessibility; + public const string SettingsApplications = Material.Rounded.SettingsApplications; + public const string SettingsBackupRestore = Material.Rounded.SettingsBackupRestore; + public const string SettingsBluetooth = Material.Rounded.SettingsBluetooth; + public const string SettingsBrightness = Material.Rounded.SettingsBrightness; + public const string SettingsCell = Material.Rounded.SettingsCell; + public const string SettingsEthernet = Material.Rounded.SettingsEthernet; + public const string SettingsInputAntenna = Material.Rounded.SettingsInputAntenna; + public const string SettingsInputComponent = Material.Rounded.SettingsInputComponent; + public const string SettingsInputComposite = Material.Rounded.SettingsInputComposite; + public const string SettingsInputHdmi = Material.Rounded.SettingsInputHdmi; + public const string SettingsInputSvideo = Material.Rounded.SettingsInputSvideo; + public const string SettingsOverscan = Material.Rounded.SettingsOverscan; + public const string SettingsPhone = Material.Rounded.SettingsPhone; + public const string SettingsPower = Material.Rounded.SettingsPower; + public const string SettingsRemote = Material.Rounded.SettingsRemote; + public const string SettingsSuggest = Material.Rounded.SettingsSuggest; + public const string SettingsSystemDaydream = Material.Rounded.SettingsSystemDaydream; + public const string SettingsVoice = Material.Rounded.SettingsVoice; + public const string SevereCold = Material.Rounded.SevereCold; + public const string Share = Material.Rounded.Share; + public const string ShareLocation = Material.Rounded.ShareLocation; + public const string Shield = Material.Rounded.Shield; + public const string ShieldMoon = Material.Rounded.ShieldMoon; + public const string Shop = Material.Rounded.Shop; + public const string Shop2 = Material.Rounded.Shop2; + public const string ShopTwo = Material.Rounded.ShopTwo; + public const string ShoppingBag = Material.Rounded.ShoppingBag; + public const string ShoppingBasket = Material.Rounded.ShoppingBasket; + public const string ShoppingCart = Material.Rounded.ShoppingCart; + public const string ShoppingCartCheckout = Material.Rounded.ShoppingCartCheckout; + public const string ShortText = Material.Rounded.ShortText; + public const string Shortcut = Material.Rounded.Shortcut; + public const string ShowChart = Material.Rounded.ShowChart; + public const string Shower = Material.Rounded.Shower; + public const string Shuffle = Material.Rounded.Shuffle; + public const string ShuffleOn = Material.Rounded.ShuffleOn; + public const string ShutterSpeed = Material.Rounded.ShutterSpeed; + public const string Sick = Material.Rounded.Sick; + public const string SignLanguage = Material.Rounded.SignLanguage; + public const string SignalCellular0Bar = Material.Rounded.SignalCellular0Bar; + public const string SignalCellular4Bar = Material.Rounded.SignalCellular4Bar; + public const string SignalCellularAlt = Material.Rounded.SignalCellularAlt; + public const string SignalCellularAlt1Bar = Material.Rounded.SignalCellularAlt1Bar; + public const string SignalCellularAlt2Bar = Material.Rounded.SignalCellularAlt2Bar; + + public const string SignalCellularConnectedNoInternet0Bar = + Material.Rounded.SignalCellularConnectedNoInternet0Bar; + + public const string SignalCellularConnectedNoInternet4Bar = + Material.Rounded.SignalCellularConnectedNoInternet4Bar; + + public const string SignalCellularNoSim = Material.Rounded.SignalCellularNoSim; + public const string SignalCellularNodata = Material.Rounded.SignalCellularNodata; + public const string SignalCellularNull = Material.Rounded.SignalCellularNull; + public const string SignalCellularOff = Material.Rounded.SignalCellularOff; + public const string SignalWifi0Bar = Material.Rounded.SignalWifi0Bar; + public const string SignalWifi4Bar = Material.Rounded.SignalWifi4Bar; + public const string SignalWifi4BarLock = Material.Rounded.SignalWifi4BarLock; + public const string SignalWifiBad = Material.Rounded.SignalWifiBad; + public const string SignalWifiConnectedNoInternet4 = Material.Rounded.SignalWifiConnectedNoInternet4; + public const string SignalWifiOff = Material.Rounded.SignalWifiOff; + public const string SignalWifiStatusbar4Bar = Material.Rounded.SignalWifiStatusbar4Bar; + + public const string SignalWifiStatusbarConnectedNoInternet4 = + Material.Rounded.SignalWifiStatusbarConnectedNoInternet4; + + public const string SignalWifiStatusbarNull = Material.Rounded.SignalWifiStatusbarNull; + public const string Signpost = Material.Rounded.Signpost; + public const string SimCard = Material.Rounded.SimCard; + public const string SimCardAlert = Material.Rounded.SimCardAlert; + public const string SimCardDownload = Material.Rounded.SimCardDownload; + public const string SingleBed = Material.Rounded.SingleBed; + public const string Sip = Material.Rounded.Sip; + public const string Skateboarding = Material.Rounded.Skateboarding; + public const string SkipNext = Material.Rounded.SkipNext; + public const string SkipPrevious = Material.Rounded.SkipPrevious; + public const string Sledding = Material.Rounded.Sledding; + public const string Slideshow = Material.Rounded.Slideshow; + public const string SlowMotionVideo = Material.Rounded.SlowMotionVideo; + public const string SmartButton = Material.Rounded.SmartButton; + public const string SmartDisplay = Material.Rounded.SmartDisplay; + public const string SmartScreen = Material.Rounded.SmartScreen; + public const string SmartToy = Material.Rounded.SmartToy; + public const string Smartphone = Material.Rounded.Smartphone; + public const string SmokeFree = Material.Rounded.SmokeFree; + public const string SmokingRooms = Material.Rounded.SmokingRooms; + public const string Sms = Material.Rounded.Sms; + public const string SmsFailed = Material.Rounded.SmsFailed; + public const string SnippetFolder = Material.Rounded.SnippetFolder; + public const string Snooze = Material.Rounded.Snooze; + public const string Snowboarding = Material.Rounded.Snowboarding; + public const string Snowmobile = Material.Rounded.Snowmobile; + public const string Snowshoeing = Material.Rounded.Snowshoeing; + public const string Soap = Material.Rounded.Soap; + public const string SocialDistance = Material.Rounded.SocialDistance; + public const string Sort = Material.Rounded.Sort; + public const string SortByAlpha = Material.Rounded.SortByAlpha; + public const string Sos = Material.Rounded.Sos; + public const string SoupKitchen = Material.Rounded.SoupKitchen; + public const string Source = Material.Rounded.Source; + public const string South = Material.Rounded.South; + public const string SouthAmerica = Material.Rounded.SouthAmerica; + public const string SouthEast = Material.Rounded.SouthEast; + public const string SouthWest = Material.Rounded.SouthWest; + public const string Spa = Material.Rounded.Spa; + public const string SpaceBar = Material.Rounded.SpaceBar; + public const string SpaceDashboard = Material.Rounded.SpaceDashboard; + public const string SpatialAudio = Material.Rounded.SpatialAudio; + public const string SpatialAudioOff = Material.Rounded.SpatialAudioOff; + public const string SpatialTracking = Material.Rounded.SpatialTracking; + public const string Speaker = Material.Rounded.Speaker; + public const string SpeakerGroup = Material.Rounded.SpeakerGroup; + public const string SpeakerNotes = Material.Rounded.SpeakerNotes; + public const string SpeakerNotesOff = Material.Rounded.SpeakerNotesOff; + public const string SpeakerPhone = Material.Rounded.SpeakerPhone; + public const string Speed = Material.Rounded.Speed; + public const string Spellcheck = Material.Rounded.Spellcheck; + public const string Splitscreen = Material.Rounded.Splitscreen; + public const string Spoke = Material.Rounded.Spoke; + public const string Sports = Material.Rounded.Sports; + public const string SportsBar = Material.Rounded.SportsBar; + public const string SportsBaseball = Material.Rounded.SportsBaseball; + public const string SportsBasketball = Material.Rounded.SportsBasketball; + public const string SportsCricket = Material.Rounded.SportsCricket; + public const string SportsEsports = Material.Rounded.SportsEsports; + public const string SportsFootball = Material.Rounded.SportsFootball; + public const string SportsGolf = Material.Rounded.SportsGolf; + public const string SportsGymnastics = Material.Rounded.SportsGymnastics; + public const string SportsHandball = Material.Rounded.SportsHandball; + public const string SportsHockey = Material.Rounded.SportsHockey; + public const string SportsKabaddi = Material.Rounded.SportsKabaddi; + public const string SportsMartialArts = Material.Rounded.SportsMartialArts; + public const string SportsMma = Material.Rounded.SportsMma; + public const string SportsMotorsports = Material.Rounded.SportsMotorsports; + public const string SportsRugby = Material.Rounded.SportsRugby; + public const string SportsScore = Material.Rounded.SportsScore; + public const string SportsSoccer = Material.Rounded.SportsSoccer; + public const string SportsTennis = Material.Rounded.SportsTennis; + public const string SportsVolleyball = Material.Rounded.SportsVolleyball; + public const string Square = Material.Rounded.Square; + public const string SquareFoot = Material.Rounded.SquareFoot; + public const string SsidChart = Material.Rounded.SsidChart; + public const string StackedBarChart = Material.Rounded.StackedBarChart; + public const string StackedLineChart = Material.Rounded.StackedLineChart; + public const string Stadium = Material.Rounded.Stadium; + public const string Stairs = Material.Rounded.Stairs; + public const string Star = Material.Rounded.Star; + public const string StarBorder = Material.Rounded.StarBorder; + public const string StarBorderPurple500 = Material.Rounded.StarBorderPurple500; + public const string StarHalf = Material.Rounded.StarHalf; + public const string StarOutline = Material.Rounded.StarOutline; + public const string StarPurple500 = Material.Rounded.StarPurple500; + public const string StarRate = Material.Rounded.StarRate; + public const string Stars = Material.Rounded.Stars; + public const string Start = Material.Rounded.Start; + public const string StayCurrentLandscape = Material.Rounded.StayCurrentLandscape; + public const string StayCurrentPortrait = Material.Rounded.StayCurrentPortrait; + public const string StayPrimaryLandscape = Material.Rounded.StayPrimaryLandscape; + public const string StayPrimaryPortrait = Material.Rounded.StayPrimaryPortrait; + public const string StickyNote2 = Material.Rounded.StickyNote2; + public const string Stop = Material.Rounded.Stop; + public const string StopCircle = Material.Rounded.StopCircle; + public const string StopScreenShare = Material.Rounded.StopScreenShare; + public const string Storage = Material.Rounded.Storage; + public const string Store = Material.Rounded.Store; + public const string StoreMallDirectory = Material.Rounded.StoreMallDirectory; + public const string Storefront = Material.Rounded.Storefront; + public const string Storm = Material.Rounded.Storm; + public const string Straight = Material.Rounded.Straight; + public const string Straighten = Material.Rounded.Straighten; + public const string Stream = Material.Rounded.Stream; + public const string Streetview = Material.Rounded.Streetview; + public const string StrikethroughS = Material.Rounded.StrikethroughS; + public const string Stroller = Material.Rounded.Stroller; + public const string Style = Material.Rounded.Style; + public const string SubdirectoryArrowLeft = Material.Rounded.SubdirectoryArrowLeft; + public const string SubdirectoryArrowRight = Material.Rounded.SubdirectoryArrowRight; + public const string Subject = Material.Rounded.Subject; + public const string Subscript = Material.Rounded.Subscript; + public const string Subscriptions = Material.Rounded.Subscriptions; + public const string Subtitles = Material.Rounded.Subtitles; + public const string SubtitlesOff = Material.Rounded.SubtitlesOff; + public const string Subway = Material.Rounded.Subway; + public const string Summarize = Material.Rounded.Summarize; + public const string Superscript = Material.Rounded.Superscript; + public const string SupervisedUserCircle = Material.Rounded.SupervisedUserCircle; + public const string SupervisorAccount = Material.Rounded.SupervisorAccount; + public const string Support = Material.Rounded.Support; + public const string SupportAgent = Material.Rounded.SupportAgent; + public const string Surfing = Material.Rounded.Surfing; + public const string SurroundSound = Material.Rounded.SurroundSound; + public const string SwapCalls = Material.Rounded.SwapCalls; + public const string SwapHoriz = Material.Rounded.SwapHoriz; + public const string SwapHorizontalCircle = Material.Rounded.SwapHorizontalCircle; + public const string SwapVert = Material.Rounded.SwapVert; + public const string SwapVerticalCircle = Material.Rounded.SwapVerticalCircle; + public const string Swipe = Material.Rounded.Swipe; + public const string SwipeDown = Material.Rounded.SwipeDown; + public const string SwipeDownAlt = Material.Rounded.SwipeDownAlt; + public const string SwipeLeft = Material.Rounded.SwipeLeft; + public const string SwipeLeftAlt = Material.Rounded.SwipeLeftAlt; + public const string SwipeRight = Material.Rounded.SwipeRight; + public const string SwipeRightAlt = Material.Rounded.SwipeRightAlt; + public const string SwipeUp = Material.Rounded.SwipeUp; + public const string SwipeUpAlt = Material.Rounded.SwipeUpAlt; + public const string SwipeVertical = Material.Rounded.SwipeVertical; + public const string SwitchAccessShortcut = Material.Rounded.SwitchAccessShortcut; + public const string SwitchAccessShortcutAdd = Material.Rounded.SwitchAccessShortcutAdd; + public const string SwitchAccount = Material.Rounded.SwitchAccount; + public const string SwitchCamera = Material.Rounded.SwitchCamera; + public const string SwitchLeft = Material.Rounded.SwitchLeft; + public const string SwitchRight = Material.Rounded.SwitchRight; + public const string SwitchVideo = Material.Rounded.SwitchVideo; + public const string Synagogue = Material.Rounded.Synagogue; + public const string Sync = Material.Rounded.Sync; + public const string SyncAlt = Material.Rounded.SyncAlt; + public const string SyncDisabled = Material.Rounded.SyncDisabled; + public const string SyncLock = Material.Rounded.SyncLock; + public const string SyncProblem = Material.Rounded.SyncProblem; + public const string SystemSecurityUpdate = Material.Rounded.SystemSecurityUpdate; + public const string SystemSecurityUpdateGood = Material.Rounded.SystemSecurityUpdateGood; + public const string SystemSecurityUpdateWarning = Material.Rounded.SystemSecurityUpdateWarning; + public const string SystemUpdate = Material.Rounded.SystemUpdate; + public const string SystemUpdateAlt = Material.Rounded.SystemUpdateAlt; + public const string Tab = Material.Rounded.Tab; + public const string TabUnselected = Material.Rounded.TabUnselected; + public const string TableBar = Material.Rounded.TableBar; + public const string TableChart = Material.Rounded.TableChart; + public const string TableRestaurant = Material.Rounded.TableRestaurant; + public const string TableRows = Material.Rounded.TableRows; + public const string TableView = Material.Rounded.TableView; + public const string Tablet = Material.Rounded.Tablet; + public const string TabletAndroid = Material.Rounded.TabletAndroid; + public const string TabletMac = Material.Rounded.TabletMac; + public const string Tag = Material.Rounded.Tag; + public const string TagFaces = Material.Rounded.TagFaces; + public const string TakeoutDining = Material.Rounded.TakeoutDining; + public const string TapAndPlay = Material.Rounded.TapAndPlay; + public const string Tapas = Material.Rounded.Tapas; + public const string Task = Material.Rounded.Task; + public const string TaskAlt = Material.Rounded.TaskAlt; + public const string TaxiAlert = Material.Rounded.TaxiAlert; + public const string TempleBuddhist = Material.Rounded.TempleBuddhist; + public const string TempleHindu = Material.Rounded.TempleHindu; + public const string Terminal = Material.Rounded.Terminal; + public const string Terrain = Material.Rounded.Terrain; + public const string TextDecrease = Material.Rounded.TextDecrease; + public const string TextFields = Material.Rounded.TextFields; + public const string TextFormat = Material.Rounded.TextFormat; + public const string TextIncrease = Material.Rounded.TextIncrease; + public const string TextRotateUp = Material.Rounded.TextRotateUp; + public const string TextRotateVertical = Material.Rounded.TextRotateVertical; + public const string TextRotationAngledown = Material.Rounded.TextRotationAngledown; + public const string TextRotationAngleup = Material.Rounded.TextRotationAngleup; + public const string TextRotationDown = Material.Rounded.TextRotationDown; + public const string TextRotationNone = Material.Rounded.TextRotationNone; + public const string TextSnippet = Material.Rounded.TextSnippet; + public const string Textsms = Material.Rounded.Textsms; + public const string Texture = Material.Rounded.Texture; + public const string TheaterComedy = Material.Rounded.TheaterComedy; + public const string Theaters = Material.Rounded.Theaters; + public const string Thermostat = Material.Rounded.Thermostat; + public const string ThermostatAuto = Material.Rounded.ThermostatAuto; + public const string ThumbDown = Material.Rounded.ThumbDown; + public const string ThumbDownAlt = Material.Rounded.ThumbDownAlt; + public const string ThumbDownOffAlt = Material.Rounded.ThumbDownOffAlt; + public const string ThumbUp = Material.Rounded.ThumbUp; + public const string ThumbUpAlt = Material.Rounded.ThumbUpAlt; + public const string ThumbUpOffAlt = Material.Rounded.ThumbUpOffAlt; + public const string ThumbsUpDown = Material.Rounded.ThumbsUpDown; + public const string Thunderstorm = Material.Rounded.Thunderstorm; + public const string TimeToLeave = Material.Rounded.TimeToLeave; + public const string Timelapse = Material.Rounded.Timelapse; + public const string Timeline = Material.Rounded.Timeline; + public const string Timer = Material.Rounded.Timer; + public const string Timer10 = Material.Rounded.Timer10; + public const string Timer10Select = Material.Rounded.Timer10Select; + public const string Timer3 = Material.Rounded.Timer3; + public const string Timer3Select = Material.Rounded.Timer3Select; + public const string TimerOff = Material.Rounded.TimerOff; + public const string TipsAndUpdates = Material.Rounded.TipsAndUpdates; + public const string TireRepair = Material.Rounded.TireRepair; + public const string Title = Material.Rounded.Title; + public const string Toc = Material.Rounded.Toc; + public const string Today = Material.Rounded.Today; + public const string ToggleOff = Material.Rounded.ToggleOff; + public const string ToggleOn = Material.Rounded.ToggleOn; + public const string Token = Material.Rounded.Token; + public const string Toll = Material.Rounded.Toll; + public const string Tonality = Material.Rounded.Tonality; + public const string Topic = Material.Rounded.Topic; + public const string TouchApp = Material.Rounded.TouchApp; + public const string Tour = Material.Rounded.Tour; + public const string Toys = Material.Rounded.Toys; + public const string TrackChanges = Material.Rounded.TrackChanges; + public const string Traffic = Material.Rounded.Traffic; + public const string Train = Material.Rounded.Train; + public const string Tram = Material.Rounded.Tram; + public const string TransferWithinAStation = Material.Rounded.TransferWithinAStation; + public const string Transform = Material.Rounded.Transform; + public const string Transgender = Material.Rounded.Transgender; + public const string TransitEnterexit = Material.Rounded.TransitEnterexit; + public const string Translate = Material.Rounded.Translate; + public const string TravelExplore = Material.Rounded.TravelExplore; + public const string TrendingDown = Material.Rounded.TrendingDown; + public const string TrendingFlat = Material.Rounded.TrendingFlat; + public const string TrendingUp = Material.Rounded.TrendingUp; + public const string TripOrigin = Material.Rounded.TripOrigin; + public const string Try = Material.Rounded.Try; + public const string Tsunami = Material.Rounded.Tsunami; + public const string Tty = Material.Rounded.Tty; + public const string Tune = Material.Rounded.Tune; + public const string Tungsten = Material.Rounded.Tungsten; + public const string TurnLeft = Material.Rounded.TurnLeft; + public const string TurnRight = Material.Rounded.TurnRight; + public const string TurnSharpLeft = Material.Rounded.TurnSharpLeft; + public const string TurnSharpRight = Material.Rounded.TurnSharpRight; + public const string TurnSlightLeft = Material.Rounded.TurnSlightLeft; + public const string TurnSlightRight = Material.Rounded.TurnSlightRight; + public const string TurnedIn = Material.Rounded.TurnedIn; + public const string TurnedInNot = Material.Rounded.TurnedInNot; + public const string Tv = Material.Rounded.Tv; + public const string TvOff = Material.Rounded.TvOff; + public const string TwoWheeler = Material.Rounded.TwoWheeler; + public const string UTurnLeft = Material.Rounded.UTurnLeft; + public const string UTurnRight = Material.Rounded.UTurnRight; + public const string Umbrella = Material.Rounded.Umbrella; + public const string Unarchive = Material.Rounded.Unarchive; + public const string Undo = Material.Rounded.Undo; + public const string UnfoldLess = Material.Rounded.UnfoldLess; + public const string UnfoldMore = Material.Rounded.UnfoldMore; + public const string Unpublished = Material.Rounded.Unpublished; + public const string Unsubscribe = Material.Rounded.Unsubscribe; + public const string Upcoming = Material.Rounded.Upcoming; + public const string Update = Material.Rounded.Update; + public const string UpdateDisabled = Material.Rounded.UpdateDisabled; + public const string Upgrade = Material.Rounded.Upgrade; + public const string Upload = Material.Rounded.Upload; + public const string UploadFile = Material.Rounded.UploadFile; + public const string Usb = Material.Rounded.Usb; + public const string UsbOff = Material.Rounded.UsbOff; + public const string Vaccines = Material.Rounded.Vaccines; + public const string VapeFree = Material.Rounded.VapeFree; + public const string VapingRooms = Material.Rounded.VapingRooms; + public const string Verified = Material.Rounded.Verified; + public const string VerifiedUser = Material.Rounded.VerifiedUser; + public const string VerticalAlignBottom = Material.Rounded.VerticalAlignBottom; + public const string VerticalAlignCenter = Material.Rounded.VerticalAlignCenter; + public const string VerticalAlignTop = Material.Rounded.VerticalAlignTop; + public const string VerticalDistribute = Material.Rounded.VerticalDistribute; + public const string VerticalSplit = Material.Rounded.VerticalSplit; + public const string Vibration = Material.Rounded.Vibration; + public const string VideoCall = Material.Rounded.VideoCall; + public const string VideoCameraBack = Material.Rounded.VideoCameraBack; + public const string VideoCameraFront = Material.Rounded.VideoCameraFront; + public const string VideoFile = Material.Rounded.VideoFile; + public const string VideoLabel = Material.Rounded.VideoLabel; + public const string VideoLibrary = Material.Rounded.VideoLibrary; + public const string VideoSettings = Material.Rounded.VideoSettings; + public const string VideoStable = Material.Rounded.VideoStable; + public const string Videocam = Material.Rounded.Videocam; + public const string VideocamOff = Material.Rounded.VideocamOff; + public const string VideogameAsset = Material.Rounded.VideogameAsset; + public const string VideogameAssetOff = Material.Rounded.VideogameAssetOff; + public const string ViewAgenda = Material.Rounded.ViewAgenda; + public const string ViewArray = Material.Rounded.ViewArray; + public const string ViewCarousel = Material.Rounded.ViewCarousel; + public const string ViewColumn = Material.Rounded.ViewColumn; + public const string ViewComfy = Material.Rounded.ViewComfy; + public const string ViewComfyAlt = Material.Rounded.ViewComfyAlt; + public const string ViewCompact = Material.Rounded.ViewCompact; + public const string ViewCompactAlt = Material.Rounded.ViewCompactAlt; + public const string ViewCozy = Material.Rounded.ViewCozy; + public const string ViewDay = Material.Rounded.ViewDay; + public const string ViewHeadline = Material.Rounded.ViewHeadline; + public const string ViewInAr = Material.Rounded.ViewInAr; + public const string ViewKanban = Material.Rounded.ViewKanban; + public const string ViewList = Material.Rounded.ViewList; + public const string ViewModule = Material.Rounded.ViewModule; + public const string ViewQuilt = Material.Rounded.ViewQuilt; + public const string ViewSidebar = Material.Rounded.ViewSidebar; + public const string ViewStream = Material.Rounded.ViewStream; + public const string ViewTimeline = Material.Rounded.ViewTimeline; + public const string ViewWeek = Material.Rounded.ViewWeek; + public const string Vignette = Material.Rounded.Vignette; + public const string Villa = Material.Rounded.Villa; + public const string Visibility = Material.Rounded.Visibility; + public const string VisibilityOff = Material.Rounded.VisibilityOff; + public const string VoiceChat = Material.Rounded.VoiceChat; + public const string VoiceOverOff = Material.Rounded.VoiceOverOff; + public const string Voicemail = Material.Rounded.Voicemail; + public const string Volcano = Material.Rounded.Volcano; + public const string VolumeDown = Material.Rounded.VolumeDown; + public const string VolumeMute = Material.Rounded.VolumeMute; + public const string VolumeOff = Material.Rounded.VolumeOff; + public const string VolumeUp = Material.Rounded.VolumeUp; + public const string VolunteerActivism = Material.Rounded.VolunteerActivism; + public const string VpnKey = Material.Rounded.VpnKey; + public const string VpnKeyOff = Material.Rounded.VpnKeyOff; + public const string VpnLock = Material.Rounded.VpnLock; + public const string Vrpano = Material.Rounded.Vrpano; + public const string Wallpaper = Material.Rounded.Wallpaper; + public const string Warehouse = Material.Rounded.Warehouse; + public const string Warning = Material.Rounded.Warning; + public const string WarningAmber = Material.Rounded.WarningAmber; + public const string Wash = Material.Rounded.Wash; + public const string Watch = Material.Rounded.Watch; + public const string WatchLater = Material.Rounded.WatchLater; + public const string WatchOff = Material.Rounded.WatchOff; + public const string Water = Material.Rounded.Water; + public const string WaterDamage = Material.Rounded.WaterDamage; + public const string WaterDrop = Material.Rounded.WaterDrop; + public const string WaterfallChart = Material.Rounded.WaterfallChart; + public const string Waves = Material.Rounded.Waves; + public const string WavingHand = Material.Rounded.WavingHand; + public const string WbAuto = Material.Rounded.WbAuto; + public const string WbCloudy = Material.Rounded.WbCloudy; + public const string WbIncandescent = Material.Rounded.WbIncandescent; + public const string WbIridescent = Material.Rounded.WbIridescent; + public const string WbShade = Material.Rounded.WbShade; + public const string WbSunny = Material.Rounded.WbSunny; + public const string WbTwilight = Material.Rounded.WbTwilight; + public const string Wc = Material.Rounded.Wc; + public const string Web = Material.Rounded.Web; + public const string WebAsset = Material.Rounded.WebAsset; + public const string WebAssetOff = Material.Rounded.WebAssetOff; + public const string Webhook = Material.Rounded.Webhook; + public const string Weekend = Material.Rounded.Weekend; + public const string West = Material.Rounded.West; + public const string Whatsapp = Material.Rounded.Whatsapp; + public const string Whatshot = Material.Rounded.Whatshot; + public const string WheelchairPickup = Material.Rounded.WheelchairPickup; + public const string WhereToVote = Material.Rounded.WhereToVote; + public const string Widgets = Material.Rounded.Widgets; + public const string Wifi = Material.Rounded.Wifi; + public const string Wifi1Bar = Material.Rounded.Wifi1Bar; + public const string Wifi2Bar = Material.Rounded.Wifi2Bar; + public const string WifiCalling = Material.Rounded.WifiCalling; + public const string WifiCalling3 = Material.Rounded.WifiCalling3; + public const string WifiChannel = Material.Rounded.WifiChannel; + public const string WifiFind = Material.Rounded.WifiFind; + public const string WifiLock = Material.Rounded.WifiLock; + public const string WifiOff = Material.Rounded.WifiOff; + public const string WifiPassword = Material.Rounded.WifiPassword; + public const string WifiProtectedSetup = Material.Rounded.WifiProtectedSetup; + public const string WifiTethering = Material.Rounded.WifiTethering; + public const string WifiTetheringError = Material.Rounded.WifiTetheringError; + public const string WifiTetheringOff = Material.Rounded.WifiTetheringOff; + public const string Window = Material.Rounded.Window; + public const string WineBar = Material.Rounded.WineBar; + public const string Woman = Material.Rounded.Woman; + public const string Work = Material.Rounded.Work; + public const string WorkOff = Material.Rounded.WorkOff; + public const string WorkOutline = Material.Rounded.WorkOutline; + public const string WorkspacePremium = Material.Rounded.WorkspacePremium; + public const string Workspaces = Material.Rounded.Workspaces; + public const string WrapText = Material.Rounded.WrapText; + public const string WrongLocation = Material.Rounded.WrongLocation; + public const string Wysiwyg = Material.Rounded.Wysiwyg; + public const string Yard = Material.Rounded.Yard; + public const string YoutubeSearchedFor = Material.Rounded.YoutubeSearchedFor; + public const string ZoomIn = Material.Rounded.ZoomIn; + public const string ZoomInMap = Material.Rounded.ZoomInMap; + public const string ZoomOut = Material.Rounded.ZoomOut; + public const string ZoomOutMap = Material.Rounded.ZoomOutMap; + } + } +} diff --git a/Icons/Obsolete/Sharp.cs b/Icons/Obsolete/Sharp.cs new file mode 100644 index 0000000..ffb3bc8 --- /dev/null +++ b/Icons/Obsolete/Sharp.cs @@ -0,0 +1,2074 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + [ExcludeFromCodeCoverage] + public partial class Sharp + { + public const string _10k = Material.Sharp._10k; + public const string _10mp = Material.Sharp._10mp; + public const string _11mp = Material.Sharp._11mp; + public const string _123 = Material.Sharp._123; + public const string _12mp = Material.Sharp._12mp; + public const string _13mp = Material.Sharp._13mp; + public const string _14mp = Material.Sharp._14mp; + public const string _15mp = Material.Sharp._15mp; + public const string _16mp = Material.Sharp._16mp; + public const string _17mp = Material.Sharp._17mp; + public const string _18mp = Material.Sharp._18mp; + public const string _19mp = Material.Sharp._19mp; + public const string _1k = Material.Sharp._1k; + public const string _1kPlus = Material.Sharp._1kPlus; + public const string _1xMobiledata = Material.Sharp._1xMobiledata; + public const string _20mp = Material.Sharp._20mp; + public const string _21mp = Material.Sharp._21mp; + public const string _22mp = Material.Sharp._22mp; + public const string _23mp = Material.Sharp._23mp; + public const string _24mp = Material.Sharp._24mp; + public const string _2k = Material.Sharp._2k; + public const string _2kPlus = Material.Sharp._2kPlus; + public const string _2mp = Material.Sharp._2mp; + public const string _30fps = Material.Sharp._30fps; + public const string _30fpsSelect = Material.Sharp._30fpsSelect; + public const string _360 = Material.Sharp._360; + public const string _3dRotation = Material.Sharp._3dRotation; + public const string _3gMobiledata = Material.Sharp._3gMobiledata; + public const string _3k = Material.Sharp._3k; + public const string _3kPlus = Material.Sharp._3kPlus; + public const string _3mp = Material.Sharp._3mp; + public const string _3p = Material.Sharp._3p; + public const string _4gMobiledata = Material.Sharp._4gMobiledata; + public const string _4gPlusMobiledata = Material.Sharp._4gPlusMobiledata; + public const string _4k = Material.Sharp._4k; + public const string _4kPlus = Material.Sharp._4kPlus; + public const string _4mp = Material.Sharp._4mp; + public const string _5g = Material.Sharp._5g; + public const string _5k = Material.Sharp._5k; + public const string _5kPlus = Material.Sharp._5kPlus; + public const string _5mp = Material.Sharp._5mp; + public const string _60fps = Material.Sharp._60fps; + public const string _60fpsSelect = Material.Sharp._60fpsSelect; + public const string _6FtApart = Material.Sharp._6FtApart; + public const string _6k = Material.Sharp._6k; + public const string _6kPlus = Material.Sharp._6kPlus; + public const string _6mp = Material.Sharp._6mp; + public const string _7k = Material.Sharp._7k; + public const string _7kPlus = Material.Sharp._7kPlus; + public const string _7mp = Material.Sharp._7mp; + public const string _8k = Material.Sharp._8k; + public const string _8kPlus = Material.Sharp._8kPlus; + public const string _8mp = Material.Sharp._8mp; + public const string _9k = Material.Sharp._9k; + public const string _9kPlus = Material.Sharp._9kPlus; + public const string _9mp = Material.Sharp._9mp; + public const string Abc = Material.Sharp.Abc; + public const string AcUnit = Material.Sharp.AcUnit; + public const string AccessAlarm = Material.Sharp.AccessAlarm; + public const string AccessAlarms = Material.Sharp.AccessAlarms; + public const string AccessTime = Material.Sharp.AccessTime; + public const string AccessTimeFilled = Material.Sharp.AccessTimeFilled; + public const string Accessibility = Material.Sharp.Accessibility; + public const string AccessibilityNew = Material.Sharp.AccessibilityNew; + public const string Accessible = Material.Sharp.Accessible; + public const string AccessibleForward = Material.Sharp.AccessibleForward; + public const string AccountBalance = Material.Sharp.AccountBalance; + public const string AccountBalanceWallet = Material.Sharp.AccountBalanceWallet; + public const string AccountBox = Material.Sharp.AccountBox; + public const string AccountCircle = Material.Sharp.AccountCircle; + public const string AccountTree = Material.Sharp.AccountTree; + public const string AdUnits = Material.Sharp.AdUnits; + public const string Adb = Material.Sharp.Adb; + public const string Add = Material.Sharp.Add; + public const string AddAPhoto = Material.Sharp.AddAPhoto; + public const string AddAlarm = Material.Sharp.AddAlarm; + public const string AddAlert = Material.Sharp.AddAlert; + public const string AddBox = Material.Sharp.AddBox; + public const string AddBusiness = Material.Sharp.AddBusiness; + public const string AddCard = Material.Sharp.AddCard; + public const string AddChart = Material.Sharp.AddChart; + public const string AddCircle = Material.Sharp.AddCircle; + public const string AddCircleOutline = Material.Sharp.AddCircleOutline; + public const string AddComment = Material.Sharp.AddComment; + public const string AddIcCall = Material.Sharp.AddIcCall; + public const string AddLink = Material.Sharp.AddLink; + public const string AddLocation = Material.Sharp.AddLocation; + public const string AddLocationAlt = Material.Sharp.AddLocationAlt; + public const string AddModerator = Material.Sharp.AddModerator; + public const string AddPhotoAlternate = Material.Sharp.AddPhotoAlternate; + public const string AddReaction = Material.Sharp.AddReaction; + public const string AddRoad = Material.Sharp.AddRoad; + public const string AddShoppingCart = Material.Sharp.AddShoppingCart; + public const string AddTask = Material.Sharp.AddTask; + public const string AddToDrive = Material.Sharp.AddToDrive; + public const string AddToHomeScreen = Material.Sharp.AddToHomeScreen; + public const string AddToPhotos = Material.Sharp.AddToPhotos; + public const string AddToQueue = Material.Sharp.AddToQueue; + public const string Addchart = Material.Sharp.Addchart; + public const string AdfScanner = Material.Sharp.AdfScanner; + public const string Adjust = Material.Sharp.Adjust; + public const string AdminPanelSettings = Material.Sharp.AdminPanelSettings; + public const string AdsClick = Material.Sharp.AdsClick; + public const string Agriculture = Material.Sharp.Agriculture; + public const string Air = Material.Sharp.Air; + public const string AirlineSeatFlat = Material.Sharp.AirlineSeatFlat; + public const string AirlineSeatFlatAngled = Material.Sharp.AirlineSeatFlatAngled; + public const string AirlineSeatIndividualSuite = Material.Sharp.AirlineSeatIndividualSuite; + public const string AirlineSeatLegroomExtra = Material.Sharp.AirlineSeatLegroomExtra; + public const string AirlineSeatLegroomNormal = Material.Sharp.AirlineSeatLegroomNormal; + public const string AirlineSeatLegroomReduced = Material.Sharp.AirlineSeatLegroomReduced; + public const string AirlineSeatReclineExtra = Material.Sharp.AirlineSeatReclineExtra; + public const string AirlineSeatReclineNormal = Material.Sharp.AirlineSeatReclineNormal; + public const string AirlineStops = Material.Sharp.AirlineStops; + public const string Airlines = Material.Sharp.Airlines; + public const string AirplaneTicket = Material.Sharp.AirplaneTicket; + public const string AirplanemodeActive = Material.Sharp.AirplanemodeActive; + public const string AirplanemodeInactive = Material.Sharp.AirplanemodeInactive; + public const string Airplay = Material.Sharp.Airplay; + public const string AirportShuttle = Material.Sharp.AirportShuttle; + public const string Alarm = Material.Sharp.Alarm; + public const string AlarmAdd = Material.Sharp.AlarmAdd; + public const string AlarmOff = Material.Sharp.AlarmOff; + public const string AlarmOn = Material.Sharp.AlarmOn; + public const string Album = Material.Sharp.Album; + public const string AlignHorizontalCenter = Material.Sharp.AlignHorizontalCenter; + public const string AlignHorizontalLeft = Material.Sharp.AlignHorizontalLeft; + public const string AlignHorizontalRight = Material.Sharp.AlignHorizontalRight; + public const string AlignVerticalBottom = Material.Sharp.AlignVerticalBottom; + public const string AlignVerticalCenter = Material.Sharp.AlignVerticalCenter; + public const string AlignVerticalTop = Material.Sharp.AlignVerticalTop; + public const string AllInbox = Material.Sharp.AllInbox; + public const string AllInclusive = Material.Sharp.AllInclusive; + public const string AllOut = Material.Sharp.AllOut; + public const string AltRoute = Material.Sharp.AltRoute; + public const string AlternateEmail = Material.Sharp.AlternateEmail; + public const string Analytics = Material.Sharp.Analytics; + public const string Anchor = Material.Sharp.Anchor; + public const string Android = Material.Sharp.Android; + public const string Animation = Material.Sharp.Animation; + public const string Announcement = Material.Sharp.Announcement; + public const string Aod = Material.Sharp.Aod; + public const string Apartment = Material.Sharp.Apartment; + public const string Api = Material.Sharp.Api; + public const string AppBlocking = Material.Sharp.AppBlocking; + public const string AppRegistration = Material.Sharp.AppRegistration; + public const string AppSettingsAlt = Material.Sharp.AppSettingsAlt; + public const string AppShortcut = Material.Sharp.AppShortcut; + public const string Approval = Material.Sharp.Approval; + public const string Apps = Material.Sharp.Apps; + public const string AppsOutage = Material.Sharp.AppsOutage; + public const string Architecture = Material.Sharp.Architecture; + public const string Archive = Material.Sharp.Archive; + public const string AreaChart = Material.Sharp.AreaChart; + public const string ArrowBack = Material.Sharp.ArrowBack; + public const string ArrowBackIos = Material.Sharp.ArrowBackIos; + public const string ArrowBackIosNew = Material.Sharp.ArrowBackIosNew; + public const string ArrowCircleDown = Material.Sharp.ArrowCircleDown; + public const string ArrowCircleLeft = Material.Sharp.ArrowCircleLeft; + public const string ArrowCircleRight = Material.Sharp.ArrowCircleRight; + public const string ArrowCircleUp = Material.Sharp.ArrowCircleUp; + public const string ArrowDownward = Material.Sharp.ArrowDownward; + public const string ArrowDropDown = Material.Sharp.ArrowDropDown; + public const string ArrowDropDownCircle = Material.Sharp.ArrowDropDownCircle; + public const string ArrowDropUp = Material.Sharp.ArrowDropUp; + public const string ArrowForward = Material.Sharp.ArrowForward; + public const string ArrowForwardIos = Material.Sharp.ArrowForwardIos; + public const string ArrowLeft = Material.Sharp.ArrowLeft; + public const string ArrowRight = Material.Sharp.ArrowRight; + public const string ArrowRightAlt = Material.Sharp.ArrowRightAlt; + public const string ArrowUpward = Material.Sharp.ArrowUpward; + public const string ArtTrack = Material.Sharp.ArtTrack; + public const string Article = Material.Sharp.Article; + public const string AspectRatio = Material.Sharp.AspectRatio; + public const string Assessment = Material.Sharp.Assessment; + public const string Assignment = Material.Sharp.Assignment; + public const string AssignmentInd = Material.Sharp.AssignmentInd; + public const string AssignmentLate = Material.Sharp.AssignmentLate; + public const string AssignmentReturn = Material.Sharp.AssignmentReturn; + public const string AssignmentReturned = Material.Sharp.AssignmentReturned; + public const string AssignmentTurnedIn = Material.Sharp.AssignmentTurnedIn; + public const string Assistant = Material.Sharp.Assistant; + public const string AssistantDirection = Material.Sharp.AssistantDirection; + public const string AssistantPhoto = Material.Sharp.AssistantPhoto; + public const string AssuredWorkload = Material.Sharp.AssuredWorkload; + public const string Atm = Material.Sharp.Atm; + public const string AttachEmail = Material.Sharp.AttachEmail; + public const string AttachFile = Material.Sharp.AttachFile; + public const string AttachMoney = Material.Sharp.AttachMoney; + public const string Attachment = Material.Sharp.Attachment; + public const string Attractions = Material.Sharp.Attractions; + public const string Attribution = Material.Sharp.Attribution; + public const string AudioFile = Material.Sharp.AudioFile; + public const string Audiotrack = Material.Sharp.Audiotrack; + public const string AutoAwesome = Material.Sharp.AutoAwesome; + public const string AutoAwesomeMosaic = Material.Sharp.AutoAwesomeMosaic; + public const string AutoAwesomeMotion = Material.Sharp.AutoAwesomeMotion; + public const string AutoDelete = Material.Sharp.AutoDelete; + public const string AutoFixHigh = Material.Sharp.AutoFixHigh; + public const string AutoFixNormal = Material.Sharp.AutoFixNormal; + public const string AutoFixOff = Material.Sharp.AutoFixOff; + public const string AutoGraph = Material.Sharp.AutoGraph; + public const string AutoStories = Material.Sharp.AutoStories; + public const string AutofpsSelect = Material.Sharp.AutofpsSelect; + public const string Autorenew = Material.Sharp.Autorenew; + public const string AvTimer = Material.Sharp.AvTimer; + public const string BabyChangingStation = Material.Sharp.BabyChangingStation; + public const string BackHand = Material.Sharp.BackHand; + public const string Backpack = Material.Sharp.Backpack; + public const string Backspace = Material.Sharp.Backspace; + public const string Backup = Material.Sharp.Backup; + public const string BackupTable = Material.Sharp.BackupTable; + public const string Badge = Material.Sharp.Badge; + public const string BakeryDining = Material.Sharp.BakeryDining; + public const string Balance = Material.Sharp.Balance; + public const string Balcony = Material.Sharp.Balcony; + public const string Ballot = Material.Sharp.Ballot; + public const string BarChart = Material.Sharp.BarChart; + public const string BatchPrediction = Material.Sharp.BatchPrediction; + public const string Bathroom = Material.Sharp.Bathroom; + public const string Bathtub = Material.Sharp.Bathtub; + public const string Battery0Bar = Material.Sharp.Battery0Bar; + public const string Battery1Bar = Material.Sharp.Battery1Bar; + public const string Battery2Bar = Material.Sharp.Battery2Bar; + public const string Battery3Bar = Material.Sharp.Battery3Bar; + public const string Battery4Bar = Material.Sharp.Battery4Bar; + public const string Battery5Bar = Material.Sharp.Battery5Bar; + public const string Battery6Bar = Material.Sharp.Battery6Bar; + public const string BatteryAlert = Material.Sharp.BatteryAlert; + public const string BatteryChargingFull = Material.Sharp.BatteryChargingFull; + public const string BatteryFull = Material.Sharp.BatteryFull; + public const string BatterySaver = Material.Sharp.BatterySaver; + public const string BatteryStd = Material.Sharp.BatteryStd; + public const string BatteryUnknown = Material.Sharp.BatteryUnknown; + public const string BeachAccess = Material.Sharp.BeachAccess; + public const string Bed = Material.Sharp.Bed; + public const string BedroomBaby = Material.Sharp.BedroomBaby; + public const string BedroomChild = Material.Sharp.BedroomChild; + public const string BedroomParent = Material.Sharp.BedroomParent; + public const string Bedtime = Material.Sharp.Bedtime; + public const string BedtimeOff = Material.Sharp.BedtimeOff; + public const string Beenhere = Material.Sharp.Beenhere; + public const string Bento = Material.Sharp.Bento; + public const string BikeScooter = Material.Sharp.BikeScooter; + public const string Biotech = Material.Sharp.Biotech; + public const string Blender = Material.Sharp.Blender; + public const string Block = Material.Sharp.Block; + public const string Bloodtype = Material.Sharp.Bloodtype; + public const string Bluetooth = Material.Sharp.Bluetooth; + public const string BluetoothAudio = Material.Sharp.BluetoothAudio; + public const string BluetoothConnected = Material.Sharp.BluetoothConnected; + public const string BluetoothDisabled = Material.Sharp.BluetoothDisabled; + public const string BluetoothDrive = Material.Sharp.BluetoothDrive; + public const string BluetoothSearching = Material.Sharp.BluetoothSearching; + public const string BlurCircular = Material.Sharp.BlurCircular; + public const string BlurLinear = Material.Sharp.BlurLinear; + public const string BlurOff = Material.Sharp.BlurOff; + public const string BlurOn = Material.Sharp.BlurOn; + public const string Bolt = Material.Sharp.Bolt; + public const string Book = Material.Sharp.Book; + public const string BookOnline = Material.Sharp.BookOnline; + public const string Bookmark = Material.Sharp.Bookmark; + public const string BookmarkAdd = Material.Sharp.BookmarkAdd; + public const string BookmarkAdded = Material.Sharp.BookmarkAdded; + public const string BookmarkBorder = Material.Sharp.BookmarkBorder; + public const string BookmarkRemove = Material.Sharp.BookmarkRemove; + public const string Bookmarks = Material.Sharp.Bookmarks; + public const string BorderAll = Material.Sharp.BorderAll; + public const string BorderBottom = Material.Sharp.BorderBottom; + public const string BorderClear = Material.Sharp.BorderClear; + public const string BorderColor = Material.Sharp.BorderColor; + public const string BorderHorizontal = Material.Sharp.BorderHorizontal; + public const string BorderInner = Material.Sharp.BorderInner; + public const string BorderLeft = Material.Sharp.BorderLeft; + public const string BorderOuter = Material.Sharp.BorderOuter; + public const string BorderRight = Material.Sharp.BorderRight; + public const string BorderStyle = Material.Sharp.BorderStyle; + public const string BorderTop = Material.Sharp.BorderTop; + public const string BorderVertical = Material.Sharp.BorderVertical; + public const string Boy = Material.Sharp.Boy; + public const string BrandingWatermark = Material.Sharp.BrandingWatermark; + public const string BreakfastDining = Material.Sharp.BreakfastDining; + public const string Brightness1 = Material.Sharp.Brightness1; + public const string Brightness2 = Material.Sharp.Brightness2; + public const string Brightness3 = Material.Sharp.Brightness3; + public const string Brightness4 = Material.Sharp.Brightness4; + public const string Brightness5 = Material.Sharp.Brightness5; + public const string Brightness6 = Material.Sharp.Brightness6; + public const string Brightness7 = Material.Sharp.Brightness7; + public const string BrightnessAuto = Material.Sharp.BrightnessAuto; + public const string BrightnessHigh = Material.Sharp.BrightnessHigh; + public const string BrightnessLow = Material.Sharp.BrightnessLow; + public const string BrightnessMedium = Material.Sharp.BrightnessMedium; + public const string BrokenImage = Material.Sharp.BrokenImage; + public const string BrowseGallery = Material.Sharp.BrowseGallery; + public const string BrowserNotSupported = Material.Sharp.BrowserNotSupported; + public const string BrowserUpdated = Material.Sharp.BrowserUpdated; + public const string BrunchDining = Material.Sharp.BrunchDining; + public const string Brush = Material.Sharp.Brush; + public const string BubbleChart = Material.Sharp.BubbleChart; + public const string BugReport = Material.Sharp.BugReport; + public const string Build = Material.Sharp.Build; + public const string BuildCircle = Material.Sharp.BuildCircle; + public const string Bungalow = Material.Sharp.Bungalow; + public const string BurstMode = Material.Sharp.BurstMode; + public const string BusAlert = Material.Sharp.BusAlert; + public const string Business = Material.Sharp.Business; + public const string BusinessCenter = Material.Sharp.BusinessCenter; + public const string Cabin = Material.Sharp.Cabin; + public const string Cable = Material.Sharp.Cable; + public const string Cached = Material.Sharp.Cached; + public const string Cake = Material.Sharp.Cake; + public const string Calculate = Material.Sharp.Calculate; + public const string CalendarMonth = Material.Sharp.CalendarMonth; + public const string CalendarToday = Material.Sharp.CalendarToday; + public const string CalendarViewDay = Material.Sharp.CalendarViewDay; + public const string CalendarViewMonth = Material.Sharp.CalendarViewMonth; + public const string CalendarViewWeek = Material.Sharp.CalendarViewWeek; + public const string Call = Material.Sharp.Call; + public const string CallEnd = Material.Sharp.CallEnd; + public const string CallMade = Material.Sharp.CallMade; + public const string CallMerge = Material.Sharp.CallMerge; + public const string CallMissed = Material.Sharp.CallMissed; + public const string CallMissedOutgoing = Material.Sharp.CallMissedOutgoing; + public const string CallReceived = Material.Sharp.CallReceived; + public const string CallSplit = Material.Sharp.CallSplit; + public const string CallToAction = Material.Sharp.CallToAction; + public const string Camera = Material.Sharp.Camera; + public const string CameraAlt = Material.Sharp.CameraAlt; + public const string CameraEnhance = Material.Sharp.CameraEnhance; + public const string CameraFront = Material.Sharp.CameraFront; + public const string CameraIndoor = Material.Sharp.CameraIndoor; + public const string CameraOutdoor = Material.Sharp.CameraOutdoor; + public const string CameraRear = Material.Sharp.CameraRear; + public const string CameraRoll = Material.Sharp.CameraRoll; + public const string Cameraswitch = Material.Sharp.Cameraswitch; + public const string Campaign = Material.Sharp.Campaign; + public const string Cancel = Material.Sharp.Cancel; + public const string CancelPresentation = Material.Sharp.CancelPresentation; + public const string CancelScheduleSend = Material.Sharp.CancelScheduleSend; + public const string CandlestickChart = Material.Sharp.CandlestickChart; + public const string CarCrash = Material.Sharp.CarCrash; + public const string CarRental = Material.Sharp.CarRental; + public const string CarRepair = Material.Sharp.CarRepair; + public const string CardGiftcard = Material.Sharp.CardGiftcard; + public const string CardMembership = Material.Sharp.CardMembership; + public const string CardTravel = Material.Sharp.CardTravel; + public const string Carpenter = Material.Sharp.Carpenter; + public const string Cases = Material.Sharp.Cases; + public const string Casino = Material.Sharp.Casino; + public const string Cast = Material.Sharp.Cast; + public const string CastConnected = Material.Sharp.CastConnected; + public const string CastForEducation = Material.Sharp.CastForEducation; + public const string Castle = Material.Sharp.Castle; + public const string CatchingPokemon = Material.Sharp.CatchingPokemon; + public const string Category = Material.Sharp.Category; + public const string Celebration = Material.Sharp.Celebration; + public const string CellTower = Material.Sharp.CellTower; + public const string CellWifi = Material.Sharp.CellWifi; + public const string CenterFocusStrong = Material.Sharp.CenterFocusStrong; + public const string CenterFocusWeak = Material.Sharp.CenterFocusWeak; + public const string Chair = Material.Sharp.Chair; + public const string ChairAlt = Material.Sharp.ChairAlt; + public const string Chalet = Material.Sharp.Chalet; + public const string ChangeCircle = Material.Sharp.ChangeCircle; + public const string ChangeHistory = Material.Sharp.ChangeHistory; + public const string ChargingStation = Material.Sharp.ChargingStation; + public const string Chat = Material.Sharp.Chat; + public const string ChatBubble = Material.Sharp.ChatBubble; + public const string ChatBubbleOutline = Material.Sharp.ChatBubbleOutline; + public const string Check = Material.Sharp.Check; + public const string CheckBox = Material.Sharp.CheckBox; + public const string CheckBoxOutlineBlank = Material.Sharp.CheckBoxOutlineBlank; + public const string CheckCircle = Material.Sharp.CheckCircle; + public const string CheckCircleOutline = Material.Sharp.CheckCircleOutline; + public const string Checklist = Material.Sharp.Checklist; + public const string ChecklistRtl = Material.Sharp.ChecklistRtl; + public const string Checkroom = Material.Sharp.Checkroom; + public const string ChevronLeft = Material.Sharp.ChevronLeft; + public const string ChevronRight = Material.Sharp.ChevronRight; + public const string ChildCare = Material.Sharp.ChildCare; + public const string ChildFriendly = Material.Sharp.ChildFriendly; + public const string ChromeReaderMode = Material.Sharp.ChromeReaderMode; + public const string Church = Material.Sharp.Church; + public const string Circle = Material.Sharp.Circle; + public const string CircleNotifications = Material.Sharp.CircleNotifications; + public const string Class = Material.Sharp.Class; + public const string CleanHands = Material.Sharp.CleanHands; + public const string CleaningServices = Material.Sharp.CleaningServices; + public const string Clear = Material.Sharp.Clear; + public const string ClearAll = Material.Sharp.ClearAll; + public const string Close = Material.Sharp.Close; + public const string CloseFullscreen = Material.Sharp.CloseFullscreen; + public const string ClosedCaption = Material.Sharp.ClosedCaption; + public const string ClosedCaptionDisabled = Material.Sharp.ClosedCaptionDisabled; + public const string ClosedCaptionOff = Material.Sharp.ClosedCaptionOff; + public const string Cloud = Material.Sharp.Cloud; + public const string CloudCircle = Material.Sharp.CloudCircle; + public const string CloudDone = Material.Sharp.CloudDone; + public const string CloudDownload = Material.Sharp.CloudDownload; + public const string CloudOff = Material.Sharp.CloudOff; + public const string CloudQueue = Material.Sharp.CloudQueue; + public const string CloudSync = Material.Sharp.CloudSync; + public const string CloudUpload = Material.Sharp.CloudUpload; + public const string Co2 = Material.Sharp.Co2; + public const string CoPresent = Material.Sharp.CoPresent; + public const string Code = Material.Sharp.Code; + public const string CodeOff = Material.Sharp.CodeOff; + public const string Coffee = Material.Sharp.Coffee; + public const string CoffeeMaker = Material.Sharp.CoffeeMaker; + public const string Collections = Material.Sharp.Collections; + public const string CollectionsBookmark = Material.Sharp.CollectionsBookmark; + public const string ColorLens = Material.Sharp.ColorLens; + public const string Colorize = Material.Sharp.Colorize; + public const string Comment = Material.Sharp.Comment; + public const string CommentBank = Material.Sharp.CommentBank; + public const string CommentsDisabled = Material.Sharp.CommentsDisabled; + public const string Commit = Material.Sharp.Commit; + public const string Commute = Material.Sharp.Commute; + public const string Compare = Material.Sharp.Compare; + public const string CompareArrows = Material.Sharp.CompareArrows; + public const string CompassCalibration = Material.Sharp.CompassCalibration; + public const string Compost = Material.Sharp.Compost; + public const string Compress = Material.Sharp.Compress; + public const string Computer = Material.Sharp.Computer; + public const string ConfirmationNumber = Material.Sharp.ConfirmationNumber; + public const string ConnectWithoutContact = Material.Sharp.ConnectWithoutContact; + public const string ConnectedTv = Material.Sharp.ConnectedTv; + public const string ConnectingAirports = Material.Sharp.ConnectingAirports; + public const string Construction = Material.Sharp.Construction; + public const string ContactMail = Material.Sharp.ContactMail; + public const string ContactPage = Material.Sharp.ContactPage; + public const string ContactPhone = Material.Sharp.ContactPhone; + public const string ContactSupport = Material.Sharp.ContactSupport; + public const string Contactless = Material.Sharp.Contactless; + public const string Contacts = Material.Sharp.Contacts; + public const string ContentCopy = Material.Sharp.ContentCopy; + public const string ContentCut = Material.Sharp.ContentCut; + public const string ContentPaste = Material.Sharp.ContentPaste; + public const string ContentPasteGo = Material.Sharp.ContentPasteGo; + public const string ContentPasteOff = Material.Sharp.ContentPasteOff; + public const string ContentPasteSearch = Material.Sharp.ContentPasteSearch; + public const string Contrast = Material.Sharp.Contrast; + public const string ControlCamera = Material.Sharp.ControlCamera; + public const string ControlPoint = Material.Sharp.ControlPoint; + public const string ControlPointDuplicate = Material.Sharp.ControlPointDuplicate; + public const string Cookie = Material.Sharp.Cookie; + public const string CopyAll = Material.Sharp.CopyAll; + public const string Copyright = Material.Sharp.Copyright; + public const string Coronavirus = Material.Sharp.Coronavirus; + public const string CorporateFare = Material.Sharp.CorporateFare; + public const string Cottage = Material.Sharp.Cottage; + public const string Countertops = Material.Sharp.Countertops; + public const string Create = Material.Sharp.Create; + public const string CreateNewFolder = Material.Sharp.CreateNewFolder; + public const string CreditCard = Material.Sharp.CreditCard; + public const string CreditCardOff = Material.Sharp.CreditCardOff; + public const string CreditScore = Material.Sharp.CreditScore; + public const string Crib = Material.Sharp.Crib; + public const string CrisisAlert = Material.Sharp.CrisisAlert; + public const string Crop = Material.Sharp.Crop; + public const string Crop169 = Material.Sharp.Crop169; + public const string Crop32 = Material.Sharp.Crop32; + public const string Crop54 = Material.Sharp.Crop54; + public const string Crop75 = Material.Sharp.Crop75; + public const string CropDin = Material.Sharp.CropDin; + public const string CropFree = Material.Sharp.CropFree; + public const string CropLandscape = Material.Sharp.CropLandscape; + public const string CropOriginal = Material.Sharp.CropOriginal; + public const string CropPortrait = Material.Sharp.CropPortrait; + public const string CropRotate = Material.Sharp.CropRotate; + public const string CropSquare = Material.Sharp.CropSquare; + public const string CrueltyFree = Material.Sharp.CrueltyFree; + public const string Css = Material.Sharp.Css; + public const string CurrencyBitcoin = Material.Sharp.CurrencyBitcoin; + public const string CurrencyExchange = Material.Sharp.CurrencyExchange; + public const string CurrencyFranc = Material.Sharp.CurrencyFranc; + public const string CurrencyLira = Material.Sharp.CurrencyLira; + public const string CurrencyPound = Material.Sharp.CurrencyPound; + public const string CurrencyRuble = Material.Sharp.CurrencyRuble; + public const string CurrencyRupee = Material.Sharp.CurrencyRupee; + public const string CurrencyYen = Material.Sharp.CurrencyYen; + public const string CurrencyYuan = Material.Sharp.CurrencyYuan; + public const string Cyclone = Material.Sharp.Cyclone; + public const string Dangerous = Material.Sharp.Dangerous; + public const string DarkMode = Material.Sharp.DarkMode; + public const string Dashboard = Material.Sharp.Dashboard; + public const string DashboardCustomize = Material.Sharp.DashboardCustomize; + public const string DataArray = Material.Sharp.DataArray; + public const string DataExploration = Material.Sharp.DataExploration; + public const string DataObject = Material.Sharp.DataObject; + public const string DataSaverOff = Material.Sharp.DataSaverOff; + public const string DataSaverOn = Material.Sharp.DataSaverOn; + public const string DataThresholding = Material.Sharp.DataThresholding; + public const string DataUsage = Material.Sharp.DataUsage; + public const string DateRange = Material.Sharp.DateRange; + public const string Deblur = Material.Sharp.Deblur; + public const string Deck = Material.Sharp.Deck; + public const string Dehaze = Material.Sharp.Dehaze; + public const string Delete = Material.Sharp.Delete; + public const string DeleteForever = Material.Sharp.DeleteForever; + public const string DeleteOutline = Material.Sharp.DeleteOutline; + public const string DeleteSweep = Material.Sharp.DeleteSweep; + public const string DeliveryDining = Material.Sharp.DeliveryDining; + public const string DensityLarge = Material.Sharp.DensityLarge; + public const string DensityMedium = Material.Sharp.DensityMedium; + public const string DensitySmall = Material.Sharp.DensitySmall; + public const string DepartureBoard = Material.Sharp.DepartureBoard; + public const string Description = Material.Sharp.Description; + public const string Deselect = Material.Sharp.Deselect; + public const string DesignServices = Material.Sharp.DesignServices; + public const string DesktopAccessDisabled = Material.Sharp.DesktopAccessDisabled; + public const string DesktopMac = Material.Sharp.DesktopMac; + public const string DesktopWindows = Material.Sharp.DesktopWindows; + public const string Details = Material.Sharp.Details; + public const string DeveloperBoard = Material.Sharp.DeveloperBoard; + public const string DeveloperBoardOff = Material.Sharp.DeveloperBoardOff; + public const string DeveloperMode = Material.Sharp.DeveloperMode; + public const string DeviceHub = Material.Sharp.DeviceHub; + public const string DeviceThermostat = Material.Sharp.DeviceThermostat; + public const string DeviceUnknown = Material.Sharp.DeviceUnknown; + public const string Devices = Material.Sharp.Devices; + public const string DevicesFold = Material.Sharp.DevicesFold; + public const string DevicesOther = Material.Sharp.DevicesOther; + public const string DialerSip = Material.Sharp.DialerSip; + public const string Dialpad = Material.Sharp.Dialpad; + public const string Diamond = Material.Sharp.Diamond; + public const string Difference = Material.Sharp.Difference; + public const string Dining = Material.Sharp.Dining; + public const string DinnerDining = Material.Sharp.DinnerDining; + public const string Directions = Material.Sharp.Directions; + public const string DirectionsBike = Material.Sharp.DirectionsBike; + public const string DirectionsBoat = Material.Sharp.DirectionsBoat; + public const string DirectionsBoatFilled = Material.Sharp.DirectionsBoatFilled; + public const string DirectionsBus = Material.Sharp.DirectionsBus; + public const string DirectionsBusFilled = Material.Sharp.DirectionsBusFilled; + public const string DirectionsCar = Material.Sharp.DirectionsCar; + public const string DirectionsCarFilled = Material.Sharp.DirectionsCarFilled; + public const string DirectionsOff = Material.Sharp.DirectionsOff; + public const string DirectionsRailway = Material.Sharp.DirectionsRailway; + public const string DirectionsRailwayFilled = Material.Sharp.DirectionsRailwayFilled; + public const string DirectionsRun = Material.Sharp.DirectionsRun; + public const string DirectionsSubway = Material.Sharp.DirectionsSubway; + public const string DirectionsSubwayFilled = Material.Sharp.DirectionsSubwayFilled; + public const string DirectionsTransit = Material.Sharp.DirectionsTransit; + public const string DirectionsTransitFilled = Material.Sharp.DirectionsTransitFilled; + public const string DirectionsWalk = Material.Sharp.DirectionsWalk; + public const string DirtyLens = Material.Sharp.DirtyLens; + public const string DisabledByDefault = Material.Sharp.DisabledByDefault; + public const string DisabledVisible = Material.Sharp.DisabledVisible; + public const string DiscFull = Material.Sharp.DiscFull; + public const string Discount = Material.Sharp.Discount; + public const string DisplaySettings = Material.Sharp.DisplaySettings; + public const string Dns = Material.Sharp.Dns; + public const string DoDisturb = Material.Sharp.DoDisturb; + public const string DoDisturbAlt = Material.Sharp.DoDisturbAlt; + public const string DoDisturbOff = Material.Sharp.DoDisturbOff; + public const string DoDisturbOn = Material.Sharp.DoDisturbOn; + public const string DoNotDisturb = Material.Sharp.DoNotDisturb; + public const string DoNotDisturbAlt = Material.Sharp.DoNotDisturbAlt; + public const string DoNotDisturbOff = Material.Sharp.DoNotDisturbOff; + public const string DoNotDisturbOn = Material.Sharp.DoNotDisturbOn; + public const string DoNotDisturbOnTotalSilence = Material.Sharp.DoNotDisturbOnTotalSilence; + public const string DoNotStep = Material.Sharp.DoNotStep; + public const string DoNotTouch = Material.Sharp.DoNotTouch; + public const string Dock = Material.Sharp.Dock; + public const string DocumentScanner = Material.Sharp.DocumentScanner; + public const string Domain = Material.Sharp.Domain; + public const string DomainAdd = Material.Sharp.DomainAdd; + public const string DomainDisabled = Material.Sharp.DomainDisabled; + public const string DomainVerification = Material.Sharp.DomainVerification; + public const string Done = Material.Sharp.Done; + public const string DoneAll = Material.Sharp.DoneAll; + public const string DoneOutline = Material.Sharp.DoneOutline; + public const string DonutLarge = Material.Sharp.DonutLarge; + public const string DonutSmall = Material.Sharp.DonutSmall; + public const string DoorBack = Material.Sharp.DoorBack; + public const string DoorFront = Material.Sharp.DoorFront; + public const string DoorSliding = Material.Sharp.DoorSliding; + public const string Doorbell = Material.Sharp.Doorbell; + public const string DoubleArrow = Material.Sharp.DoubleArrow; + public const string DownhillSkiing = Material.Sharp.DownhillSkiing; + public const string Download = Material.Sharp.Download; + public const string DownloadDone = Material.Sharp.DownloadDone; + public const string DownloadForOffline = Material.Sharp.DownloadForOffline; + public const string Downloading = Material.Sharp.Downloading; + public const string Drafts = Material.Sharp.Drafts; + public const string DragHandle = Material.Sharp.DragHandle; + public const string DragIndicator = Material.Sharp.DragIndicator; + public const string Draw = Material.Sharp.Draw; + public const string DriveEta = Material.Sharp.DriveEta; + public const string DriveFileMove = Material.Sharp.DriveFileMove; + public const string DriveFileMoveRtl = Material.Sharp.DriveFileMoveRtl; + public const string DriveFileRenameOutline = Material.Sharp.DriveFileRenameOutline; + public const string DriveFolderUpload = Material.Sharp.DriveFolderUpload; + public const string Dry = Material.Sharp.Dry; + public const string DryCleaning = Material.Sharp.DryCleaning; + public const string Duo = Material.Sharp.Duo; + public const string Dvr = Material.Sharp.Dvr; + public const string DynamicFeed = Material.Sharp.DynamicFeed; + public const string DynamicForm = Material.Sharp.DynamicForm; + public const string EMobiledata = Material.Sharp.EMobiledata; + public const string Earbuds = Material.Sharp.Earbuds; + public const string EarbudsBattery = Material.Sharp.EarbudsBattery; + public const string East = Material.Sharp.East; + public const string EdgesensorHigh = Material.Sharp.EdgesensorHigh; + public const string EdgesensorLow = Material.Sharp.EdgesensorLow; + public const string Edit = Material.Sharp.Edit; + public const string EditAttributes = Material.Sharp.EditAttributes; + public const string EditCalendar = Material.Sharp.EditCalendar; + public const string EditLocation = Material.Sharp.EditLocation; + public const string EditLocationAlt = Material.Sharp.EditLocationAlt; + public const string EditNote = Material.Sharp.EditNote; + public const string EditNotifications = Material.Sharp.EditNotifications; + public const string EditOff = Material.Sharp.EditOff; + public const string EditRoad = Material.Sharp.EditRoad; + public const string Egg = Material.Sharp.Egg; + public const string EggAlt = Material.Sharp.EggAlt; + public const string Eject = Material.Sharp.Eject; + public const string Elderly = Material.Sharp.Elderly; + public const string ElderlyWoman = Material.Sharp.ElderlyWoman; + public const string ElectricBike = Material.Sharp.ElectricBike; + public const string ElectricCar = Material.Sharp.ElectricCar; + public const string ElectricMoped = Material.Sharp.ElectricMoped; + public const string ElectricRickshaw = Material.Sharp.ElectricRickshaw; + public const string ElectricScooter = Material.Sharp.ElectricScooter; + public const string ElectricalServices = Material.Sharp.ElectricalServices; + public const string Elevator = Material.Sharp.Elevator; + public const string Email = Material.Sharp.Email; + public const string Emergency = Material.Sharp.Emergency; + public const string EmergencyRecording = Material.Sharp.EmergencyRecording; + public const string EmergencyShare = Material.Sharp.EmergencyShare; + public const string EmojiEmotions = Material.Sharp.EmojiEmotions; + public const string EmojiEvents = Material.Sharp.EmojiEvents; + public const string EmojiFoodBeverage = Material.Sharp.EmojiFoodBeverage; + public const string EmojiNature = Material.Sharp.EmojiNature; + public const string EmojiObjects = Material.Sharp.EmojiObjects; + public const string EmojiPeople = Material.Sharp.EmojiPeople; + public const string EmojiSymbols = Material.Sharp.EmojiSymbols; + public const string EmojiTransportation = Material.Sharp.EmojiTransportation; + public const string Engineering = Material.Sharp.Engineering; + public const string EnhancedEncryption = Material.Sharp.EnhancedEncryption; + public const string Equalizer = Material.Sharp.Equalizer; + public const string Error = Material.Sharp.Error; + public const string ErrorOutline = Material.Sharp.ErrorOutline; + public const string Escalator = Material.Sharp.Escalator; + public const string EscalatorWarning = Material.Sharp.EscalatorWarning; + public const string Euro = Material.Sharp.Euro; + public const string EuroSymbol = Material.Sharp.EuroSymbol; + public const string EvStation = Material.Sharp.EvStation; + public const string Event = Material.Sharp.Event; + public const string EventAvailable = Material.Sharp.EventAvailable; + public const string EventBusy = Material.Sharp.EventBusy; + public const string EventNote = Material.Sharp.EventNote; + public const string EventRepeat = Material.Sharp.EventRepeat; + public const string EventSeat = Material.Sharp.EventSeat; + public const string ExitToApp = Material.Sharp.ExitToApp; + public const string Expand = Material.Sharp.Expand; + public const string ExpandCircleDown = Material.Sharp.ExpandCircleDown; + public const string ExpandLess = Material.Sharp.ExpandLess; + public const string ExpandMore = Material.Sharp.ExpandMore; + public const string Explicit = Material.Sharp.Explicit; + public const string Explore = Material.Sharp.Explore; + public const string ExploreOff = Material.Sharp.ExploreOff; + public const string Exposure = Material.Sharp.Exposure; + public const string ExposureNeg1 = Material.Sharp.ExposureNeg1; + public const string ExposureNeg2 = Material.Sharp.ExposureNeg2; + public const string ExposurePlus1 = Material.Sharp.ExposurePlus1; + public const string ExposurePlus2 = Material.Sharp.ExposurePlus2; + public const string ExposureZero = Material.Sharp.ExposureZero; + public const string Extension = Material.Sharp.Extension; + public const string ExtensionOff = Material.Sharp.ExtensionOff; + public const string Face = Material.Sharp.Face; + public const string FaceRetouchingNatural = Material.Sharp.FaceRetouchingNatural; + public const string FaceRetouchingOff = Material.Sharp.FaceRetouchingOff; + public const string FactCheck = Material.Sharp.FactCheck; + public const string Factory = Material.Sharp.Factory; + public const string FamilyRestroom = Material.Sharp.FamilyRestroom; + public const string FastForward = Material.Sharp.FastForward; + public const string FastRewind = Material.Sharp.FastRewind; + public const string Fastfood = Material.Sharp.Fastfood; + public const string Favorite = Material.Sharp.Favorite; + public const string FavoriteBorder = Material.Sharp.FavoriteBorder; + public const string Fax = Material.Sharp.Fax; + public const string FeaturedPlayList = Material.Sharp.FeaturedPlayList; + public const string FeaturedVideo = Material.Sharp.FeaturedVideo; + public const string Feed = Material.Sharp.Feed; + public const string Feedback = Material.Sharp.Feedback; + public const string Female = Material.Sharp.Female; + public const string Fence = Material.Sharp.Fence; + public const string Festival = Material.Sharp.Festival; + public const string FiberDvr = Material.Sharp.FiberDvr; + public const string FiberManualRecord = Material.Sharp.FiberManualRecord; + public const string FiberNew = Material.Sharp.FiberNew; + public const string FiberPin = Material.Sharp.FiberPin; + public const string FiberSmartRecord = Material.Sharp.FiberSmartRecord; + public const string FileCopy = Material.Sharp.FileCopy; + public const string FileDownload = Material.Sharp.FileDownload; + public const string FileDownloadDone = Material.Sharp.FileDownloadDone; + public const string FileDownloadOff = Material.Sharp.FileDownloadOff; + public const string FileOpen = Material.Sharp.FileOpen; + public const string FilePresent = Material.Sharp.FilePresent; + public const string FileUpload = Material.Sharp.FileUpload; + public const string Filter = Material.Sharp.Filter; + public const string Filter1 = Material.Sharp.Filter1; + public const string Filter2 = Material.Sharp.Filter2; + public const string Filter3 = Material.Sharp.Filter3; + public const string Filter4 = Material.Sharp.Filter4; + public const string Filter5 = Material.Sharp.Filter5; + public const string Filter6 = Material.Sharp.Filter6; + public const string Filter7 = Material.Sharp.Filter7; + public const string Filter8 = Material.Sharp.Filter8; + public const string Filter9 = Material.Sharp.Filter9; + public const string Filter9Plus = Material.Sharp.Filter9Plus; + public const string FilterAlt = Material.Sharp.FilterAlt; + public const string FilterAltOff = Material.Sharp.FilterAltOff; + public const string FilterBAndW = Material.Sharp.FilterBAndW; + public const string FilterCenterFocus = Material.Sharp.FilterCenterFocus; + public const string FilterDrama = Material.Sharp.FilterDrama; + public const string FilterFrames = Material.Sharp.FilterFrames; + public const string FilterHdr = Material.Sharp.FilterHdr; + public const string FilterList = Material.Sharp.FilterList; + public const string FilterListOff = Material.Sharp.FilterListOff; + public const string FilterNone = Material.Sharp.FilterNone; + public const string FilterTiltShift = Material.Sharp.FilterTiltShift; + public const string FilterVintage = Material.Sharp.FilterVintage; + public const string FindInPage = Material.Sharp.FindInPage; + public const string FindReplace = Material.Sharp.FindReplace; + public const string Fingerprint = Material.Sharp.Fingerprint; + public const string FireExtinguisher = Material.Sharp.FireExtinguisher; + public const string Fireplace = Material.Sharp.Fireplace; + public const string FirstPage = Material.Sharp.FirstPage; + public const string FitScreen = Material.Sharp.FitScreen; + public const string Fitbit = Material.Sharp.Fitbit; + public const string FitnessCenter = Material.Sharp.FitnessCenter; + public const string Flag = Material.Sharp.Flag; + public const string FlagCircle = Material.Sharp.FlagCircle; + public const string Flaky = Material.Sharp.Flaky; + public const string Flare = Material.Sharp.Flare; + public const string FlashAuto = Material.Sharp.FlashAuto; + public const string FlashOff = Material.Sharp.FlashOff; + public const string FlashOn = Material.Sharp.FlashOn; + public const string FlashlightOff = Material.Sharp.FlashlightOff; + public const string FlashlightOn = Material.Sharp.FlashlightOn; + public const string Flatware = Material.Sharp.Flatware; + public const string Flight = Material.Sharp.Flight; + public const string FlightClass = Material.Sharp.FlightClass; + public const string FlightLand = Material.Sharp.FlightLand; + public const string FlightTakeoff = Material.Sharp.FlightTakeoff; + public const string Flip = Material.Sharp.Flip; + public const string FlipCameraAndroid = Material.Sharp.FlipCameraAndroid; + public const string FlipCameraIos = Material.Sharp.FlipCameraIos; + public const string FlipToBack = Material.Sharp.FlipToBack; + public const string FlipToFront = Material.Sharp.FlipToFront; + public const string Flood = Material.Sharp.Flood; + public const string Flourescent = Material.Sharp.Flourescent; + public const string FlutterDash = Material.Sharp.FlutterDash; + public const string FmdBad = Material.Sharp.FmdBad; + public const string FmdGood = Material.Sharp.FmdGood; + public const string Folder = Material.Sharp.Folder; + public const string FolderCopy = Material.Sharp.FolderCopy; + public const string FolderDelete = Material.Sharp.FolderDelete; + public const string FolderOff = Material.Sharp.FolderOff; + public const string FolderOpen = Material.Sharp.FolderOpen; + public const string FolderShared = Material.Sharp.FolderShared; + public const string FolderSpecial = Material.Sharp.FolderSpecial; + public const string FolderZip = Material.Sharp.FolderZip; + public const string FollowTheSigns = Material.Sharp.FollowTheSigns; + public const string FontDownload = Material.Sharp.FontDownload; + public const string FontDownloadOff = Material.Sharp.FontDownloadOff; + public const string FoodBank = Material.Sharp.FoodBank; + public const string Forest = Material.Sharp.Forest; + public const string ForkLeft = Material.Sharp.ForkLeft; + public const string ForkRight = Material.Sharp.ForkRight; + public const string FormatAlignCenter = Material.Sharp.FormatAlignCenter; + public const string FormatAlignJustify = Material.Sharp.FormatAlignJustify; + public const string FormatAlignLeft = Material.Sharp.FormatAlignLeft; + public const string FormatAlignRight = Material.Sharp.FormatAlignRight; + public const string FormatBold = Material.Sharp.FormatBold; + public const string FormatClear = Material.Sharp.FormatClear; + public const string FormatColorFill = Material.Sharp.FormatColorFill; + public const string FormatColorReset = Material.Sharp.FormatColorReset; + public const string FormatColorText = Material.Sharp.FormatColorText; + public const string FormatIndentDecrease = Material.Sharp.FormatIndentDecrease; + public const string FormatIndentIncrease = Material.Sharp.FormatIndentIncrease; + public const string FormatItalic = Material.Sharp.FormatItalic; + public const string FormatLineSpacing = Material.Sharp.FormatLineSpacing; + public const string FormatListBulleted = Material.Sharp.FormatListBulleted; + public const string FormatListNumbered = Material.Sharp.FormatListNumbered; + public const string FormatListNumberedRtl = Material.Sharp.FormatListNumberedRtl; + public const string FormatOverline = Material.Sharp.FormatOverline; + public const string FormatPaint = Material.Sharp.FormatPaint; + public const string FormatQuote = Material.Sharp.FormatQuote; + public const string FormatShapes = Material.Sharp.FormatShapes; + public const string FormatSize = Material.Sharp.FormatSize; + public const string FormatStrikethrough = Material.Sharp.FormatStrikethrough; + public const string FormatTextdirectionLToR = Material.Sharp.FormatTextdirectionLToR; + public const string FormatTextdirectionRToL = Material.Sharp.FormatTextdirectionRToL; + public const string FormatUnderlined = Material.Sharp.FormatUnderlined; + public const string Fort = Material.Sharp.Fort; + public const string Forum = Material.Sharp.Forum; + public const string Forward = Material.Sharp.Forward; + public const string Forward10 = Material.Sharp.Forward10; + public const string Forward30 = Material.Sharp.Forward30; + public const string Forward5 = Material.Sharp.Forward5; + public const string ForwardToInbox = Material.Sharp.ForwardToInbox; + public const string Foundation = Material.Sharp.Foundation; + public const string FreeBreakfast = Material.Sharp.FreeBreakfast; + public const string FreeCancellation = Material.Sharp.FreeCancellation; + public const string FrontHand = Material.Sharp.FrontHand; + public const string Fullscreen = Material.Sharp.Fullscreen; + public const string FullscreenExit = Material.Sharp.FullscreenExit; + public const string Functions = Material.Sharp.Functions; + public const string GMobiledata = Material.Sharp.GMobiledata; + public const string GTranslate = Material.Sharp.GTranslate; + public const string Gamepad = Material.Sharp.Gamepad; + public const string Games = Material.Sharp.Games; + public const string Garage = Material.Sharp.Garage; + public const string Gavel = Material.Sharp.Gavel; + public const string GeneratingTokens = Material.Sharp.GeneratingTokens; + public const string Gesture = Material.Sharp.Gesture; + public const string GetApp = Material.Sharp.GetApp; + public const string Gif = Material.Sharp.Gif; + public const string GifBox = Material.Sharp.GifBox; + public const string Girl = Material.Sharp.Girl; + public const string Gite = Material.Sharp.Gite; + public const string GolfCourse = Material.Sharp.GolfCourse; + public const string GppBad = Material.Sharp.GppBad; + public const string GppGood = Material.Sharp.GppGood; + public const string GppMaybe = Material.Sharp.GppMaybe; + public const string GpsFixed = Material.Sharp.GpsFixed; + public const string GpsNotFixed = Material.Sharp.GpsNotFixed; + public const string GpsOff = Material.Sharp.GpsOff; + public const string Grade = Material.Sharp.Grade; + public const string Gradient = Material.Sharp.Gradient; + public const string Grading = Material.Sharp.Grading; + public const string Grain = Material.Sharp.Grain; + public const string GraphicEq = Material.Sharp.GraphicEq; + public const string Grass = Material.Sharp.Grass; + public const string Grid3x3 = Material.Sharp.Grid3x3; + public const string Grid4x4 = Material.Sharp.Grid4x4; + public const string GridGoldenratio = Material.Sharp.GridGoldenratio; + public const string GridOff = Material.Sharp.GridOff; + public const string GridOn = Material.Sharp.GridOn; + public const string GridView = Material.Sharp.GridView; + public const string Group = Material.Sharp.Group; + public const string GroupAdd = Material.Sharp.GroupAdd; + public const string GroupOff = Material.Sharp.GroupOff; + public const string GroupRemove = Material.Sharp.GroupRemove; + public const string GroupWork = Material.Sharp.GroupWork; + public const string Groups = Material.Sharp.Groups; + public const string HMobiledata = Material.Sharp.HMobiledata; + public const string HPlusMobiledata = Material.Sharp.HPlusMobiledata; + public const string Hail = Material.Sharp.Hail; + public const string Handshake = Material.Sharp.Handshake; + public const string Handyman = Material.Sharp.Handyman; + public const string Hardware = Material.Sharp.Hardware; + public const string Hd = Material.Sharp.Hd; + public const string HdrAuto = Material.Sharp.HdrAuto; + public const string HdrAutoSelect = Material.Sharp.HdrAutoSelect; + public const string HdrEnhancedSelect = Material.Sharp.HdrEnhancedSelect; + public const string HdrOff = Material.Sharp.HdrOff; + public const string HdrOffSelect = Material.Sharp.HdrOffSelect; + public const string HdrOn = Material.Sharp.HdrOn; + public const string HdrOnSelect = Material.Sharp.HdrOnSelect; + public const string HdrPlus = Material.Sharp.HdrPlus; + public const string HdrStrong = Material.Sharp.HdrStrong; + public const string HdrWeak = Material.Sharp.HdrWeak; + public const string Headphones = Material.Sharp.Headphones; + public const string HeadphonesBattery = Material.Sharp.HeadphonesBattery; + public const string Headset = Material.Sharp.Headset; + public const string HeadsetMic = Material.Sharp.HeadsetMic; + public const string HeadsetOff = Material.Sharp.HeadsetOff; + public const string Healing = Material.Sharp.Healing; + public const string HealthAndSafety = Material.Sharp.HealthAndSafety; + public const string Hearing = Material.Sharp.Hearing; + public const string HearingDisabled = Material.Sharp.HearingDisabled; + public const string HeartBroken = Material.Sharp.HeartBroken; + public const string Height = Material.Sharp.Height; + public const string Help = Material.Sharp.Help; + public const string HelpCenter = Material.Sharp.HelpCenter; + public const string HelpOutline = Material.Sharp.HelpOutline; + public const string Hevc = Material.Sharp.Hevc; + public const string Hexagon = Material.Sharp.Hexagon; + public const string HideImage = Material.Sharp.HideImage; + public const string HideSource = Material.Sharp.HideSource; + public const string HighQuality = Material.Sharp.HighQuality; + public const string Highlight = Material.Sharp.Highlight; + public const string HighlightAlt = Material.Sharp.HighlightAlt; + public const string HighlightOff = Material.Sharp.HighlightOff; + public const string Hiking = Material.Sharp.Hiking; + public const string History = Material.Sharp.History; + public const string HistoryEdu = Material.Sharp.HistoryEdu; + public const string HistoryToggleOff = Material.Sharp.HistoryToggleOff; + public const string Hive = Material.Sharp.Hive; + public const string Hls = Material.Sharp.Hls; + public const string HlsOff = Material.Sharp.HlsOff; + public const string HolidayVillage = Material.Sharp.HolidayVillage; + public const string Home = Material.Sharp.Home; + public const string HomeMax = Material.Sharp.HomeMax; + public const string HomeMini = Material.Sharp.HomeMini; + public const string HomeRepairService = Material.Sharp.HomeRepairService; + public const string HomeWork = Material.Sharp.HomeWork; + public const string HorizontalDistribute = Material.Sharp.HorizontalDistribute; + public const string HorizontalRule = Material.Sharp.HorizontalRule; + public const string HorizontalSplit = Material.Sharp.HorizontalSplit; + public const string HotTub = Material.Sharp.HotTub; + public const string Hotel = Material.Sharp.Hotel; + public const string HotelClass = Material.Sharp.HotelClass; + public const string HourglassBottom = Material.Sharp.HourglassBottom; + public const string HourglassDisabled = Material.Sharp.HourglassDisabled; + public const string HourglassEmpty = Material.Sharp.HourglassEmpty; + public const string HourglassFull = Material.Sharp.HourglassFull; + public const string HourglassTop = Material.Sharp.HourglassTop; + public const string House = Material.Sharp.House; + public const string HouseSiding = Material.Sharp.HouseSiding; + public const string Houseboat = Material.Sharp.Houseboat; + public const string HowToReg = Material.Sharp.HowToReg; + public const string HowToVote = Material.Sharp.HowToVote; + public const string Html = Material.Sharp.Html; + public const string Http = Material.Sharp.Http; + public const string Https = Material.Sharp.Https; + public const string Hub = Material.Sharp.Hub; + public const string Hvac = Material.Sharp.Hvac; + public const string IceSkating = Material.Sharp.IceSkating; + public const string Icecream = Material.Sharp.Icecream; + public const string Image = Material.Sharp.Image; + public const string ImageAspectRatio = Material.Sharp.ImageAspectRatio; + public const string ImageNotSupported = Material.Sharp.ImageNotSupported; + public const string ImageSearch = Material.Sharp.ImageSearch; + public const string ImagesearchRoller = Material.Sharp.ImagesearchRoller; + public const string ImportContacts = Material.Sharp.ImportContacts; + public const string ImportExport = Material.Sharp.ImportExport; + public const string ImportantDevices = Material.Sharp.ImportantDevices; + public const string Inbox = Material.Sharp.Inbox; + public const string IncompleteCircle = Material.Sharp.IncompleteCircle; + public const string IndeterminateCheckBox = Material.Sharp.IndeterminateCheckBox; + public const string Info = Material.Sharp.Info; + public const string Input = Material.Sharp.Input; + public const string InsertChart = Material.Sharp.InsertChart; + public const string InsertChartOutlined = Material.Sharp.InsertChartOutlined; + public const string InsertComment = Material.Sharp.InsertComment; + public const string InsertDriveFile = Material.Sharp.InsertDriveFile; + public const string InsertEmoticon = Material.Sharp.InsertEmoticon; + public const string InsertInvitation = Material.Sharp.InsertInvitation; + public const string InsertLink = Material.Sharp.InsertLink; + public const string InsertPageBreak = Material.Sharp.InsertPageBreak; + public const string InsertPhoto = Material.Sharp.InsertPhoto; + public const string Insights = Material.Sharp.Insights; + public const string InstallDesktop = Material.Sharp.InstallDesktop; + public const string InstallMobile = Material.Sharp.InstallMobile; + public const string IntegrationInstructions = Material.Sharp.IntegrationInstructions; + public const string Interests = Material.Sharp.Interests; + public const string InterpreterMode = Material.Sharp.InterpreterMode; + public const string Inventory = Material.Sharp.Inventory; + public const string Inventory2 = Material.Sharp.Inventory2; + public const string InvertColors = Material.Sharp.InvertColors; + public const string InvertColorsOff = Material.Sharp.InvertColorsOff; + public const string IosShare = Material.Sharp.IosShare; + public const string Iron = Material.Sharp.Iron; + public const string Iso = Material.Sharp.Iso; + public const string Javascript = Material.Sharp.Javascript; + public const string JoinFull = Material.Sharp.JoinFull; + public const string JoinInner = Material.Sharp.JoinInner; + public const string JoinLeft = Material.Sharp.JoinLeft; + public const string JoinRight = Material.Sharp.JoinRight; + public const string Kayaking = Material.Sharp.Kayaking; + public const string KebabDining = Material.Sharp.KebabDining; + public const string Key = Material.Sharp.Key; + public const string KeyOff = Material.Sharp.KeyOff; + public const string Keyboard = Material.Sharp.Keyboard; + public const string KeyboardAlt = Material.Sharp.KeyboardAlt; + public const string KeyboardArrowDown = Material.Sharp.KeyboardArrowDown; + public const string KeyboardArrowLeft = Material.Sharp.KeyboardArrowLeft; + public const string KeyboardArrowRight = Material.Sharp.KeyboardArrowRight; + public const string KeyboardArrowUp = Material.Sharp.KeyboardArrowUp; + public const string KeyboardBackspace = Material.Sharp.KeyboardBackspace; + public const string KeyboardCapslock = Material.Sharp.KeyboardCapslock; + public const string KeyboardCommandKey = Material.Sharp.KeyboardCommandKey; + public const string KeyboardControlKey = Material.Sharp.KeyboardControlKey; + public const string KeyboardDoubleArrowDown = Material.Sharp.KeyboardDoubleArrowDown; + public const string KeyboardDoubleArrowLeft = Material.Sharp.KeyboardDoubleArrowLeft; + public const string KeyboardDoubleArrowRight = Material.Sharp.KeyboardDoubleArrowRight; + public const string KeyboardDoubleArrowUp = Material.Sharp.KeyboardDoubleArrowUp; + public const string KeyboardHide = Material.Sharp.KeyboardHide; + public const string KeyboardOptionKey = Material.Sharp.KeyboardOptionKey; + public const string KeyboardReturn = Material.Sharp.KeyboardReturn; + public const string KeyboardTab = Material.Sharp.KeyboardTab; + public const string KeyboardVoice = Material.Sharp.KeyboardVoice; + public const string KingBed = Material.Sharp.KingBed; + public const string Kitchen = Material.Sharp.Kitchen; + public const string Kitesurfing = Material.Sharp.Kitesurfing; + public const string Label = Material.Sharp.Label; + public const string LabelImportant = Material.Sharp.LabelImportant; + public const string LabelOff = Material.Sharp.LabelOff; + public const string Lan = Material.Sharp.Lan; + public const string Landscape = Material.Sharp.Landscape; + public const string Landslide = Material.Sharp.Landslide; + public const string Language = Material.Sharp.Language; + public const string Laptop = Material.Sharp.Laptop; + public const string LaptopChromebook = Material.Sharp.LaptopChromebook; + public const string LaptopMac = Material.Sharp.LaptopMac; + public const string LaptopWindows = Material.Sharp.LaptopWindows; + public const string LastPage = Material.Sharp.LastPage; + public const string Launch = Material.Sharp.Launch; + public const string Layers = Material.Sharp.Layers; + public const string LayersClear = Material.Sharp.LayersClear; + public const string Leaderboard = Material.Sharp.Leaderboard; + public const string LeakAdd = Material.Sharp.LeakAdd; + public const string LeakRemove = Material.Sharp.LeakRemove; + public const string LegendToggle = Material.Sharp.LegendToggle; + public const string Lens = Material.Sharp.Lens; + public const string LensBlur = Material.Sharp.LensBlur; + public const string LibraryAdd = Material.Sharp.LibraryAdd; + public const string LibraryAddCheck = Material.Sharp.LibraryAddCheck; + public const string LibraryBooks = Material.Sharp.LibraryBooks; + public const string LibraryMusic = Material.Sharp.LibraryMusic; + public const string Light = Material.Sharp.Light; + public const string LightMode = Material.Sharp.LightMode; + public const string Lightbulb = Material.Sharp.Lightbulb; + public const string LightbulbCircle = Material.Sharp.LightbulbCircle; + public const string LineAxis = Material.Sharp.LineAxis; + public const string LineStyle = Material.Sharp.LineStyle; + public const string LineWeight = Material.Sharp.LineWeight; + public const string LinearScale = Material.Sharp.LinearScale; + public const string Link = Material.Sharp.Link; + public const string LinkOff = Material.Sharp.LinkOff; + public const string LinkedCamera = Material.Sharp.LinkedCamera; + public const string Liquor = Material.Sharp.Liquor; + public const string List = Material.Sharp.List; + public const string ListAlt = Material.Sharp.ListAlt; + public const string LiveHelp = Material.Sharp.LiveHelp; + public const string LiveTv = Material.Sharp.LiveTv; + public const string Living = Material.Sharp.Living; + public const string LocalActivity = Material.Sharp.LocalActivity; + public const string LocalAirport = Material.Sharp.LocalAirport; + public const string LocalAtm = Material.Sharp.LocalAtm; + public const string LocalBar = Material.Sharp.LocalBar; + public const string LocalCafe = Material.Sharp.LocalCafe; + public const string LocalCarWash = Material.Sharp.LocalCarWash; + public const string LocalConvenienceStore = Material.Sharp.LocalConvenienceStore; + public const string LocalDining = Material.Sharp.LocalDining; + public const string LocalDrink = Material.Sharp.LocalDrink; + public const string LocalFireDepartment = Material.Sharp.LocalFireDepartment; + public const string LocalFlorist = Material.Sharp.LocalFlorist; + public const string LocalGasStation = Material.Sharp.LocalGasStation; + public const string LocalGroceryStore = Material.Sharp.LocalGroceryStore; + public const string LocalHospital = Material.Sharp.LocalHospital; + public const string LocalHotel = Material.Sharp.LocalHotel; + public const string LocalLaundryService = Material.Sharp.LocalLaundryService; + public const string LocalLibrary = Material.Sharp.LocalLibrary; + public const string LocalMall = Material.Sharp.LocalMall; + public const string LocalMovies = Material.Sharp.LocalMovies; + public const string LocalOffer = Material.Sharp.LocalOffer; + public const string LocalParking = Material.Sharp.LocalParking; + public const string LocalPharmacy = Material.Sharp.LocalPharmacy; + public const string LocalPhone = Material.Sharp.LocalPhone; + public const string LocalPizza = Material.Sharp.LocalPizza; + public const string LocalPlay = Material.Sharp.LocalPlay; + public const string LocalPolice = Material.Sharp.LocalPolice; + public const string LocalPostOffice = Material.Sharp.LocalPostOffice; + public const string LocalPrintshop = Material.Sharp.LocalPrintshop; + public const string LocalSee = Material.Sharp.LocalSee; + public const string LocalShipping = Material.Sharp.LocalShipping; + public const string LocalTaxi = Material.Sharp.LocalTaxi; + public const string LocationCity = Material.Sharp.LocationCity; + public const string LocationDisabled = Material.Sharp.LocationDisabled; + public const string LocationOff = Material.Sharp.LocationOff; + public const string LocationOn = Material.Sharp.LocationOn; + public const string LocationSearching = Material.Sharp.LocationSearching; + public const string Lock = Material.Sharp.Lock; + public const string LockClock = Material.Sharp.LockClock; + public const string LockOpen = Material.Sharp.LockOpen; + public const string LockReset = Material.Sharp.LockReset; + public const string Login = Material.Sharp.Login; + public const string LogoDev = Material.Sharp.LogoDev; + public const string Logout = Material.Sharp.Logout; + public const string Looks = Material.Sharp.Looks; + public const string Looks3 = Material.Sharp.Looks3; + public const string Looks4 = Material.Sharp.Looks4; + public const string Looks5 = Material.Sharp.Looks5; + public const string Looks6 = Material.Sharp.Looks6; + public const string LooksOne = Material.Sharp.LooksOne; + public const string LooksTwo = Material.Sharp.LooksTwo; + public const string Loop = Material.Sharp.Loop; + public const string Loupe = Material.Sharp.Loupe; + public const string LowPriority = Material.Sharp.LowPriority; + public const string Loyalty = Material.Sharp.Loyalty; + public const string LteMobiledata = Material.Sharp.LteMobiledata; + public const string LtePlusMobiledata = Material.Sharp.LtePlusMobiledata; + public const string Luggage = Material.Sharp.Luggage; + public const string LunchDining = Material.Sharp.LunchDining; + public const string Mail = Material.Sharp.Mail; + public const string MailOutline = Material.Sharp.MailOutline; + public const string Male = Material.Sharp.Male; + public const string Man = Material.Sharp.Man; + public const string ManageAccounts = Material.Sharp.ManageAccounts; + public const string ManageHistory = Material.Sharp.ManageHistory; + public const string ManageSearch = Material.Sharp.ManageSearch; + public const string Map = Material.Sharp.Map; + public const string MapsHomeWork = Material.Sharp.MapsHomeWork; + public const string MapsUgc = Material.Sharp.MapsUgc; + public const string Margin = Material.Sharp.Margin; + public const string MarkAsUnread = Material.Sharp.MarkAsUnread; + public const string MarkChatRead = Material.Sharp.MarkChatRead; + public const string MarkChatUnread = Material.Sharp.MarkChatUnread; + public const string MarkEmailRead = Material.Sharp.MarkEmailRead; + public const string MarkEmailUnread = Material.Sharp.MarkEmailUnread; + public const string MarkUnreadChatAlt = Material.Sharp.MarkUnreadChatAlt; + public const string Markunread = Material.Sharp.Markunread; + public const string MarkunreadMailbox = Material.Sharp.MarkunreadMailbox; + public const string Masks = Material.Sharp.Masks; + public const string Maximize = Material.Sharp.Maximize; + public const string MediaBluetoothOff = Material.Sharp.MediaBluetoothOff; + public const string MediaBluetoothOn = Material.Sharp.MediaBluetoothOn; + public const string Mediation = Material.Sharp.Mediation; + public const string MedicalInformation = Material.Sharp.MedicalInformation; + public const string MedicalServices = Material.Sharp.MedicalServices; + public const string Medication = Material.Sharp.Medication; + public const string MedicationLiquid = Material.Sharp.MedicationLiquid; + public const string MeetingRoom = Material.Sharp.MeetingRoom; + public const string Memory = Material.Sharp.Memory; + public const string Menu = Material.Sharp.Menu; + public const string MenuBook = Material.Sharp.MenuBook; + public const string MenuOpen = Material.Sharp.MenuOpen; + public const string Merge = Material.Sharp.Merge; + public const string MergeType = Material.Sharp.MergeType; + public const string Message = Material.Sharp.Message; + public const string Mic = Material.Sharp.Mic; + public const string MicExternalOff = Material.Sharp.MicExternalOff; + public const string MicExternalOn = Material.Sharp.MicExternalOn; + public const string MicNone = Material.Sharp.MicNone; + public const string MicOff = Material.Sharp.MicOff; + public const string Microwave = Material.Sharp.Microwave; + public const string MilitaryTech = Material.Sharp.MilitaryTech; + public const string Minimize = Material.Sharp.Minimize; + public const string MinorCrash = Material.Sharp.MinorCrash; + public const string MiscellaneousServices = Material.Sharp.MiscellaneousServices; + public const string MissedVideoCall = Material.Sharp.MissedVideoCall; + public const string Mms = Material.Sharp.Mms; + public const string MobileFriendly = Material.Sharp.MobileFriendly; + public const string MobileOff = Material.Sharp.MobileOff; + public const string MobileScreenShare = Material.Sharp.MobileScreenShare; + public const string MobiledataOff = Material.Sharp.MobiledataOff; + public const string Mode = Material.Sharp.Mode; + public const string ModeComment = Material.Sharp.ModeComment; + public const string ModeEdit = Material.Sharp.ModeEdit; + public const string ModeEditOutline = Material.Sharp.ModeEditOutline; + public const string ModeNight = Material.Sharp.ModeNight; + public const string ModeOfTravel = Material.Sharp.ModeOfTravel; + public const string ModeStandby = Material.Sharp.ModeStandby; + public const string ModelTraining = Material.Sharp.ModelTraining; + public const string MonetizationOn = Material.Sharp.MonetizationOn; + public const string Money = Material.Sharp.Money; + public const string MoneyOff = Material.Sharp.MoneyOff; + public const string MoneyOffCsred = Material.Sharp.MoneyOffCsred; + public const string Monitor = Material.Sharp.Monitor; + public const string MonitorHeart = Material.Sharp.MonitorHeart; + public const string MonitorWeight = Material.Sharp.MonitorWeight; + public const string MonochromePhotos = Material.Sharp.MonochromePhotos; + public const string Mood = Material.Sharp.Mood; + public const string MoodBad = Material.Sharp.MoodBad; + public const string Moped = Material.Sharp.Moped; + public const string More = Material.Sharp.More; + public const string MoreHoriz = Material.Sharp.MoreHoriz; + public const string MoreTime = Material.Sharp.MoreTime; + public const string MoreVert = Material.Sharp.MoreVert; + public const string Mosque = Material.Sharp.Mosque; + public const string MotionPhotosAuto = Material.Sharp.MotionPhotosAuto; + public const string MotionPhotosOff = Material.Sharp.MotionPhotosOff; + public const string MotionPhotosOn = Material.Sharp.MotionPhotosOn; + public const string MotionPhotosPause = Material.Sharp.MotionPhotosPause; + public const string MotionPhotosPaused = Material.Sharp.MotionPhotosPaused; + public const string Mouse = Material.Sharp.Mouse; + public const string MoveDown = Material.Sharp.MoveDown; + public const string MoveToInbox = Material.Sharp.MoveToInbox; + public const string MoveUp = Material.Sharp.MoveUp; + public const string Movie = Material.Sharp.Movie; + public const string MovieCreation = Material.Sharp.MovieCreation; + public const string MovieFilter = Material.Sharp.MovieFilter; + public const string Moving = Material.Sharp.Moving; + public const string Mp = Material.Sharp.Mp; + public const string MultilineChart = Material.Sharp.MultilineChart; + public const string MultipleStop = Material.Sharp.MultipleStop; + public const string Museum = Material.Sharp.Museum; + public const string MusicNote = Material.Sharp.MusicNote; + public const string MusicOff = Material.Sharp.MusicOff; + public const string MusicVideo = Material.Sharp.MusicVideo; + public const string MyLocation = Material.Sharp.MyLocation; + public const string Nat = Material.Sharp.Nat; + public const string Nature = Material.Sharp.Nature; + public const string NaturePeople = Material.Sharp.NaturePeople; + public const string NavigateBefore = Material.Sharp.NavigateBefore; + public const string NavigateNext = Material.Sharp.NavigateNext; + public const string Navigation = Material.Sharp.Navigation; + public const string NearMe = Material.Sharp.NearMe; + public const string NearMeDisabled = Material.Sharp.NearMeDisabled; + public const string NearbyError = Material.Sharp.NearbyError; + public const string NearbyOff = Material.Sharp.NearbyOff; + public const string NetworkCell = Material.Sharp.NetworkCell; + public const string NetworkCheck = Material.Sharp.NetworkCheck; + public const string NetworkLocked = Material.Sharp.NetworkLocked; + public const string NetworkPing = Material.Sharp.NetworkPing; + public const string NetworkWifi = Material.Sharp.NetworkWifi; + public const string NetworkWifi1Bar = Material.Sharp.NetworkWifi1Bar; + public const string NetworkWifi2Bar = Material.Sharp.NetworkWifi2Bar; + public const string NetworkWifi3Bar = Material.Sharp.NetworkWifi3Bar; + public const string NewLabel = Material.Sharp.NewLabel; + public const string NewReleases = Material.Sharp.NewReleases; + public const string Newspaper = Material.Sharp.Newspaper; + public const string NextPlan = Material.Sharp.NextPlan; + public const string NextWeek = Material.Sharp.NextWeek; + public const string Nfc = Material.Sharp.Nfc; + public const string NightShelter = Material.Sharp.NightShelter; + public const string Nightlife = Material.Sharp.Nightlife; + public const string Nightlight = Material.Sharp.Nightlight; + public const string NightlightRound = Material.Sharp.NightlightRound; + public const string NightsStay = Material.Sharp.NightsStay; + public const string NoAccounts = Material.Sharp.NoAccounts; + public const string NoBackpack = Material.Sharp.NoBackpack; + public const string NoCell = Material.Sharp.NoCell; + public const string NoCrash = Material.Sharp.NoCrash; + public const string NoDrinks = Material.Sharp.NoDrinks; + public const string NoEncryption = Material.Sharp.NoEncryption; + public const string NoEncryptionGmailerrorred = Material.Sharp.NoEncryptionGmailerrorred; + public const string NoFlash = Material.Sharp.NoFlash; + public const string NoFood = Material.Sharp.NoFood; + public const string NoLuggage = Material.Sharp.NoLuggage; + public const string NoMeals = Material.Sharp.NoMeals; + public const string NoMeetingRoom = Material.Sharp.NoMeetingRoom; + public const string NoPhotography = Material.Sharp.NoPhotography; + public const string NoSim = Material.Sharp.NoSim; + public const string NoStroller = Material.Sharp.NoStroller; + public const string NoTransfer = Material.Sharp.NoTransfer; + public const string NoiseAware = Material.Sharp.NoiseAware; + public const string NoiseControlOff = Material.Sharp.NoiseControlOff; + public const string NordicWalking = Material.Sharp.NordicWalking; + public const string North = Material.Sharp.North; + public const string NorthEast = Material.Sharp.NorthEast; + public const string NorthWest = Material.Sharp.NorthWest; + public const string NotAccessible = Material.Sharp.NotAccessible; + public const string NotInterested = Material.Sharp.NotInterested; + public const string NotListedLocation = Material.Sharp.NotListedLocation; + public const string NotStarted = Material.Sharp.NotStarted; + public const string Note = Material.Sharp.Note; + public const string NoteAdd = Material.Sharp.NoteAdd; + public const string NoteAlt = Material.Sharp.NoteAlt; + public const string Notes = Material.Sharp.Notes; + public const string NotificationAdd = Material.Sharp.NotificationAdd; + public const string NotificationImportant = Material.Sharp.NotificationImportant; + public const string Notifications = Material.Sharp.Notifications; + public const string NotificationsActive = Material.Sharp.NotificationsActive; + public const string NotificationsNone = Material.Sharp.NotificationsNone; + public const string NotificationsOff = Material.Sharp.NotificationsOff; + public const string NotificationsPaused = Material.Sharp.NotificationsPaused; + public const string Numbers = Material.Sharp.Numbers; + public const string OfflineBolt = Material.Sharp.OfflineBolt; + public const string OfflinePin = Material.Sharp.OfflinePin; + public const string OfflineShare = Material.Sharp.OfflineShare; + public const string OnDeviceTraining = Material.Sharp.OnDeviceTraining; + public const string OndemandVideo = Material.Sharp.OndemandVideo; + public const string OnlinePrediction = Material.Sharp.OnlinePrediction; + public const string Opacity = Material.Sharp.Opacity; + public const string OpenInBrowser = Material.Sharp.OpenInBrowser; + public const string OpenInFull = Material.Sharp.OpenInFull; + public const string OpenInNew = Material.Sharp.OpenInNew; + public const string OpenInNewOff = Material.Sharp.OpenInNewOff; + public const string OpenWith = Material.Sharp.OpenWith; + public const string OtherHouses = Material.Sharp.OtherHouses; + public const string Outbound = Material.Sharp.Outbound; + public const string Outbox = Material.Sharp.Outbox; + public const string OutdoorGrill = Material.Sharp.OutdoorGrill; + public const string Outlet = Material.Sharp.Outlet; + public const string OutlinedFlag = Material.Sharp.OutlinedFlag; + public const string Output = Material.Sharp.Output; + public const string Padding = Material.Sharp.Padding; + public const string Pages = Material.Sharp.Pages; + public const string Pageview = Material.Sharp.Pageview; + public const string Paid = Material.Sharp.Paid; + public const string Palette = Material.Sharp.Palette; + public const string PanTool = Material.Sharp.PanTool; + public const string PanToolAlt = Material.Sharp.PanToolAlt; + public const string Panorama = Material.Sharp.Panorama; + public const string PanoramaFishEye = Material.Sharp.PanoramaFishEye; + public const string PanoramaHorizontal = Material.Sharp.PanoramaHorizontal; + public const string PanoramaHorizontalSelect = Material.Sharp.PanoramaHorizontalSelect; + public const string PanoramaPhotosphere = Material.Sharp.PanoramaPhotosphere; + public const string PanoramaPhotosphereSelect = Material.Sharp.PanoramaPhotosphereSelect; + public const string PanoramaVertical = Material.Sharp.PanoramaVertical; + public const string PanoramaVerticalSelect = Material.Sharp.PanoramaVerticalSelect; + public const string PanoramaWideAngle = Material.Sharp.PanoramaWideAngle; + public const string PanoramaWideAngleSelect = Material.Sharp.PanoramaWideAngleSelect; + public const string Paragliding = Material.Sharp.Paragliding; + public const string Park = Material.Sharp.Park; + public const string PartyMode = Material.Sharp.PartyMode; + public const string Password = Material.Sharp.Password; + public const string Pattern = Material.Sharp.Pattern; + public const string Pause = Material.Sharp.Pause; + public const string PauseCircle = Material.Sharp.PauseCircle; + public const string PauseCircleFilled = Material.Sharp.PauseCircleFilled; + public const string PauseCircleOutline = Material.Sharp.PauseCircleOutline; + public const string PausePresentation = Material.Sharp.PausePresentation; + public const string Payment = Material.Sharp.Payment; + public const string Payments = Material.Sharp.Payments; + public const string PedalBike = Material.Sharp.PedalBike; + public const string Pending = Material.Sharp.Pending; + public const string PendingActions = Material.Sharp.PendingActions; + public const string Pentagon = Material.Sharp.Pentagon; + public const string People = Material.Sharp.People; + public const string PeopleAlt = Material.Sharp.PeopleAlt; + public const string PeopleOutline = Material.Sharp.PeopleOutline; + public const string Percent = Material.Sharp.Percent; + public const string PermCameraMic = Material.Sharp.PermCameraMic; + public const string PermContactCalendar = Material.Sharp.PermContactCalendar; + public const string PermDataSetting = Material.Sharp.PermDataSetting; + public const string PermDeviceInformation = Material.Sharp.PermDeviceInformation; + public const string PermIdentity = Material.Sharp.PermIdentity; + public const string PermMedia = Material.Sharp.PermMedia; + public const string PermPhoneMsg = Material.Sharp.PermPhoneMsg; + public const string PermScanWifi = Material.Sharp.PermScanWifi; + public const string Person = Material.Sharp.Person; + public const string PersonAdd = Material.Sharp.PersonAdd; + public const string PersonAddAlt = Material.Sharp.PersonAddAlt; + public const string PersonAddAlt1 = Material.Sharp.PersonAddAlt1; + public const string PersonAddDisabled = Material.Sharp.PersonAddDisabled; + public const string PersonOff = Material.Sharp.PersonOff; + public const string PersonOutline = Material.Sharp.PersonOutline; + public const string PersonPin = Material.Sharp.PersonPin; + public const string PersonPinCircle = Material.Sharp.PersonPinCircle; + public const string PersonRemove = Material.Sharp.PersonRemove; + public const string PersonRemoveAlt1 = Material.Sharp.PersonRemoveAlt1; + public const string PersonSearch = Material.Sharp.PersonSearch; + public const string PersonalInjury = Material.Sharp.PersonalInjury; + public const string PersonalVideo = Material.Sharp.PersonalVideo; + public const string PestControl = Material.Sharp.PestControl; + public const string PestControlRodent = Material.Sharp.PestControlRodent; + public const string Pets = Material.Sharp.Pets; + public const string Phishing = Material.Sharp.Phishing; + public const string Phone = Material.Sharp.Phone; + public const string PhoneAndroid = Material.Sharp.PhoneAndroid; + public const string PhoneBluetoothSpeaker = Material.Sharp.PhoneBluetoothSpeaker; + public const string PhoneCallback = Material.Sharp.PhoneCallback; + public const string PhoneDisabled = Material.Sharp.PhoneDisabled; + public const string PhoneEnabled = Material.Sharp.PhoneEnabled; + public const string PhoneForwarded = Material.Sharp.PhoneForwarded; + public const string PhoneInTalk = Material.Sharp.PhoneInTalk; + public const string PhoneIphone = Material.Sharp.PhoneIphone; + public const string PhoneLocked = Material.Sharp.PhoneLocked; + public const string PhoneMissed = Material.Sharp.PhoneMissed; + public const string PhonePaused = Material.Sharp.PhonePaused; + public const string Phonelink = Material.Sharp.Phonelink; + public const string PhonelinkErase = Material.Sharp.PhonelinkErase; + public const string PhonelinkLock = Material.Sharp.PhonelinkLock; + public const string PhonelinkOff = Material.Sharp.PhonelinkOff; + public const string PhonelinkRing = Material.Sharp.PhonelinkRing; + public const string PhonelinkSetup = Material.Sharp.PhonelinkSetup; + public const string Photo = Material.Sharp.Photo; + public const string PhotoAlbum = Material.Sharp.PhotoAlbum; + public const string PhotoCamera = Material.Sharp.PhotoCamera; + public const string PhotoCameraBack = Material.Sharp.PhotoCameraBack; + public const string PhotoCameraFront = Material.Sharp.PhotoCameraFront; + public const string PhotoFilter = Material.Sharp.PhotoFilter; + public const string PhotoLibrary = Material.Sharp.PhotoLibrary; + public const string PhotoSizeSelectActual = Material.Sharp.PhotoSizeSelectActual; + public const string PhotoSizeSelectLarge = Material.Sharp.PhotoSizeSelectLarge; + public const string PhotoSizeSelectSmall = Material.Sharp.PhotoSizeSelectSmall; + public const string Php = Material.Sharp.Php; + public const string Piano = Material.Sharp.Piano; + public const string PianoOff = Material.Sharp.PianoOff; + public const string PictureAsPdf = Material.Sharp.PictureAsPdf; + public const string PictureInPicture = Material.Sharp.PictureInPicture; + public const string PictureInPictureAlt = Material.Sharp.PictureInPictureAlt; + public const string PieChart = Material.Sharp.PieChart; + public const string PieChartOutline = Material.Sharp.PieChartOutline; + public const string Pin = Material.Sharp.Pin; + public const string PinDrop = Material.Sharp.PinDrop; + public const string PinEnd = Material.Sharp.PinEnd; + public const string PinInvoke = Material.Sharp.PinInvoke; + public const string Pinch = Material.Sharp.Pinch; + public const string PivotTableChart = Material.Sharp.PivotTableChart; + public const string Pix = Material.Sharp.Pix; + public const string Place = Material.Sharp.Place; + public const string Plagiarism = Material.Sharp.Plagiarism; + public const string PlayArrow = Material.Sharp.PlayArrow; + public const string PlayCircle = Material.Sharp.PlayCircle; + public const string PlayCircleFilled = Material.Sharp.PlayCircleFilled; + public const string PlayCircleOutline = Material.Sharp.PlayCircleOutline; + public const string PlayDisabled = Material.Sharp.PlayDisabled; + public const string PlayForWork = Material.Sharp.PlayForWork; + public const string PlayLesson = Material.Sharp.PlayLesson; + public const string PlaylistAdd = Material.Sharp.PlaylistAdd; + public const string PlaylistAddCheck = Material.Sharp.PlaylistAddCheck; + public const string PlaylistAddCheckCircle = Material.Sharp.PlaylistAddCheckCircle; + public const string PlaylistAddCircle = Material.Sharp.PlaylistAddCircle; + public const string PlaylistPlay = Material.Sharp.PlaylistPlay; + public const string PlaylistRemove = Material.Sharp.PlaylistRemove; + public const string Plumbing = Material.Sharp.Plumbing; + public const string PlusOne = Material.Sharp.PlusOne; + public const string Podcasts = Material.Sharp.Podcasts; + public const string PointOfSale = Material.Sharp.PointOfSale; + public const string Policy = Material.Sharp.Policy; + public const string Poll = Material.Sharp.Poll; + public const string Polyline = Material.Sharp.Polyline; + public const string Polymer = Material.Sharp.Polymer; + public const string Pool = Material.Sharp.Pool; + public const string PortableWifiOff = Material.Sharp.PortableWifiOff; + public const string Portrait = Material.Sharp.Portrait; + public const string PostAdd = Material.Sharp.PostAdd; + public const string Power = Material.Sharp.Power; + public const string PowerInput = Material.Sharp.PowerInput; + public const string PowerOff = Material.Sharp.PowerOff; + public const string PowerSettingsNew = Material.Sharp.PowerSettingsNew; + public const string PrecisionManufacturing = Material.Sharp.PrecisionManufacturing; + public const string PregnantWoman = Material.Sharp.PregnantWoman; + public const string PresentToAll = Material.Sharp.PresentToAll; + public const string Preview = Material.Sharp.Preview; + public const string PriceChange = Material.Sharp.PriceChange; + public const string PriceCheck = Material.Sharp.PriceCheck; + public const string Print = Material.Sharp.Print; + public const string PrintDisabled = Material.Sharp.PrintDisabled; + public const string PriorityHigh = Material.Sharp.PriorityHigh; + public const string PrivacyTip = Material.Sharp.PrivacyTip; + public const string PrivateConnectivity = Material.Sharp.PrivateConnectivity; + public const string ProductionQuantityLimits = Material.Sharp.ProductionQuantityLimits; + public const string Psychology = Material.Sharp.Psychology; + public const string Public = Material.Sharp.Public; + public const string PublicOff = Material.Sharp.PublicOff; + public const string Publish = Material.Sharp.Publish; + public const string PublishedWithChanges = Material.Sharp.PublishedWithChanges; + public const string PunchClock = Material.Sharp.PunchClock; + public const string PushPin = Material.Sharp.PushPin; + public const string QrCode = Material.Sharp.QrCode; + public const string QrCode2 = Material.Sharp.QrCode2; + public const string QrCodeScanner = Material.Sharp.QrCodeScanner; + public const string QueryBuilder = Material.Sharp.QueryBuilder; + public const string QueryStats = Material.Sharp.QueryStats; + public const string QuestionAnswer = Material.Sharp.QuestionAnswer; + public const string QuestionMark = Material.Sharp.QuestionMark; + public const string Queue = Material.Sharp.Queue; + public const string QueueMusic = Material.Sharp.QueueMusic; + public const string QueuePlayNext = Material.Sharp.QueuePlayNext; + public const string Quickreply = Material.Sharp.Quickreply; + public const string Quiz = Material.Sharp.Quiz; + public const string RMobiledata = Material.Sharp.RMobiledata; + public const string Radar = Material.Sharp.Radar; + public const string Radio = Material.Sharp.Radio; + public const string RadioButtonChecked = Material.Sharp.RadioButtonChecked; + public const string RadioButtonUnchecked = Material.Sharp.RadioButtonUnchecked; + public const string RailwayAlert = Material.Sharp.RailwayAlert; + public const string RamenDining = Material.Sharp.RamenDining; + public const string RampLeft = Material.Sharp.RampLeft; + public const string RampRight = Material.Sharp.RampRight; + public const string RateReview = Material.Sharp.RateReview; + public const string RawOff = Material.Sharp.RawOff; + public const string RawOn = Material.Sharp.RawOn; + public const string ReadMore = Material.Sharp.ReadMore; + public const string RealEstateAgent = Material.Sharp.RealEstateAgent; + public const string Receipt = Material.Sharp.Receipt; + public const string ReceiptLong = Material.Sharp.ReceiptLong; + public const string RecentActors = Material.Sharp.RecentActors; + public const string Recommend = Material.Sharp.Recommend; + public const string RecordVoiceOver = Material.Sharp.RecordVoiceOver; + public const string Rectangle = Material.Sharp.Rectangle; + public const string Recycling = Material.Sharp.Recycling; + public const string Redeem = Material.Sharp.Redeem; + public const string Redo = Material.Sharp.Redo; + public const string ReduceCapacity = Material.Sharp.ReduceCapacity; + public const string Refresh = Material.Sharp.Refresh; + public const string RememberMe = Material.Sharp.RememberMe; + public const string Remove = Material.Sharp.Remove; + public const string RemoveCircle = Material.Sharp.RemoveCircle; + public const string RemoveCircleOutline = Material.Sharp.RemoveCircleOutline; + public const string RemoveDone = Material.Sharp.RemoveDone; + public const string RemoveFromQueue = Material.Sharp.RemoveFromQueue; + public const string RemoveModerator = Material.Sharp.RemoveModerator; + public const string RemoveRedEye = Material.Sharp.RemoveRedEye; + public const string RemoveRoad = Material.Sharp.RemoveRoad; + public const string RemoveShoppingCart = Material.Sharp.RemoveShoppingCart; + public const string Reorder = Material.Sharp.Reorder; + public const string Repeat = Material.Sharp.Repeat; + public const string RepeatOn = Material.Sharp.RepeatOn; + public const string RepeatOne = Material.Sharp.RepeatOne; + public const string RepeatOneOn = Material.Sharp.RepeatOneOn; + public const string Replay = Material.Sharp.Replay; + public const string Replay10 = Material.Sharp.Replay10; + public const string Replay30 = Material.Sharp.Replay30; + public const string Replay5 = Material.Sharp.Replay5; + public const string ReplayCircleFilled = Material.Sharp.ReplayCircleFilled; + public const string Reply = Material.Sharp.Reply; + public const string ReplyAll = Material.Sharp.ReplyAll; + public const string Report = Material.Sharp.Report; + public const string ReportGmailerrorred = Material.Sharp.ReportGmailerrorred; + public const string ReportOff = Material.Sharp.ReportOff; + public const string ReportProblem = Material.Sharp.ReportProblem; + public const string RequestPage = Material.Sharp.RequestPage; + public const string RequestQuote = Material.Sharp.RequestQuote; + public const string ResetTv = Material.Sharp.ResetTv; + public const string RestartAlt = Material.Sharp.RestartAlt; + public const string Restaurant = Material.Sharp.Restaurant; + public const string RestaurantMenu = Material.Sharp.RestaurantMenu; + public const string Restore = Material.Sharp.Restore; + public const string RestoreFromTrash = Material.Sharp.RestoreFromTrash; + public const string RestorePage = Material.Sharp.RestorePage; + public const string Reviews = Material.Sharp.Reviews; + public const string RiceBowl = Material.Sharp.RiceBowl; + public const string RingVolume = Material.Sharp.RingVolume; + public const string Rocket = Material.Sharp.Rocket; + public const string RocketLaunch = Material.Sharp.RocketLaunch; + public const string RollerSkating = Material.Sharp.RollerSkating; + public const string Roofing = Material.Sharp.Roofing; + public const string Room = Material.Sharp.Room; + public const string RoomPreferences = Material.Sharp.RoomPreferences; + public const string RoomService = Material.Sharp.RoomService; + public const string Rotate90DegreesCcw = Material.Sharp.Rotate90DegreesCcw; + public const string Rotate90DegreesCw = Material.Sharp.Rotate90DegreesCw; + public const string RotateLeft = Material.Sharp.RotateLeft; + public const string RotateRight = Material.Sharp.RotateRight; + public const string RoundaboutLeft = Material.Sharp.RoundaboutLeft; + public const string RoundaboutRight = Material.Sharp.RoundaboutRight; + public const string RoundedCorner = Material.Sharp.RoundedCorner; + public const string Route = Material.Sharp.Route; + public const string Router = Material.Sharp.Router; + public const string Rowing = Material.Sharp.Rowing; + public const string RssFeed = Material.Sharp.RssFeed; + public const string Rsvp = Material.Sharp.Rsvp; + public const string Rtt = Material.Sharp.Rtt; + public const string Rule = Material.Sharp.Rule; + public const string RuleFolder = Material.Sharp.RuleFolder; + public const string RunCircle = Material.Sharp.RunCircle; + public const string RunningWithErrors = Material.Sharp.RunningWithErrors; + public const string RvHookup = Material.Sharp.RvHookup; + public const string SafetyCheck = Material.Sharp.SafetyCheck; + public const string SafetyDivider = Material.Sharp.SafetyDivider; + public const string Sailing = Material.Sharp.Sailing; + public const string Sanitizer = Material.Sharp.Sanitizer; + public const string Satellite = Material.Sharp.Satellite; + public const string SatelliteAlt = Material.Sharp.SatelliteAlt; + public const string Save = Material.Sharp.Save; + public const string SaveAlt = Material.Sharp.SaveAlt; + public const string SaveAs = Material.Sharp.SaveAs; + public const string SavedSearch = Material.Sharp.SavedSearch; + public const string Savings = Material.Sharp.Savings; + public const string Scale = Material.Sharp.Scale; + public const string Scanner = Material.Sharp.Scanner; + public const string ScatterPlot = Material.Sharp.ScatterPlot; + public const string Schedule = Material.Sharp.Schedule; + public const string ScheduleSend = Material.Sharp.ScheduleSend; + public const string Schema = Material.Sharp.Schema; + public const string School = Material.Sharp.School; + public const string Science = Material.Sharp.Science; + public const string Score = Material.Sharp.Score; + public const string Scoreboard = Material.Sharp.Scoreboard; + public const string ScreenLockLandscape = Material.Sharp.ScreenLockLandscape; + public const string ScreenLockPortrait = Material.Sharp.ScreenLockPortrait; + public const string ScreenLockRotation = Material.Sharp.ScreenLockRotation; + public const string ScreenRotation = Material.Sharp.ScreenRotation; + public const string ScreenRotationAlt = Material.Sharp.ScreenRotationAlt; + public const string ScreenSearchDesktop = Material.Sharp.ScreenSearchDesktop; + public const string ScreenShare = Material.Sharp.ScreenShare; + public const string Screenshot = Material.Sharp.Screenshot; + public const string ScubaDiving = Material.Sharp.ScubaDiving; + public const string Sd = Material.Sharp.Sd; + public const string SdCard = Material.Sharp.SdCard; + public const string SdCardAlert = Material.Sharp.SdCardAlert; + public const string SdStorage = Material.Sharp.SdStorage; + public const string Search = Material.Sharp.Search; + public const string SearchOff = Material.Sharp.SearchOff; + public const string Security = Material.Sharp.Security; + public const string SecurityUpdate = Material.Sharp.SecurityUpdate; + public const string SecurityUpdateGood = Material.Sharp.SecurityUpdateGood; + public const string SecurityUpdateWarning = Material.Sharp.SecurityUpdateWarning; + public const string Segment = Material.Sharp.Segment; + public const string SelectAll = Material.Sharp.SelectAll; + public const string SelfImprovement = Material.Sharp.SelfImprovement; + public const string Sell = Material.Sharp.Sell; + public const string Send = Material.Sharp.Send; + public const string SendAndArchive = Material.Sharp.SendAndArchive; + public const string SendTimeExtension = Material.Sharp.SendTimeExtension; + public const string SendToMobile = Material.Sharp.SendToMobile; + public const string SensorDoor = Material.Sharp.SensorDoor; + public const string SensorWindow = Material.Sharp.SensorWindow; + public const string Sensors = Material.Sharp.Sensors; + public const string SensorsOff = Material.Sharp.SensorsOff; + public const string SentimentDissatisfied = Material.Sharp.SentimentDissatisfied; + public const string SentimentNeutral = Material.Sharp.SentimentNeutral; + public const string SentimentSatisfied = Material.Sharp.SentimentSatisfied; + public const string SentimentSatisfiedAlt = Material.Sharp.SentimentSatisfiedAlt; + public const string SentimentVeryDissatisfied = Material.Sharp.SentimentVeryDissatisfied; + public const string SentimentVerySatisfied = Material.Sharp.SentimentVerySatisfied; + public const string SetMeal = Material.Sharp.SetMeal; + public const string Settings = Material.Sharp.Settings; + public const string SettingsAccessibility = Material.Sharp.SettingsAccessibility; + public const string SettingsApplications = Material.Sharp.SettingsApplications; + public const string SettingsBackupRestore = Material.Sharp.SettingsBackupRestore; + public const string SettingsBluetooth = Material.Sharp.SettingsBluetooth; + public const string SettingsBrightness = Material.Sharp.SettingsBrightness; + public const string SettingsCell = Material.Sharp.SettingsCell; + public const string SettingsEthernet = Material.Sharp.SettingsEthernet; + public const string SettingsInputAntenna = Material.Sharp.SettingsInputAntenna; + public const string SettingsInputComponent = Material.Sharp.SettingsInputComponent; + public const string SettingsInputComposite = Material.Sharp.SettingsInputComposite; + public const string SettingsInputHdmi = Material.Sharp.SettingsInputHdmi; + public const string SettingsInputSvideo = Material.Sharp.SettingsInputSvideo; + public const string SettingsOverscan = Material.Sharp.SettingsOverscan; + public const string SettingsPhone = Material.Sharp.SettingsPhone; + public const string SettingsPower = Material.Sharp.SettingsPower; + public const string SettingsRemote = Material.Sharp.SettingsRemote; + public const string SettingsSuggest = Material.Sharp.SettingsSuggest; + public const string SettingsSystemDaydream = Material.Sharp.SettingsSystemDaydream; + public const string SettingsVoice = Material.Sharp.SettingsVoice; + public const string SevereCold = Material.Sharp.SevereCold; + public const string Share = Material.Sharp.Share; + public const string ShareLocation = Material.Sharp.ShareLocation; + public const string Shield = Material.Sharp.Shield; + public const string ShieldMoon = Material.Sharp.ShieldMoon; + public const string Shop = Material.Sharp.Shop; + public const string Shop2 = Material.Sharp.Shop2; + public const string ShopTwo = Material.Sharp.ShopTwo; + public const string ShoppingBag = Material.Sharp.ShoppingBag; + public const string ShoppingBasket = Material.Sharp.ShoppingBasket; + public const string ShoppingCart = Material.Sharp.ShoppingCart; + public const string ShoppingCartCheckout = Material.Sharp.ShoppingCartCheckout; + public const string ShortText = Material.Sharp.ShortText; + public const string Shortcut = Material.Sharp.Shortcut; + public const string ShowChart = Material.Sharp.ShowChart; + public const string Shower = Material.Sharp.Shower; + public const string Shuffle = Material.Sharp.Shuffle; + public const string ShuffleOn = Material.Sharp.ShuffleOn; + public const string ShutterSpeed = Material.Sharp.ShutterSpeed; + public const string Sick = Material.Sharp.Sick; + public const string SignLanguage = Material.Sharp.SignLanguage; + public const string SignalCellular0Bar = Material.Sharp.SignalCellular0Bar; + public const string SignalCellular4Bar = Material.Sharp.SignalCellular4Bar; + public const string SignalCellularAlt = Material.Sharp.SignalCellularAlt; + public const string SignalCellularAlt1Bar = Material.Sharp.SignalCellularAlt1Bar; + public const string SignalCellularAlt2Bar = Material.Sharp.SignalCellularAlt2Bar; + + public const string SignalCellularConnectedNoInternet0Bar = + Material.Sharp.SignalCellularConnectedNoInternet0Bar; + + public const string SignalCellularConnectedNoInternet4Bar = + Material.Sharp.SignalCellularConnectedNoInternet4Bar; + + public const string SignalCellularNoSim = Material.Sharp.SignalCellularNoSim; + public const string SignalCellularNodata = Material.Sharp.SignalCellularNodata; + public const string SignalCellularNull = Material.Sharp.SignalCellularNull; + public const string SignalCellularOff = Material.Sharp.SignalCellularOff; + public const string SignalWifi0Bar = Material.Sharp.SignalWifi0Bar; + public const string SignalWifi4Bar = Material.Sharp.SignalWifi4Bar; + public const string SignalWifi4BarLock = Material.Sharp.SignalWifi4BarLock; + public const string SignalWifiBad = Material.Sharp.SignalWifiBad; + public const string SignalWifiConnectedNoInternet4 = Material.Sharp.SignalWifiConnectedNoInternet4; + public const string SignalWifiOff = Material.Sharp.SignalWifiOff; + public const string SignalWifiStatusbar4Bar = Material.Sharp.SignalWifiStatusbar4Bar; + + public const string SignalWifiStatusbarConnectedNoInternet4 = + Material.Sharp.SignalWifiStatusbarConnectedNoInternet4; + + public const string SignalWifiStatusbarNull = Material.Sharp.SignalWifiStatusbarNull; + public const string Signpost = Material.Sharp.Signpost; + public const string SimCard = Material.Sharp.SimCard; + public const string SimCardAlert = Material.Sharp.SimCardAlert; + public const string SimCardDownload = Material.Sharp.SimCardDownload; + public const string SingleBed = Material.Sharp.SingleBed; + public const string Sip = Material.Sharp.Sip; + public const string Skateboarding = Material.Sharp.Skateboarding; + public const string SkipNext = Material.Sharp.SkipNext; + public const string SkipPrevious = Material.Sharp.SkipPrevious; + public const string Sledding = Material.Sharp.Sledding; + public const string Slideshow = Material.Sharp.Slideshow; + public const string SlowMotionVideo = Material.Sharp.SlowMotionVideo; + public const string SmartButton = Material.Sharp.SmartButton; + public const string SmartDisplay = Material.Sharp.SmartDisplay; + public const string SmartScreen = Material.Sharp.SmartScreen; + public const string SmartToy = Material.Sharp.SmartToy; + public const string Smartphone = Material.Sharp.Smartphone; + public const string SmokeFree = Material.Sharp.SmokeFree; + public const string SmokingRooms = Material.Sharp.SmokingRooms; + public const string Sms = Material.Sharp.Sms; + public const string SmsFailed = Material.Sharp.SmsFailed; + public const string SnippetFolder = Material.Sharp.SnippetFolder; + public const string Snooze = Material.Sharp.Snooze; + public const string Snowboarding = Material.Sharp.Snowboarding; + public const string Snowmobile = Material.Sharp.Snowmobile; + public const string Snowshoeing = Material.Sharp.Snowshoeing; + public const string Soap = Material.Sharp.Soap; + public const string SocialDistance = Material.Sharp.SocialDistance; + public const string Sort = Material.Sharp.Sort; + public const string SortByAlpha = Material.Sharp.SortByAlpha; + public const string Sos = Material.Sharp.Sos; + public const string SoupKitchen = Material.Sharp.SoupKitchen; + public const string Source = Material.Sharp.Source; + public const string South = Material.Sharp.South; + public const string SouthAmerica = Material.Sharp.SouthAmerica; + public const string SouthEast = Material.Sharp.SouthEast; + public const string SouthWest = Material.Sharp.SouthWest; + public const string Spa = Material.Sharp.Spa; + public const string SpaceBar = Material.Sharp.SpaceBar; + public const string SpaceDashboard = Material.Sharp.SpaceDashboard; + public const string SpatialAudio = Material.Sharp.SpatialAudio; + public const string SpatialAudioOff = Material.Sharp.SpatialAudioOff; + public const string SpatialTracking = Material.Sharp.SpatialTracking; + public const string Speaker = Material.Sharp.Speaker; + public const string SpeakerGroup = Material.Sharp.SpeakerGroup; + public const string SpeakerNotes = Material.Sharp.SpeakerNotes; + public const string SpeakerNotesOff = Material.Sharp.SpeakerNotesOff; + public const string SpeakerPhone = Material.Sharp.SpeakerPhone; + public const string Speed = Material.Sharp.Speed; + public const string Spellcheck = Material.Sharp.Spellcheck; + public const string Splitscreen = Material.Sharp.Splitscreen; + public const string Spoke = Material.Sharp.Spoke; + public const string Sports = Material.Sharp.Sports; + public const string SportsBar = Material.Sharp.SportsBar; + public const string SportsBaseball = Material.Sharp.SportsBaseball; + public const string SportsBasketball = Material.Sharp.SportsBasketball; + public const string SportsCricket = Material.Sharp.SportsCricket; + public const string SportsEsports = Material.Sharp.SportsEsports; + public const string SportsFootball = Material.Sharp.SportsFootball; + public const string SportsGolf = Material.Sharp.SportsGolf; + public const string SportsGymnastics = Material.Sharp.SportsGymnastics; + public const string SportsHandball = Material.Sharp.SportsHandball; + public const string SportsHockey = Material.Sharp.SportsHockey; + public const string SportsKabaddi = Material.Sharp.SportsKabaddi; + public const string SportsMartialArts = Material.Sharp.SportsMartialArts; + public const string SportsMma = Material.Sharp.SportsMma; + public const string SportsMotorsports = Material.Sharp.SportsMotorsports; + public const string SportsRugby = Material.Sharp.SportsRugby; + public const string SportsScore = Material.Sharp.SportsScore; + public const string SportsSoccer = Material.Sharp.SportsSoccer; + public const string SportsTennis = Material.Sharp.SportsTennis; + public const string SportsVolleyball = Material.Sharp.SportsVolleyball; + public const string Square = Material.Sharp.Square; + public const string SquareFoot = Material.Sharp.SquareFoot; + public const string SsidChart = Material.Sharp.SsidChart; + public const string StackedBarChart = Material.Sharp.StackedBarChart; + public const string StackedLineChart = Material.Sharp.StackedLineChart; + public const string Stadium = Material.Sharp.Stadium; + public const string Stairs = Material.Sharp.Stairs; + public const string Star = Material.Sharp.Star; + public const string StarBorder = Material.Sharp.StarBorder; + public const string StarBorderPurple500 = Material.Sharp.StarBorderPurple500; + public const string StarHalf = Material.Sharp.StarHalf; + public const string StarOutline = Material.Sharp.StarOutline; + public const string StarPurple500 = Material.Sharp.StarPurple500; + public const string StarRate = Material.Sharp.StarRate; + public const string Stars = Material.Sharp.Stars; + public const string Start = Material.Sharp.Start; + public const string StayCurrentLandscape = Material.Sharp.StayCurrentLandscape; + public const string StayCurrentPortrait = Material.Sharp.StayCurrentPortrait; + public const string StayPrimaryLandscape = Material.Sharp.StayPrimaryLandscape; + public const string StayPrimaryPortrait = Material.Sharp.StayPrimaryPortrait; + public const string StickyNote2 = Material.Sharp.StickyNote2; + public const string Stop = Material.Sharp.Stop; + public const string StopCircle = Material.Sharp.StopCircle; + public const string StopScreenShare = Material.Sharp.StopScreenShare; + public const string Storage = Material.Sharp.Storage; + public const string Store = Material.Sharp.Store; + public const string StoreMallDirectory = Material.Sharp.StoreMallDirectory; + public const string Storefront = Material.Sharp.Storefront; + public const string Storm = Material.Sharp.Storm; + public const string Straight = Material.Sharp.Straight; + public const string Straighten = Material.Sharp.Straighten; + public const string Stream = Material.Sharp.Stream; + public const string Streetview = Material.Sharp.Streetview; + public const string StrikethroughS = Material.Sharp.StrikethroughS; + public const string Stroller = Material.Sharp.Stroller; + public const string Style = Material.Sharp.Style; + public const string SubdirectoryArrowLeft = Material.Sharp.SubdirectoryArrowLeft; + public const string SubdirectoryArrowRight = Material.Sharp.SubdirectoryArrowRight; + public const string Subject = Material.Sharp.Subject; + public const string Subscript = Material.Sharp.Subscript; + public const string Subscriptions = Material.Sharp.Subscriptions; + public const string Subtitles = Material.Sharp.Subtitles; + public const string SubtitlesOff = Material.Sharp.SubtitlesOff; + public const string Subway = Material.Sharp.Subway; + public const string Summarize = Material.Sharp.Summarize; + public const string Superscript = Material.Sharp.Superscript; + public const string SupervisedUserCircle = Material.Sharp.SupervisedUserCircle; + public const string SupervisorAccount = Material.Sharp.SupervisorAccount; + public const string Support = Material.Sharp.Support; + public const string SupportAgent = Material.Sharp.SupportAgent; + public const string Surfing = Material.Sharp.Surfing; + public const string SurroundSound = Material.Sharp.SurroundSound; + public const string SwapCalls = Material.Sharp.SwapCalls; + public const string SwapHoriz = Material.Sharp.SwapHoriz; + public const string SwapHorizontalCircle = Material.Sharp.SwapHorizontalCircle; + public const string SwapVert = Material.Sharp.SwapVert; + public const string SwapVerticalCircle = Material.Sharp.SwapVerticalCircle; + public const string Swipe = Material.Sharp.Swipe; + public const string SwipeDown = Material.Sharp.SwipeDown; + public const string SwipeDownAlt = Material.Sharp.SwipeDownAlt; + public const string SwipeLeft = Material.Sharp.SwipeLeft; + public const string SwipeLeftAlt = Material.Sharp.SwipeLeftAlt; + public const string SwipeRight = Material.Sharp.SwipeRight; + public const string SwipeRightAlt = Material.Sharp.SwipeRightAlt; + public const string SwipeUp = Material.Sharp.SwipeUp; + public const string SwipeUpAlt = Material.Sharp.SwipeUpAlt; + public const string SwipeVertical = Material.Sharp.SwipeVertical; + public const string SwitchAccessShortcut = Material.Sharp.SwitchAccessShortcut; + public const string SwitchAccessShortcutAdd = Material.Sharp.SwitchAccessShortcutAdd; + public const string SwitchAccount = Material.Sharp.SwitchAccount; + public const string SwitchCamera = Material.Sharp.SwitchCamera; + public const string SwitchLeft = Material.Sharp.SwitchLeft; + public const string SwitchRight = Material.Sharp.SwitchRight; + public const string SwitchVideo = Material.Sharp.SwitchVideo; + public const string Synagogue = Material.Sharp.Synagogue; + public const string Sync = Material.Sharp.Sync; + public const string SyncAlt = Material.Sharp.SyncAlt; + public const string SyncDisabled = Material.Sharp.SyncDisabled; + public const string SyncLock = Material.Sharp.SyncLock; + public const string SyncProblem = Material.Sharp.SyncProblem; + public const string SystemSecurityUpdate = Material.Sharp.SystemSecurityUpdate; + public const string SystemSecurityUpdateGood = Material.Sharp.SystemSecurityUpdateGood; + public const string SystemSecurityUpdateWarning = Material.Sharp.SystemSecurityUpdateWarning; + public const string SystemUpdate = Material.Sharp.SystemUpdate; + public const string SystemUpdateAlt = Material.Sharp.SystemUpdateAlt; + public const string Tab = Material.Sharp.Tab; + public const string TabUnselected = Material.Sharp.TabUnselected; + public const string TableBar = Material.Sharp.TableBar; + public const string TableChart = Material.Sharp.TableChart; + public const string TableRestaurant = Material.Sharp.TableRestaurant; + public const string TableRows = Material.Sharp.TableRows; + public const string TableView = Material.Sharp.TableView; + public const string Tablet = Material.Sharp.Tablet; + public const string TabletAndroid = Material.Sharp.TabletAndroid; + public const string TabletMac = Material.Sharp.TabletMac; + public const string Tag = Material.Sharp.Tag; + public const string TagFaces = Material.Sharp.TagFaces; + public const string TakeoutDining = Material.Sharp.TakeoutDining; + public const string TapAndPlay = Material.Sharp.TapAndPlay; + public const string Tapas = Material.Sharp.Tapas; + public const string Task = Material.Sharp.Task; + public const string TaskAlt = Material.Sharp.TaskAlt; + public const string TaxiAlert = Material.Sharp.TaxiAlert; + public const string TempleBuddhist = Material.Sharp.TempleBuddhist; + public const string TempleHindu = Material.Sharp.TempleHindu; + public const string Terminal = Material.Sharp.Terminal; + public const string Terrain = Material.Sharp.Terrain; + public const string TextDecrease = Material.Sharp.TextDecrease; + public const string TextFields = Material.Sharp.TextFields; + public const string TextFormat = Material.Sharp.TextFormat; + public const string TextIncrease = Material.Sharp.TextIncrease; + public const string TextRotateUp = Material.Sharp.TextRotateUp; + public const string TextRotateVertical = Material.Sharp.TextRotateVertical; + public const string TextRotationAngledown = Material.Sharp.TextRotationAngledown; + public const string TextRotationAngleup = Material.Sharp.TextRotationAngleup; + public const string TextRotationDown = Material.Sharp.TextRotationDown; + public const string TextRotationNone = Material.Sharp.TextRotationNone; + public const string TextSnippet = Material.Sharp.TextSnippet; + public const string Textsms = Material.Sharp.Textsms; + public const string Texture = Material.Sharp.Texture; + public const string TheaterComedy = Material.Sharp.TheaterComedy; + public const string Theaters = Material.Sharp.Theaters; + public const string Thermostat = Material.Sharp.Thermostat; + public const string ThermostatAuto = Material.Sharp.ThermostatAuto; + public const string ThumbDown = Material.Sharp.ThumbDown; + public const string ThumbDownAlt = Material.Sharp.ThumbDownAlt; + public const string ThumbDownOffAlt = Material.Sharp.ThumbDownOffAlt; + public const string ThumbUp = Material.Sharp.ThumbUp; + public const string ThumbUpAlt = Material.Sharp.ThumbUpAlt; + public const string ThumbUpOffAlt = Material.Sharp.ThumbUpOffAlt; + public const string ThumbsUpDown = Material.Sharp.ThumbsUpDown; + public const string Thunderstorm = Material.Sharp.Thunderstorm; + public const string TimeToLeave = Material.Sharp.TimeToLeave; + public const string Timelapse = Material.Sharp.Timelapse; + public const string Timeline = Material.Sharp.Timeline; + public const string Timer = Material.Sharp.Timer; + public const string Timer10 = Material.Sharp.Timer10; + public const string Timer10Select = Material.Sharp.Timer10Select; + public const string Timer3 = Material.Sharp.Timer3; + public const string Timer3Select = Material.Sharp.Timer3Select; + public const string TimerOff = Material.Sharp.TimerOff; + public const string TipsAndUpdates = Material.Sharp.TipsAndUpdates; + public const string TireRepair = Material.Sharp.TireRepair; + public const string Title = Material.Sharp.Title; + public const string Toc = Material.Sharp.Toc; + public const string Today = Material.Sharp.Today; + public const string ToggleOff = Material.Sharp.ToggleOff; + public const string ToggleOn = Material.Sharp.ToggleOn; + public const string Token = Material.Sharp.Token; + public const string Toll = Material.Sharp.Toll; + public const string Tonality = Material.Sharp.Tonality; + public const string Topic = Material.Sharp.Topic; + public const string TouchApp = Material.Sharp.TouchApp; + public const string Tour = Material.Sharp.Tour; + public const string Toys = Material.Sharp.Toys; + public const string TrackChanges = Material.Sharp.TrackChanges; + public const string Traffic = Material.Sharp.Traffic; + public const string Train = Material.Sharp.Train; + public const string Tram = Material.Sharp.Tram; + public const string TransferWithinAStation = Material.Sharp.TransferWithinAStation; + public const string Transform = Material.Sharp.Transform; + public const string Transgender = Material.Sharp.Transgender; + public const string TransitEnterexit = Material.Sharp.TransitEnterexit; + public const string Translate = Material.Sharp.Translate; + public const string TravelExplore = Material.Sharp.TravelExplore; + public const string TrendingDown = Material.Sharp.TrendingDown; + public const string TrendingFlat = Material.Sharp.TrendingFlat; + public const string TrendingUp = Material.Sharp.TrendingUp; + public const string TripOrigin = Material.Sharp.TripOrigin; + public const string Try = Material.Sharp.Try; + public const string Tsunami = Material.Sharp.Tsunami; + public const string Tty = Material.Sharp.Tty; + public const string Tune = Material.Sharp.Tune; + public const string Tungsten = Material.Sharp.Tungsten; + public const string TurnLeft = Material.Sharp.TurnLeft; + public const string TurnRight = Material.Sharp.TurnRight; + public const string TurnSharpLeft = Material.Sharp.TurnSharpLeft; + public const string TurnSharpRight = Material.Sharp.TurnSharpRight; + public const string TurnSlightLeft = Material.Sharp.TurnSlightLeft; + public const string TurnSlightRight = Material.Sharp.TurnSlightRight; + public const string TurnedIn = Material.Sharp.TurnedIn; + public const string TurnedInNot = Material.Sharp.TurnedInNot; + public const string Tv = Material.Sharp.Tv; + public const string TvOff = Material.Sharp.TvOff; + public const string TwoWheeler = Material.Sharp.TwoWheeler; + public const string UTurnLeft = Material.Sharp.UTurnLeft; + public const string UTurnRight = Material.Sharp.UTurnRight; + public const string Umbrella = Material.Sharp.Umbrella; + public const string Unarchive = Material.Sharp.Unarchive; + public const string Undo = Material.Sharp.Undo; + public const string UnfoldLess = Material.Sharp.UnfoldLess; + public const string UnfoldMore = Material.Sharp.UnfoldMore; + public const string Unpublished = Material.Sharp.Unpublished; + public const string Unsubscribe = Material.Sharp.Unsubscribe; + public const string Upcoming = Material.Sharp.Upcoming; + public const string Update = Material.Sharp.Update; + public const string UpdateDisabled = Material.Sharp.UpdateDisabled; + public const string Upgrade = Material.Sharp.Upgrade; + public const string Upload = Material.Sharp.Upload; + public const string UploadFile = Material.Sharp.UploadFile; + public const string Usb = Material.Sharp.Usb; + public const string UsbOff = Material.Sharp.UsbOff; + public const string Vaccines = Material.Sharp.Vaccines; + public const string VapeFree = Material.Sharp.VapeFree; + public const string VapingRooms = Material.Sharp.VapingRooms; + public const string Verified = Material.Sharp.Verified; + public const string VerifiedUser = Material.Sharp.VerifiedUser; + public const string VerticalAlignBottom = Material.Sharp.VerticalAlignBottom; + public const string VerticalAlignCenter = Material.Sharp.VerticalAlignCenter; + public const string VerticalAlignTop = Material.Sharp.VerticalAlignTop; + public const string VerticalDistribute = Material.Sharp.VerticalDistribute; + public const string VerticalSplit = Material.Sharp.VerticalSplit; + public const string Vibration = Material.Sharp.Vibration; + public const string VideoCall = Material.Sharp.VideoCall; + public const string VideoCameraBack = Material.Sharp.VideoCameraBack; + public const string VideoCameraFront = Material.Sharp.VideoCameraFront; + public const string VideoFile = Material.Sharp.VideoFile; + public const string VideoLabel = Material.Sharp.VideoLabel; + public const string VideoLibrary = Material.Sharp.VideoLibrary; + public const string VideoSettings = Material.Sharp.VideoSettings; + public const string VideoStable = Material.Sharp.VideoStable; + public const string Videocam = Material.Sharp.Videocam; + public const string VideocamOff = Material.Sharp.VideocamOff; + public const string VideogameAsset = Material.Sharp.VideogameAsset; + public const string VideogameAssetOff = Material.Sharp.VideogameAssetOff; + public const string ViewAgenda = Material.Sharp.ViewAgenda; + public const string ViewArray = Material.Sharp.ViewArray; + public const string ViewCarousel = Material.Sharp.ViewCarousel; + public const string ViewColumn = Material.Sharp.ViewColumn; + public const string ViewComfy = Material.Sharp.ViewComfy; + public const string ViewComfyAlt = Material.Sharp.ViewComfyAlt; + public const string ViewCompact = Material.Sharp.ViewCompact; + public const string ViewCompactAlt = Material.Sharp.ViewCompactAlt; + public const string ViewCozy = Material.Sharp.ViewCozy; + public const string ViewDay = Material.Sharp.ViewDay; + public const string ViewHeadline = Material.Sharp.ViewHeadline; + public const string ViewInAr = Material.Sharp.ViewInAr; + public const string ViewKanban = Material.Sharp.ViewKanban; + public const string ViewList = Material.Sharp.ViewList; + public const string ViewModule = Material.Sharp.ViewModule; + public const string ViewQuilt = Material.Sharp.ViewQuilt; + public const string ViewSidebar = Material.Sharp.ViewSidebar; + public const string ViewStream = Material.Sharp.ViewStream; + public const string ViewTimeline = Material.Sharp.ViewTimeline; + public const string ViewWeek = Material.Sharp.ViewWeek; + public const string Vignette = Material.Sharp.Vignette; + public const string Villa = Material.Sharp.Villa; + public const string Visibility = Material.Sharp.Visibility; + public const string VisibilityOff = Material.Sharp.VisibilityOff; + public const string VoiceChat = Material.Sharp.VoiceChat; + public const string VoiceOverOff = Material.Sharp.VoiceOverOff; + public const string Voicemail = Material.Sharp.Voicemail; + public const string Volcano = Material.Sharp.Volcano; + public const string VolumeDown = Material.Sharp.VolumeDown; + public const string VolumeMute = Material.Sharp.VolumeMute; + public const string VolumeOff = Material.Sharp.VolumeOff; + public const string VolumeUp = Material.Sharp.VolumeUp; + public const string VolunteerActivism = Material.Sharp.VolunteerActivism; + public const string VpnKey = Material.Sharp.VpnKey; + public const string VpnKeyOff = Material.Sharp.VpnKeyOff; + public const string VpnLock = Material.Sharp.VpnLock; + public const string Vrpano = Material.Sharp.Vrpano; + public const string Wallpaper = Material.Sharp.Wallpaper; + public const string Warehouse = Material.Sharp.Warehouse; + public const string Warning = Material.Sharp.Warning; + public const string WarningAmber = Material.Sharp.WarningAmber; + public const string Wash = Material.Sharp.Wash; + public const string Watch = Material.Sharp.Watch; + public const string WatchLater = Material.Sharp.WatchLater; + public const string WatchOff = Material.Sharp.WatchOff; + public const string Water = Material.Sharp.Water; + public const string WaterDamage = Material.Sharp.WaterDamage; + public const string WaterDrop = Material.Sharp.WaterDrop; + public const string WaterfallChart = Material.Sharp.WaterfallChart; + public const string Waves = Material.Sharp.Waves; + public const string WavingHand = Material.Sharp.WavingHand; + public const string WbAuto = Material.Sharp.WbAuto; + public const string WbCloudy = Material.Sharp.WbCloudy; + public const string WbIncandescent = Material.Sharp.WbIncandescent; + public const string WbIridescent = Material.Sharp.WbIridescent; + public const string WbShade = Material.Sharp.WbShade; + public const string WbSunny = Material.Sharp.WbSunny; + public const string WbTwilight = Material.Sharp.WbTwilight; + public const string Wc = Material.Sharp.Wc; + public const string Web = Material.Sharp.Web; + public const string WebAsset = Material.Sharp.WebAsset; + public const string WebAssetOff = Material.Sharp.WebAssetOff; + public const string Webhook = Material.Sharp.Webhook; + public const string Weekend = Material.Sharp.Weekend; + public const string West = Material.Sharp.West; + public const string Whatsapp = Material.Sharp.Whatsapp; + public const string Whatshot = Material.Sharp.Whatshot; + public const string WheelchairPickup = Material.Sharp.WheelchairPickup; + public const string WhereToVote = Material.Sharp.WhereToVote; + public const string Widgets = Material.Sharp.Widgets; + public const string Wifi = Material.Sharp.Wifi; + public const string Wifi1Bar = Material.Sharp.Wifi1Bar; + public const string Wifi2Bar = Material.Sharp.Wifi2Bar; + public const string WifiCalling = Material.Sharp.WifiCalling; + public const string WifiCalling3 = Material.Sharp.WifiCalling3; + public const string WifiChannel = Material.Sharp.WifiChannel; + public const string WifiFind = Material.Sharp.WifiFind; + public const string WifiLock = Material.Sharp.WifiLock; + public const string WifiOff = Material.Sharp.WifiOff; + public const string WifiPassword = Material.Sharp.WifiPassword; + public const string WifiProtectedSetup = Material.Sharp.WifiProtectedSetup; + public const string WifiTethering = Material.Sharp.WifiTethering; + public const string WifiTetheringError = Material.Sharp.WifiTetheringError; + public const string WifiTetheringOff = Material.Sharp.WifiTetheringOff; + public const string Window = Material.Sharp.Window; + public const string WineBar = Material.Sharp.WineBar; + public const string Woman = Material.Sharp.Woman; + public const string Work = Material.Sharp.Work; + public const string WorkOff = Material.Sharp.WorkOff; + public const string WorkOutline = Material.Sharp.WorkOutline; + public const string WorkspacePremium = Material.Sharp.WorkspacePremium; + public const string Workspaces = Material.Sharp.Workspaces; + public const string WrapText = Material.Sharp.WrapText; + public const string WrongLocation = Material.Sharp.WrongLocation; + public const string Wysiwyg = Material.Sharp.Wysiwyg; + public const string Yard = Material.Sharp.Yard; + public const string YoutubeSearchedFor = Material.Sharp.YoutubeSearchedFor; + public const string ZoomIn = Material.Sharp.ZoomIn; + public const string ZoomInMap = Material.Sharp.ZoomInMap; + public const string ZoomOut = Material.Sharp.ZoomOut; + public const string ZoomOutMap = Material.Sharp.ZoomOutMap; + } + } +} diff --git a/Icons/Obsolete/TwoTone.cs b/Icons/Obsolete/TwoTone.cs new file mode 100644 index 0000000..f039f74 --- /dev/null +++ b/Icons/Obsolete/TwoTone.cs @@ -0,0 +1,2074 @@ +/* + * This file was auto-generated by Update-MudIcons.ps1 + * 2022.02.01_04:17:46 + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + public partial class Icons + { + [ExcludeFromCodeCoverage] + public class TwoTone + { + public const string _10k = Material.TwoTone._10k; + public const string _10mp = Material.TwoTone._10mp; + public const string _11mp = Material.TwoTone._11mp; + public const string _123 = Material.TwoTone._123; + public const string _12mp = Material.TwoTone._12mp; + public const string _13mp = Material.TwoTone._13mp; + public const string _14mp = Material.TwoTone._14mp; + public const string _15mp = Material.TwoTone._15mp; + public const string _16mp = Material.TwoTone._16mp; + public const string _17mp = Material.TwoTone._17mp; + public const string _18mp = Material.TwoTone._18mp; + public const string _19mp = Material.TwoTone._19mp; + public const string _1k = Material.TwoTone._1k; + public const string _1kPlus = Material.TwoTone._1kPlus; + public const string _1xMobiledata = Material.TwoTone._1xMobiledata; + public const string _20mp = Material.TwoTone._20mp; + public const string _21mp = Material.TwoTone._21mp; + public const string _22mp = Material.TwoTone._22mp; + public const string _23mp = Material.TwoTone._23mp; + public const string _24mp = Material.TwoTone._24mp; + public const string _2k = Material.TwoTone._2k; + public const string _2kPlus = Material.TwoTone._2kPlus; + public const string _2mp = Material.TwoTone._2mp; + public const string _30fps = Material.TwoTone._30fps; + public const string _30fpsSelect = Material.TwoTone._30fpsSelect; + public const string _360 = Material.TwoTone._360; + public const string _3dRotation = Material.TwoTone._3dRotation; + public const string _3gMobiledata = Material.TwoTone._3gMobiledata; + public const string _3k = Material.TwoTone._3k; + public const string _3kPlus = Material.TwoTone._3kPlus; + public const string _3mp = Material.TwoTone._3mp; + public const string _3p = Material.TwoTone._3p; + public const string _4gMobiledata = Material.TwoTone._4gMobiledata; + public const string _4gPlusMobiledata = Material.TwoTone._4gPlusMobiledata; + public const string _4k = Material.TwoTone._4k; + public const string _4kPlus = Material.TwoTone._4kPlus; + public const string _4mp = Material.TwoTone._4mp; + public const string _5g = Material.TwoTone._5g; + public const string _5k = Material.TwoTone._5k; + public const string _5kPlus = Material.TwoTone._5kPlus; + public const string _5mp = Material.TwoTone._5mp; + public const string _60fps = Material.TwoTone._60fps; + public const string _60fpsSelect = Material.TwoTone._60fpsSelect; + public const string _6FtApart = Material.TwoTone._6FtApart; + public const string _6k = Material.TwoTone._6k; + public const string _6kPlus = Material.TwoTone._6kPlus; + public const string _6mp = Material.TwoTone._6mp; + public const string _7k = Material.TwoTone._7k; + public const string _7kPlus = Material.TwoTone._7kPlus; + public const string _7mp = Material.TwoTone._7mp; + public const string _8k = Material.TwoTone._8k; + public const string _8kPlus = Material.TwoTone._8kPlus; + public const string _8mp = Material.TwoTone._8mp; + public const string _9k = Material.TwoTone._9k; + public const string _9kPlus = Material.TwoTone._9kPlus; + public const string _9mp = Material.TwoTone._9mp; + public const string Abc = Material.TwoTone.Abc; + public const string AcUnit = Material.TwoTone.AcUnit; + public const string AccessAlarm = Material.TwoTone.AccessAlarm; + public const string AccessAlarms = Material.TwoTone.AccessAlarms; + public const string AccessTime = Material.TwoTone.AccessTime; + public const string AccessTimeFilled = Material.TwoTone.AccessTimeFilled; + public const string Accessibility = Material.TwoTone.Accessibility; + public const string AccessibilityNew = Material.TwoTone.AccessibilityNew; + public const string Accessible = Material.TwoTone.Accessible; + public const string AccessibleForward = Material.TwoTone.AccessibleForward; + public const string AccountBalance = Material.TwoTone.AccountBalance; + public const string AccountBalanceWallet = Material.TwoTone.AccountBalanceWallet; + public const string AccountBox = Material.TwoTone.AccountBox; + public const string AccountCircle = Material.TwoTone.AccountCircle; + public const string AccountTree = Material.TwoTone.AccountTree; + public const string AdUnits = Material.TwoTone.AdUnits; + public const string Adb = Material.TwoTone.Adb; + public const string Add = Material.TwoTone.Add; + public const string AddAPhoto = Material.TwoTone.AddAPhoto; + public const string AddAlarm = Material.TwoTone.AddAlarm; + public const string AddAlert = Material.TwoTone.AddAlert; + public const string AddBox = Material.TwoTone.AddBox; + public const string AddBusiness = Material.TwoTone.AddBusiness; + public const string AddCard = Material.TwoTone.AddCard; + public const string AddChart = Material.TwoTone.AddChart; + public const string AddCircle = Material.TwoTone.AddCircle; + public const string AddCircleOutline = Material.TwoTone.AddCircleOutline; + public const string AddComment = Material.TwoTone.AddComment; + public const string AddIcCall = Material.TwoTone.AddIcCall; + public const string AddLink = Material.TwoTone.AddLink; + public const string AddLocation = Material.TwoTone.AddLocation; + public const string AddLocationAlt = Material.TwoTone.AddLocationAlt; + public const string AddModerator = Material.TwoTone.AddModerator; + public const string AddPhotoAlternate = Material.TwoTone.AddPhotoAlternate; + public const string AddReaction = Material.TwoTone.AddReaction; + public const string AddRoad = Material.TwoTone.AddRoad; + public const string AddShoppingCart = Material.TwoTone.AddShoppingCart; + public const string AddTask = Material.TwoTone.AddTask; + public const string AddToDrive = Material.TwoTone.AddToDrive; + public const string AddToHomeScreen = Material.TwoTone.AddToHomeScreen; + public const string AddToPhotos = Material.TwoTone.AddToPhotos; + public const string AddToQueue = Material.TwoTone.AddToQueue; + public const string Addchart = Material.TwoTone.Addchart; + public const string AdfScanner = Material.TwoTone.AdfScanner; + public const string Adjust = Material.TwoTone.Adjust; + public const string AdminPanelSettings = Material.TwoTone.AdminPanelSettings; + public const string AdsClick = Material.TwoTone.AdsClick; + public const string Agriculture = Material.TwoTone.Agriculture; + public const string Air = Material.TwoTone.Air; + public const string AirlineSeatFlat = Material.TwoTone.AirlineSeatFlat; + public const string AirlineSeatFlatAngled = Material.TwoTone.AirlineSeatFlatAngled; + public const string AirlineSeatIndividualSuite = Material.TwoTone.AirlineSeatIndividualSuite; + public const string AirlineSeatLegroomExtra = Material.TwoTone.AirlineSeatLegroomExtra; + public const string AirlineSeatLegroomNormal = Material.TwoTone.AirlineSeatLegroomNormal; + public const string AirlineSeatLegroomReduced = Material.TwoTone.AirlineSeatLegroomReduced; + public const string AirlineSeatReclineExtra = Material.TwoTone.AirlineSeatReclineExtra; + public const string AirlineSeatReclineNormal = Material.TwoTone.AirlineSeatReclineNormal; + public const string AirlineStops = Material.TwoTone.AirlineStops; + public const string Airlines = Material.TwoTone.Airlines; + public const string AirplaneTicket = Material.TwoTone.AirplaneTicket; + public const string AirplanemodeActive = Material.TwoTone.AirplanemodeActive; + public const string AirplanemodeInactive = Material.TwoTone.AirplanemodeInactive; + public const string Airplay = Material.TwoTone.Airplay; + public const string AirportShuttle = Material.TwoTone.AirportShuttle; + public const string Alarm = Material.TwoTone.Alarm; + public const string AlarmAdd = Material.TwoTone.AlarmAdd; + public const string AlarmOff = Material.TwoTone.AlarmOff; + public const string AlarmOn = Material.TwoTone.AlarmOn; + public const string Album = Material.TwoTone.Album; + public const string AlignHorizontalCenter = Material.TwoTone.AlignHorizontalCenter; + public const string AlignHorizontalLeft = Material.TwoTone.AlignHorizontalLeft; + public const string AlignHorizontalRight = Material.TwoTone.AlignHorizontalRight; + public const string AlignVerticalBottom = Material.TwoTone.AlignVerticalBottom; + public const string AlignVerticalCenter = Material.TwoTone.AlignVerticalCenter; + public const string AlignVerticalTop = Material.TwoTone.AlignVerticalTop; + public const string AllInbox = Material.TwoTone.AllInbox; + public const string AllInclusive = Material.TwoTone.AllInclusive; + public const string AllOut = Material.TwoTone.AllOut; + public const string AltRoute = Material.TwoTone.AltRoute; + public const string AlternateEmail = Material.TwoTone.AlternateEmail; + public const string Analytics = Material.TwoTone.Analytics; + public const string Anchor = Material.TwoTone.Anchor; + public const string Android = Material.TwoTone.Android; + public const string Animation = Material.TwoTone.Animation; + public const string Announcement = Material.TwoTone.Announcement; + public const string Aod = Material.TwoTone.Aod; + public const string Apartment = Material.TwoTone.Apartment; + public const string Api = Material.TwoTone.Api; + public const string AppBlocking = Material.TwoTone.AppBlocking; + public const string AppRegistration = Material.TwoTone.AppRegistration; + public const string AppSettingsAlt = Material.TwoTone.AppSettingsAlt; + public const string AppShortcut = Material.TwoTone.AppShortcut; + public const string Approval = Material.TwoTone.Approval; + public const string Apps = Material.TwoTone.Apps; + public const string AppsOutage = Material.TwoTone.AppsOutage; + public const string Architecture = Material.TwoTone.Architecture; + public const string Archive = Material.TwoTone.Archive; + public const string AreaChart = Material.TwoTone.AreaChart; + public const string ArrowBack = Material.TwoTone.ArrowBack; + public const string ArrowBackIos = Material.TwoTone.ArrowBackIos; + public const string ArrowBackIosNew = Material.TwoTone.ArrowBackIosNew; + public const string ArrowCircleDown = Material.TwoTone.ArrowCircleDown; + public const string ArrowCircleLeft = Material.TwoTone.ArrowCircleLeft; + public const string ArrowCircleRight = Material.TwoTone.ArrowCircleRight; + public const string ArrowCircleUp = Material.TwoTone.ArrowCircleUp; + public const string ArrowDownward = Material.TwoTone.ArrowDownward; + public const string ArrowDropDown = Material.TwoTone.ArrowDropDown; + public const string ArrowDropDownCircle = Material.TwoTone.ArrowDropDownCircle; + public const string ArrowDropUp = Material.TwoTone.ArrowDropUp; + public const string ArrowForward = Material.TwoTone.ArrowForward; + public const string ArrowForwardIos = Material.TwoTone.ArrowForwardIos; + public const string ArrowLeft = Material.TwoTone.ArrowLeft; + public const string ArrowRight = Material.TwoTone.ArrowRight; + public const string ArrowRightAlt = Material.TwoTone.ArrowRightAlt; + public const string ArrowUpward = Material.TwoTone.ArrowUpward; + public const string ArtTrack = Material.TwoTone.ArtTrack; + public const string Article = Material.TwoTone.Article; + public const string AspectRatio = Material.TwoTone.AspectRatio; + public const string Assessment = Material.TwoTone.Assessment; + public const string Assignment = Material.TwoTone.Assignment; + public const string AssignmentInd = Material.TwoTone.AssignmentInd; + public const string AssignmentLate = Material.TwoTone.AssignmentLate; + public const string AssignmentReturn = Material.TwoTone.AssignmentReturn; + public const string AssignmentReturned = Material.TwoTone.AssignmentReturned; + public const string AssignmentTurnedIn = Material.TwoTone.AssignmentTurnedIn; + public const string Assistant = Material.TwoTone.Assistant; + public const string AssistantDirection = Material.TwoTone.AssistantDirection; + public const string AssistantPhoto = Material.TwoTone.AssistantPhoto; + public const string AssuredWorkload = Material.TwoTone.AssuredWorkload; + public const string Atm = Material.TwoTone.Atm; + public const string AttachEmail = Material.TwoTone.AttachEmail; + public const string AttachFile = Material.TwoTone.AttachFile; + public const string AttachMoney = Material.TwoTone.AttachMoney; + public const string Attachment = Material.TwoTone.Attachment; + public const string Attractions = Material.TwoTone.Attractions; + public const string Attribution = Material.TwoTone.Attribution; + public const string AudioFile = Material.TwoTone.AudioFile; + public const string Audiotrack = Material.TwoTone.Audiotrack; + public const string AutoAwesome = Material.TwoTone.AutoAwesome; + public const string AutoAwesomeMosaic = Material.TwoTone.AutoAwesomeMosaic; + public const string AutoAwesomeMotion = Material.TwoTone.AutoAwesomeMotion; + public const string AutoDelete = Material.TwoTone.AutoDelete; + public const string AutoFixHigh = Material.TwoTone.AutoFixHigh; + public const string AutoFixNormal = Material.TwoTone.AutoFixNormal; + public const string AutoFixOff = Material.TwoTone.AutoFixOff; + public const string AutoGraph = Material.TwoTone.AutoGraph; + public const string AutoStories = Material.TwoTone.AutoStories; + public const string AutofpsSelect = Material.TwoTone.AutofpsSelect; + public const string Autorenew = Material.TwoTone.Autorenew; + public const string AvTimer = Material.TwoTone.AvTimer; + public const string BabyChangingStation = Material.TwoTone.BabyChangingStation; + public const string BackHand = Material.TwoTone.BackHand; + public const string Backpack = Material.TwoTone.Backpack; + public const string Backspace = Material.TwoTone.Backspace; + public const string Backup = Material.TwoTone.Backup; + public const string BackupTable = Material.TwoTone.BackupTable; + public const string Badge = Material.TwoTone.Badge; + public const string BakeryDining = Material.TwoTone.BakeryDining; + public const string Balance = Material.TwoTone.Balance; + public const string Balcony = Material.TwoTone.Balcony; + public const string Ballot = Material.TwoTone.Ballot; + public const string BarChart = Material.TwoTone.BarChart; + public const string BatchPrediction = Material.TwoTone.BatchPrediction; + public const string Bathroom = Material.TwoTone.Bathroom; + public const string Bathtub = Material.TwoTone.Bathtub; + public const string Battery0Bar = Material.TwoTone.Battery0Bar; + public const string Battery1Bar = Material.TwoTone.Battery1Bar; + public const string Battery2Bar = Material.TwoTone.Battery2Bar; + public const string Battery3Bar = Material.TwoTone.Battery3Bar; + public const string Battery4Bar = Material.TwoTone.Battery4Bar; + public const string Battery5Bar = Material.TwoTone.Battery5Bar; + public const string Battery6Bar = Material.TwoTone.Battery6Bar; + public const string BatteryAlert = Material.TwoTone.BatteryAlert; + public const string BatteryChargingFull = Material.TwoTone.BatteryChargingFull; + public const string BatteryFull = Material.TwoTone.BatteryFull; + public const string BatterySaver = Material.TwoTone.BatterySaver; + public const string BatteryStd = Material.TwoTone.BatteryStd; + public const string BatteryUnknown = Material.TwoTone.BatteryUnknown; + public const string BeachAccess = Material.TwoTone.BeachAccess; + public const string Bed = Material.TwoTone.Bed; + public const string BedroomBaby = Material.TwoTone.BedroomBaby; + public const string BedroomChild = Material.TwoTone.BedroomChild; + public const string BedroomParent = Material.TwoTone.BedroomParent; + public const string Bedtime = Material.TwoTone.Bedtime; + public const string BedtimeOff = Material.TwoTone.BedtimeOff; + public const string Beenhere = Material.TwoTone.Beenhere; + public const string Bento = Material.TwoTone.Bento; + public const string BikeScooter = Material.TwoTone.BikeScooter; + public const string Biotech = Material.TwoTone.Biotech; + public const string Blender = Material.TwoTone.Blender; + public const string Block = Material.TwoTone.Block; + public const string Bloodtype = Material.TwoTone.Bloodtype; + public const string Bluetooth = Material.TwoTone.Bluetooth; + public const string BluetoothAudio = Material.TwoTone.BluetoothAudio; + public const string BluetoothConnected = Material.TwoTone.BluetoothConnected; + public const string BluetoothDisabled = Material.TwoTone.BluetoothDisabled; + public const string BluetoothDrive = Material.TwoTone.BluetoothDrive; + public const string BluetoothSearching = Material.TwoTone.BluetoothSearching; + public const string BlurCircular = Material.TwoTone.BlurCircular; + public const string BlurLinear = Material.TwoTone.BlurLinear; + public const string BlurOff = Material.TwoTone.BlurOff; + public const string BlurOn = Material.TwoTone.BlurOn; + public const string Bolt = Material.TwoTone.Bolt; + public const string Book = Material.TwoTone.Book; + public const string BookOnline = Material.TwoTone.BookOnline; + public const string Bookmark = Material.TwoTone.Bookmark; + public const string BookmarkAdd = Material.TwoTone.BookmarkAdd; + public const string BookmarkAdded = Material.TwoTone.BookmarkAdded; + public const string BookmarkBorder = Material.TwoTone.BookmarkBorder; + public const string BookmarkRemove = Material.TwoTone.BookmarkRemove; + public const string Bookmarks = Material.TwoTone.Bookmarks; + public const string BorderAll = Material.TwoTone.BorderAll; + public const string BorderBottom = Material.TwoTone.BorderBottom; + public const string BorderClear = Material.TwoTone.BorderClear; + public const string BorderColor = Material.TwoTone.BorderColor; + public const string BorderHorizontal = Material.TwoTone.BorderHorizontal; + public const string BorderInner = Material.TwoTone.BorderInner; + public const string BorderLeft = Material.TwoTone.BorderLeft; + public const string BorderOuter = Material.TwoTone.BorderOuter; + public const string BorderRight = Material.TwoTone.BorderRight; + public const string BorderStyle = Material.TwoTone.BorderStyle; + public const string BorderTop = Material.TwoTone.BorderTop; + public const string BorderVertical = Material.TwoTone.BorderVertical; + public const string Boy = Material.TwoTone.Boy; + public const string BrandingWatermark = Material.TwoTone.BrandingWatermark; + public const string BreakfastDining = Material.TwoTone.BreakfastDining; + public const string Brightness1 = Material.TwoTone.Brightness1; + public const string Brightness2 = Material.TwoTone.Brightness2; + public const string Brightness3 = Material.TwoTone.Brightness3; + public const string Brightness4 = Material.TwoTone.Brightness4; + public const string Brightness5 = Material.TwoTone.Brightness5; + public const string Brightness6 = Material.TwoTone.Brightness6; + public const string Brightness7 = Material.TwoTone.Brightness7; + public const string BrightnessAuto = Material.TwoTone.BrightnessAuto; + public const string BrightnessHigh = Material.TwoTone.BrightnessHigh; + public const string BrightnessLow = Material.TwoTone.BrightnessLow; + public const string BrightnessMedium = Material.TwoTone.BrightnessMedium; + public const string BrokenImage = Material.TwoTone.BrokenImage; + public const string BrowseGallery = Material.TwoTone.BrowseGallery; + public const string BrowserNotSupported = Material.TwoTone.BrowserNotSupported; + public const string BrowserUpdated = Material.TwoTone.BrowserUpdated; + public const string BrunchDining = Material.TwoTone.BrunchDining; + public const string Brush = Material.TwoTone.Brush; + public const string BubbleChart = Material.TwoTone.BubbleChart; + public const string BugReport = Material.TwoTone.BugReport; + public const string Build = Material.TwoTone.Build; + public const string BuildCircle = Material.TwoTone.BuildCircle; + public const string Bungalow = Material.TwoTone.Bungalow; + public const string BurstMode = Material.TwoTone.BurstMode; + public const string BusAlert = Material.TwoTone.BusAlert; + public const string Business = Material.TwoTone.Business; + public const string BusinessCenter = Material.TwoTone.BusinessCenter; + public const string Cabin = Material.TwoTone.Cabin; + public const string Cable = Material.TwoTone.Cable; + public const string Cached = Material.TwoTone.Cached; + public const string Cake = Material.TwoTone.Cake; + public const string Calculate = Material.TwoTone.Calculate; + public const string CalendarMonth = Material.TwoTone.CalendarMonth; + public const string CalendarToday = Material.TwoTone.CalendarToday; + public const string CalendarViewDay = Material.TwoTone.CalendarViewDay; + public const string CalendarViewMonth = Material.TwoTone.CalendarViewMonth; + public const string CalendarViewWeek = Material.TwoTone.CalendarViewWeek; + public const string Call = Material.TwoTone.Call; + public const string CallEnd = Material.TwoTone.CallEnd; + public const string CallMade = Material.TwoTone.CallMade; + public const string CallMerge = Material.TwoTone.CallMerge; + public const string CallMissed = Material.TwoTone.CallMissed; + public const string CallMissedOutgoing = Material.TwoTone.CallMissedOutgoing; + public const string CallReceived = Material.TwoTone.CallReceived; + public const string CallSplit = Material.TwoTone.CallSplit; + public const string CallToAction = Material.TwoTone.CallToAction; + public const string Camera = Material.TwoTone.Camera; + public const string CameraAlt = Material.TwoTone.CameraAlt; + public const string CameraEnhance = Material.TwoTone.CameraEnhance; + public const string CameraFront = Material.TwoTone.CameraFront; + public const string CameraIndoor = Material.TwoTone.CameraIndoor; + public const string CameraOutdoor = Material.TwoTone.CameraOutdoor; + public const string CameraRear = Material.TwoTone.CameraRear; + public const string CameraRoll = Material.TwoTone.CameraRoll; + public const string Cameraswitch = Material.TwoTone.Cameraswitch; + public const string Campaign = Material.TwoTone.Campaign; + public const string Cancel = Material.TwoTone.Cancel; + public const string CancelPresentation = Material.TwoTone.CancelPresentation; + public const string CancelScheduleSend = Material.TwoTone.CancelScheduleSend; + public const string CandlestickChart = Material.TwoTone.CandlestickChart; + public const string CarCrash = Material.TwoTone.CarCrash; + public const string CarRental = Material.TwoTone.CarRental; + public const string CarRepair = Material.TwoTone.CarRepair; + public const string CardGiftcard = Material.TwoTone.CardGiftcard; + public const string CardMembership = Material.TwoTone.CardMembership; + public const string CardTravel = Material.TwoTone.CardTravel; + public const string Carpenter = Material.TwoTone.Carpenter; + public const string Cases = Material.TwoTone.Cases; + public const string Casino = Material.TwoTone.Casino; + public const string Cast = Material.TwoTone.Cast; + public const string CastConnected = Material.TwoTone.CastConnected; + public const string CastForEducation = Material.TwoTone.CastForEducation; + public const string Castle = Material.TwoTone.Castle; + public const string CatchingPokemon = Material.TwoTone.CatchingPokemon; + public const string Category = Material.TwoTone.Category; + public const string Celebration = Material.TwoTone.Celebration; + public const string CellTower = Material.TwoTone.CellTower; + public const string CellWifi = Material.TwoTone.CellWifi; + public const string CenterFocusStrong = Material.TwoTone.CenterFocusStrong; + public const string CenterFocusWeak = Material.TwoTone.CenterFocusWeak; + public const string Chair = Material.TwoTone.Chair; + public const string ChairAlt = Material.TwoTone.ChairAlt; + public const string Chalet = Material.TwoTone.Chalet; + public const string ChangeCircle = Material.TwoTone.ChangeCircle; + public const string ChangeHistory = Material.TwoTone.ChangeHistory; + public const string ChargingStation = Material.TwoTone.ChargingStation; + public const string Chat = Material.TwoTone.Chat; + public const string ChatBubble = Material.TwoTone.ChatBubble; + public const string ChatBubbleOutline = Material.TwoTone.ChatBubbleOutline; + public const string Check = Material.TwoTone.Check; + public const string CheckBox = Material.TwoTone.CheckBox; + public const string CheckBoxOutlineBlank = Material.TwoTone.CheckBoxOutlineBlank; + public const string CheckCircle = Material.TwoTone.CheckCircle; + public const string CheckCircleOutline = Material.TwoTone.CheckCircleOutline; + public const string Checklist = Material.TwoTone.Checklist; + public const string ChecklistRtl = Material.TwoTone.ChecklistRtl; + public const string Checkroom = Material.TwoTone.Checkroom; + public const string ChevronLeft = Material.TwoTone.ChevronLeft; + public const string ChevronRight = Material.TwoTone.ChevronRight; + public const string ChildCare = Material.TwoTone.ChildCare; + public const string ChildFriendly = Material.TwoTone.ChildFriendly; + public const string ChromeReaderMode = Material.TwoTone.ChromeReaderMode; + public const string Church = Material.TwoTone.Church; + public const string Circle = Material.TwoTone.Circle; + public const string CircleNotifications = Material.TwoTone.CircleNotifications; + public const string Class = Material.TwoTone.Class; + public const string CleanHands = Material.TwoTone.CleanHands; + public const string CleaningServices = Material.TwoTone.CleaningServices; + public const string Clear = Material.TwoTone.Clear; + public const string ClearAll = Material.TwoTone.ClearAll; + public const string Close = Material.TwoTone.Close; + public const string CloseFullscreen = Material.TwoTone.CloseFullscreen; + public const string ClosedCaption = Material.TwoTone.ClosedCaption; + public const string ClosedCaptionDisabled = Material.TwoTone.ClosedCaptionDisabled; + public const string ClosedCaptionOff = Material.TwoTone.ClosedCaptionOff; + public const string Cloud = Material.TwoTone.Cloud; + public const string CloudCircle = Material.TwoTone.CloudCircle; + public const string CloudDone = Material.TwoTone.CloudDone; + public const string CloudDownload = Material.TwoTone.CloudDownload; + public const string CloudOff = Material.TwoTone.CloudOff; + public const string CloudQueue = Material.TwoTone.CloudQueue; + public const string CloudSync = Material.TwoTone.CloudSync; + public const string CloudUpload = Material.TwoTone.CloudUpload; + public const string Co2 = Material.TwoTone.Co2; + public const string CoPresent = Material.TwoTone.CoPresent; + public const string Code = Material.TwoTone.Code; + public const string CodeOff = Material.TwoTone.CodeOff; + public const string Coffee = Material.TwoTone.Coffee; + public const string CoffeeMaker = Material.TwoTone.CoffeeMaker; + public const string Collections = Material.TwoTone.Collections; + public const string CollectionsBookmark = Material.TwoTone.CollectionsBookmark; + public const string ColorLens = Material.TwoTone.ColorLens; + public const string Colorize = Material.TwoTone.Colorize; + public const string Comment = Material.TwoTone.Comment; + public const string CommentBank = Material.TwoTone.CommentBank; + public const string CommentsDisabled = Material.TwoTone.CommentsDisabled; + public const string Commit = Material.TwoTone.Commit; + public const string Commute = Material.TwoTone.Commute; + public const string Compare = Material.TwoTone.Compare; + public const string CompareArrows = Material.TwoTone.CompareArrows; + public const string CompassCalibration = Material.TwoTone.CompassCalibration; + public const string Compost = Material.TwoTone.Compost; + public const string Compress = Material.TwoTone.Compress; + public const string Computer = Material.TwoTone.Computer; + public const string ConfirmationNumber = Material.TwoTone.ConfirmationNumber; + public const string ConnectWithoutContact = Material.TwoTone.ConnectWithoutContact; + public const string ConnectedTv = Material.TwoTone.ConnectedTv; + public const string ConnectingAirports = Material.TwoTone.ConnectingAirports; + public const string Construction = Material.TwoTone.Construction; + public const string ContactMail = Material.TwoTone.ContactMail; + public const string ContactPage = Material.TwoTone.ContactPage; + public const string ContactPhone = Material.TwoTone.ContactPhone; + public const string ContactSupport = Material.TwoTone.ContactSupport; + public const string Contactless = Material.TwoTone.Contactless; + public const string Contacts = Material.TwoTone.Contacts; + public const string ContentCopy = Material.TwoTone.ContentCopy; + public const string ContentCut = Material.TwoTone.ContentCut; + public const string ContentPaste = Material.TwoTone.ContentPaste; + public const string ContentPasteGo = Material.TwoTone.ContentPasteGo; + public const string ContentPasteOff = Material.TwoTone.ContentPasteOff; + public const string ContentPasteSearch = Material.TwoTone.ContentPasteSearch; + public const string Contrast = Material.TwoTone.Contrast; + public const string ControlCamera = Material.TwoTone.ControlCamera; + public const string ControlPoint = Material.TwoTone.ControlPoint; + public const string ControlPointDuplicate = Material.TwoTone.ControlPointDuplicate; + public const string Cookie = Material.TwoTone.Cookie; + public const string CopyAll = Material.TwoTone.CopyAll; + public const string Copyright = Material.TwoTone.Copyright; + public const string Coronavirus = Material.TwoTone.Coronavirus; + public const string CorporateFare = Material.TwoTone.CorporateFare; + public const string Cottage = Material.TwoTone.Cottage; + public const string Countertops = Material.TwoTone.Countertops; + public const string Create = Material.TwoTone.Create; + public const string CreateNewFolder = Material.TwoTone.CreateNewFolder; + public const string CreditCard = Material.TwoTone.CreditCard; + public const string CreditCardOff = Material.TwoTone.CreditCardOff; + public const string CreditScore = Material.TwoTone.CreditScore; + public const string Crib = Material.TwoTone.Crib; + public const string CrisisAlert = Material.TwoTone.CrisisAlert; + public const string Crop = Material.TwoTone.Crop; + public const string Crop169 = Material.TwoTone.Crop169; + public const string Crop32 = Material.TwoTone.Crop32; + public const string Crop54 = Material.TwoTone.Crop54; + public const string Crop75 = Material.TwoTone.Crop75; + public const string CropDin = Material.TwoTone.CropDin; + public const string CropFree = Material.TwoTone.CropFree; + public const string CropLandscape = Material.TwoTone.CropLandscape; + public const string CropOriginal = Material.TwoTone.CropOriginal; + public const string CropPortrait = Material.TwoTone.CropPortrait; + public const string CropRotate = Material.TwoTone.CropRotate; + public const string CropSquare = Material.TwoTone.CropSquare; + public const string CrueltyFree = Material.TwoTone.CrueltyFree; + public const string Css = Material.TwoTone.Css; + public const string CurrencyBitcoin = Material.TwoTone.CurrencyBitcoin; + public const string CurrencyExchange = Material.TwoTone.CurrencyExchange; + public const string CurrencyFranc = Material.TwoTone.CurrencyFranc; + public const string CurrencyLira = Material.TwoTone.CurrencyLira; + public const string CurrencyPound = Material.TwoTone.CurrencyPound; + public const string CurrencyRuble = Material.TwoTone.CurrencyRuble; + public const string CurrencyRupee = Material.TwoTone.CurrencyRupee; + public const string CurrencyYen = Material.TwoTone.CurrencyYen; + public const string CurrencyYuan = Material.TwoTone.CurrencyYuan; + public const string Cyclone = Material.TwoTone.Cyclone; + public const string Dangerous = Material.TwoTone.Dangerous; + public const string DarkMode = Material.TwoTone.DarkMode; + public const string Dashboard = Material.TwoTone.Dashboard; + public const string DashboardCustomize = Material.TwoTone.DashboardCustomize; + public const string DataArray = Material.TwoTone.DataArray; + public const string DataExploration = Material.TwoTone.DataExploration; + public const string DataObject = Material.TwoTone.DataObject; + public const string DataSaverOff = Material.TwoTone.DataSaverOff; + public const string DataSaverOn = Material.TwoTone.DataSaverOn; + public const string DataThresholding = Material.TwoTone.DataThresholding; + public const string DataUsage = Material.TwoTone.DataUsage; + public const string DateRange = Material.TwoTone.DateRange; + public const string Deblur = Material.TwoTone.Deblur; + public const string Deck = Material.TwoTone.Deck; + public const string Dehaze = Material.TwoTone.Dehaze; + public const string Delete = Material.TwoTone.Delete; + public const string DeleteForever = Material.TwoTone.DeleteForever; + public const string DeleteOutline = Material.TwoTone.DeleteOutline; + public const string DeleteSweep = Material.TwoTone.DeleteSweep; + public const string DeliveryDining = Material.TwoTone.DeliveryDining; + public const string DensityLarge = Material.TwoTone.DensityLarge; + public const string DensityMedium = Material.TwoTone.DensityMedium; + public const string DensitySmall = Material.TwoTone.DensitySmall; + public const string DepartureBoard = Material.TwoTone.DepartureBoard; + public const string Description = Material.TwoTone.Description; + public const string Deselect = Material.TwoTone.Deselect; + public const string DesignServices = Material.TwoTone.DesignServices; + public const string DesktopAccessDisabled = Material.TwoTone.DesktopAccessDisabled; + public const string DesktopMac = Material.TwoTone.DesktopMac; + public const string DesktopWindows = Material.TwoTone.DesktopWindows; + public const string Details = Material.TwoTone.Details; + public const string DeveloperBoard = Material.TwoTone.DeveloperBoard; + public const string DeveloperBoardOff = Material.TwoTone.DeveloperBoardOff; + public const string DeveloperMode = Material.TwoTone.DeveloperMode; + public const string DeviceHub = Material.TwoTone.DeviceHub; + public const string DeviceThermostat = Material.TwoTone.DeviceThermostat; + public const string DeviceUnknown = Material.TwoTone.DeviceUnknown; + public const string Devices = Material.TwoTone.Devices; + public const string DevicesFold = Material.TwoTone.DevicesFold; + public const string DevicesOther = Material.TwoTone.DevicesOther; + public const string DialerSip = Material.TwoTone.DialerSip; + public const string Dialpad = Material.TwoTone.Dialpad; + public const string Diamond = Material.TwoTone.Diamond; + public const string Difference = Material.TwoTone.Difference; + public const string Dining = Material.TwoTone.Dining; + public const string DinnerDining = Material.TwoTone.DinnerDining; + public const string Directions = Material.TwoTone.Directions; + public const string DirectionsBike = Material.TwoTone.DirectionsBike; + public const string DirectionsBoat = Material.TwoTone.DirectionsBoat; + public const string DirectionsBoatFilled = Material.TwoTone.DirectionsBoatFilled; + public const string DirectionsBus = Material.TwoTone.DirectionsBus; + public const string DirectionsBusFilled = Material.TwoTone.DirectionsBusFilled; + public const string DirectionsCar = Material.TwoTone.DirectionsCar; + public const string DirectionsCarFilled = Material.TwoTone.DirectionsCarFilled; + public const string DirectionsOff = Material.TwoTone.DirectionsOff; + public const string DirectionsRailway = Material.TwoTone.DirectionsRailway; + public const string DirectionsRailwayFilled = Material.TwoTone.DirectionsRailwayFilled; + public const string DirectionsRun = Material.TwoTone.DirectionsRun; + public const string DirectionsSubway = Material.TwoTone.DirectionsSubway; + public const string DirectionsSubwayFilled = Material.TwoTone.DirectionsSubwayFilled; + public const string DirectionsTransit = Material.TwoTone.DirectionsTransit; + public const string DirectionsTransitFilled = Material.TwoTone.DirectionsTransitFilled; + public const string DirectionsWalk = Material.TwoTone.DirectionsWalk; + public const string DirtyLens = Material.TwoTone.DirtyLens; + public const string DisabledByDefault = Material.TwoTone.DisabledByDefault; + public const string DisabledVisible = Material.TwoTone.DisabledVisible; + public const string DiscFull = Material.TwoTone.DiscFull; + public const string Discount = Material.TwoTone.Discount; + public const string DisplaySettings = Material.TwoTone.DisplaySettings; + public const string Dns = Material.TwoTone.Dns; + public const string DoDisturb = Material.TwoTone.DoDisturb; + public const string DoDisturbAlt = Material.TwoTone.DoDisturbAlt; + public const string DoDisturbOff = Material.TwoTone.DoDisturbOff; + public const string DoDisturbOn = Material.TwoTone.DoDisturbOn; + public const string DoNotDisturb = Material.TwoTone.DoNotDisturb; + public const string DoNotDisturbAlt = Material.TwoTone.DoNotDisturbAlt; + public const string DoNotDisturbOff = Material.TwoTone.DoNotDisturbOff; + public const string DoNotDisturbOn = Material.TwoTone.DoNotDisturbOn; + public const string DoNotDisturbOnTotalSilence = Material.TwoTone.DoNotDisturbOnTotalSilence; + public const string DoNotStep = Material.TwoTone.DoNotStep; + public const string DoNotTouch = Material.TwoTone.DoNotTouch; + public const string Dock = Material.TwoTone.Dock; + public const string DocumentScanner = Material.TwoTone.DocumentScanner; + public const string Domain = Material.TwoTone.Domain; + public const string DomainAdd = Material.TwoTone.DomainAdd; + public const string DomainDisabled = Material.TwoTone.DomainDisabled; + public const string DomainVerification = Material.TwoTone.DomainVerification; + public const string Done = Material.TwoTone.Done; + public const string DoneAll = Material.TwoTone.DoneAll; + public const string DoneOutline = Material.TwoTone.DoneOutline; + public const string DonutLarge = Material.TwoTone.DonutLarge; + public const string DonutSmall = Material.TwoTone.DonutSmall; + public const string DoorBack = Material.TwoTone.DoorBack; + public const string DoorFront = Material.TwoTone.DoorFront; + public const string DoorSliding = Material.TwoTone.DoorSliding; + public const string Doorbell = Material.TwoTone.Doorbell; + public const string DoubleArrow = Material.TwoTone.DoubleArrow; + public const string DownhillSkiing = Material.TwoTone.DownhillSkiing; + public const string Download = Material.TwoTone.Download; + public const string DownloadDone = Material.TwoTone.DownloadDone; + public const string DownloadForOffline = Material.TwoTone.DownloadForOffline; + public const string Downloading = Material.TwoTone.Downloading; + public const string Drafts = Material.TwoTone.Drafts; + public const string DragHandle = Material.TwoTone.DragHandle; + public const string DragIndicator = Material.TwoTone.DragIndicator; + public const string Draw = Material.TwoTone.Draw; + public const string DriveEta = Material.TwoTone.DriveEta; + public const string DriveFileMove = Material.TwoTone.DriveFileMove; + public const string DriveFileMoveRtl = Material.TwoTone.DriveFileMoveRtl; + public const string DriveFileRenameOutline = Material.TwoTone.DriveFileRenameOutline; + public const string DriveFolderUpload = Material.TwoTone.DriveFolderUpload; + public const string Dry = Material.TwoTone.Dry; + public const string DryCleaning = Material.TwoTone.DryCleaning; + public const string Duo = Material.TwoTone.Duo; + public const string Dvr = Material.TwoTone.Dvr; + public const string DynamicFeed = Material.TwoTone.DynamicFeed; + public const string DynamicForm = Material.TwoTone.DynamicForm; + public const string EMobiledata = Material.TwoTone.EMobiledata; + public const string Earbuds = Material.TwoTone.Earbuds; + public const string EarbudsBattery = Material.TwoTone.EarbudsBattery; + public const string East = Material.TwoTone.East; + public const string EdgesensorHigh = Material.TwoTone.EdgesensorHigh; + public const string EdgesensorLow = Material.TwoTone.EdgesensorLow; + public const string Edit = Material.TwoTone.Edit; + public const string EditAttributes = Material.TwoTone.EditAttributes; + public const string EditCalendar = Material.TwoTone.EditCalendar; + public const string EditLocation = Material.TwoTone.EditLocation; + public const string EditLocationAlt = Material.TwoTone.EditLocationAlt; + public const string EditNote = Material.TwoTone.EditNote; + public const string EditNotifications = Material.TwoTone.EditNotifications; + public const string EditOff = Material.TwoTone.EditOff; + public const string EditRoad = Material.TwoTone.EditRoad; + public const string Egg = Material.TwoTone.Egg; + public const string EggAlt = Material.TwoTone.EggAlt; + public const string Eject = Material.TwoTone.Eject; + public const string Elderly = Material.TwoTone.Elderly; + public const string ElderlyWoman = Material.TwoTone.ElderlyWoman; + public const string ElectricBike = Material.TwoTone.ElectricBike; + public const string ElectricCar = Material.TwoTone.ElectricCar; + public const string ElectricMoped = Material.TwoTone.ElectricMoped; + public const string ElectricRickshaw = Material.TwoTone.ElectricRickshaw; + public const string ElectricScooter = Material.TwoTone.ElectricScooter; + public const string ElectricalServices = Material.TwoTone.ElectricalServices; + public const string Elevator = Material.TwoTone.Elevator; + public const string Email = Material.TwoTone.Email; + public const string Emergency = Material.TwoTone.Emergency; + public const string EmergencyRecording = Material.TwoTone.EmergencyRecording; + public const string EmergencyShare = Material.TwoTone.EmergencyShare; + public const string EmojiEmotions = Material.TwoTone.EmojiEmotions; + public const string EmojiEvents = Material.TwoTone.EmojiEvents; + public const string EmojiFoodBeverage = Material.TwoTone.EmojiFoodBeverage; + public const string EmojiNature = Material.TwoTone.EmojiNature; + public const string EmojiObjects = Material.TwoTone.EmojiObjects; + public const string EmojiPeople = Material.TwoTone.EmojiPeople; + public const string EmojiSymbols = Material.TwoTone.EmojiSymbols; + public const string EmojiTransportation = Material.TwoTone.EmojiTransportation; + public const string Engineering = Material.TwoTone.Engineering; + public const string EnhancedEncryption = Material.TwoTone.EnhancedEncryption; + public const string Equalizer = Material.TwoTone.Equalizer; + public const string Error = Material.TwoTone.Error; + public const string ErrorOutline = Material.TwoTone.ErrorOutline; + public const string Escalator = Material.TwoTone.Escalator; + public const string EscalatorWarning = Material.TwoTone.EscalatorWarning; + public const string Euro = Material.TwoTone.Euro; + public const string EuroSymbol = Material.TwoTone.EuroSymbol; + public const string EvStation = Material.TwoTone.EvStation; + public const string Event = Material.TwoTone.Event; + public const string EventAvailable = Material.TwoTone.EventAvailable; + public const string EventBusy = Material.TwoTone.EventBusy; + public const string EventNote = Material.TwoTone.EventNote; + public const string EventRepeat = Material.TwoTone.EventRepeat; + public const string EventSeat = Material.TwoTone.EventSeat; + public const string ExitToApp = Material.TwoTone.ExitToApp; + public const string Expand = Material.TwoTone.Expand; + public const string ExpandCircleDown = Material.TwoTone.ExpandCircleDown; + public const string ExpandLess = Material.TwoTone.ExpandLess; + public const string ExpandMore = Material.TwoTone.ExpandMore; + public const string Explicit = Material.TwoTone.Explicit; + public const string Explore = Material.TwoTone.Explore; + public const string ExploreOff = Material.TwoTone.ExploreOff; + public const string Exposure = Material.TwoTone.Exposure; + public const string ExposureNeg1 = Material.TwoTone.ExposureNeg1; + public const string ExposureNeg2 = Material.TwoTone.ExposureNeg2; + public const string ExposurePlus1 = Material.TwoTone.ExposurePlus1; + public const string ExposurePlus2 = Material.TwoTone.ExposurePlus2; + public const string ExposureZero = Material.TwoTone.ExposureZero; + public const string Extension = Material.TwoTone.Extension; + public const string ExtensionOff = Material.TwoTone.ExtensionOff; + public const string Face = Material.TwoTone.Face; + public const string FaceRetouchingNatural = Material.TwoTone.FaceRetouchingNatural; + public const string FaceRetouchingOff = Material.TwoTone.FaceRetouchingOff; + public const string FactCheck = Material.TwoTone.FactCheck; + public const string Factory = Material.TwoTone.Factory; + public const string FamilyRestroom = Material.TwoTone.FamilyRestroom; + public const string FastForward = Material.TwoTone.FastForward; + public const string FastRewind = Material.TwoTone.FastRewind; + public const string Fastfood = Material.TwoTone.Fastfood; + public const string Favorite = Material.TwoTone.Favorite; + public const string FavoriteBorder = Material.TwoTone.FavoriteBorder; + public const string Fax = Material.TwoTone.Fax; + public const string FeaturedPlayList = Material.TwoTone.FeaturedPlayList; + public const string FeaturedVideo = Material.TwoTone.FeaturedVideo; + public const string Feed = Material.TwoTone.Feed; + public const string Feedback = Material.TwoTone.Feedback; + public const string Female = Material.TwoTone.Female; + public const string Fence = Material.TwoTone.Fence; + public const string Festival = Material.TwoTone.Festival; + public const string FiberDvr = Material.TwoTone.FiberDvr; + public const string FiberManualRecord = Material.TwoTone.FiberManualRecord; + public const string FiberNew = Material.TwoTone.FiberNew; + public const string FiberPin = Material.TwoTone.FiberPin; + public const string FiberSmartRecord = Material.TwoTone.FiberSmartRecord; + public const string FileCopy = Material.TwoTone.FileCopy; + public const string FileDownload = Material.TwoTone.FileDownload; + public const string FileDownloadDone = Material.TwoTone.FileDownloadDone; + public const string FileDownloadOff = Material.TwoTone.FileDownloadOff; + public const string FileOpen = Material.TwoTone.FileOpen; + public const string FilePresent = Material.TwoTone.FilePresent; + public const string FileUpload = Material.TwoTone.FileUpload; + public const string Filter = Material.TwoTone.Filter; + public const string Filter1 = Material.TwoTone.Filter1; + public const string Filter2 = Material.TwoTone.Filter2; + public const string Filter3 = Material.TwoTone.Filter3; + public const string Filter4 = Material.TwoTone.Filter4; + public const string Filter5 = Material.TwoTone.Filter5; + public const string Filter6 = Material.TwoTone.Filter6; + public const string Filter7 = Material.TwoTone.Filter7; + public const string Filter8 = Material.TwoTone.Filter8; + public const string Filter9 = Material.TwoTone.Filter9; + public const string Filter9Plus = Material.TwoTone.Filter9Plus; + public const string FilterAlt = Material.TwoTone.FilterAlt; + public const string FilterAltOff = Material.TwoTone.FilterAltOff; + public const string FilterBAndW = Material.TwoTone.FilterBAndW; + public const string FilterCenterFocus = Material.TwoTone.FilterCenterFocus; + public const string FilterDrama = Material.TwoTone.FilterDrama; + public const string FilterFrames = Material.TwoTone.FilterFrames; + public const string FilterHdr = Material.TwoTone.FilterHdr; + public const string FilterList = Material.TwoTone.FilterList; + public const string FilterListOff = Material.TwoTone.FilterListOff; + public const string FilterNone = Material.TwoTone.FilterNone; + public const string FilterTiltShift = Material.TwoTone.FilterTiltShift; + public const string FilterVintage = Material.TwoTone.FilterVintage; + public const string FindInPage = Material.TwoTone.FindInPage; + public const string FindReplace = Material.TwoTone.FindReplace; + public const string Fingerprint = Material.TwoTone.Fingerprint; + public const string FireExtinguisher = Material.TwoTone.FireExtinguisher; + public const string Fireplace = Material.TwoTone.Fireplace; + public const string FirstPage = Material.TwoTone.FirstPage; + public const string FitScreen = Material.TwoTone.FitScreen; + public const string Fitbit = Material.TwoTone.Fitbit; + public const string FitnessCenter = Material.TwoTone.FitnessCenter; + public const string Flag = Material.TwoTone.Flag; + public const string FlagCircle = Material.TwoTone.FlagCircle; + public const string Flaky = Material.TwoTone.Flaky; + public const string Flare = Material.TwoTone.Flare; + public const string FlashAuto = Material.TwoTone.FlashAuto; + public const string FlashOff = Material.TwoTone.FlashOff; + public const string FlashOn = Material.TwoTone.FlashOn; + public const string FlashlightOff = Material.TwoTone.FlashlightOff; + public const string FlashlightOn = Material.TwoTone.FlashlightOn; + public const string Flatware = Material.TwoTone.Flatware; + public const string Flight = Material.TwoTone.Flight; + public const string FlightClass = Material.TwoTone.FlightClass; + public const string FlightLand = Material.TwoTone.FlightLand; + public const string FlightTakeoff = Material.TwoTone.FlightTakeoff; + public const string Flip = Material.TwoTone.Flip; + public const string FlipCameraAndroid = Material.TwoTone.FlipCameraAndroid; + public const string FlipCameraIos = Material.TwoTone.FlipCameraIos; + public const string FlipToBack = Material.TwoTone.FlipToBack; + public const string FlipToFront = Material.TwoTone.FlipToFront; + public const string Flood = Material.TwoTone.Flood; + public const string Flourescent = Material.TwoTone.Flourescent; + public const string FlutterDash = Material.TwoTone.FlutterDash; + public const string FmdBad = Material.TwoTone.FmdBad; + public const string FmdGood = Material.TwoTone.FmdGood; + public const string Folder = Material.TwoTone.Folder; + public const string FolderCopy = Material.TwoTone.FolderCopy; + public const string FolderDelete = Material.TwoTone.FolderDelete; + public const string FolderOff = Material.TwoTone.FolderOff; + public const string FolderOpen = Material.TwoTone.FolderOpen; + public const string FolderShared = Material.TwoTone.FolderShared; + public const string FolderSpecial = Material.TwoTone.FolderSpecial; + public const string FolderZip = Material.TwoTone.FolderZip; + public const string FollowTheSigns = Material.TwoTone.FollowTheSigns; + public const string FontDownload = Material.TwoTone.FontDownload; + public const string FontDownloadOff = Material.TwoTone.FontDownloadOff; + public const string FoodBank = Material.TwoTone.FoodBank; + public const string Forest = Material.TwoTone.Forest; + public const string ForkLeft = Material.TwoTone.ForkLeft; + public const string ForkRight = Material.TwoTone.ForkRight; + public const string FormatAlignCenter = Material.TwoTone.FormatAlignCenter; + public const string FormatAlignJustify = Material.TwoTone.FormatAlignJustify; + public const string FormatAlignLeft = Material.TwoTone.FormatAlignLeft; + public const string FormatAlignRight = Material.TwoTone.FormatAlignRight; + public const string FormatBold = Material.TwoTone.FormatBold; + public const string FormatClear = Material.TwoTone.FormatClear; + public const string FormatColorFill = Material.TwoTone.FormatColorFill; + public const string FormatColorReset = Material.TwoTone.FormatColorReset; + public const string FormatColorText = Material.TwoTone.FormatColorText; + public const string FormatIndentDecrease = Material.TwoTone.FormatIndentDecrease; + public const string FormatIndentIncrease = Material.TwoTone.FormatIndentIncrease; + public const string FormatItalic = Material.TwoTone.FormatItalic; + public const string FormatLineSpacing = Material.TwoTone.FormatLineSpacing; + public const string FormatListBulleted = Material.TwoTone.FormatListBulleted; + public const string FormatListNumbered = Material.TwoTone.FormatListNumbered; + public const string FormatListNumberedRtl = Material.TwoTone.FormatListNumberedRtl; + public const string FormatOverline = Material.TwoTone.FormatOverline; + public const string FormatPaint = Material.TwoTone.FormatPaint; + public const string FormatQuote = Material.TwoTone.FormatQuote; + public const string FormatShapes = Material.TwoTone.FormatShapes; + public const string FormatSize = Material.TwoTone.FormatSize; + public const string FormatStrikethrough = Material.TwoTone.FormatStrikethrough; + public const string FormatTextdirectionLToR = Material.TwoTone.FormatTextdirectionLToR; + public const string FormatTextdirectionRToL = Material.TwoTone.FormatTextdirectionRToL; + public const string FormatUnderlined = Material.TwoTone.FormatUnderlined; + public const string Fort = Material.TwoTone.Fort; + public const string Forum = Material.TwoTone.Forum; + public const string Forward = Material.TwoTone.Forward; + public const string Forward10 = Material.TwoTone.Forward10; + public const string Forward30 = Material.TwoTone.Forward30; + public const string Forward5 = Material.TwoTone.Forward5; + public const string ForwardToInbox = Material.TwoTone.ForwardToInbox; + public const string Foundation = Material.TwoTone.Foundation; + public const string FreeBreakfast = Material.TwoTone.FreeBreakfast; + public const string FreeCancellation = Material.TwoTone.FreeCancellation; + public const string FrontHand = Material.TwoTone.FrontHand; + public const string Fullscreen = Material.TwoTone.Fullscreen; + public const string FullscreenExit = Material.TwoTone.FullscreenExit; + public const string Functions = Material.TwoTone.Functions; + public const string GMobiledata = Material.TwoTone.GMobiledata; + public const string GTranslate = Material.TwoTone.GTranslate; + public const string Gamepad = Material.TwoTone.Gamepad; + public const string Games = Material.TwoTone.Games; + public const string Garage = Material.TwoTone.Garage; + public const string Gavel = Material.TwoTone.Gavel; + public const string GeneratingTokens = Material.TwoTone.GeneratingTokens; + public const string Gesture = Material.TwoTone.Gesture; + public const string GetApp = Material.TwoTone.GetApp; + public const string Gif = Material.TwoTone.Gif; + public const string GifBox = Material.TwoTone.GifBox; + public const string Girl = Material.TwoTone.Girl; + public const string Gite = Material.TwoTone.Gite; + public const string GolfCourse = Material.TwoTone.GolfCourse; + public const string GppBad = Material.TwoTone.GppBad; + public const string GppGood = Material.TwoTone.GppGood; + public const string GppMaybe = Material.TwoTone.GppMaybe; + public const string GpsFixed = Material.TwoTone.GpsFixed; + public const string GpsNotFixed = Material.TwoTone.GpsNotFixed; + public const string GpsOff = Material.TwoTone.GpsOff; + public const string Grade = Material.TwoTone.Grade; + public const string Gradient = Material.TwoTone.Gradient; + public const string Grading = Material.TwoTone.Grading; + public const string Grain = Material.TwoTone.Grain; + public const string GraphicEq = Material.TwoTone.GraphicEq; + public const string Grass = Material.TwoTone.Grass; + public const string Grid3x3 = Material.TwoTone.Grid3x3; + public const string Grid4x4 = Material.TwoTone.Grid4x4; + public const string GridGoldenratio = Material.TwoTone.GridGoldenratio; + public const string GridOff = Material.TwoTone.GridOff; + public const string GridOn = Material.TwoTone.GridOn; + public const string GridView = Material.TwoTone.GridView; + public const string Group = Material.TwoTone.Group; + public const string GroupAdd = Material.TwoTone.GroupAdd; + public const string GroupOff = Material.TwoTone.GroupOff; + public const string GroupRemove = Material.TwoTone.GroupRemove; + public const string GroupWork = Material.TwoTone.GroupWork; + public const string Groups = Material.TwoTone.Groups; + public const string HMobiledata = Material.TwoTone.HMobiledata; + public const string HPlusMobiledata = Material.TwoTone.HPlusMobiledata; + public const string Hail = Material.TwoTone.Hail; + public const string Handshake = Material.TwoTone.Handshake; + public const string Handyman = Material.TwoTone.Handyman; + public const string Hardware = Material.TwoTone.Hardware; + public const string Hd = Material.TwoTone.Hd; + public const string HdrAuto = Material.TwoTone.HdrAuto; + public const string HdrAutoSelect = Material.TwoTone.HdrAutoSelect; + public const string HdrEnhancedSelect = Material.TwoTone.HdrEnhancedSelect; + public const string HdrOff = Material.TwoTone.HdrOff; + public const string HdrOffSelect = Material.TwoTone.HdrOffSelect; + public const string HdrOn = Material.TwoTone.HdrOn; + public const string HdrOnSelect = Material.TwoTone.HdrOnSelect; + public const string HdrPlus = Material.TwoTone.HdrPlus; + public const string HdrStrong = Material.TwoTone.HdrStrong; + public const string HdrWeak = Material.TwoTone.HdrWeak; + public const string Headphones = Material.TwoTone.Headphones; + public const string HeadphonesBattery = Material.TwoTone.HeadphonesBattery; + public const string Headset = Material.TwoTone.Headset; + public const string HeadsetMic = Material.TwoTone.HeadsetMic; + public const string HeadsetOff = Material.TwoTone.HeadsetOff; + public const string Healing = Material.TwoTone.Healing; + public const string HealthAndSafety = Material.TwoTone.HealthAndSafety; + public const string Hearing = Material.TwoTone.Hearing; + public const string HearingDisabled = Material.TwoTone.HearingDisabled; + public const string HeartBroken = Material.TwoTone.HeartBroken; + public const string Height = Material.TwoTone.Height; + public const string Help = Material.TwoTone.Help; + public const string HelpCenter = Material.TwoTone.HelpCenter; + public const string HelpOutline = Material.TwoTone.HelpOutline; + public const string Hevc = Material.TwoTone.Hevc; + public const string Hexagon = Material.TwoTone.Hexagon; + public const string HideImage = Material.TwoTone.HideImage; + public const string HideSource = Material.TwoTone.HideSource; + public const string HighQuality = Material.TwoTone.HighQuality; + public const string Highlight = Material.TwoTone.Highlight; + public const string HighlightAlt = Material.TwoTone.HighlightAlt; + public const string HighlightOff = Material.TwoTone.HighlightOff; + public const string Hiking = Material.TwoTone.Hiking; + public const string History = Material.TwoTone.History; + public const string HistoryEdu = Material.TwoTone.HistoryEdu; + public const string HistoryToggleOff = Material.TwoTone.HistoryToggleOff; + public const string Hive = Material.TwoTone.Hive; + public const string Hls = Material.TwoTone.Hls; + public const string HlsOff = Material.TwoTone.HlsOff; + public const string HolidayVillage = Material.TwoTone.HolidayVillage; + public const string Home = Material.TwoTone.Home; + public const string HomeMax = Material.TwoTone.HomeMax; + public const string HomeMini = Material.TwoTone.HomeMini; + public const string HomeRepairService = Material.TwoTone.HomeRepairService; + public const string HomeWork = Material.TwoTone.HomeWork; + public const string HorizontalDistribute = Material.TwoTone.HorizontalDistribute; + public const string HorizontalRule = Material.TwoTone.HorizontalRule; + public const string HorizontalSplit = Material.TwoTone.HorizontalSplit; + public const string HotTub = Material.TwoTone.HotTub; + public const string Hotel = Material.TwoTone.Hotel; + public const string HotelClass = Material.TwoTone.HotelClass; + public const string HourglassBottom = Material.TwoTone.HourglassBottom; + public const string HourglassDisabled = Material.TwoTone.HourglassDisabled; + public const string HourglassEmpty = Material.TwoTone.HourglassEmpty; + public const string HourglassFull = Material.TwoTone.HourglassFull; + public const string HourglassTop = Material.TwoTone.HourglassTop; + public const string House = Material.TwoTone.House; + public const string HouseSiding = Material.TwoTone.HouseSiding; + public const string Houseboat = Material.TwoTone.Houseboat; + public const string HowToReg = Material.TwoTone.HowToReg; + public const string HowToVote = Material.TwoTone.HowToVote; + public const string Html = Material.TwoTone.Html; + public const string Http = Material.TwoTone.Http; + public const string Https = Material.TwoTone.Https; + public const string Hub = Material.TwoTone.Hub; + public const string Hvac = Material.TwoTone.Hvac; + public const string IceSkating = Material.TwoTone.IceSkating; + public const string Icecream = Material.TwoTone.Icecream; + public const string Image = Material.TwoTone.Image; + public const string ImageAspectRatio = Material.TwoTone.ImageAspectRatio; + public const string ImageNotSupported = Material.TwoTone.ImageNotSupported; + public const string ImageSearch = Material.TwoTone.ImageSearch; + public const string ImagesearchRoller = Material.TwoTone.ImagesearchRoller; + public const string ImportContacts = Material.TwoTone.ImportContacts; + public const string ImportExport = Material.TwoTone.ImportExport; + public const string ImportantDevices = Material.TwoTone.ImportantDevices; + public const string Inbox = Material.TwoTone.Inbox; + public const string IncompleteCircle = Material.TwoTone.IncompleteCircle; + public const string IndeterminateCheckBox = Material.TwoTone.IndeterminateCheckBox; + public const string Info = Material.TwoTone.Info; + public const string Input = Material.TwoTone.Input; + public const string InsertChart = Material.TwoTone.InsertChart; + public const string InsertChartOutlined = Material.TwoTone.InsertChartOutlined; + public const string InsertComment = Material.TwoTone.InsertComment; + public const string InsertDriveFile = Material.TwoTone.InsertDriveFile; + public const string InsertEmoticon = Material.TwoTone.InsertEmoticon; + public const string InsertInvitation = Material.TwoTone.InsertInvitation; + public const string InsertLink = Material.TwoTone.InsertLink; + public const string InsertPageBreak = Material.TwoTone.InsertPageBreak; + public const string InsertPhoto = Material.TwoTone.InsertPhoto; + public const string Insights = Material.TwoTone.Insights; + public const string InstallDesktop = Material.TwoTone.InstallDesktop; + public const string InstallMobile = Material.TwoTone.InstallMobile; + public const string IntegrationInstructions = Material.TwoTone.IntegrationInstructions; + public const string Interests = Material.TwoTone.Interests; + public const string InterpreterMode = Material.TwoTone.InterpreterMode; + public const string Inventory = Material.TwoTone.Inventory; + public const string Inventory2 = Material.TwoTone.Inventory2; + public const string InvertColors = Material.TwoTone.InvertColors; + public const string InvertColorsOff = Material.TwoTone.InvertColorsOff; + public const string IosShare = Material.TwoTone.IosShare; + public const string Iron = Material.TwoTone.Iron; + public const string Iso = Material.TwoTone.Iso; + public const string Javascript = Material.TwoTone.Javascript; + public const string JoinFull = Material.TwoTone.JoinFull; + public const string JoinInner = Material.TwoTone.JoinInner; + public const string JoinLeft = Material.TwoTone.JoinLeft; + public const string JoinRight = Material.TwoTone.JoinRight; + public const string Kayaking = Material.TwoTone.Kayaking; + public const string KebabDining = Material.TwoTone.KebabDining; + public const string Key = Material.TwoTone.Key; + public const string KeyOff = Material.TwoTone.KeyOff; + public const string Keyboard = Material.TwoTone.Keyboard; + public const string KeyboardAlt = Material.TwoTone.KeyboardAlt; + public const string KeyboardArrowDown = Material.TwoTone.KeyboardArrowDown; + public const string KeyboardArrowLeft = Material.TwoTone.KeyboardArrowLeft; + public const string KeyboardArrowRight = Material.TwoTone.KeyboardArrowRight; + public const string KeyboardArrowUp = Material.TwoTone.KeyboardArrowUp; + public const string KeyboardBackspace = Material.TwoTone.KeyboardBackspace; + public const string KeyboardCapslock = Material.TwoTone.KeyboardCapslock; + public const string KeyboardCommandKey = Material.TwoTone.KeyboardCommandKey; + public const string KeyboardControlKey = Material.TwoTone.KeyboardControlKey; + public const string KeyboardDoubleArrowDown = Material.TwoTone.KeyboardDoubleArrowDown; + public const string KeyboardDoubleArrowLeft = Material.TwoTone.KeyboardDoubleArrowLeft; + public const string KeyboardDoubleArrowRight = Material.TwoTone.KeyboardDoubleArrowRight; + public const string KeyboardDoubleArrowUp = Material.TwoTone.KeyboardDoubleArrowUp; + public const string KeyboardHide = Material.TwoTone.KeyboardHide; + public const string KeyboardOptionKey = Material.TwoTone.KeyboardOptionKey; + public const string KeyboardReturn = Material.TwoTone.KeyboardReturn; + public const string KeyboardTab = Material.TwoTone.KeyboardTab; + public const string KeyboardVoice = Material.TwoTone.KeyboardVoice; + public const string KingBed = Material.TwoTone.KingBed; + public const string Kitchen = Material.TwoTone.Kitchen; + public const string Kitesurfing = Material.TwoTone.Kitesurfing; + public const string Label = Material.TwoTone.Label; + public const string LabelImportant = Material.TwoTone.LabelImportant; + public const string LabelOff = Material.TwoTone.LabelOff; + public const string Lan = Material.TwoTone.Lan; + public const string Landscape = Material.TwoTone.Landscape; + public const string Landslide = Material.TwoTone.Landslide; + public const string Language = Material.TwoTone.Language; + public const string Laptop = Material.TwoTone.Laptop; + public const string LaptopChromebook = Material.TwoTone.LaptopChromebook; + public const string LaptopMac = Material.TwoTone.LaptopMac; + public const string LaptopWindows = Material.TwoTone.LaptopWindows; + public const string LastPage = Material.TwoTone.LastPage; + public const string Launch = Material.TwoTone.Launch; + public const string Layers = Material.TwoTone.Layers; + public const string LayersClear = Material.TwoTone.LayersClear; + public const string Leaderboard = Material.TwoTone.Leaderboard; + public const string LeakAdd = Material.TwoTone.LeakAdd; + public const string LeakRemove = Material.TwoTone.LeakRemove; + public const string LegendToggle = Material.TwoTone.LegendToggle; + public const string Lens = Material.TwoTone.Lens; + public const string LensBlur = Material.TwoTone.LensBlur; + public const string LibraryAdd = Material.TwoTone.LibraryAdd; + public const string LibraryAddCheck = Material.TwoTone.LibraryAddCheck; + public const string LibraryBooks = Material.TwoTone.LibraryBooks; + public const string LibraryMusic = Material.TwoTone.LibraryMusic; + public const string Light = Material.TwoTone.Light; + public const string LightMode = Material.TwoTone.LightMode; + public const string Lightbulb = Material.TwoTone.Lightbulb; + public const string LightbulbCircle = Material.TwoTone.LightbulbCircle; + public const string LineAxis = Material.TwoTone.LineAxis; + public const string LineStyle = Material.TwoTone.LineStyle; + public const string LineWeight = Material.TwoTone.LineWeight; + public const string LinearScale = Material.TwoTone.LinearScale; + public const string Link = Material.TwoTone.Link; + public const string LinkOff = Material.TwoTone.LinkOff; + public const string LinkedCamera = Material.TwoTone.LinkedCamera; + public const string Liquor = Material.TwoTone.Liquor; + public const string List = Material.TwoTone.List; + public const string ListAlt = Material.TwoTone.ListAlt; + public const string LiveHelp = Material.TwoTone.LiveHelp; + public const string LiveTv = Material.TwoTone.LiveTv; + public const string Living = Material.TwoTone.Living; + public const string LocalActivity = Material.TwoTone.LocalActivity; + public const string LocalAirport = Material.TwoTone.LocalAirport; + public const string LocalAtm = Material.TwoTone.LocalAtm; + public const string LocalBar = Material.TwoTone.LocalBar; + public const string LocalCafe = Material.TwoTone.LocalCafe; + public const string LocalCarWash = Material.TwoTone.LocalCarWash; + public const string LocalConvenienceStore = Material.TwoTone.LocalConvenienceStore; + public const string LocalDining = Material.TwoTone.LocalDining; + public const string LocalDrink = Material.TwoTone.LocalDrink; + public const string LocalFireDepartment = Material.TwoTone.LocalFireDepartment; + public const string LocalFlorist = Material.TwoTone.LocalFlorist; + public const string LocalGasStation = Material.TwoTone.LocalGasStation; + public const string LocalGroceryStore = Material.TwoTone.LocalGroceryStore; + public const string LocalHospital = Material.TwoTone.LocalHospital; + public const string LocalHotel = Material.TwoTone.LocalHotel; + public const string LocalLaundryService = Material.TwoTone.LocalLaundryService; + public const string LocalLibrary = Material.TwoTone.LocalLibrary; + public const string LocalMall = Material.TwoTone.LocalMall; + public const string LocalMovies = Material.TwoTone.LocalMovies; + public const string LocalOffer = Material.TwoTone.LocalOffer; + public const string LocalParking = Material.TwoTone.LocalParking; + public const string LocalPharmacy = Material.TwoTone.LocalPharmacy; + public const string LocalPhone = Material.TwoTone.LocalPhone; + public const string LocalPizza = Material.TwoTone.LocalPizza; + public const string LocalPlay = Material.TwoTone.LocalPlay; + public const string LocalPolice = Material.TwoTone.LocalPolice; + public const string LocalPostOffice = Material.TwoTone.LocalPostOffice; + public const string LocalPrintshop = Material.TwoTone.LocalPrintshop; + public const string LocalSee = Material.TwoTone.LocalSee; + public const string LocalShipping = Material.TwoTone.LocalShipping; + public const string LocalTaxi = Material.TwoTone.LocalTaxi; + public const string LocationCity = Material.TwoTone.LocationCity; + public const string LocationDisabled = Material.TwoTone.LocationDisabled; + public const string LocationOff = Material.TwoTone.LocationOff; + public const string LocationOn = Material.TwoTone.LocationOn; + public const string LocationSearching = Material.TwoTone.LocationSearching; + public const string Lock = Material.TwoTone.Lock; + public const string LockClock = Material.TwoTone.LockClock; + public const string LockOpen = Material.TwoTone.LockOpen; + public const string LockReset = Material.TwoTone.LockReset; + public const string Login = Material.TwoTone.Login; + public const string LogoDev = Material.TwoTone.LogoDev; + public const string Logout = Material.TwoTone.Logout; + public const string Looks = Material.TwoTone.Looks; + public const string Looks3 = Material.TwoTone.Looks3; + public const string Looks4 = Material.TwoTone.Looks4; + public const string Looks5 = Material.TwoTone.Looks5; + public const string Looks6 = Material.TwoTone.Looks6; + public const string LooksOne = Material.TwoTone.LooksOne; + public const string LooksTwo = Material.TwoTone.LooksTwo; + public const string Loop = Material.TwoTone.Loop; + public const string Loupe = Material.TwoTone.Loupe; + public const string LowPriority = Material.TwoTone.LowPriority; + public const string Loyalty = Material.TwoTone.Loyalty; + public const string LteMobiledata = Material.TwoTone.LteMobiledata; + public const string LtePlusMobiledata = Material.TwoTone.LtePlusMobiledata; + public const string Luggage = Material.TwoTone.Luggage; + public const string LunchDining = Material.TwoTone.LunchDining; + public const string Mail = Material.TwoTone.Mail; + public const string MailOutline = Material.TwoTone.MailOutline; + public const string Male = Material.TwoTone.Male; + public const string Man = Material.TwoTone.Man; + public const string ManageAccounts = Material.TwoTone.ManageAccounts; + public const string ManageHistory = Material.TwoTone.ManageHistory; + public const string ManageSearch = Material.TwoTone.ManageSearch; + public const string Map = Material.TwoTone.Map; + public const string MapsHomeWork = Material.TwoTone.MapsHomeWork; + public const string MapsUgc = Material.TwoTone.MapsUgc; + public const string Margin = Material.TwoTone.Margin; + public const string MarkAsUnread = Material.TwoTone.MarkAsUnread; + public const string MarkChatRead = Material.TwoTone.MarkChatRead; + public const string MarkChatUnread = Material.TwoTone.MarkChatUnread; + public const string MarkEmailRead = Material.TwoTone.MarkEmailRead; + public const string MarkEmailUnread = Material.TwoTone.MarkEmailUnread; + public const string MarkUnreadChatAlt = Material.TwoTone.MarkUnreadChatAlt; + public const string Markunread = Material.TwoTone.Markunread; + public const string MarkunreadMailbox = Material.TwoTone.MarkunreadMailbox; + public const string Masks = Material.TwoTone.Masks; + public const string Maximize = Material.TwoTone.Maximize; + public const string MediaBluetoothOff = Material.TwoTone.MediaBluetoothOff; + public const string MediaBluetoothOn = Material.TwoTone.MediaBluetoothOn; + public const string Mediation = Material.TwoTone.Mediation; + public const string MedicalInformation = Material.TwoTone.MedicalInformation; + public const string MedicalServices = Material.TwoTone.MedicalServices; + public const string Medication = Material.TwoTone.Medication; + public const string MedicationLiquid = Material.TwoTone.MedicationLiquid; + public const string MeetingRoom = Material.TwoTone.MeetingRoom; + public const string Memory = Material.TwoTone.Memory; + public const string Menu = Material.TwoTone.Menu; + public const string MenuBook = Material.TwoTone.MenuBook; + public const string MenuOpen = Material.TwoTone.MenuOpen; + public const string Merge = Material.TwoTone.Merge; + public const string MergeType = Material.TwoTone.MergeType; + public const string Message = Material.TwoTone.Message; + public const string Mic = Material.TwoTone.Mic; + public const string MicExternalOff = Material.TwoTone.MicExternalOff; + public const string MicExternalOn = Material.TwoTone.MicExternalOn; + public const string MicNone = Material.TwoTone.MicNone; + public const string MicOff = Material.TwoTone.MicOff; + public const string Microwave = Material.TwoTone.Microwave; + public const string MilitaryTech = Material.TwoTone.MilitaryTech; + public const string Minimize = Material.TwoTone.Minimize; + public const string MinorCrash = Material.TwoTone.MinorCrash; + public const string MiscellaneousServices = Material.TwoTone.MiscellaneousServices; + public const string MissedVideoCall = Material.TwoTone.MissedVideoCall; + public const string Mms = Material.TwoTone.Mms; + public const string MobileFriendly = Material.TwoTone.MobileFriendly; + public const string MobileOff = Material.TwoTone.MobileOff; + public const string MobileScreenShare = Material.TwoTone.MobileScreenShare; + public const string MobiledataOff = Material.TwoTone.MobiledataOff; + public const string Mode = Material.TwoTone.Mode; + public const string ModeComment = Material.TwoTone.ModeComment; + public const string ModeEdit = Material.TwoTone.ModeEdit; + public const string ModeEditOutline = Material.TwoTone.ModeEditOutline; + public const string ModeNight = Material.TwoTone.ModeNight; + public const string ModeOfTravel = Material.TwoTone.ModeOfTravel; + public const string ModeStandby = Material.TwoTone.ModeStandby; + public const string ModelTraining = Material.TwoTone.ModelTraining; + public const string MonetizationOn = Material.TwoTone.MonetizationOn; + public const string Money = Material.TwoTone.Money; + public const string MoneyOff = Material.TwoTone.MoneyOff; + public const string MoneyOffCsred = Material.TwoTone.MoneyOffCsred; + public const string Monitor = Material.TwoTone.Monitor; + public const string MonitorHeart = Material.TwoTone.MonitorHeart; + public const string MonitorWeight = Material.TwoTone.MonitorWeight; + public const string MonochromePhotos = Material.TwoTone.MonochromePhotos; + public const string Mood = Material.TwoTone.Mood; + public const string MoodBad = Material.TwoTone.MoodBad; + public const string Moped = Material.TwoTone.Moped; + public const string More = Material.TwoTone.More; + public const string MoreHoriz = Material.TwoTone.MoreHoriz; + public const string MoreTime = Material.TwoTone.MoreTime; + public const string MoreVert = Material.TwoTone.MoreVert; + public const string Mosque = Material.TwoTone.Mosque; + public const string MotionPhotosAuto = Material.TwoTone.MotionPhotosAuto; + public const string MotionPhotosOff = Material.TwoTone.MotionPhotosOff; + public const string MotionPhotosOn = Material.TwoTone.MotionPhotosOn; + public const string MotionPhotosPause = Material.TwoTone.MotionPhotosPause; + public const string MotionPhotosPaused = Material.TwoTone.MotionPhotosPaused; + public const string Mouse = Material.TwoTone.Mouse; + public const string MoveDown = Material.TwoTone.MoveDown; + public const string MoveToInbox = Material.TwoTone.MoveToInbox; + public const string MoveUp = Material.TwoTone.MoveUp; + public const string Movie = Material.TwoTone.Movie; + public const string MovieCreation = Material.TwoTone.MovieCreation; + public const string MovieFilter = Material.TwoTone.MovieFilter; + public const string Moving = Material.TwoTone.Moving; + public const string Mp = Material.TwoTone.Mp; + public const string MultilineChart = Material.TwoTone.MultilineChart; + public const string MultipleStop = Material.TwoTone.MultipleStop; + public const string Museum = Material.TwoTone.Museum; + public const string MusicNote = Material.TwoTone.MusicNote; + public const string MusicOff = Material.TwoTone.MusicOff; + public const string MusicVideo = Material.TwoTone.MusicVideo; + public const string MyLocation = Material.TwoTone.MyLocation; + public const string Nat = Material.TwoTone.Nat; + public const string Nature = Material.TwoTone.Nature; + public const string NaturePeople = Material.TwoTone.NaturePeople; + public const string NavigateBefore = Material.TwoTone.NavigateBefore; + public const string NavigateNext = Material.TwoTone.NavigateNext; + public const string Navigation = Material.TwoTone.Navigation; + public const string NearMe = Material.TwoTone.NearMe; + public const string NearMeDisabled = Material.TwoTone.NearMeDisabled; + public const string NearbyError = Material.TwoTone.NearbyError; + public const string NearbyOff = Material.TwoTone.NearbyOff; + public const string NetworkCell = Material.TwoTone.NetworkCell; + public const string NetworkCheck = Material.TwoTone.NetworkCheck; + public const string NetworkLocked = Material.TwoTone.NetworkLocked; + public const string NetworkPing = Material.TwoTone.NetworkPing; + public const string NetworkWifi = Material.TwoTone.NetworkWifi; + public const string NetworkWifi1Bar = Material.TwoTone.NetworkWifi1Bar; + public const string NetworkWifi2Bar = Material.TwoTone.NetworkWifi2Bar; + public const string NetworkWifi3Bar = Material.TwoTone.NetworkWifi3Bar; + public const string NewLabel = Material.TwoTone.NewLabel; + public const string NewReleases = Material.TwoTone.NewReleases; + public const string Newspaper = Material.TwoTone.Newspaper; + public const string NextPlan = Material.TwoTone.NextPlan; + public const string NextWeek = Material.TwoTone.NextWeek; + public const string Nfc = Material.TwoTone.Nfc; + public const string NightShelter = Material.TwoTone.NightShelter; + public const string Nightlife = Material.TwoTone.Nightlife; + public const string Nightlight = Material.TwoTone.Nightlight; + public const string NightlightRound = Material.TwoTone.NightlightRound; + public const string NightsStay = Material.TwoTone.NightsStay; + public const string NoAccounts = Material.TwoTone.NoAccounts; + public const string NoBackpack = Material.TwoTone.NoBackpack; + public const string NoCell = Material.TwoTone.NoCell; + public const string NoCrash = Material.TwoTone.NoCrash; + public const string NoDrinks = Material.TwoTone.NoDrinks; + public const string NoEncryption = Material.TwoTone.NoEncryption; + public const string NoEncryptionGmailerrorred = Material.TwoTone.NoEncryptionGmailerrorred; + public const string NoFlash = Material.TwoTone.NoFlash; + public const string NoFood = Material.TwoTone.NoFood; + public const string NoLuggage = Material.TwoTone.NoLuggage; + public const string NoMeals = Material.TwoTone.NoMeals; + public const string NoMeetingRoom = Material.TwoTone.NoMeetingRoom; + public const string NoPhotography = Material.TwoTone.NoPhotography; + public const string NoSim = Material.TwoTone.NoSim; + public const string NoStroller = Material.TwoTone.NoStroller; + public const string NoTransfer = Material.TwoTone.NoTransfer; + public const string NoiseAware = Material.TwoTone.NoiseAware; + public const string NoiseControlOff = Material.TwoTone.NoiseControlOff; + public const string NordicWalking = Material.TwoTone.NordicWalking; + public const string North = Material.TwoTone.North; + public const string NorthEast = Material.TwoTone.NorthEast; + public const string NorthWest = Material.TwoTone.NorthWest; + public const string NotAccessible = Material.TwoTone.NotAccessible; + public const string NotInterested = Material.TwoTone.NotInterested; + public const string NotListedLocation = Material.TwoTone.NotListedLocation; + public const string NotStarted = Material.TwoTone.NotStarted; + public const string Note = Material.TwoTone.Note; + public const string NoteAdd = Material.TwoTone.NoteAdd; + public const string NoteAlt = Material.TwoTone.NoteAlt; + public const string Notes = Material.TwoTone.Notes; + public const string NotificationAdd = Material.TwoTone.NotificationAdd; + public const string NotificationImportant = Material.TwoTone.NotificationImportant; + public const string Notifications = Material.TwoTone.Notifications; + public const string NotificationsActive = Material.TwoTone.NotificationsActive; + public const string NotificationsNone = Material.TwoTone.NotificationsNone; + public const string NotificationsOff = Material.TwoTone.NotificationsOff; + public const string NotificationsPaused = Material.TwoTone.NotificationsPaused; + public const string Numbers = Material.TwoTone.Numbers; + public const string OfflineBolt = Material.TwoTone.OfflineBolt; + public const string OfflinePin = Material.TwoTone.OfflinePin; + public const string OfflineShare = Material.TwoTone.OfflineShare; + public const string OnDeviceTraining = Material.TwoTone.OnDeviceTraining; + public const string OndemandVideo = Material.TwoTone.OndemandVideo; + public const string OnlinePrediction = Material.TwoTone.OnlinePrediction; + public const string Opacity = Material.TwoTone.Opacity; + public const string OpenInBrowser = Material.TwoTone.OpenInBrowser; + public const string OpenInFull = Material.TwoTone.OpenInFull; + public const string OpenInNew = Material.TwoTone.OpenInNew; + public const string OpenInNewOff = Material.TwoTone.OpenInNewOff; + public const string OpenWith = Material.TwoTone.OpenWith; + public const string OtherHouses = Material.TwoTone.OtherHouses; + public const string Outbound = Material.TwoTone.Outbound; + public const string Outbox = Material.TwoTone.Outbox; + public const string OutdoorGrill = Material.TwoTone.OutdoorGrill; + public const string Outlet = Material.TwoTone.Outlet; + public const string OutlinedFlag = Material.TwoTone.OutlinedFlag; + public const string Output = Material.TwoTone.Output; + public const string Padding = Material.TwoTone.Padding; + public const string Pages = Material.TwoTone.Pages; + public const string Pageview = Material.TwoTone.Pageview; + public const string Paid = Material.TwoTone.Paid; + public const string Palette = Material.TwoTone.Palette; + public const string PanTool = Material.TwoTone.PanTool; + public const string PanToolAlt = Material.TwoTone.PanToolAlt; + public const string Panorama = Material.TwoTone.Panorama; + public const string PanoramaFishEye = Material.TwoTone.PanoramaFishEye; + public const string PanoramaHorizontal = Material.TwoTone.PanoramaHorizontal; + public const string PanoramaHorizontalSelect = Material.TwoTone.PanoramaHorizontalSelect; + public const string PanoramaPhotosphere = Material.TwoTone.PanoramaPhotosphere; + public const string PanoramaPhotosphereSelect = Material.TwoTone.PanoramaPhotosphereSelect; + public const string PanoramaVertical = Material.TwoTone.PanoramaVertical; + public const string PanoramaVerticalSelect = Material.TwoTone.PanoramaVerticalSelect; + public const string PanoramaWideAngle = Material.TwoTone.PanoramaWideAngle; + public const string PanoramaWideAngleSelect = Material.TwoTone.PanoramaWideAngleSelect; + public const string Paragliding = Material.TwoTone.Paragliding; + public const string Park = Material.TwoTone.Park; + public const string PartyMode = Material.TwoTone.PartyMode; + public const string Password = Material.TwoTone.Password; + public const string Pattern = Material.TwoTone.Pattern; + public const string Pause = Material.TwoTone.Pause; + public const string PauseCircle = Material.TwoTone.PauseCircle; + public const string PauseCircleFilled = Material.TwoTone.PauseCircleFilled; + public const string PauseCircleOutline = Material.TwoTone.PauseCircleOutline; + public const string PausePresentation = Material.TwoTone.PausePresentation; + public const string Payment = Material.TwoTone.Payment; + public const string Payments = Material.TwoTone.Payments; + public const string PedalBike = Material.TwoTone.PedalBike; + public const string Pending = Material.TwoTone.Pending; + public const string PendingActions = Material.TwoTone.PendingActions; + public const string Pentagon = Material.TwoTone.Pentagon; + public const string People = Material.TwoTone.People; + public const string PeopleAlt = Material.TwoTone.PeopleAlt; + public const string PeopleOutline = Material.TwoTone.PeopleOutline; + public const string Percent = Material.TwoTone.Percent; + public const string PermCameraMic = Material.TwoTone.PermCameraMic; + public const string PermContactCalendar = Material.TwoTone.PermContactCalendar; + public const string PermDataSetting = Material.TwoTone.PermDataSetting; + public const string PermDeviceInformation = Material.TwoTone.PermDeviceInformation; + public const string PermIdentity = Material.TwoTone.PermIdentity; + public const string PermMedia = Material.TwoTone.PermMedia; + public const string PermPhoneMsg = Material.TwoTone.PermPhoneMsg; + public const string PermScanWifi = Material.TwoTone.PermScanWifi; + public const string Person = Material.TwoTone.Person; + public const string PersonAdd = Material.TwoTone.PersonAdd; + public const string PersonAddAlt = Material.TwoTone.PersonAddAlt; + public const string PersonAddAlt1 = Material.TwoTone.PersonAddAlt1; + public const string PersonAddDisabled = Material.TwoTone.PersonAddDisabled; + public const string PersonOff = Material.TwoTone.PersonOff; + public const string PersonOutline = Material.TwoTone.PersonOutline; + public const string PersonPin = Material.TwoTone.PersonPin; + public const string PersonPinCircle = Material.TwoTone.PersonPinCircle; + public const string PersonRemove = Material.TwoTone.PersonRemove; + public const string PersonRemoveAlt1 = Material.TwoTone.PersonRemoveAlt1; + public const string PersonSearch = Material.TwoTone.PersonSearch; + public const string PersonalInjury = Material.TwoTone.PersonalInjury; + public const string PersonalVideo = Material.TwoTone.PersonalVideo; + public const string PestControl = Material.TwoTone.PestControl; + public const string PestControlRodent = Material.TwoTone.PestControlRodent; + public const string Pets = Material.TwoTone.Pets; + public const string Phishing = Material.TwoTone.Phishing; + public const string Phone = Material.TwoTone.Phone; + public const string PhoneAndroid = Material.TwoTone.PhoneAndroid; + public const string PhoneBluetoothSpeaker = Material.TwoTone.PhoneBluetoothSpeaker; + public const string PhoneCallback = Material.TwoTone.PhoneCallback; + public const string PhoneDisabled = Material.TwoTone.PhoneDisabled; + public const string PhoneEnabled = Material.TwoTone.PhoneEnabled; + public const string PhoneForwarded = Material.TwoTone.PhoneForwarded; + public const string PhoneInTalk = Material.TwoTone.PhoneInTalk; + public const string PhoneIphone = Material.TwoTone.PhoneIphone; + public const string PhoneLocked = Material.TwoTone.PhoneLocked; + public const string PhoneMissed = Material.TwoTone.PhoneMissed; + public const string PhonePaused = Material.TwoTone.PhonePaused; + public const string Phonelink = Material.TwoTone.Phonelink; + public const string PhonelinkErase = Material.TwoTone.PhonelinkErase; + public const string PhonelinkLock = Material.TwoTone.PhonelinkLock; + public const string PhonelinkOff = Material.TwoTone.PhonelinkOff; + public const string PhonelinkRing = Material.TwoTone.PhonelinkRing; + public const string PhonelinkSetup = Material.TwoTone.PhonelinkSetup; + public const string Photo = Material.TwoTone.Photo; + public const string PhotoAlbum = Material.TwoTone.PhotoAlbum; + public const string PhotoCamera = Material.TwoTone.PhotoCamera; + public const string PhotoCameraBack = Material.TwoTone.PhotoCameraBack; + public const string PhotoCameraFront = Material.TwoTone.PhotoCameraFront; + public const string PhotoFilter = Material.TwoTone.PhotoFilter; + public const string PhotoLibrary = Material.TwoTone.PhotoLibrary; + public const string PhotoSizeSelectActual = Material.TwoTone.PhotoSizeSelectActual; + public const string PhotoSizeSelectLarge = Material.TwoTone.PhotoSizeSelectLarge; + public const string PhotoSizeSelectSmall = Material.TwoTone.PhotoSizeSelectSmall; + public const string Php = Material.TwoTone.Php; + public const string Piano = Material.TwoTone.Piano; + public const string PianoOff = Material.TwoTone.PianoOff; + public const string PictureAsPdf = Material.TwoTone.PictureAsPdf; + public const string PictureInPicture = Material.TwoTone.PictureInPicture; + public const string PictureInPictureAlt = Material.TwoTone.PictureInPictureAlt; + public const string PieChart = Material.TwoTone.PieChart; + public const string PieChartOutline = Material.TwoTone.PieChartOutline; + public const string Pin = Material.TwoTone.Pin; + public const string PinDrop = Material.TwoTone.PinDrop; + public const string PinEnd = Material.TwoTone.PinEnd; + public const string PinInvoke = Material.TwoTone.PinInvoke; + public const string Pinch = Material.TwoTone.Pinch; + public const string PivotTableChart = Material.TwoTone.PivotTableChart; + public const string Pix = Material.TwoTone.Pix; + public const string Place = Material.TwoTone.Place; + public const string Plagiarism = Material.TwoTone.Plagiarism; + public const string PlayArrow = Material.TwoTone.PlayArrow; + public const string PlayCircle = Material.TwoTone.PlayCircle; + public const string PlayCircleFilled = Material.TwoTone.PlayCircleFilled; + public const string PlayCircleOutline = Material.TwoTone.PlayCircleOutline; + public const string PlayDisabled = Material.TwoTone.PlayDisabled; + public const string PlayForWork = Material.TwoTone.PlayForWork; + public const string PlayLesson = Material.TwoTone.PlayLesson; + public const string PlaylistAdd = Material.TwoTone.PlaylistAdd; + public const string PlaylistAddCheck = Material.TwoTone.PlaylistAddCheck; + public const string PlaylistAddCheckCircle = Material.TwoTone.PlaylistAddCheckCircle; + public const string PlaylistAddCircle = Material.TwoTone.PlaylistAddCircle; + public const string PlaylistPlay = Material.TwoTone.PlaylistPlay; + public const string PlaylistRemove = Material.TwoTone.PlaylistRemove; + public const string Plumbing = Material.TwoTone.Plumbing; + public const string PlusOne = Material.TwoTone.PlusOne; + public const string Podcasts = Material.TwoTone.Podcasts; + public const string PointOfSale = Material.TwoTone.PointOfSale; + public const string Policy = Material.TwoTone.Policy; + public const string Poll = Material.TwoTone.Poll; + public const string Polyline = Material.TwoTone.Polyline; + public const string Polymer = Material.TwoTone.Polymer; + public const string Pool = Material.TwoTone.Pool; + public const string PortableWifiOff = Material.TwoTone.PortableWifiOff; + public const string Portrait = Material.TwoTone.Portrait; + public const string PostAdd = Material.TwoTone.PostAdd; + public const string Power = Material.TwoTone.Power; + public const string PowerInput = Material.TwoTone.PowerInput; + public const string PowerOff = Material.TwoTone.PowerOff; + public const string PowerSettingsNew = Material.TwoTone.PowerSettingsNew; + public const string PrecisionManufacturing = Material.TwoTone.PrecisionManufacturing; + public const string PregnantWoman = Material.TwoTone.PregnantWoman; + public const string PresentToAll = Material.TwoTone.PresentToAll; + public const string Preview = Material.TwoTone.Preview; + public const string PriceChange = Material.TwoTone.PriceChange; + public const string PriceCheck = Material.TwoTone.PriceCheck; + public const string Print = Material.TwoTone.Print; + public const string PrintDisabled = Material.TwoTone.PrintDisabled; + public const string PriorityHigh = Material.TwoTone.PriorityHigh; + public const string PrivacyTip = Material.TwoTone.PrivacyTip; + public const string PrivateConnectivity = Material.TwoTone.PrivateConnectivity; + public const string ProductionQuantityLimits = Material.TwoTone.ProductionQuantityLimits; + public const string Psychology = Material.TwoTone.Psychology; + public const string Public = Material.TwoTone.Public; + public const string PublicOff = Material.TwoTone.PublicOff; + public const string Publish = Material.TwoTone.Publish; + public const string PublishedWithChanges = Material.TwoTone.PublishedWithChanges; + public const string PunchClock = Material.TwoTone.PunchClock; + public const string PushPin = Material.TwoTone.PushPin; + public const string QrCode = Material.TwoTone.QrCode; + public const string QrCode2 = Material.TwoTone.QrCode2; + public const string QrCodeScanner = Material.TwoTone.QrCodeScanner; + public const string QueryBuilder = Material.TwoTone.QueryBuilder; + public const string QueryStats = Material.TwoTone.QueryStats; + public const string QuestionAnswer = Material.TwoTone.QuestionAnswer; + public const string QuestionMark = Material.TwoTone.QuestionMark; + public const string Queue = Material.TwoTone.Queue; + public const string QueueMusic = Material.TwoTone.QueueMusic; + public const string QueuePlayNext = Material.TwoTone.QueuePlayNext; + public const string Quickreply = Material.TwoTone.Quickreply; + public const string Quiz = Material.TwoTone.Quiz; + public const string RMobiledata = Material.TwoTone.RMobiledata; + public const string Radar = Material.TwoTone.Radar; + public const string Radio = Material.TwoTone.Radio; + public const string RadioButtonChecked = Material.TwoTone.RadioButtonChecked; + public const string RadioButtonUnchecked = Material.TwoTone.RadioButtonUnchecked; + public const string RailwayAlert = Material.TwoTone.RailwayAlert; + public const string RamenDining = Material.TwoTone.RamenDining; + public const string RampLeft = Material.TwoTone.RampLeft; + public const string RampRight = Material.TwoTone.RampRight; + public const string RateReview = Material.TwoTone.RateReview; + public const string RawOff = Material.TwoTone.RawOff; + public const string RawOn = Material.TwoTone.RawOn; + public const string ReadMore = Material.TwoTone.ReadMore; + public const string RealEstateAgent = Material.TwoTone.RealEstateAgent; + public const string Receipt = Material.TwoTone.Receipt; + public const string ReceiptLong = Material.TwoTone.ReceiptLong; + public const string RecentActors = Material.TwoTone.RecentActors; + public const string Recommend = Material.TwoTone.Recommend; + public const string RecordVoiceOver = Material.TwoTone.RecordVoiceOver; + public const string Rectangle = Material.TwoTone.Rectangle; + public const string Recycling = Material.TwoTone.Recycling; + public const string Redeem = Material.TwoTone.Redeem; + public const string Redo = Material.TwoTone.Redo; + public const string ReduceCapacity = Material.TwoTone.ReduceCapacity; + public const string Refresh = Material.TwoTone.Refresh; + public const string RememberMe = Material.TwoTone.RememberMe; + public const string Remove = Material.TwoTone.Remove; + public const string RemoveCircle = Material.TwoTone.RemoveCircle; + public const string RemoveCircleOutline = Material.TwoTone.RemoveCircleOutline; + public const string RemoveDone = Material.TwoTone.RemoveDone; + public const string RemoveFromQueue = Material.TwoTone.RemoveFromQueue; + public const string RemoveModerator = Material.TwoTone.RemoveModerator; + public const string RemoveRedEye = Material.TwoTone.RemoveRedEye; + public const string RemoveRoad = Material.TwoTone.RemoveRoad; + public const string RemoveShoppingCart = Material.TwoTone.RemoveShoppingCart; + public const string Reorder = Material.TwoTone.Reorder; + public const string Repeat = Material.TwoTone.Repeat; + public const string RepeatOn = Material.TwoTone.RepeatOn; + public const string RepeatOne = Material.TwoTone.RepeatOne; + public const string RepeatOneOn = Material.TwoTone.RepeatOneOn; + public const string Replay = Material.TwoTone.Replay; + public const string Replay10 = Material.TwoTone.Replay10; + public const string Replay30 = Material.TwoTone.Replay30; + public const string Replay5 = Material.TwoTone.Replay5; + public const string ReplayCircleFilled = Material.TwoTone.ReplayCircleFilled; + public const string Reply = Material.TwoTone.Reply; + public const string ReplyAll = Material.TwoTone.ReplyAll; + public const string Report = Material.TwoTone.Report; + public const string ReportGmailerrorred = Material.TwoTone.ReportGmailerrorred; + public const string ReportOff = Material.TwoTone.ReportOff; + public const string ReportProblem = Material.TwoTone.ReportProblem; + public const string RequestPage = Material.TwoTone.RequestPage; + public const string RequestQuote = Material.TwoTone.RequestQuote; + public const string ResetTv = Material.TwoTone.ResetTv; + public const string RestartAlt = Material.TwoTone.RestartAlt; + public const string Restaurant = Material.TwoTone.Restaurant; + public const string RestaurantMenu = Material.TwoTone.RestaurantMenu; + public const string Restore = Material.TwoTone.Restore; + public const string RestoreFromTrash = Material.TwoTone.RestoreFromTrash; + public const string RestorePage = Material.TwoTone.RestorePage; + public const string Reviews = Material.TwoTone.Reviews; + public const string RiceBowl = Material.TwoTone.RiceBowl; + public const string RingVolume = Material.TwoTone.RingVolume; + public const string Rocket = Material.TwoTone.Rocket; + public const string RocketLaunch = Material.TwoTone.RocketLaunch; + public const string RollerSkating = Material.TwoTone.RollerSkating; + public const string Roofing = Material.TwoTone.Roofing; + public const string Room = Material.TwoTone.Room; + public const string RoomPreferences = Material.TwoTone.RoomPreferences; + public const string RoomService = Material.TwoTone.RoomService; + public const string Rotate90DegreesCcw = Material.TwoTone.Rotate90DegreesCcw; + public const string Rotate90DegreesCw = Material.TwoTone.Rotate90DegreesCw; + public const string RotateLeft = Material.TwoTone.RotateLeft; + public const string RotateRight = Material.TwoTone.RotateRight; + public const string RoundaboutLeft = Material.TwoTone.RoundaboutLeft; + public const string RoundaboutRight = Material.TwoTone.RoundaboutRight; + public const string RoundedCorner = Material.TwoTone.RoundedCorner; + public const string Route = Material.TwoTone.Route; + public const string Router = Material.TwoTone.Router; + public const string Rowing = Material.TwoTone.Rowing; + public const string RssFeed = Material.TwoTone.RssFeed; + public const string Rsvp = Material.TwoTone.Rsvp; + public const string Rtt = Material.TwoTone.Rtt; + public const string Rule = Material.TwoTone.Rule; + public const string RuleFolder = Material.TwoTone.RuleFolder; + public const string RunCircle = Material.TwoTone.RunCircle; + public const string RunningWithErrors = Material.TwoTone.RunningWithErrors; + public const string RvHookup = Material.TwoTone.RvHookup; + public const string SafetyCheck = Material.TwoTone.SafetyCheck; + public const string SafetyDivider = Material.TwoTone.SafetyDivider; + public const string Sailing = Material.TwoTone.Sailing; + public const string Sanitizer = Material.TwoTone.Sanitizer; + public const string Satellite = Material.TwoTone.Satellite; + public const string SatelliteAlt = Material.TwoTone.SatelliteAlt; + public const string Save = Material.TwoTone.Save; + public const string SaveAlt = Material.TwoTone.SaveAlt; + public const string SaveAs = Material.TwoTone.SaveAs; + public const string SavedSearch = Material.TwoTone.SavedSearch; + public const string Savings = Material.TwoTone.Savings; + public const string Scale = Material.TwoTone.Scale; + public const string Scanner = Material.TwoTone.Scanner; + public const string ScatterPlot = Material.TwoTone.ScatterPlot; + public const string Schedule = Material.TwoTone.Schedule; + public const string ScheduleSend = Material.TwoTone.ScheduleSend; + public const string Schema = Material.TwoTone.Schema; + public const string School = Material.TwoTone.School; + public const string Science = Material.TwoTone.Science; + public const string Score = Material.TwoTone.Score; + public const string Scoreboard = Material.TwoTone.Scoreboard; + public const string ScreenLockLandscape = Material.TwoTone.ScreenLockLandscape; + public const string ScreenLockPortrait = Material.TwoTone.ScreenLockPortrait; + public const string ScreenLockRotation = Material.TwoTone.ScreenLockRotation; + public const string ScreenRotation = Material.TwoTone.ScreenRotation; + public const string ScreenRotationAlt = Material.TwoTone.ScreenRotationAlt; + public const string ScreenSearchDesktop = Material.TwoTone.ScreenSearchDesktop; + public const string ScreenShare = Material.TwoTone.ScreenShare; + public const string Screenshot = Material.TwoTone.Screenshot; + public const string ScubaDiving = Material.TwoTone.ScubaDiving; + public const string Sd = Material.TwoTone.Sd; + public const string SdCard = Material.TwoTone.SdCard; + public const string SdCardAlert = Material.TwoTone.SdCardAlert; + public const string SdStorage = Material.TwoTone.SdStorage; + public const string Search = Material.TwoTone.Search; + public const string SearchOff = Material.TwoTone.SearchOff; + public const string Security = Material.TwoTone.Security; + public const string SecurityUpdate = Material.TwoTone.SecurityUpdate; + public const string SecurityUpdateGood = Material.TwoTone.SecurityUpdateGood; + public const string SecurityUpdateWarning = Material.TwoTone.SecurityUpdateWarning; + public const string Segment = Material.TwoTone.Segment; + public const string SelectAll = Material.TwoTone.SelectAll; + public const string SelfImprovement = Material.TwoTone.SelfImprovement; + public const string Sell = Material.TwoTone.Sell; + public const string Send = Material.TwoTone.Send; + public const string SendAndArchive = Material.TwoTone.SendAndArchive; + public const string SendTimeExtension = Material.TwoTone.SendTimeExtension; + public const string SendToMobile = Material.TwoTone.SendToMobile; + public const string SensorDoor = Material.TwoTone.SensorDoor; + public const string SensorWindow = Material.TwoTone.SensorWindow; + public const string Sensors = Material.TwoTone.Sensors; + public const string SensorsOff = Material.TwoTone.SensorsOff; + public const string SentimentDissatisfied = Material.TwoTone.SentimentDissatisfied; + public const string SentimentNeutral = Material.TwoTone.SentimentNeutral; + public const string SentimentSatisfied = Material.TwoTone.SentimentSatisfied; + public const string SentimentSatisfiedAlt = Material.TwoTone.SentimentSatisfiedAlt; + public const string SentimentVeryDissatisfied = Material.TwoTone.SentimentVeryDissatisfied; + public const string SentimentVerySatisfied = Material.TwoTone.SentimentVerySatisfied; + public const string SetMeal = Material.TwoTone.SetMeal; + public const string Settings = Material.TwoTone.Settings; + public const string SettingsAccessibility = Material.TwoTone.SettingsAccessibility; + public const string SettingsApplications = Material.TwoTone.SettingsApplications; + public const string SettingsBackupRestore = Material.TwoTone.SettingsBackupRestore; + public const string SettingsBluetooth = Material.TwoTone.SettingsBluetooth; + public const string SettingsBrightness = Material.TwoTone.SettingsBrightness; + public const string SettingsCell = Material.TwoTone.SettingsCell; + public const string SettingsEthernet = Material.TwoTone.SettingsEthernet; + public const string SettingsInputAntenna = Material.TwoTone.SettingsInputAntenna; + public const string SettingsInputComponent = Material.TwoTone.SettingsInputComponent; + public const string SettingsInputComposite = Material.TwoTone.SettingsInputComposite; + public const string SettingsInputHdmi = Material.TwoTone.SettingsInputHdmi; + public const string SettingsInputSvideo = Material.TwoTone.SettingsInputSvideo; + public const string SettingsOverscan = Material.TwoTone.SettingsOverscan; + public const string SettingsPhone = Material.TwoTone.SettingsPhone; + public const string SettingsPower = Material.TwoTone.SettingsPower; + public const string SettingsRemote = Material.TwoTone.SettingsRemote; + public const string SettingsSuggest = Material.TwoTone.SettingsSuggest; + public const string SettingsSystemDaydream = Material.TwoTone.SettingsSystemDaydream; + public const string SettingsVoice = Material.TwoTone.SettingsVoice; + public const string SevereCold = Material.TwoTone.SevereCold; + public const string Share = Material.TwoTone.Share; + public const string ShareLocation = Material.TwoTone.ShareLocation; + public const string Shield = Material.TwoTone.Shield; + public const string ShieldMoon = Material.TwoTone.ShieldMoon; + public const string Shop = Material.TwoTone.Shop; + public const string Shop2 = Material.TwoTone.Shop2; + public const string ShopTwo = Material.TwoTone.ShopTwo; + public const string ShoppingBag = Material.TwoTone.ShoppingBag; + public const string ShoppingBasket = Material.TwoTone.ShoppingBasket; + public const string ShoppingCart = Material.TwoTone.ShoppingCart; + public const string ShoppingCartCheckout = Material.TwoTone.ShoppingCartCheckout; + public const string ShortText = Material.TwoTone.ShortText; + public const string Shortcut = Material.TwoTone.Shortcut; + public const string ShowChart = Material.TwoTone.ShowChart; + public const string Shower = Material.TwoTone.Shower; + public const string Shuffle = Material.TwoTone.Shuffle; + public const string ShuffleOn = Material.TwoTone.ShuffleOn; + public const string ShutterSpeed = Material.TwoTone.ShutterSpeed; + public const string Sick = Material.TwoTone.Sick; + public const string SignLanguage = Material.TwoTone.SignLanguage; + public const string SignalCellular0Bar = Material.TwoTone.SignalCellular0Bar; + public const string SignalCellular4Bar = Material.TwoTone.SignalCellular4Bar; + public const string SignalCellularAlt = Material.TwoTone.SignalCellularAlt; + public const string SignalCellularAlt1Bar = Material.TwoTone.SignalCellularAlt1Bar; + public const string SignalCellularAlt2Bar = Material.TwoTone.SignalCellularAlt2Bar; + + public const string SignalCellularConnectedNoInternet0Bar = + Material.TwoTone.SignalCellularConnectedNoInternet0Bar; + + public const string SignalCellularConnectedNoInternet4Bar = + Material.TwoTone.SignalCellularConnectedNoInternet4Bar; + + public const string SignalCellularNoSim = Material.TwoTone.SignalCellularNoSim; + public const string SignalCellularNodata = Material.TwoTone.SignalCellularNodata; + public const string SignalCellularNull = Material.TwoTone.SignalCellularNull; + public const string SignalCellularOff = Material.TwoTone.SignalCellularOff; + public const string SignalWifi0Bar = Material.TwoTone.SignalWifi0Bar; + public const string SignalWifi4Bar = Material.TwoTone.SignalWifi4Bar; + public const string SignalWifi4BarLock = Material.TwoTone.SignalWifi4BarLock; + public const string SignalWifiBad = Material.TwoTone.SignalWifiBad; + public const string SignalWifiConnectedNoInternet4 = Material.TwoTone.SignalWifiConnectedNoInternet4; + public const string SignalWifiOff = Material.TwoTone.SignalWifiOff; + public const string SignalWifiStatusbar4Bar = Material.TwoTone.SignalWifiStatusbar4Bar; + + public const string SignalWifiStatusbarConnectedNoInternet4 = + Material.TwoTone.SignalWifiStatusbarConnectedNoInternet4; + + public const string SignalWifiStatusbarNull = Material.TwoTone.SignalWifiStatusbarNull; + public const string Signpost = Material.TwoTone.Signpost; + public const string SimCard = Material.TwoTone.SimCard; + public const string SimCardAlert = Material.TwoTone.SimCardAlert; + public const string SimCardDownload = Material.TwoTone.SimCardDownload; + public const string SingleBed = Material.TwoTone.SingleBed; + public const string Sip = Material.TwoTone.Sip; + public const string Skateboarding = Material.TwoTone.Skateboarding; + public const string SkipNext = Material.TwoTone.SkipNext; + public const string SkipPrevious = Material.TwoTone.SkipPrevious; + public const string Sledding = Material.TwoTone.Sledding; + public const string Slideshow = Material.TwoTone.Slideshow; + public const string SlowMotionVideo = Material.TwoTone.SlowMotionVideo; + public const string SmartButton = Material.TwoTone.SmartButton; + public const string SmartDisplay = Material.TwoTone.SmartDisplay; + public const string SmartScreen = Material.TwoTone.SmartScreen; + public const string SmartToy = Material.TwoTone.SmartToy; + public const string Smartphone = Material.TwoTone.Smartphone; + public const string SmokeFree = Material.TwoTone.SmokeFree; + public const string SmokingRooms = Material.TwoTone.SmokingRooms; + public const string Sms = Material.TwoTone.Sms; + public const string SmsFailed = Material.TwoTone.SmsFailed; + public const string SnippetFolder = Material.TwoTone.SnippetFolder; + public const string Snooze = Material.TwoTone.Snooze; + public const string Snowboarding = Material.TwoTone.Snowboarding; + public const string Snowmobile = Material.TwoTone.Snowmobile; + public const string Snowshoeing = Material.TwoTone.Snowshoeing; + public const string Soap = Material.TwoTone.Soap; + public const string SocialDistance = Material.TwoTone.SocialDistance; + public const string Sort = Material.TwoTone.Sort; + public const string SortByAlpha = Material.TwoTone.SortByAlpha; + public const string Sos = Material.TwoTone.Sos; + public const string SoupKitchen = Material.TwoTone.SoupKitchen; + public const string Source = Material.TwoTone.Source; + public const string South = Material.TwoTone.South; + public const string SouthAmerica = Material.TwoTone.SouthAmerica; + public const string SouthEast = Material.TwoTone.SouthEast; + public const string SouthWest = Material.TwoTone.SouthWest; + public const string Spa = Material.TwoTone.Spa; + public const string SpaceBar = Material.TwoTone.SpaceBar; + public const string SpaceDashboard = Material.TwoTone.SpaceDashboard; + public const string SpatialAudio = Material.TwoTone.SpatialAudio; + public const string SpatialAudioOff = Material.TwoTone.SpatialAudioOff; + public const string SpatialTracking = Material.TwoTone.SpatialTracking; + public const string Speaker = Material.TwoTone.Speaker; + public const string SpeakerGroup = Material.TwoTone.SpeakerGroup; + public const string SpeakerNotes = Material.TwoTone.SpeakerNotes; + public const string SpeakerNotesOff = Material.TwoTone.SpeakerNotesOff; + public const string SpeakerPhone = Material.TwoTone.SpeakerPhone; + public const string Speed = Material.TwoTone.Speed; + public const string Spellcheck = Material.TwoTone.Spellcheck; + public const string Splitscreen = Material.TwoTone.Splitscreen; + public const string Spoke = Material.TwoTone.Spoke; + public const string Sports = Material.TwoTone.Sports; + public const string SportsBar = Material.TwoTone.SportsBar; + public const string SportsBaseball = Material.TwoTone.SportsBaseball; + public const string SportsBasketball = Material.TwoTone.SportsBasketball; + public const string SportsCricket = Material.TwoTone.SportsCricket; + public const string SportsEsports = Material.TwoTone.SportsEsports; + public const string SportsFootball = Material.TwoTone.SportsFootball; + public const string SportsGolf = Material.TwoTone.SportsGolf; + public const string SportsGymnastics = Material.TwoTone.SportsGymnastics; + public const string SportsHandball = Material.TwoTone.SportsHandball; + public const string SportsHockey = Material.TwoTone.SportsHockey; + public const string SportsKabaddi = Material.TwoTone.SportsKabaddi; + public const string SportsMartialArts = Material.TwoTone.SportsMartialArts; + public const string SportsMma = Material.TwoTone.SportsMma; + public const string SportsMotorsports = Material.TwoTone.SportsMotorsports; + public const string SportsRugby = Material.TwoTone.SportsRugby; + public const string SportsScore = Material.TwoTone.SportsScore; + public const string SportsSoccer = Material.TwoTone.SportsSoccer; + public const string SportsTennis = Material.TwoTone.SportsTennis; + public const string SportsVolleyball = Material.TwoTone.SportsVolleyball; + public const string Square = Material.TwoTone.Square; + public const string SquareFoot = Material.TwoTone.SquareFoot; + public const string SsidChart = Material.TwoTone.SsidChart; + public const string StackedBarChart = Material.TwoTone.StackedBarChart; + public const string StackedLineChart = Material.TwoTone.StackedLineChart; + public const string Stadium = Material.TwoTone.Stadium; + public const string Stairs = Material.TwoTone.Stairs; + public const string Star = Material.TwoTone.Star; + public const string StarBorder = Material.TwoTone.StarBorder; + public const string StarBorderPurple500 = Material.TwoTone.StarBorderPurple500; + public const string StarHalf = Material.TwoTone.StarHalf; + public const string StarOutline = Material.TwoTone.StarOutline; + public const string StarPurple500 = Material.TwoTone.StarPurple500; + public const string StarRate = Material.TwoTone.StarRate; + public const string Stars = Material.TwoTone.Stars; + public const string Start = Material.TwoTone.Start; + public const string StayCurrentLandscape = Material.TwoTone.StayCurrentLandscape; + public const string StayCurrentPortrait = Material.TwoTone.StayCurrentPortrait; + public const string StayPrimaryLandscape = Material.TwoTone.StayPrimaryLandscape; + public const string StayPrimaryPortrait = Material.TwoTone.StayPrimaryPortrait; + public const string StickyNote2 = Material.TwoTone.StickyNote2; + public const string Stop = Material.TwoTone.Stop; + public const string StopCircle = Material.TwoTone.StopCircle; + public const string StopScreenShare = Material.TwoTone.StopScreenShare; + public const string Storage = Material.TwoTone.Storage; + public const string Store = Material.TwoTone.Store; + public const string StoreMallDirectory = Material.TwoTone.StoreMallDirectory; + public const string Storefront = Material.TwoTone.Storefront; + public const string Storm = Material.TwoTone.Storm; + public const string Straight = Material.TwoTone.Straight; + public const string Straighten = Material.TwoTone.Straighten; + public const string Stream = Material.TwoTone.Stream; + public const string Streetview = Material.TwoTone.Streetview; + public const string StrikethroughS = Material.TwoTone.StrikethroughS; + public const string Stroller = Material.TwoTone.Stroller; + public const string Style = Material.TwoTone.Style; + public const string SubdirectoryArrowLeft = Material.TwoTone.SubdirectoryArrowLeft; + public const string SubdirectoryArrowRight = Material.TwoTone.SubdirectoryArrowRight; + public const string Subject = Material.TwoTone.Subject; + public const string Subscript = Material.TwoTone.Subscript; + public const string Subscriptions = Material.TwoTone.Subscriptions; + public const string Subtitles = Material.TwoTone.Subtitles; + public const string SubtitlesOff = Material.TwoTone.SubtitlesOff; + public const string Subway = Material.TwoTone.Subway; + public const string Summarize = Material.TwoTone.Summarize; + public const string Superscript = Material.TwoTone.Superscript; + public const string SupervisedUserCircle = Material.TwoTone.SupervisedUserCircle; + public const string SupervisorAccount = Material.TwoTone.SupervisorAccount; + public const string Support = Material.TwoTone.Support; + public const string SupportAgent = Material.TwoTone.SupportAgent; + public const string Surfing = Material.TwoTone.Surfing; + public const string SurroundSound = Material.TwoTone.SurroundSound; + public const string SwapCalls = Material.TwoTone.SwapCalls; + public const string SwapHoriz = Material.TwoTone.SwapHoriz; + public const string SwapHorizontalCircle = Material.TwoTone.SwapHorizontalCircle; + public const string SwapVert = Material.TwoTone.SwapVert; + public const string SwapVerticalCircle = Material.TwoTone.SwapVerticalCircle; + public const string Swipe = Material.TwoTone.Swipe; + public const string SwipeDown = Material.TwoTone.SwipeDown; + public const string SwipeDownAlt = Material.TwoTone.SwipeDownAlt; + public const string SwipeLeft = Material.TwoTone.SwipeLeft; + public const string SwipeLeftAlt = Material.TwoTone.SwipeLeftAlt; + public const string SwipeRight = Material.TwoTone.SwipeRight; + public const string SwipeRightAlt = Material.TwoTone.SwipeRightAlt; + public const string SwipeUp = Material.TwoTone.SwipeUp; + public const string SwipeUpAlt = Material.TwoTone.SwipeUpAlt; + public const string SwipeVertical = Material.TwoTone.SwipeVertical; + public const string SwitchAccessShortcut = Material.TwoTone.SwitchAccessShortcut; + public const string SwitchAccessShortcutAdd = Material.TwoTone.SwitchAccessShortcutAdd; + public const string SwitchAccount = Material.TwoTone.SwitchAccount; + public const string SwitchCamera = Material.TwoTone.SwitchCamera; + public const string SwitchLeft = Material.TwoTone.SwitchLeft; + public const string SwitchRight = Material.TwoTone.SwitchRight; + public const string SwitchVideo = Material.TwoTone.SwitchVideo; + public const string Synagogue = Material.TwoTone.Synagogue; + public const string Sync = Material.TwoTone.Sync; + public const string SyncAlt = Material.TwoTone.SyncAlt; + public const string SyncDisabled = Material.TwoTone.SyncDisabled; + public const string SyncLock = Material.TwoTone.SyncLock; + public const string SyncProblem = Material.TwoTone.SyncProblem; + public const string SystemSecurityUpdate = Material.TwoTone.SystemSecurityUpdate; + public const string SystemSecurityUpdateGood = Material.TwoTone.SystemSecurityUpdateGood; + public const string SystemSecurityUpdateWarning = Material.TwoTone.SystemSecurityUpdateWarning; + public const string SystemUpdate = Material.TwoTone.SystemUpdate; + public const string SystemUpdateAlt = Material.TwoTone.SystemUpdateAlt; + public const string Tab = Material.TwoTone.Tab; + public const string TabUnselected = Material.TwoTone.TabUnselected; + public const string TableBar = Material.TwoTone.TableBar; + public const string TableChart = Material.TwoTone.TableChart; + public const string TableRestaurant = Material.TwoTone.TableRestaurant; + public const string TableRows = Material.TwoTone.TableRows; + public const string TableView = Material.TwoTone.TableView; + public const string Tablet = Material.TwoTone.Tablet; + public const string TabletAndroid = Material.TwoTone.TabletAndroid; + public const string TabletMac = Material.TwoTone.TabletMac; + public const string Tag = Material.TwoTone.Tag; + public const string TagFaces = Material.TwoTone.TagFaces; + public const string TakeoutDining = Material.TwoTone.TakeoutDining; + public const string TapAndPlay = Material.TwoTone.TapAndPlay; + public const string Tapas = Material.TwoTone.Tapas; + public const string Task = Material.TwoTone.Task; + public const string TaskAlt = Material.TwoTone.TaskAlt; + public const string TaxiAlert = Material.TwoTone.TaxiAlert; + public const string TempleBuddhist = Material.TwoTone.TempleBuddhist; + public const string TempleHindu = Material.TwoTone.TempleHindu; + public const string Terminal = Material.TwoTone.Terminal; + public const string Terrain = Material.TwoTone.Terrain; + public const string TextDecrease = Material.TwoTone.TextDecrease; + public const string TextFields = Material.TwoTone.TextFields; + public const string TextFormat = Material.TwoTone.TextFormat; + public const string TextIncrease = Material.TwoTone.TextIncrease; + public const string TextRotateUp = Material.TwoTone.TextRotateUp; + public const string TextRotateVertical = Material.TwoTone.TextRotateVertical; + public const string TextRotationAngledown = Material.TwoTone.TextRotationAngledown; + public const string TextRotationAngleup = Material.TwoTone.TextRotationAngleup; + public const string TextRotationDown = Material.TwoTone.TextRotationDown; + public const string TextRotationNone = Material.TwoTone.TextRotationNone; + public const string TextSnippet = Material.TwoTone.TextSnippet; + public const string Textsms = Material.TwoTone.Textsms; + public const string Texture = Material.TwoTone.Texture; + public const string TheaterComedy = Material.TwoTone.TheaterComedy; + public const string Theaters = Material.TwoTone.Theaters; + public const string Thermostat = Material.TwoTone.Thermostat; + public const string ThermostatAuto = Material.TwoTone.ThermostatAuto; + public const string ThumbDown = Material.TwoTone.ThumbDown; + public const string ThumbDownAlt = Material.TwoTone.ThumbDownAlt; + public const string ThumbDownOffAlt = Material.TwoTone.ThumbDownOffAlt; + public const string ThumbUp = Material.TwoTone.ThumbUp; + public const string ThumbUpAlt = Material.TwoTone.ThumbUpAlt; + public const string ThumbUpOffAlt = Material.TwoTone.ThumbUpOffAlt; + public const string ThumbsUpDown = Material.TwoTone.ThumbsUpDown; + public const string Thunderstorm = Material.TwoTone.Thunderstorm; + public const string TimeToLeave = Material.TwoTone.TimeToLeave; + public const string Timelapse = Material.TwoTone.Timelapse; + public const string Timeline = Material.TwoTone.Timeline; + public const string Timer = Material.TwoTone.Timer; + public const string Timer10 = Material.TwoTone.Timer10; + public const string Timer10Select = Material.TwoTone.Timer10Select; + public const string Timer3 = Material.TwoTone.Timer3; + public const string Timer3Select = Material.TwoTone.Timer3Select; + public const string TimerOff = Material.TwoTone.TimerOff; + public const string TipsAndUpdates = Material.TwoTone.TipsAndUpdates; + public const string TireRepair = Material.TwoTone.TireRepair; + public const string Title = Material.TwoTone.Title; + public const string Toc = Material.TwoTone.Toc; + public const string Today = Material.TwoTone.Today; + public const string ToggleOff = Material.TwoTone.ToggleOff; + public const string ToggleOn = Material.TwoTone.ToggleOn; + public const string Token = Material.TwoTone.Token; + public const string Toll = Material.TwoTone.Toll; + public const string Tonality = Material.TwoTone.Tonality; + public const string Topic = Material.TwoTone.Topic; + public const string TouchApp = Material.TwoTone.TouchApp; + public const string Tour = Material.TwoTone.Tour; + public const string Toys = Material.TwoTone.Toys; + public const string TrackChanges = Material.TwoTone.TrackChanges; + public const string Traffic = Material.TwoTone.Traffic; + public const string Train = Material.TwoTone.Train; + public const string Tram = Material.TwoTone.Tram; + public const string TransferWithinAStation = Material.TwoTone.TransferWithinAStation; + public const string Transform = Material.TwoTone.Transform; + public const string Transgender = Material.TwoTone.Transgender; + public const string TransitEnterexit = Material.TwoTone.TransitEnterexit; + public const string Translate = Material.TwoTone.Translate; + public const string TravelExplore = Material.TwoTone.TravelExplore; + public const string TrendingDown = Material.TwoTone.TrendingDown; + public const string TrendingFlat = Material.TwoTone.TrendingFlat; + public const string TrendingUp = Material.TwoTone.TrendingUp; + public const string TripOrigin = Material.TwoTone.TripOrigin; + public const string Try = Material.TwoTone.Try; + public const string Tsunami = Material.TwoTone.Tsunami; + public const string Tty = Material.TwoTone.Tty; + public const string Tune = Material.TwoTone.Tune; + public const string Tungsten = Material.TwoTone.Tungsten; + public const string TurnLeft = Material.TwoTone.TurnLeft; + public const string TurnRight = Material.TwoTone.TurnRight; + public const string TurnSharpLeft = Material.TwoTone.TurnSharpLeft; + public const string TurnSharpRight = Material.TwoTone.TurnSharpRight; + public const string TurnSlightLeft = Material.TwoTone.TurnSlightLeft; + public const string TurnSlightRight = Material.TwoTone.TurnSlightRight; + public const string TurnedIn = Material.TwoTone.TurnedIn; + public const string TurnedInNot = Material.TwoTone.TurnedInNot; + public const string Tv = Material.TwoTone.Tv; + public const string TvOff = Material.TwoTone.TvOff; + public const string TwoWheeler = Material.TwoTone.TwoWheeler; + public const string UTurnLeft = Material.TwoTone.UTurnLeft; + public const string UTurnRight = Material.TwoTone.UTurnRight; + public const string Umbrella = Material.TwoTone.Umbrella; + public const string Unarchive = Material.TwoTone.Unarchive; + public const string Undo = Material.TwoTone.Undo; + public const string UnfoldLess = Material.TwoTone.UnfoldLess; + public const string UnfoldMore = Material.TwoTone.UnfoldMore; + public const string Unpublished = Material.TwoTone.Unpublished; + public const string Unsubscribe = Material.TwoTone.Unsubscribe; + public const string Upcoming = Material.TwoTone.Upcoming; + public const string Update = Material.TwoTone.Update; + public const string UpdateDisabled = Material.TwoTone.UpdateDisabled; + public const string Upgrade = Material.TwoTone.Upgrade; + public const string Upload = Material.TwoTone.Upload; + public const string UploadFile = Material.TwoTone.UploadFile; + public const string Usb = Material.TwoTone.Usb; + public const string UsbOff = Material.TwoTone.UsbOff; + public const string Vaccines = Material.TwoTone.Vaccines; + public const string VapeFree = Material.TwoTone.VapeFree; + public const string VapingRooms = Material.TwoTone.VapingRooms; + public const string Verified = Material.TwoTone.Verified; + public const string VerifiedUser = Material.TwoTone.VerifiedUser; + public const string VerticalAlignBottom = Material.TwoTone.VerticalAlignBottom; + public const string VerticalAlignCenter = Material.TwoTone.VerticalAlignCenter; + public const string VerticalAlignTop = Material.TwoTone.VerticalAlignTop; + public const string VerticalDistribute = Material.TwoTone.VerticalDistribute; + public const string VerticalSplit = Material.TwoTone.VerticalSplit; + public const string Vibration = Material.TwoTone.Vibration; + public const string VideoCall = Material.TwoTone.VideoCall; + public const string VideoCameraBack = Material.TwoTone.VideoCameraBack; + public const string VideoCameraFront = Material.TwoTone.VideoCameraFront; + public const string VideoFile = Material.TwoTone.VideoFile; + public const string VideoLabel = Material.TwoTone.VideoLabel; + public const string VideoLibrary = Material.TwoTone.VideoLibrary; + public const string VideoSettings = Material.TwoTone.VideoSettings; + public const string VideoStable = Material.TwoTone.VideoStable; + public const string Videocam = Material.TwoTone.Videocam; + public const string VideocamOff = Material.TwoTone.VideocamOff; + public const string VideogameAsset = Material.TwoTone.VideogameAsset; + public const string VideogameAssetOff = Material.TwoTone.VideogameAssetOff; + public const string ViewAgenda = Material.TwoTone.ViewAgenda; + public const string ViewArray = Material.TwoTone.ViewArray; + public const string ViewCarousel = Material.TwoTone.ViewCarousel; + public const string ViewColumn = Material.TwoTone.ViewColumn; + public const string ViewComfy = Material.TwoTone.ViewComfy; + public const string ViewComfyAlt = Material.TwoTone.ViewComfyAlt; + public const string ViewCompact = Material.TwoTone.ViewCompact; + public const string ViewCompactAlt = Material.TwoTone.ViewCompactAlt; + public const string ViewCozy = Material.TwoTone.ViewCozy; + public const string ViewDay = Material.TwoTone.ViewDay; + public const string ViewHeadline = Material.TwoTone.ViewHeadline; + public const string ViewInAr = Material.TwoTone.ViewInAr; + public const string ViewKanban = Material.TwoTone.ViewKanban; + public const string ViewList = Material.TwoTone.ViewList; + public const string ViewModule = Material.TwoTone.ViewModule; + public const string ViewQuilt = Material.TwoTone.ViewQuilt; + public const string ViewSidebar = Material.TwoTone.ViewSidebar; + public const string ViewStream = Material.TwoTone.ViewStream; + public const string ViewTimeline = Material.TwoTone.ViewTimeline; + public const string ViewWeek = Material.TwoTone.ViewWeek; + public const string Vignette = Material.TwoTone.Vignette; + public const string Villa = Material.TwoTone.Villa; + public const string Visibility = Material.TwoTone.Visibility; + public const string VisibilityOff = Material.TwoTone.VisibilityOff; + public const string VoiceChat = Material.TwoTone.VoiceChat; + public const string VoiceOverOff = Material.TwoTone.VoiceOverOff; + public const string Voicemail = Material.TwoTone.Voicemail; + public const string Volcano = Material.TwoTone.Volcano; + public const string VolumeDown = Material.TwoTone.VolumeDown; + public const string VolumeMute = Material.TwoTone.VolumeMute; + public const string VolumeOff = Material.TwoTone.VolumeOff; + public const string VolumeUp = Material.TwoTone.VolumeUp; + public const string VolunteerActivism = Material.TwoTone.VolunteerActivism; + public const string VpnKey = Material.TwoTone.VpnKey; + public const string VpnKeyOff = Material.TwoTone.VpnKeyOff; + public const string VpnLock = Material.TwoTone.VpnLock; + public const string Vrpano = Material.TwoTone.Vrpano; + public const string Wallpaper = Material.TwoTone.Wallpaper; + public const string Warehouse = Material.TwoTone.Warehouse; + public const string Warning = Material.TwoTone.Warning; + public const string WarningAmber = Material.TwoTone.WarningAmber; + public const string Wash = Material.TwoTone.Wash; + public const string Watch = Material.TwoTone.Watch; + public const string WatchLater = Material.TwoTone.WatchLater; + public const string WatchOff = Material.TwoTone.WatchOff; + public const string Water = Material.TwoTone.Water; + public const string WaterDamage = Material.TwoTone.WaterDamage; + public const string WaterDrop = Material.TwoTone.WaterDrop; + public const string WaterfallChart = Material.TwoTone.WaterfallChart; + public const string Waves = Material.TwoTone.Waves; + public const string WavingHand = Material.TwoTone.WavingHand; + public const string WbAuto = Material.TwoTone.WbAuto; + public const string WbCloudy = Material.TwoTone.WbCloudy; + public const string WbIncandescent = Material.TwoTone.WbIncandescent; + public const string WbIridescent = Material.TwoTone.WbIridescent; + public const string WbShade = Material.TwoTone.WbShade; + public const string WbSunny = Material.TwoTone.WbSunny; + public const string WbTwilight = Material.TwoTone.WbTwilight; + public const string Wc = Material.TwoTone.Wc; + public const string Web = Material.TwoTone.Web; + public const string WebAsset = Material.TwoTone.WebAsset; + public const string WebAssetOff = Material.TwoTone.WebAssetOff; + public const string Webhook = Material.TwoTone.Webhook; + public const string Weekend = Material.TwoTone.Weekend; + public const string West = Material.TwoTone.West; + public const string Whatsapp = Material.TwoTone.Whatsapp; + public const string Whatshot = Material.TwoTone.Whatshot; + public const string WheelchairPickup = Material.TwoTone.WheelchairPickup; + public const string WhereToVote = Material.TwoTone.WhereToVote; + public const string Widgets = Material.TwoTone.Widgets; + public const string Wifi = Material.TwoTone.Wifi; + public const string Wifi1Bar = Material.TwoTone.Wifi1Bar; + public const string Wifi2Bar = Material.TwoTone.Wifi2Bar; + public const string WifiCalling = Material.TwoTone.WifiCalling; + public const string WifiCalling3 = Material.TwoTone.WifiCalling3; + public const string WifiChannel = Material.TwoTone.WifiChannel; + public const string WifiFind = Material.TwoTone.WifiFind; + public const string WifiLock = Material.TwoTone.WifiLock; + public const string WifiOff = Material.TwoTone.WifiOff; + public const string WifiPassword = Material.TwoTone.WifiPassword; + public const string WifiProtectedSetup = Material.TwoTone.WifiProtectedSetup; + public const string WifiTethering = Material.TwoTone.WifiTethering; + public const string WifiTetheringError = Material.TwoTone.WifiTetheringError; + public const string WifiTetheringOff = Material.TwoTone.WifiTetheringOff; + public const string Window = Material.TwoTone.Window; + public const string WineBar = Material.TwoTone.WineBar; + public const string Woman = Material.TwoTone.Woman; + public const string Work = Material.TwoTone.Work; + public const string WorkOff = Material.TwoTone.WorkOff; + public const string WorkOutline = Material.TwoTone.WorkOutline; + public const string WorkspacePremium = Material.TwoTone.WorkspacePremium; + public const string Workspaces = Material.TwoTone.Workspaces; + public const string WrapText = Material.TwoTone.WrapText; + public const string WrongLocation = Material.TwoTone.WrongLocation; + public const string Wysiwyg = Material.TwoTone.Wysiwyg; + public const string Yard = Material.TwoTone.Yard; + public const string YoutubeSearchedFor = Material.TwoTone.YoutubeSearchedFor; + public const string ZoomIn = Material.TwoTone.ZoomIn; + public const string ZoomInMap = Material.TwoTone.ZoomInMap; + public const string ZoomOut = Material.TwoTone.ZoomOut; + public const string ZoomOutMap = Material.TwoTone.ZoomOutMap; + } + } +} diff --git a/Icons/Obsolete/_Obsolete.cs b/Icons/Obsolete/_Obsolete.cs new file mode 100644 index 0000000..9fda7a0 --- /dev/null +++ b/Icons/Obsolete/_Obsolete.cs @@ -0,0 +1,196 @@ +using System; + +namespace Connected +{ + // These icons have been removed from the Google Material Design Icons set either + // due to typo corrections, improved consistency in naming or simply because they + // have been retired. They may be removed in a future version of MudBlazor so + // it is strongly recommended to remove or update any references to them. + public partial class Icons + { + public partial class Filled + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string BlockFlipped = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string OutgoingMail = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string HomeFilled = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string AssistantNavigation = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string LocationPin = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Workspaces` icon.", true)] + public string WorkspacesFilled => Workspaces; + + [Obsolete("Removed from Material Design Icons. Replace with `FilterAlt` icon.", true)] + public string FilterListAlt => FilterAlt; + + [Obsolete("Removed from Material Design Icons. Replace with `AddIcCall` icon.", true)] + public string AddCall => AddIcCall; + + [Obsolete("Removed from Material Design Icons. Replace with `WbTwilight` icon.", true)] + public string WbTwighlight => WbTwilight; + + [Obsolete("Removed from Material Design Icons. Replace with `PieChartOutline` icon.", true)] + public string PieChartOutlined => PieChartOutline; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Workspaces` icon.", true)] + public string WorkspacesOutline => Outlined.Workspaces; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.DriveFileMove` icon.", true)] + public string DriveFileMoveOutline => Outlined.DriveFileMove; + + [Obsolete("Removed from Material Design Icons. Replace with `NoMeals` icon.", true)] + public string NoMealsOuline => NoMeals; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Filled.Flag` icon.", false)] + public string EmojiFlags => Filled.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Filled.Lock` icon.", false)] + public string LockOutline => Filled.Lock; + } + + public partial class Outlined + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Flag` icon.", false)] + public string EmojiFlags => Outlined.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + + public partial class Rounded + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Rounded.Flag` icon.", false)] + public string EmojiFlags => Rounded.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + + public partial class Sharp + { + [Obsolete("Removed from Material Design Icons.", true)] + public const string AmpStories = + ""; + + [Obsolete("Removed from Material Design Icons.", true)] + public const string Eco = + ""; + + [Obsolete("Removed from Material Design Icons. Replace with `Face` icon.", true)] + public string FaceUnlock => Face; + + [Obsolete("Removed from Material Design Icons. Replace with `Outbound` icon.", true)] + public string Outbond => Outbound; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lock` icon.", true)] + public string LockOutlined => Outlined.Lock; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Info` icon.", true)] + public string InfoOutlined => Outlined.Info; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Label` icon.", true)] + public string LabelOutline => Outlined.Label; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.LabelImportant` icon.", true)] + public string LabelImportantOutline => Outlined.LabelImportant; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Outlined.Lightbulb` icon.", true)] + public string LightbulbOutline => Outlined.Lightbulb; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Sharp.Flag` icon.", false)] + public string EmojiFlags => Sharp.Flag; + + [Obsolete("Removed from Material Design Icons. Replace with `Icons.Custom.Brands.Facebook` icon.", false)] + public string Facebook => Custom.Brands.Facebook; + } + } +} diff --git a/Instance.cs b/Instance.cs new file mode 100644 index 0000000..19a273b --- /dev/null +++ b/Instance.cs @@ -0,0 +1,63 @@ +using Connected.Middleware; +using Connected.Startup; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; + +namespace Connected; + +public static class Instance +{ + public static WebAssemblyHost Host { get; private set; } = default!; + private static IServiceProvider ServiceProvider { get; set; } = default!; + + internal static T? GetService() + { + return ServiceProvider.GetService(); + } + public static async Task Start(List startups, Dictionary args) where TApp : IComponent + { + var builder = WebAssemblyHostBuilder.CreateDefault(UnpackArguments(args)); + + builder.RootComponents.Add("#app"); + builder.RootComponents.Add("head::after"); + + builder.Services.AddHttpClient(); + + builder.Services.AddSingleton(typeof(IComponentMiddlewareService), typeof(ComponentMiddlewareService)); + builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + + foreach (var startup in startups) + await startup.ConfigureServices(builder.Services); + + Host = builder.Build(); + + foreach (var startup in startups) + await startup.Configure(Host); + + await Host.RunAsync(); + } + + private static string[] UnpackArguments(Dictionary args) + { + var result = new string[args.Count]; + + for (var i = 0; i < args.Count; i++) + { + var arg = args.ElementAt(i); + + result[i] = string.IsNullOrWhiteSpace(arg.Value) ? arg.Key : $"{arg.Key}={arg.Value}"; + } + + return result; + } + + public static void UseMiddlewareComponent(this WebAssemblyHost app) + { + if (app.Services.GetService() is not IComponentMiddlewareService service) + throw new NullReferenceException(nameof(IComponentMiddlewareService)); + + service.Add(); + } +} diff --git a/Interop/BoundingClientRect.cs b/Interop/BoundingClientRect.cs new file mode 100644 index 0000000..4cd74aa --- /dev/null +++ b/Interop/BoundingClientRect.cs @@ -0,0 +1,84 @@ +namespace Connected.Interop +{ + public class BoundingClientRect + { + public double Top { get; set; } + public double Left { get; set; } + + public double Width { get; set; } + public double Height { get; set; } + + /// + /// height of the viewport + /// + public double WindowHeight { get; set; } + + /// + /// width of the viewport + /// + public double WindowWidth { get; set; } + + /// + /// the horizontal offset since the left of the page + /// + public double ScrollX { get; set; } + + /// + /// the vertical offset since the top of the page + /// + public double ScrollY { get; set; } + + // computed properties, read only + public double X => Left; + public double Y => Top; + public double Bottom => Top + Height; + public double Right => Left + Width; + + public double AbsoluteLeft => Left + ScrollX; + + public double AbsoluteTop => Top + ScrollY; + + public double AbsoluteRight => Right + ScrollX; + + public double AbsoluteBottom => Bottom + ScrollY; + + //check if the rect is outside of the viewport + public bool IsOutsideBottom => Bottom > WindowHeight; + + public bool IsOutsideLeft => Left < 0; + + public bool IsOutsideTop => Top < 0; + + public bool IsOutsideRight => Right > WindowWidth; + + public BoundingClientRect Clone() + { + return new BoundingClientRect + { + Left = Left, + Top = Top, + Width = Width, + Height = Height, + WindowHeight = WindowHeight, + WindowWidth = WindowWidth, + ScrollX = ScrollX, + ScrollY = ScrollY + }; + } + } + public static class BoundingClientRectExtensions + { + public static bool IsEqualTo(this BoundingClientRect sourceRect, BoundingClientRect targetRect) + { + if (sourceRect is null || targetRect is null) return false; + return sourceRect.Top == targetRect.Top + && sourceRect.Left == targetRect.Left + && sourceRect.Width == targetRect.Width + && sourceRect.Height == targetRect.Height + && sourceRect.WindowHeight == targetRect.WindowHeight + && sourceRect.WindowWidth == targetRect.WindowWidth + && sourceRect.ScrollX == targetRect.ScrollX + && sourceRect.ScrollY == targetRect.ScrollY; + } + } +} diff --git a/Interop/EventHandlers.cs b/Interop/EventHandlers.cs new file mode 100644 index 0000000..6d7ac4f --- /dev/null +++ b/Interop/EventHandlers.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected +{ + // used in MudCollapse + [EventHandler("onanimationend", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: false)] +#if !NET7_0_OR_GREATER + [EventHandler("onmouseenter", typeof(MouseEventArgs), enableStopPropagation: true, enablePreventDefault: true)] + [EventHandler("onmouseleave", typeof(MouseEventArgs), enableStopPropagation: true, enablePreventDefault: true)] +#endif + public static class EventHandlers + { + + } + +} diff --git a/Layouts/DefaultLayout.razor b/Layouts/DefaultLayout.razor new file mode 100644 index 0000000..2fce8ce --- /dev/null +++ b/Layouts/DefaultLayout.razor @@ -0,0 +1,9 @@ +@inherits LayoutComponentBase + + + + + + + +@Body \ No newline at end of file diff --git a/Middleware/ComponentMiddlewareService.cs b/Middleware/ComponentMiddlewareService.cs new file mode 100644 index 0000000..902d30a --- /dev/null +++ b/Middleware/ComponentMiddlewareService.cs @@ -0,0 +1,42 @@ +using System.Collections.Concurrent; + +namespace Connected.Middleware; + +internal class ComponentMiddlewareService : IComponentMiddlewareService +{ + public ComponentMiddlewareService() + { + Middleware = new(); + } + + private ConcurrentDictionary> Middleware { get; } + + public void Add() + { + var componentName = typeof(TComponent).FullName; + + if (string.IsNullOrEmpty(componentName)) + throw new ArgumentException(null, nameof(TMiddleware)); + + if (Middleware.TryGetValue(componentName, out List? items)) + { + //TODO: sort by priority so multiple inheritance would work + items.Add(typeof(TMiddleware)); + } + else + Middleware.TryAdd(componentName, new List { typeof(TMiddleware) }); + } + + public Type? Select() + { + var typeName = typeof(TComponent).FullName; + + if (string.IsNullOrEmpty(typeName)) + throw new ArgumentException(null, nameof(TComponent)); + + if (Middleware.TryGetValue(typeName, out List? items) && items is not null && items.Any()) + return items[0]; + + return null; + } +} diff --git a/Middleware/IComponentMiddlewareService.cs b/Middleware/IComponentMiddlewareService.cs new file mode 100644 index 0000000..4b347b3 --- /dev/null +++ b/Middleware/IComponentMiddlewareService.cs @@ -0,0 +1,8 @@ +namespace Connected.Middleware; + +public interface IComponentMiddlewareService +{ + void Add(); + + Type? Select(); +} diff --git a/Routes.cs b/Routes.cs new file mode 100644 index 0000000..65ca957 --- /dev/null +++ b/Routes.cs @@ -0,0 +1,6 @@ +namespace Connected; + +public static class UIRoutes +{ + public const string Management = "management"; +} diff --git a/Services/BrowserWindowSizeProvider.cs b/Services/BrowserWindowSizeProvider.cs new file mode 100644 index 0000000..1662261 --- /dev/null +++ b/Services/BrowserWindowSizeProvider.cs @@ -0,0 +1,33 @@ +using Connected.Services; +using Microsoft.JSInterop; + +namespace Connected; + +public interface IBrowserWindowSizeProvider +{ + ValueTask GetBrowserWindowSize(); +} + +/// +/// This provider calls the JS method resizeListener.getBrowserWindowSize to get the browser window size +/// +public class BrowserWindowSizeProvider : IBrowserWindowSizeProvider +{ + private readonly IJSRuntime _jsRuntime; + + /// + /// + /// + /// + public BrowserWindowSizeProvider(IJSRuntime jsRuntime) + { + this._jsRuntime = jsRuntime; + } + + /// + /// Get the current BrowserWindowSize, this includes the Height and Width of the document. + /// + /// + public ValueTask GetBrowserWindowSize() => +_jsRuntime.InvokeAsync($"mudResizeListener.getBrowserWindowSize"); +} diff --git a/Services/DialogResult.cs b/Services/DialogResult.cs new file mode 100644 index 0000000..5065328 --- /dev/null +++ b/Services/DialogResult.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2020 Jonny Larsson +// License: MIT +// See https://github.com/MudBlazor/MudBlazor +// Modified version of Blazored Modal +// Copyright (c) 2019 Blazored +// License: MIT +// See https://github.com/Blazored + +using System; + +namespace Connected +{ + public class DialogResult + { + public object Data { get; } + public Type DataType { get; } + public bool Cancelled { get; } + + protected internal DialogResult(object data, Type resultType, bool cancelled) + { + Data = data; + DataType = resultType; + Cancelled = cancelled; + } + + public static DialogResult Ok(T result) => Ok(result, default); + + public static DialogResult Ok(T result, Type dialogType) => new(result, dialogType, false); + + public static DialogResult Cancel() => new(default, typeof(object), true); + } +} diff --git a/Services/DialogService.cs b/Services/DialogService.cs new file mode 100644 index 0000000..8f6f06d --- /dev/null +++ b/Services/DialogService.cs @@ -0,0 +1,258 @@ +// Copyright (c) 2019 Blazored (https://github.com/Blazored) +// Copyright (c) 2020 Jonny Larsson (https://github.com/MudBlazor/MudBlazor) +// Copyright (c) 2021 improvements by Meinrad Recheis +// See https://github.com/Blazored +// License: MIT + +using System.Diagnostics.CodeAnalysis; +using Connected.Components; +using Microsoft.AspNetCore.Components; + +namespace Connected +{ + public class DialogService : IDialogService + { + /// + /// This internal wrapper components prevents overwriting parameters of once + /// instanciated dialog instances + /// + private class DialogHelperComponent : IComponent + { + const string ChildContent = nameof(ChildContent); + RenderFragment _renderFragment; + RenderHandle _renderHandle; + void IComponent.Attach(RenderHandle renderHandle) => _renderHandle = renderHandle; + Task IComponent.SetParametersAsync(ParameterView parameters) + { + if (_renderFragment == null) + { + if (parameters.TryGetValue(ChildContent, out _renderFragment)) + { + _renderHandle.Render(_renderFragment); + } + } + return Task.CompletedTask; + } + public static RenderFragment Wrap(RenderFragment renderFragment) + => new RenderFragment(builder => + { + builder.OpenComponent(1); + builder.AddAttribute(2, ChildContent, renderFragment); + builder.CloseComponent(); + }); + } + + public event Action OnDialogInstanceAdded; + public event Action OnDialogCloseRequested; + + public IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() where T : ComponentBase + { + return Show(string.Empty, new DialogParameters(), new DialogOptions()); + } + + public IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title) where T : ComponentBase + { + return Show(title, new DialogParameters(), new DialogOptions()); + } + + public IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogOptions options) where T : ComponentBase + { + return Show(title, new DialogParameters(), options); + } + + public IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogParameters parameters) where T : ComponentBase + { + return Show(title, parameters, new DialogOptions()); + } + + public IDialogReference Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogParameters parameters, DialogOptions options) where T : ComponentBase + { + return Show(typeof(T), title, parameters, options); + } + + public IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent) + { + return Show(contentComponent, string.Empty, new DialogParameters(), new DialogOptions()); + } + + public IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title) + { + return Show(contentComponent, title, new DialogParameters(), new DialogOptions()); + } + + public IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogOptions options) + { + return Show(contentComponent, title, new DialogParameters(), options); + } + + public IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogParameters parameters) + { + return Show(contentComponent, title, parameters, new DialogOptions()); + } + + public IDialogReference Show([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogParameters parameters, DialogOptions options) + { + if (!typeof(ComponentBase).IsAssignableFrom(contentComponent)) + { + throw new ArgumentException($"{contentComponent?.FullName} must be a Blazor Component"); + } + var dialogReference = CreateReference(); + + var dialogContent = DialogHelperComponent.Wrap(new RenderFragment(builder => + { + var i = 0; + builder.OpenComponent(i++, contentComponent); + foreach (var parameter in parameters) + { + builder.AddAttribute(i++, parameter.Key, parameter.Value); + } + builder.AddComponentReferenceCapture(i++, inst => { dialogReference.InjectDialog(inst); }); + builder.CloseComponent(); + })); + var dialogInstance = new RenderFragment(builder => + { + builder.OpenComponent(0); + builder.SetKey(dialogReference.Id); + builder.AddAttribute(1, "Options", options); + builder.AddAttribute(2, "Title", title); + builder.AddAttribute(3, "Content", dialogContent); + builder.AddAttribute(4, "Id", dialogReference.Id); + builder.CloseComponent(); + }); + dialogReference.InjectRenderFragment(dialogInstance); + OnDialogInstanceAdded?.Invoke(dialogReference); + + return dialogReference; + } + + public Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() where T : ComponentBase + { + return ShowAsync(string.Empty, new DialogParameters(), new DialogOptions()); + } + + public Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title) where T : ComponentBase + { + return ShowAsync(title, new DialogParameters(), new DialogOptions()); + } + + public Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogOptions options) where T : ComponentBase + { + return ShowAsync(title, new DialogParameters(), options); + } + + public Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogParameters parameters) where T : ComponentBase + { + return ShowAsync(title, parameters, new DialogOptions()); + } + + public Task ShowAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string title, DialogParameters parameters, DialogOptions options) where T : ComponentBase + { + return ShowAsync(typeof(T), title, parameters, options); + } + + public Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent) + { + return ShowAsync(contentComponent, string.Empty, new DialogParameters(), new DialogOptions()); + } + + public Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title) + { + return ShowAsync(contentComponent, title, new DialogParameters(), new DialogOptions()); + } + + public Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogOptions options) + { + return ShowAsync(contentComponent, title, new DialogParameters(), options); + } + + public Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogParameters parameters) + { + return ShowAsync(contentComponent, title, parameters, new DialogOptions()); + } + + public async Task ShowAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type contentComponent, string title, DialogParameters parameters, DialogOptions options) + { + var dialogReference = Show(contentComponent, title, parameters, options); + + //Do not wait forever, what if render fails because of some internal exception and we will never release the method. + var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var token = cancellationTokenSource.Token; + await using (token.Register(() => dialogReference.RenderCompleteTaskCompletionSource.TrySetResult(false))) + { + await dialogReference.RenderCompleteTaskCompletionSource.Task; + + return dialogReference; + } + } + + public Task ShowMessageBox(string title, string message, string yesText = "OK", + string noText = null, string cancelText = null, DialogOptions options = null) + { + return this.ShowMessageBox(new MessageBoxOptions + { + Title = title, + Message = message, + YesText = yesText, + NoText = noText, + CancelText = cancelText, + }, options); + } + + public Task ShowMessageBox(string title, MarkupString markupMessage, string yesText = "OK", + string noText = null, string cancelText = null, DialogOptions options = null) + { + return this.ShowMessageBox(new MessageBoxOptions + { + Title = title, + MarkupMessage = markupMessage, + YesText = yesText, + NoText = noText, + CancelText = cancelText, + }, options); + } + + public async Task ShowMessageBox(MessageBoxOptions messageBoxOptions, DialogOptions options = null) + { + var parameters = new DialogParameters() + { + [nameof(MessageBoxOptions.Title)] = messageBoxOptions.Title, + [nameof(MessageBoxOptions.Message)] = messageBoxOptions.Message, + [nameof(MessageBoxOptions.MarkupMessage)] = messageBoxOptions.MarkupMessage, + [nameof(MessageBoxOptions.CancelText)] = messageBoxOptions.CancelText, + [nameof(MessageBoxOptions.NoText)] = messageBoxOptions.NoText, + [nameof(MessageBoxOptions.YesText)] = messageBoxOptions.YesText, + }; + var reference = await ShowAsync(parameters: parameters, options: options, title: messageBoxOptions.Title); + var result = await reference.Result; + if (result.Cancelled || result.Data is not bool data) + return null; + return data; + } + + public void Close(DialogReference dialog) + { + Close(dialog, DialogResult.Ok(null)); + } + + public virtual void Close(DialogReference dialog, DialogResult result) + { + OnDialogCloseRequested?.Invoke(dialog, result); + } + + public virtual IDialogReference CreateReference() + { + return new DialogReference(Guid.NewGuid(), this); + } + } + + [ExcludeFromCodeCoverage] + public class MessageBoxOptions + { + public string Title { get; set; } + public string Message { get; set; } + public MarkupString MarkupMessage { get; set; } + public string YesText { get; set; } = "OK"; + public string NoText { get; set; } + public string CancelText { get; set; } + } +} diff --git a/Services/EventManager/EventManager.cs b/Services/EventManager/EventManager.cs new file mode 100644 index 0000000..507c4c5 --- /dev/null +++ b/Services/EventManager/EventManager.cs @@ -0,0 +1,206 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected +{ + public interface IEventListenerFactory + { + IEventListener Create(); + } + + public class EventListenerFactory : IEventListenerFactory + { + private readonly IServiceProvider _provider; + + public EventListenerFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IEventListener Create() => + new EventListener(_provider.GetRequiredService()); + } + + public interface IEventListener : IAsyncDisposable + { + /// + /// Listing to a javascript event + /// + /// The type of the event args for instance MouseEventArgs for mousemove + /// Name of the DOM event without "on" + /// The value of the id field of the DOM element + /// The name of a JS function (relative to window) that used to project the event before it is send back to .NET. Can be null, if no projection is needed + /// The delay between the last time the event occurred and the callback is fired. Set to zero, if no delay is requested + /// The method that is invoked, if the DOM element is fired. Object will be of type T + /// A unique identifier for the event subscription. Should be used to cancel the subscription + Task Subscribe<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string eventName, string elementId, string projectionName, int throotleInterval, Func callback); + + /// + /// Listing to a javascript event on the document itself + /// + /// The type of the event args for instance MouseEventArgs for mousemove + /// Name of the DOM event without "on" + /// The delay between the last time the event occurred and the callback is fired. Set to zero, if no delay is requested + /// The method that is invoked, if the DOM element is fired. Object will be of type T + /// A unique identifier for the event subscription. Should be used to cancel the subscription + Task SubscribeGlobal<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string eventName, int throotleInterval, Func callback); + + /// + /// Cancel (unsubscribe) the listening to a DOM event, previous connected by Subscribe + /// + /// The unique event identifier + /// true for if the event listener was detached, false if not + Task Unsubscribe(Guid key); + } + + public class EventListener : IEventListener, IAsyncDisposable, IDisposable + { + private readonly IJSRuntime _jsRuntime; + private readonly DotNetObjectReference _dotNetRef; + private bool _disposed = false; + + private Dictionary callback)> _callbackResolver = new(); + + [DynamicDependency(nameof(OnEventOccur))] + public EventListener(IJSRuntime runtime) + { + _jsRuntime = runtime; + _dotNetRef = DotNetObjectReference.Create(this); + } + + [JSInvokable] + public async Task OnEventOccur(Guid key, string @eventData) + { + if (_callbackResolver.ContainsKey(key) == false) { return; } + + var element = _callbackResolver[key]; + + var @event = JsonSerializer.Deserialize(eventData, element.eventType, new WebEventJsonContext(new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true, + })); + + if (element.callback != null) + { + await element.callback.Invoke(@event); + } + } + + public async Task Subscribe<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string eventName, string elementId, string projectionName, int throotleInterval, Func callback) + { + var (type, properties) = GetTypeInformation(); + var key = RegisterCallBack(type, callback); + + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudThrottledEventManager.subscribe", eventName, elementId, projectionName, throotleInterval, key, properties, _dotNetRef); + + return key; + } + + public async Task SubscribeGlobal<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string eventName, int throotleInterval, Func callback) + { + var (type, properties) = GetTypeInformation(); + var key = RegisterCallBack(type, callback); + + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudThrottledEventManager.subscribeGlobal", eventName, throotleInterval, key, properties, _dotNetRef); + + return key; + } + + public async Task Unsubscribe(Guid key) + { + if (_callbackResolver.ContainsKey(key) == false) { return false; } + + try + { + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudThrottledEventManager.unsubscribe", key); + return true; + } + catch (Exception) + { + return false; + } + } + + private (Type Type, string[] Properties) GetTypeInformation<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>() + { + var type = typeof(T); + var properties = type.GetProperties().Select(x => char.ToLower(x.Name[0]) + x.Name.Substring(1)).ToArray(); + + return (type, properties); + } + + private Guid RegisterCallBack(Type type, Func callback) + { + var key = Guid.NewGuid(); + _callbackResolver.Add(key, (type, callback)); + + return key; + } + + #region disposing + + public async ValueTask DisposeAsync() + { + if (_disposed == true) { return; } + + foreach (var item in _callbackResolver) + { + try + { + await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudThrottledEventManager.unsubscribe", item.Key); + } + catch (Exception) + { + //ignore + } + } + + _dotNetRef.Dispose(); + _disposed = true; + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + _dotNetRef.Dispose(); + + foreach (var item in _callbackResolver) + { + try + { + _jsRuntime.InvokeVoidAsync("mudThrottledEventManager.unsubscribe", item.Key); + } + catch (Exception) + { + //ignore + } + } + } + + _disposed = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/Services/EventManager/WebEventJsonContext.cs b/Services/EventManager/WebEventJsonContext.cs new file mode 100644 index 0000000..9cc4838 --- /dev/null +++ b/Services/EventManager/WebEventJsonContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected +{ + [JsonSerializable(typeof(EventArgs))] + [JsonSerializable(typeof(ChangeEventArgs))] + [JsonSerializable(typeof(ClipboardEventArgs))] + [JsonSerializable(typeof(DragEventArgs))] + [JsonSerializable(typeof(Microsoft.AspNetCore.Components.Web.ErrorEventArgs))] + [JsonSerializable(typeof(FocusEventArgs))] + [JsonSerializable(typeof(KeyboardEventArgs))] + [JsonSerializable(typeof(MouseEventArgs))] + [JsonSerializable(typeof(PointerEventArgs))] + [JsonSerializable(typeof(ProgressEventArgs))] + [JsonSerializable(typeof(TouchEventArgs))] + [JsonSerializable(typeof(WheelEventArgs))] + internal sealed partial class WebEventJsonContext : JsonSerializerContext + { + } +} diff --git a/Services/IIJSRuntimeExtentions.cs b/Services/IIJSRuntimeExtentions.cs new file mode 100644 index 0000000..3561e5d --- /dev/null +++ b/Services/IIJSRuntimeExtentions.cs @@ -0,0 +1,130 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Microsoft.JSInterop; + +namespace Connected +{ + public static class IIJSRuntimeExtentions + { + /// + /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException + /// + /// The . + /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. + /// JSON-serializable arguments. + /// A that represents the asynchronous invocation operation. + public static async ValueTask InvokeVoidAsyncIgnoreErrors(this IJSRuntime jsRuntime, string identifier, params object[] args) + { + try + { + await jsRuntime.InvokeVoidAsync(identifier, args); + } +#if DEBUG +#else + catch (JSException) + { + } +#endif + // catch prerending errors since there is no browser at this point. + catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) + { + } + catch (JSDisconnectedException) + { + } + catch (TaskCanceledException) + { + } + } + + /// + /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException + /// + /// The . + /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. + /// JSON-serializable arguments. + /// A that represents the asynchronous invocation operation and resolves to true in case no exception has occured ohterwise false. + public static async ValueTask InvokeVoidAsyncWithErrorHandling(this IJSRuntime jsRuntime, string identifier, params object[] args) + { + try + { + await jsRuntime.InvokeVoidAsync(identifier, args); + return true; + } +#if DEBUG +#else + catch (JSException) + { + return false; + } +#endif + // catch prerending errors since there is no browser at this point. + catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) + { + return false; + } + catch (JSDisconnectedException) + { + return false; + } + catch (TaskCanceledException) + { + return false; + } + } + + /// + /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException. In case an exception occured the default value of is returned + /// + /// The JSON-serializable return type. + /// The . + /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. + /// JSON-serializable arguments. + /// An instance of obtained by JSON-deserializing the return value into a tuple. The first item (sucess) is true in case where there was no exception, otherwise fall. + public static async ValueTask<(bool success, TValue value)> InvokeAsyncWithErrorHandling(this IJSRuntime jsRuntime, string identifier, params object[] args) + => await jsRuntime.InvokeAsyncWithErrorHandling(default(TValue), identifier, args); + + /// + /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException + /// + /// The JSON-serializable return type. + /// The . + /// The value that should be returned in case an exception occured + /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. + /// JSON-serializable arguments. + /// An instance of obtained by JSON-deserializing the return value into a tuple. The first item (sucess) is true in case where there was no exception, otherwise fall. + public static async ValueTask<(bool success, TValue value)> InvokeAsyncWithErrorHandling<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this IJSRuntime jsRuntime, TValue fallbackValue, string identifier, params object[] args) + { + try + { + var result = await jsRuntime.InvokeAsync(identifier: identifier, args: args); + return (true, result); + } +#if DEBUG +#else + catch (JSException) + { + return (false, fallbackValue); + } +#endif + // catch prerending errors since there is no browser at this point. + catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) + { + return (false, fallbackValue);; + } + catch (JSDisconnectedException) + { + return (false, fallbackValue); + } + catch (TaskCanceledException) + { + return (false, fallbackValue); + } + } + } +} diff --git a/Services/JsApiService.cs b/Services/JsApiService.cs new file mode 100644 index 0000000..257e9ce --- /dev/null +++ b/Services/JsApiService.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using Microsoft.JSInterop; + +namespace Connected +{ + public interface IJsApiService + { + ValueTask CopyToClipboardAsync(string text); + ValueTask OpenInNewTabAsync(string url); + ValueTask Open(string link, string target); + } + + public class JsApiService : IJsApiService + { + private readonly IJSRuntime _jsRuntime; + + public JsApiService(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + public ValueTask CopyToClipboardAsync(string text) => + _jsRuntime.InvokeVoidAsync("mudWindow.copyToClipboard", text); + + public ValueTask Open(string link, string target) + { + if (target == "_blank") + return OpenInNewTabAsync(link); + + return _jsRuntime.InvokeVoidAsync("open", link, target); + } + + public ValueTask OpenInNewTabAsync(string url) => + _jsRuntime.InvokeVoidAsync("mudWindow.open", url, "_blank"); + } +} diff --git a/Services/JsEvent/JsEvent.cs b/Services/JsEvent/JsEvent.cs new file mode 100644 index 0000000..f434df1 --- /dev/null +++ b/Services/JsEvent/JsEvent.cs @@ -0,0 +1,238 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + public interface IJsEvent : IDisposable + { + Task Connect(string elementId, JsEventOptions options); + Task Disconnect(); + event Action CaretPositionChanged; + event Action Paste; + event Action Select; + } + + /// + /// Subscribe JS events of any element by html id + /// + public class JsEvent : IJsEvent + { + private bool _isDisposed = false; + + private readonly DotNetObjectReference _dotNetRef; + private readonly IJSRuntime _jsRuntime; + private string _elementId; + private bool _isObserving; + internal HashSet _subscribedEvents = new HashSet(); + + [DynamicDependency(nameof(OnCaretPositionChanged))] + [DynamicDependency(nameof(OnPaste))] + [DynamicDependency(nameof(OnSelect))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(JsEventOptions))] + public JsEvent(IJSRuntime jsRuntime) + { + _dotNetRef = DotNetObjectReference.Create(this); + _jsRuntime = jsRuntime; + } + + /// + /// Connect to the ancestor element of the element(s) that should be observed + /// + /// Ancestor html element id + /// Define here the descendant(s) by setting TargetClass and the keystrokes to be monitored + public async Task Connect(string elementId, JsEventOptions options) + { + if (_isObserving || _isDisposed) + return; + _elementId = elementId; + _isObserving = await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudJsEvent.connect", _dotNetRef, elementId, options); ; + } + + /// + /// Disconnect from the previously connected ancestor and its descendants + /// + public async Task Disconnect() + { + if (_elementId == null) + return; + await UnsubscribeAll(); + try + { + await _jsRuntime.InvokeVoidAsync($"mudJsEvent.disconnect", _elementId); + } + catch (Exception) { /*ignore*/ } + _isObserving = false; + } + + internal void Subscribe(string eventName) + { + if (_elementId == null) + throw new InvalidOperationException("Call Connect(...) before attaching events!"); + if (_subscribedEvents.Contains(eventName) || _isDisposed) + return; + try + { + _jsRuntime.InvokeVoidAsync("mudJsEvent.subscribe", _elementId, eventName).AndForget(); + _subscribedEvents.Add(eventName); + } + catch (JSDisconnectedException) { } + catch (TaskCanceledException) { } + } + + internal async Task Unsubscribe(string eventName) + { + if (_elementId == null) + return; + try + { + await _jsRuntime.InvokeVoidAsync($"mudJsEvent.unsubscribe", _elementId, eventName); + } + catch (Exception) { /*ignore*/ } + _subscribedEvents.Remove(eventName); + } + + internal async Task UnsubscribeAll() + { + if (_elementId == null) + return; + try + { + foreach (var eventName in _subscribedEvents) + await _jsRuntime.InvokeVoidAsync($"mudJsEvent.unsubscribe", _elementId, eventName); + } + catch (Exception) { /*ignore*/ } + _subscribedEvents.Clear(); + } + + List> _caretPositionChangedHandlers = new List>(); + + /// + /// Subscribe this event to get notified about caret changes in an input on click and on keyup + /// + public event Action CaretPositionChanged + { + add + { + if (_caretPositionChangedHandlers.Count == 0) + { + Subscribe("click"); + Subscribe("keyup"); + } + _caretPositionChangedHandlers.Add(value); + } + remove + { + if (_caretPositionChangedHandlers.Count == 0) + return; + if (_caretPositionChangedHandlers.Count == 1) + { + Unsubscribe("click").AndForget(); + Unsubscribe("keyup").AndForget(); + } + _caretPositionChangedHandlers.Remove(value); + } + } + + /// + /// To be invoked only by JS + /// + [JSInvokable] + public void OnCaretPositionChanged(int caretPosition) + { + foreach (var handler in _caretPositionChangedHandlers) + { + handler.Invoke(caretPosition); + } + } + + List> _pasteHandlers = new List>(); + + /// + /// Subscribe this event to get notified about paste actions + /// + public event Action Paste + { + add + { + if (_pasteHandlers.Count == 0) + Subscribe("paste"); + _pasteHandlers.Add(value); + } + remove + { + if (_pasteHandlers.Count == 0) + return; + if (_pasteHandlers.Count == 1) + Unsubscribe("paste").AndForget(); + _pasteHandlers.Remove(value); + } + } + + /// + /// To be invoked only by JS + /// + [JSInvokable] + public void OnPaste(string text) + { + foreach (var handler in _pasteHandlers) + { + handler.Invoke(text); + } + } + + List> _selectHandlers = new List>(); + + /// + /// Subscribe this event to get notified about paste actions + /// + public event Action Select + { + add + { + if (_selectHandlers.Count == 0) + Subscribe("select"); + _selectHandlers.Add(value); + } + remove + { + if (_selectHandlers.Count == 0) + return; + if (_selectHandlers.Count == 1) + Unsubscribe("select").AndForget(); + _selectHandlers.Remove(value); + } + } + + /// + /// To be invoked only by JS + /// + [JSInvokable] + public void OnSelect(int start, int end) + { + foreach (var handler in _selectHandlers) + { + handler.Invoke(start, end); + } + } + + protected virtual void Dispose(bool disposing) + { + if (!disposing || _isDisposed) + return; + _isDisposed = true; + Disconnect().AndForget(); + _dotNetRef.Dispose(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + } +} diff --git a/Services/JsEvent/JsEventFactory.cs b/Services/JsEvent/JsEventFactory.cs new file mode 100644 index 0000000..91d863e --- /dev/null +++ b/Services/JsEvent/JsEventFactory.cs @@ -0,0 +1,33 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + public interface IJsEventFactory + { + IJsEvent Create(); + } + + public class JsEventFactory : IJsEventFactory + { + private readonly IServiceProvider _provider; + + public JsEventFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IJsEvent Create() => + new JsEvent(_provider.GetRequiredService()); + } + +} diff --git a/Services/JsEvent/JsEventOptions.cs b/Services/JsEvent/JsEventOptions.cs new file mode 100644 index 0000000..a81d010 --- /dev/null +++ b/Services/JsEvent/JsEventOptions.cs @@ -0,0 +1,28 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +namespace Connected.Services +{ + public class JsEventOptions + { + /// + /// Class of the target node which should be observed for keyboard events + /// + /// Note: this must be a single class + /// + public string TargetClass { get; set; } + + /// + /// The tag name of the element to register events with. Must be all uppercase, like "INPUT" + /// + public string TagName { get; set; } + + /// + /// Report resize events in the browser's console. + /// + public bool EnableLogging { get; set; } = false; + } +} diff --git a/Services/KeyInterceptor/IKeyInterceptor.cs b/Services/KeyInterceptor/IKeyInterceptor.cs new file mode 100644 index 0000000..de7d2df --- /dev/null +++ b/Services/KeyInterceptor/IKeyInterceptor.cs @@ -0,0 +1,21 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.AspNetCore.Components.Web; + +namespace Connected.Services; + + +public delegate void KeyboardEvent(KeyboardEventArgs args); + +public interface IKeyInterceptor : IDisposable +{ + Task Connect(string elementId, KeyInterceptorOptions options); + Task Disconnect(); + Task UpdateKey(KeyOptions option); + + event KeyboardEvent KeyDown; + event KeyboardEvent KeyUp; + +} diff --git a/Services/KeyInterceptor/KeyInterceptor.cs b/Services/KeyInterceptor/KeyInterceptor.cs new file mode 100644 index 0000000..3337551 --- /dev/null +++ b/Services/KeyInterceptor/KeyInterceptor.cs @@ -0,0 +1,105 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.JSInterop; + +namespace Connected.Services; + +/// +/// This transient service binds itself to a parent element to observe the keys of one of its children. +/// It can call preventDefault or stopPropagation directly on the JavaScript side for single key strokes / key combinations as per configuration. +/// Furthermore, you can precisely subscribe single keystrokes or combinations and only the subscribed ones will be forwarded into .NET +/// +public class KeyInterceptor : IKeyInterceptor, IDisposable +{ + private bool _isDisposed = false; + + private readonly DotNetObjectReference _dotNetRef; + private readonly IJSRuntime _jsRuntime; + private bool _isObserving; + private string _elementId; + + [DynamicDependency(nameof(OnKeyDown))] + [DynamicDependency(nameof(OnKeyUp))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(KeyboardEvent))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(KeyboardEventArgs))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(KeyOptions))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(KeyInterceptorOptions))] + public KeyInterceptor(IJSRuntime jsRuntime) + { + _dotNetRef = DotNetObjectReference.Create(this); + _jsRuntime = jsRuntime; + } + + /// + /// Connect to the ancestor element of the element(s) that should be observed + /// + /// Ancestor html element id + /// Define here the descendant(s) by setting TargetClass and the keystrokes to be monitored / suppressed + public async Task Connect(string elementId, KeyInterceptorOptions options) + { + if (_isObserving || _isDisposed) + return; + _elementId = elementId; + _isObserving = await _jsRuntime.InvokeVoidAsyncWithErrorHandling("mudKeyInterceptor.connect", _dotNetRef, elementId, options); + } + + /// + /// Update behavior of a registered keyoption + /// The keystrike to update has to be monitored previously + /// + /// Define KeyOption to update + public async Task UpdateKey(KeyOptions option) + { + await _jsRuntime.InvokeVoidAsync($"mudKeyInterceptor.updatekey", _elementId, option); + } + + /// + /// Disconnect from the previously connected ancestor and its descendants + /// + public async Task Disconnect() + { + try + { + await _jsRuntime.InvokeVoidAsync($"mudKeyInterceptor.disconnect", _elementId); + } + catch (Exception) { /*ignore*/ } + _isObserving = false; + } + + [JSInvokable] + public void OnKeyDown(KeyboardEventArgs args) + { + KeyDown?.Invoke(args); + } + + [JSInvokable] + public void OnKeyUp(KeyboardEventArgs args) + { + KeyUp?.Invoke(args); + } + + public event KeyboardEvent KeyDown; + public event KeyboardEvent KeyUp; + + protected virtual void Dispose(bool disposing) + { + if (!disposing || _isDisposed) + return; + _isDisposed = true; + KeyDown = null; + KeyUp = null; + Disconnect().AndForget(); + _dotNetRef.Dispose(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + +} diff --git a/Services/KeyInterceptor/KeyInterceptorFactory.cs b/Services/KeyInterceptor/KeyInterceptorFactory.cs new file mode 100644 index 0000000..c9dee78 --- /dev/null +++ b/Services/KeyInterceptor/KeyInterceptorFactory.cs @@ -0,0 +1,32 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + public interface IKeyInterceptorFactory + { + public IKeyInterceptor Create(); + } + + public class KeyInterceptorFactory : IKeyInterceptorFactory + { + private readonly IServiceProvider _provider; + + public KeyInterceptorFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IKeyInterceptor Create() => + new KeyInterceptor(_provider.GetRequiredService()); + } +} diff --git a/Services/KeyInterceptor/KeyInterceptorOptions.cs b/Services/KeyInterceptor/KeyInterceptorOptions.cs new file mode 100644 index 0000000..2a66b70 --- /dev/null +++ b/Services/KeyInterceptor/KeyInterceptorOptions.cs @@ -0,0 +1,82 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +namespace Connected.Services +{ + public class KeyInterceptorOptions + { + /// + /// Class of the target node which should be observed for keyboard events + /// + /// Note: this must be a single class + /// + public string TargetClass { get; set; } + + /// + /// Report resize events in the browser's console. + /// + public bool EnableLogging { get; set; } = false; + + /// + /// Intercept configuration for keys of interest + /// + public List Keys { get; set; } = new List(); + } + + /// + /// Configuration for preventDefault() and stopPropagation() control + /// + /// For PreventDown, PreventUp, StopDown and StopUp the configuration which key combinations should match + /// is a Javascript boolean expression. + /// + /// Examples: + /// For the examples, let's assume the Tab key was pressed. + /// Note: for combinations of more than one modifier the following order of modifiers must be followed strictly: shift+ctrl+alt+meta + /// + /// * Don't prevent key down: + /// PreventDown=null or PreventDown="none" + /// * Prevent key down of unmodified keystrokes such as "Tab": + /// PreventDown="key+none" + /// * Prevent key down of Tab and Ctrl+Tab + /// PreventDown="key+none|key+ctrl" + /// * Prevent key down of just Ctrl+Tab + /// PreventDown="key+ctrl" + /// * Prevent key down of Ctrl+Tab and Shift+Tab but not Shift+Ctrl+Tab: + /// PreventDown="key+shift|key+ctrl" + /// * Prevent key down of Shift+Ctrl+Tab and Ctrl+Tab but not Shift+Tab: + /// PreventDown="key+shift+ctrl|key+ctrl" + /// * Prevent any combination of key and modifiers, but not the unmodified key: + /// PreventDown="key+any" + /// * Prevent any combination of key and modifiers, even the unmodified key: + /// PreventDown="any" + /// + public class KeyOptions + { + /// + /// Javascript keyboard event.key + /// + /// Examples: " " for space, "Tab" for tab, "a" for lowercase A-key. + /// Also allowed: JS regex such as "/[a-z]/" or "/a|b/" but NOT "/[a-z]/g" or "/[a-z]/i" + /// regex must be enclosed in two forward slashes! + /// + public string Key { get; set; } + + /// + /// Subscribe down key and invoke event KeyDown on c# side + /// + public bool SubscribeDown { get; set; } + + /// + /// Subscribe up key and invoke event KeyUp on c# side + /// + public bool SubscribeUp { get; set; } + + public string PreventDown { get; set; } = "none"; + public string PreventUp { get; set; } = "none"; + public string StopDown { get; set; } = "none"; + public string StopUp { get; set; } = "none"; + } +} diff --git a/Services/ReseizeObserver/IResizeObserver.cs b/Services/ReseizeObserver/IResizeObserver.cs new file mode 100644 index 0000000..f1ceb38 --- /dev/null +++ b/Services/ReseizeObserver/IResizeObserver.cs @@ -0,0 +1,22 @@ +using Connected.Interop; +using Microsoft.AspNetCore.Components; + +namespace Connected.Services; + + +public delegate void SizeChanged(IDictionary changes); + +public interface IResizeObserver : IAsyncDisposable, IDisposable +{ + Task Observe(ElementReference element); + Task> Observe(IEnumerable elements); + Task Unobserve(ElementReference element); + + double GetWidth(ElementReference reference); + double GetHeight(ElementReference reference); + BoundingClientRect GetSizeInfo(ElementReference reference); + + event SizeChanged OnResized; + + bool IsElementObserved(ElementReference reference); +} diff --git a/Services/ReseizeObserver/IResizeObserverFactory.cs b/Services/ReseizeObserver/IResizeObserverFactory.cs new file mode 100644 index 0000000..95b6ea9 --- /dev/null +++ b/Services/ReseizeObserver/IResizeObserverFactory.cs @@ -0,0 +1,8 @@ +namespace Connected.Services +{ + public interface IResizeObserverFactory + { + IResizeObserver Create(ResizeObserverOptions options); + IResizeObserver Create(); + } +} diff --git a/Services/ReseizeObserver/ResizeObserver.cs b/Services/ReseizeObserver/ResizeObserver.cs new file mode 100644 index 0000000..abea75f --- /dev/null +++ b/Services/ReseizeObserver/ResizeObserver.cs @@ -0,0 +1,145 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Interop; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Services; + +public class ResizeObserver : IResizeObserver, IDisposable, IAsyncDisposable +{ + private Boolean _isDisposed = false; + + private readonly DotNetObjectReference _dotNetRef; + private readonly IJSRuntime _jsRuntime; + + private readonly Dictionary _cachedValueIds = new(); + private readonly Dictionary _cachedValues = new(); + + private Guid _id = Guid.NewGuid(); + private ResizeObserverOptions _options; + + [DynamicDependency(nameof(OnSizeChanged))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(SizeChangeUpdateInfo))] + public ResizeObserver(IJSRuntime jsRuntime, ResizeObserverOptions options) + { + _dotNetRef = DotNetObjectReference.Create(this); + _jsRuntime = jsRuntime; + _options = options; + } + + public ResizeObserver(IJSRuntime jsRuntime, IOptions options = null) : this(jsRuntime, options?.Value ?? new ResizeObserverOptions()) + { + } + + public async Task Observe(ElementReference element) => (await Observe(new[] { element })).FirstOrDefault(); + + public async Task> Observe(IEnumerable elements) + { + var filteredElements = elements.Where(x => x.Context != null && _cachedValues.ContainsKey(x) == false).ToList(); + if (filteredElements.Any() == false) + { + return Array.Empty(); + } + + List elementIds = new(); + + foreach (var item in filteredElements) + { + var id = Guid.NewGuid(); + elementIds.Add(id); + _cachedValueIds.Add(id, item); + } + + var result = await _jsRuntime.InvokeAsync>("mudResizeObserver.connect", _id, _dotNetRef, filteredElements, elementIds, _options) ?? Array.Empty(); + var counter = 0; + foreach (var item in result) + { + _cachedValues.Add(filteredElements.ElementAt(counter), item); + counter++; + } + + return result; + } + + public async Task Unobserve(ElementReference element) + { + var elementId = _cachedValueIds.FirstOrDefault(x => x.Value.Id == element.Id).Key; + if (elementId == default) { return; } + + //if the unobserve happens during a component teardown, the try-catch is a safe guard to prevent a "pseudo" exception + try { await _jsRuntime.InvokeVoidAsync($"mudResizeObserver.disconnect", _id, elementId); } catch (Exception) { } + + _cachedValueIds.Remove(elementId); + _cachedValues.Remove(element); + } + + public bool IsElementObserved(ElementReference reference) => _cachedValues.ContainsKey(reference); + + public record SizeChangeUpdateInfo(Guid Id, BoundingClientRect Size); + + [JSInvokable] + public void OnSizeChanged(IEnumerable changes) + { + Dictionary parsedChanges = new(); + foreach (var item in changes) + { + if (_cachedValueIds.ContainsKey(item.Id) == false) { continue; } + + var elementRef = _cachedValueIds[item.Id]; + _cachedValues[elementRef] = item.Size; + parsedChanges.Add(elementRef, item.Size); + } + + OnResized?.Invoke(parsedChanges); + } + + public event SizeChanged OnResized; + + public BoundingClientRect GetSizeInfo(ElementReference reference) + { + if (_cachedValues.ContainsKey(reference) == false) + { + return null; + } + + return _cachedValues[reference]; + } + + public double GetHeight(ElementReference reference) => GetSizeInfo(reference)?.Height ?? 0.0; + public double GetWidth(ElementReference reference) => GetSizeInfo(reference)?.Width ?? 0.0; + + protected virtual void Dispose(bool disposing) + { + if (disposing && _isDisposed == false) + { + _isDisposed = true; + _dotNetRef.Dispose(); + _cachedValueIds.Clear(); + _cachedValues.Clear(); + + //in a fire and forget manner, we just "trying" to cancel the listener. So, we are not interested in an potential error + try { _ = _jsRuntime.InvokeVoidAsync($"mudResizeObserver.cancelListener", _id); } catch (Exception) { } + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public async ValueTask DisposeAsync() + { + if (_isDisposed == true) { return; } + + _isDisposed = true; + + _dotNetRef.Dispose(); + _cachedValueIds.Clear(); + _cachedValues.Clear(); + + //in a fire and forget manner, we just "trying" to cancel the listener. So, we are not interested in an potential error + try { await _jsRuntime.InvokeVoidAsync($"mudResizeObserver.cancelListener", _id); } catch (Exception) { } + } +} diff --git a/Services/ReseizeObserver/ResizeObserverFactory.cs b/Services/ReseizeObserver/ResizeObserverFactory.cs new file mode 100644 index 0000000..e90d88c --- /dev/null +++ b/Services/ReseizeObserver/ResizeObserverFactory.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + public class ResizeObserverFactory : IResizeObserverFactory + { + private readonly IServiceProvider _provider; + + public ResizeObserverFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IResizeObserver Create(ResizeObserverOptions options) => + new ResizeObserver(_provider.GetRequiredService(), options); + + public IResizeObserver Create() + { + var options = _provider.GetService>(); + return Create(options?.Value ?? new ResizeObserverOptions()); + } + } +} diff --git a/Services/ReseizeObserver/ResizeObserverOptions.cs b/Services/ReseizeObserver/ResizeObserverOptions.cs new file mode 100644 index 0000000..93f51a7 --- /dev/null +++ b/Services/ReseizeObserver/ResizeObserverOptions.cs @@ -0,0 +1,16 @@ +namespace Connected.Services +{ + public class ResizeObserverOptions + { + /// + /// Timepsan in milliseconds after the browser detect the last chance and notify the interop service. + /// Setting this value too low can cause poor application performance. + /// + public int ReportRate { get; set; } = 200; + + /// + /// Report resize events in the browser's console. + /// + public bool EnableLogging { get; set; } = false; + } +} diff --git a/Services/ResizeListener/Breakpoint.cs b/Services/ResizeListener/Breakpoint.cs new file mode 100644 index 0000000..5355bed --- /dev/null +++ b/Services/ResizeListener/Breakpoint.cs @@ -0,0 +1,14 @@ +namespace Connected +{ + /// + /// Breakpoints describe certain user interfaces sizes or ranges. Use them in conjunction with MudHidden or ResizeListenerService + /// + public enum Breakpoint + { + Xs, Sm, Md, Lg, Xl, Xxl, + SmAndDown, MdAndDown, LgAndDown, XlAndDown, + SmAndUp, MdAndUp, LgAndUp, XlAndUp, + None, + Always + } +} diff --git a/Services/ResizeListener/BreakpointService .cs b/Services/ResizeListener/BreakpointService .cs new file mode 100644 index 0000000..3c5d054 --- /dev/null +++ b/Services/ResizeListener/BreakpointService .cs @@ -0,0 +1,245 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + + public class BreakpointService : + ResizeBasedService, + IBreakpointService + { + private readonly IJSRuntime _jsRuntime; + private readonly ResizeOptions _options; + private IBrowserWindowSizeProvider _browserWindowSizeProvider; + private BrowserWindowSize _windowSize; + private Breakpoint _breakpoint = Breakpoint.None; + + /// + /// + /// + /// + /// + /// + [DynamicDependency(nameof(RaiseOnResized))] + public BreakpointService(IJSRuntime jsRuntime, IBrowserWindowSizeProvider browserWindowSizeProvider, IOptions options = null) + : base(jsRuntime) + { + this._options = options?.Value ?? new ResizeOptions(); + this._jsRuntime = jsRuntime; + this._browserWindowSizeProvider = browserWindowSizeProvider; + } + + /// + /// Invoked by jsInterop, use the OnResized event handler to subscribe. + /// + /// + /// + /// + [JSInvokable] + public void RaiseOnResized(BrowserWindowSize browserWindowSize, Breakpoint breakpoint, Guid optionId) + { + _windowSize = browserWindowSize; + _breakpoint = breakpoint; + + if (Listeners.ContainsKey(optionId) == false) { return; } + + var listenerInfo = Listeners[optionId]; + listenerInfo.InvokeCallbacks(breakpoint); + } + + /// + /// Determine if the Document matches the provided media query. + /// + /// + /// Returns true if matched. + public async ValueTask MatchMedia(string mediaQuery) => + await _jsRuntime.InvokeAsync($"mudResizeListener.matchMedia", mediaQuery); + + public static Dictionary DefaultBreakpointDefinitions { get; set; } = new Dictionary() + { + [Breakpoint.Xl] = 1920, + [Breakpoint.Lg] = 1280, + [Breakpoint.Md] = 960, + [Breakpoint.Sm] = 600, + [Breakpoint.Xs] = 0, + }; + + public async Task GetBreakpoint() + { + // note: we don't need to get the size if we are listening for updates, so only if onResized==null, get the actual size + if (_windowSize == null) + _windowSize = await _browserWindowSizeProvider.GetBrowserWindowSize(); + if (_windowSize == null) + return Breakpoint.Xs; + if (_windowSize.Width >= DefaultBreakpointDefinitions[Breakpoint.Xl]) + return Breakpoint.Xl; + else if (_windowSize.Width >= DefaultBreakpointDefinitions[Breakpoint.Lg]) + return Breakpoint.Lg; + else if (_windowSize.Width >= DefaultBreakpointDefinitions[Breakpoint.Md]) + return Breakpoint.Md; + else if (_windowSize.Width >= DefaultBreakpointDefinitions[Breakpoint.Sm]) + return Breakpoint.Sm; + else + return Breakpoint.Xs; + } + + public async Task IsMediaSize(Breakpoint breakpoint) + { + if (breakpoint == Breakpoint.None) + return false; + + return IsMediaSize(breakpoint, await GetBreakpoint()); + } + + public bool IsMediaSize(Breakpoint breakpoint, Breakpoint reference) + { + if (breakpoint == Breakpoint.None) + return false; + + return breakpoint switch + { + Breakpoint.Xs => reference == Breakpoint.Xs, + Breakpoint.Sm => reference == Breakpoint.Sm, + Breakpoint.Md => reference == Breakpoint.Md, + Breakpoint.Lg => reference == Breakpoint.Lg, + Breakpoint.Xl => reference == Breakpoint.Xl, + // * and down + Breakpoint.SmAndDown => reference <= Breakpoint.Sm, + Breakpoint.MdAndDown => reference <= Breakpoint.Md, + Breakpoint.LgAndDown => reference <= Breakpoint.Lg, + // * and up + Breakpoint.SmAndUp => reference >= Breakpoint.Sm, + Breakpoint.MdAndUp => reference >= Breakpoint.Md, + Breakpoint.LgAndUp => reference >= Breakpoint.Lg, + _ => false, + }; + } + + public async Task Subscribe(Action callback) => await Subscribe(callback, _options); + + public async Task Subscribe(Action callback, ResizeOptions options) + { + if (callback is null) + { + throw new ArgumentNullException(nameof(callback)); + } + + options ??= _options; + if (options.BreakpointDefinitions == null || options.BreakpointDefinitions.Count == 0) + { + options.BreakpointDefinitions = DefaultBreakpointDefinitions.ToDictionary(x => x.Key.ToString(), x => x.Value); + } + + if (DotNetRef == null) + { + DotNetRef = DotNetObjectReference.Create(this); + } + + + try + { + await Semaphore.WaitAsync(); + + var existingOptionId = Listeners.Where(x => x.Value.Option == options).Select(x => x.Key).FirstOrDefault(); + + if (existingOptionId == default) + { + var subscriptionInfo = new BreakpointServiceSubscriptionInfo(options); + var subscriptionId = subscriptionInfo.AddSubscription(callback); + var listenerId = Guid.NewGuid(); + + Listeners.Add(listenerId, subscriptionInfo); + + var interopResult = await JsRuntime.InvokeVoidAsyncWithErrorHandling + ("mudResizeListenerFactory.listenForResize", DotNetRef, options, listenerId); + + if (interopResult == true) + { + if (_breakpoint == Breakpoint.None) + { + _breakpoint = await GetBreakpoint(); + + } + } + + return new BreakpointServiceSubscribeResult(subscriptionId, _breakpoint); + } + else + { + var entry = Listeners[existingOptionId]; + var subscriptionId = entry.AddSubscription(callback); + + return new BreakpointServiceSubscribeResult(subscriptionId, _breakpoint); + } + } + finally + { + Semaphore.Release(); + } + } + } + + /// + /// The result of a subscription to the BreakpointListener + /// + /// The subscription id, can be used for cancel the subscription later + /// The current breakpoint of the window + public record BreakpointServiceSubscribeResult(Guid SubscriptionId, Breakpoint Breakpoint); + + public interface IBreakpointService : IAsyncDisposable + { + /// + /// Check if the current breakpoint fits within the current window size + /// + /// + /// True if the media size is meet, false otherwise. For instance if the current window size is sm and the breakpoint is SmAndSmaller, this method returns true + Task IsMediaSize(Breakpoint breakpoint); + + /// + /// Check if the current breakpoint fits within the reference size + /// + /// The breakpoint to check + /// The reference breakpoint (xs,sm,md,lg,xl) + /// True if the media size is meet, false otherwise. For instance if the reference size is sm and the breakpoint is SmAndSmaller, this method returns true + bool IsMediaSize(Breakpoint breakpoint, Breakpoint reference); + + /// + /// Get the current breakpoint + /// + /// + Task GetBreakpoint(); + + /// + /// Subscribe to size changes of the browser window with default options + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// Returning an object containing the current breakpoint and a subscription id, that should be used for unsubscribe + Task Subscribe(Action callback); + + /// + /// Subscribe to size changes of the browser window using the provided options + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// The options used to subscribe to changes + /// Returning an object containing the current breakpoint and a subscription id, that should be used for unsubscribe + Task Subscribe(Action callback, ResizeOptions options); + + /// + /// Used for cancel the subscription to the resize event. + /// + /// The subscription id (return of subscribe) to cancel + /// True if the subscription could be cancel, false otherwise + Task Unsubscribe(Guid subscriptionId); + } +} diff --git a/Services/ResizeListener/BrowserWindowSize.cs b/Services/ResizeListener/BrowserWindowSize.cs new file mode 100644 index 0000000..a804360 --- /dev/null +++ b/Services/ResizeListener/BrowserWindowSize.cs @@ -0,0 +1,10 @@ +using System; + +namespace Connected.Services +{ + public class BrowserWindowSize : EventArgs + { + public int Height { get; set; } + public int Width { get; set; } + } +} diff --git a/Services/ResizeListener/ResizeBasedService.cs b/Services/ResizeListener/ResizeBasedService.cs new file mode 100644 index 0000000..ea66946 --- /dev/null +++ b/Services/ResizeListener/ResizeBasedService.cs @@ -0,0 +1,84 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + public abstract class ResizeBasedService<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TSelf, TInfo, TAction, TTaskOption> : IAsyncDisposable + where TSelf : class + where TInfo : SubscriptionInfo + { + protected SemaphoreSlim Semaphore = new(1, 1); + + protected Dictionary Listeners { get; } = new(); + + protected IJSRuntime JsRuntime { get; init; } + + protected DotNetObjectReference DotNetRef { get; set; } + + public ResizeBasedService(IJSRuntime jsRuntime) + { + JsRuntime = jsRuntime; + } + + public async Task Unsubscribe(Guid subscriptionId) + { + if (DotNetRef is null) + { + return false; + } + + var info = Listeners.FirstOrDefault(x => x.Value.ContainsSubscription(subscriptionId)); + if (info.Value is null) + { + return false; + } + + try + { + await Semaphore.WaitAsync(); + + var isLastSubscriber = info.Value.RemoveSubscription(subscriptionId); + if (isLastSubscriber) + { + Listeners.Remove(info.Key); + + await JsRuntime.InvokeVoidAsyncWithErrorHandling("mudResizeListenerFactory.cancelListener", info.Key); + } + + if (Listeners.Count == 0) + { + DotNetRef.Dispose(); + DotNetRef = null; + } + } + finally + { + Semaphore.Release(); + } + + return true; + } + + public async ValueTask DisposeAsync() + { + if (DotNetRef is null) { return; } + if (Listeners.Count == 0) { return; } + + var ids = Listeners.Keys.ToArray(); + Listeners.Clear(); + + await JsRuntime.InvokeVoidAsyncWithErrorHandling("mudResizeListenerFactory.cancelListeners", ids); + + DotNetRef.Dispose(); + } + } +} diff --git a/Services/ResizeListener/ResizeListenerService.cs b/Services/ResizeListener/ResizeListenerService.cs new file mode 100644 index 0000000..704ac34 --- /dev/null +++ b/Services/ResizeListener/ResizeListenerService.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + /// + /// This service listens to browser resize events and allows you to react to a changing window size in Blazor + /// + public class ResizeListenerService : IResizeListenerService, IDisposable + { + /// + /// + /// + /// + /// + /// + [DynamicDependency(nameof(RaiseOnResized))] + public ResizeListenerService(IJSRuntime jsRuntime, IBrowserWindowSizeProvider browserWindowSizeProvider, IOptions options = null) + { + this._dotNetRef = DotNetObjectReference.Create(this); + this._options = options?.Value ?? new ResizeOptions(); + this._options.BreakpointDefinitions = BreakpointDefinitions.ToDictionary(x => x.Key.ToString(), x => x.Value); + this._jsRuntime = jsRuntime; + this._browserWindowSizeProvider = browserWindowSizeProvider; + } + + private readonly IJSRuntime _jsRuntime; + private readonly IBrowserWindowSizeProvider _browserWindowSizeProvider; + private readonly ResizeOptions _options; + private readonly DotNetObjectReference _dotNetRef; +#nullable enable + private EventHandler? _onResized; + private EventHandler? _onBreakpointChanged; + + /// + /// Subscribe to the browsers resize() event. + /// + public event EventHandler? OnResized + { + add + { + _options.NotifyOnBreakpointOnly = false; + Start(); + _onResized += value; + } + remove + { + _onResized -= value; + Cancel().ConfigureAwait(false); + } + } + + /// + /// Subscribe to the browsers resize() event. + /// + public event EventHandler? OnBreakpointChanged + { + add + { + _options.NotifyOnBreakpointOnly = _onResized == null; + Start(); + _onBreakpointChanged += value; + } + remove + { + _onBreakpointChanged -= value; + Cancel().ConfigureAwait(false); + } + } +#nullable disable + + private async void Start() + { + if (_onResized == null || _onBreakpointChanged == null) + { + await _jsRuntime.InvokeVoidAsyncWithErrorHandling($"mudResizeListener.listenForResize", _dotNetRef, _options); + } + } + + private async ValueTask Cancel() + { + try + { + if (_onResized == null && _onBreakpointChanged == null) + { + await _jsRuntime.InvokeVoidAsyncWithErrorHandling($"mudResizeListener.cancelListener"); + } + else if (_onResized == null && _onBreakpointChanged != null && !_options.NotifyOnBreakpointOnly) + { + _options.NotifyOnBreakpointOnly = true; + Start(); + } + } + catch (Exception) + { + /* ignore */ + } + } + + /// + /// Determine if the Document matches the provided media query. + /// + /// + /// Returns true if matched. + public ValueTask MatchMedia(string mediaQuery) => +_jsRuntime.InvokeAsync($"mudResizeListener.matchMedia", mediaQuery); + + /// + /// Get the current BrowserWindowSize, this includes the Height and Width of the document. + /// + public ValueTask GetBrowserWindowSize() => + _browserWindowSizeProvider.GetBrowserWindowSize(); + + /// + /// Invoked by jsInterop, use the OnResized event handler to subscribe. + /// + /// + /// + [JSInvokable] + public void RaiseOnResized(BrowserWindowSize browserWindowSize, Breakpoint breakpoint) + { + _windowSize = browserWindowSize; + _onResized?.Invoke(this, browserWindowSize); + _onBreakpointChanged?.Invoke(this, breakpoint); + } + + private BrowserWindowSize _windowSize; + + public static Dictionary BreakpointDefinitions { get; set; } = new Dictionary() + { + [Breakpoint.Xxl] = 2560, + [Breakpoint.Xl] = 1920, + [Breakpoint.Lg] = 1280, + [Breakpoint.Md] = 960, + [Breakpoint.Sm] = 600, + [Breakpoint.Xs] = 0, + }; + + public async Task GetBreakpoint() + { + // note: we don't need to get the size if we are listening for updates, so only if onResized==null, get the actual size + if (_onResized == null || _windowSize == null) + _windowSize = await _browserWindowSizeProvider.GetBrowserWindowSize(); + if (_windowSize == null) + return Breakpoint.Xs; + if (_windowSize.Width >= BreakpointDefinitions[Breakpoint.Xxl]) + return Breakpoint.Xxl; + else if (_windowSize.Width >= BreakpointDefinitions[Breakpoint.Xl]) + return Breakpoint.Xl; + else if (_windowSize.Width >= BreakpointDefinitions[Breakpoint.Lg]) + return Breakpoint.Lg; + else if (_windowSize.Width >= BreakpointDefinitions[Breakpoint.Md]) + return Breakpoint.Md; + else if (_windowSize.Width >= BreakpointDefinitions[Breakpoint.Sm]) + return Breakpoint.Sm; + else + return Breakpoint.Xs; + } + + public async Task IsMediaSize(Breakpoint breakpoint) + { + if (breakpoint == Breakpoint.None) + return false; + + return IsMediaSize(breakpoint, await GetBreakpoint()); + } + + public bool IsMediaSize(Breakpoint breakpoint, Breakpoint reference) + { + if (breakpoint == Breakpoint.None) + return false; + + return breakpoint switch + { + Breakpoint.Xs => reference == Breakpoint.Xs, + Breakpoint.Sm => reference == Breakpoint.Sm, + Breakpoint.Md => reference == Breakpoint.Md, + Breakpoint.Lg => reference == Breakpoint.Lg, + Breakpoint.Xl => reference == Breakpoint.Xl, + Breakpoint.Xxl => reference == Breakpoint.Xxl, + // * and down + Breakpoint.SmAndDown => reference <= Breakpoint.Sm, + Breakpoint.MdAndDown => reference <= Breakpoint.Md, + Breakpoint.LgAndDown => reference <= Breakpoint.Lg, + Breakpoint.XlAndDown => reference <= Breakpoint.Xl, + // * and up + Breakpoint.SmAndUp => reference >= Breakpoint.Sm, + Breakpoint.MdAndUp => reference >= Breakpoint.Md, + Breakpoint.LgAndUp => reference >= Breakpoint.Lg, + Breakpoint.XlAndUp => reference >= Breakpoint.Xl, + _ => false, + }; + } + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + _ = Cancel(); + if (disposing) + { + _onResized = null; + _onBreakpointChanged = null; + _dotNetRef?.Dispose(); + } + _disposed = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + + public interface IResizeListenerService : IDisposable + { +#nullable enable + event EventHandler? OnResized; + event EventHandler? OnBreakpointChanged; +#nullable disable + ValueTask GetBrowserWindowSize(); + Task IsMediaSize(Breakpoint breakpoint); + bool IsMediaSize(Breakpoint breakpoint, Breakpoint reference); + Task GetBreakpoint(); + } +} diff --git a/Services/ResizeListener/ResizeOptions.cs b/Services/ResizeListener/ResizeOptions.cs new file mode 100644 index 0000000..9dda7fe --- /dev/null +++ b/Services/ResizeListener/ResizeOptions.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +namespace Connected.Services +{ + public class ResizeOptions : IEquatable + { + /// + /// Rate in milliseconds that the browsers `resize()` event should report a change. + /// Setting this value too low can cause poor application performance. + /// + public int ReportRate { get; set; } = 100; + + /// + /// Report resize events and media queries in the browser's console. + /// + public bool EnableLogging { get; set; } = false; + + /// + /// Suppress the first OnResized that is invoked when a new event handler is added. + /// + public bool SuppressInitEvent { get; set; } = true; + + /// + /// If true, RaiseOnResized is called only when breakpoint has changed. + /// + public bool NotifyOnBreakpointOnly { get; set; } = true; + + /// + /// Breakpoint definitions. + /// + public Dictionary BreakpointDefinitions { get; set; } = new(); + + public static bool operator ==(ResizeOptions l, ResizeOptions r) => l.Equals(r); + public static bool operator !=(ResizeOptions l, ResizeOptions r) => !l.Equals(r); + + public override bool Equals(object obj) + { + if (obj is not ResizeOptions) { return false; } + + return Equals((ResizeOptions)obj); + } + + public bool Equals(ResizeOptions other) + { + if (ReportRate != other.ReportRate || + EnableLogging != other.EnableLogging || + SuppressInitEvent != other.SuppressInitEvent || + NotifyOnBreakpointOnly != other.NotifyOnBreakpointOnly) + { + return false; + } + + if (BreakpointDefinitions is not null) + { + if (other.BreakpointDefinitions is null) { return false; } + else + { + if (BreakpointDefinitions.Count != other.BreakpointDefinitions.Count) + { + return false; + } + + foreach (var item in BreakpointDefinitions.Keys) + { + if (other.BreakpointDefinitions.ContainsKey(item) == false) + { + return false; + } + + if (BreakpointDefinitions[item] != other.BreakpointDefinitions[item]) + { + return false; + } + } + + return true; + } + } + else + { + return other.BreakpointDefinitions is null; + } + } + + public override int GetHashCode() => ReportRate; + } +} diff --git a/Services/ResizeListener/ResizeService.cs b/Services/ResizeListener/ResizeService.cs new file mode 100644 index 0000000..98ef282 --- /dev/null +++ b/Services/ResizeListener/ResizeService.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Connected.Services +{ + /// + /// This service listens to browser resize events and allows you to react to a changing window size in Blazor + /// + public class ResizeService : + ResizeBasedService, + IResizeService + { + private readonly IBrowserWindowSizeProvider _browserWindowSizeProvider; + private readonly ResizeOptions _options; + + /// + /// + /// + /// + /// + /// + [DynamicDependency(nameof(RaiseOnResized))] + public ResizeService(IJSRuntime jsRuntime, IBrowserWindowSizeProvider browserWindowSizeProvider, IOptions options = null) : + base(jsRuntime) + { + this._options = options?.Value ?? new ResizeOptions(); + this._browserWindowSizeProvider = browserWindowSizeProvider; + } + + /// + /// Get the current BrowserWindowSize, this includes the Height and Width of the document. + /// + public ValueTask GetBrowserWindowSize() => + _browserWindowSizeProvider.GetBrowserWindowSize(); + + /// + /// Invoked by jsInterop, use the OnResized event handler to subscribe. + /// + /// + /// + /// + [JSInvokable] + public void RaiseOnResized(BrowserWindowSize browserWindowSize, Breakpoint _, Guid optionId) + { + if (Listeners.ContainsKey(optionId) == false) { return; } + + var listenerInfo = Listeners[optionId]; + listenerInfo.InvokeCallbacks(browserWindowSize); + } + + /// + /// Subscribe to size changes of the browser window. Default ResizeOptions will be used + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// The subscription id. This id is needed for unscribe + public async Task Subscribe(Action callback) => await Subscribe(callback, _options); + + /// + /// Subscribe to size changes of the browser window using the provided options + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// + /// The subscription id. This id is needed for unscribe + public async Task Subscribe(Action callback, ResizeOptions options) + { + if (callback is null) + { + throw new ArgumentNullException(nameof(callback)); + } + + options ??= _options; + + if (DotNetRef == null) + { + DotNetRef = DotNetObjectReference.Create(this); + } + + var existingOptionId = Listeners.Where(x => x.Value.Option == options).Select(x => x.Key).FirstOrDefault(); + + if (existingOptionId == default) + { + var subscriptionInfo = new ResizeServiceSubscriptionInfo(options); + var subscriptionId = subscriptionInfo.AddSubscription(callback); + var listenerId = Guid.NewGuid(); + + Listeners.Add(listenerId, subscriptionInfo); + + await JsRuntime.InvokeVoidAsyncWithErrorHandling($"mudResizeListenerFactory.listenForResize", DotNetRef, options, listenerId); + + return subscriptionId; + } + else + { + var entry = Listeners[existingOptionId]; + var subscriptionId = entry.AddSubscription(callback); + + return subscriptionId; + } + } + } + + public interface IResizeService : IAsyncDisposable + { + /// + /// Get the current size of the window + /// + /// A task representing the current browser size + ValueTask GetBrowserWindowSize(); + + /// + /// Subscribe to size changes of the browser window. Default ResizeOptions will be used + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// The subscription id. This id is needed for unscribe + Task Subscribe(Action callback); + + /// + /// Subscribe to size changes of the browser window using the provided options + /// + /// The method (callbacK) that is invoke as soon as the size of the window has changed + /// The options used to subscribe to changes + /// The subscription id. This id is needed for unscribe + Task Subscribe(Action callback, ResizeOptions options); + + /// + /// Used for cancel the subscription to the resize event. + /// + /// The subscription id (return of subscribe) to cancel + /// True if the subscription could be cancel, false otherwise + Task Unsubscribe(Guid subscriptionId); + } +} diff --git a/Services/ResizeListener/SubscriptionInfo.cs b/Services/ResizeListener/SubscriptionInfo.cs new file mode 100644 index 0000000..066eb9c --- /dev/null +++ b/Services/ResizeListener/SubscriptionInfo.cs @@ -0,0 +1,59 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; + +namespace Connected.Services +{ + public class SubscriptionInfo + { + private readonly Dictionary> _subscriptions; + public TOption Option { get; init; } + + public SubscriptionInfo(TOption options) + { + Option = options; + _subscriptions = new(); + } + + public Guid AddSubscription(Action action) + { + var id = Guid.NewGuid(); + _subscriptions.Add(id, action); + + return id; + } + + public bool ContainsSubscription(Guid listenerId) => _subscriptions.ContainsKey(listenerId); + + public bool RemoveSubscription(Guid listenerId) + { + _subscriptions.Remove(listenerId); + return _subscriptions.Count == 0; + } + + public void InvokeCallbacks(TAction browserWindowSize) + { + foreach (var item in _subscriptions.Values) + { + item.Invoke(browserWindowSize); + } + } + } + + public class ResizeServiceSubscriptionInfo : SubscriptionInfo + { + public ResizeServiceSubscriptionInfo(ResizeOptions options) : base(options) + { + } + } + + public class BreakpointServiceSubscriptionInfo : SubscriptionInfo + { + public BreakpointServiceSubscriptionInfo(ResizeOptions options) : base(options) + { + } + } +} diff --git a/Services/Scroll/ScrollEventArgs.cs b/Services/Scroll/ScrollEventArgs.cs new file mode 100644 index 0000000..9e14b78 --- /dev/null +++ b/Services/Scroll/ScrollEventArgs.cs @@ -0,0 +1,38 @@ +using Connected.Interop; + +namespace Connected; + +public class ScrollEventArgs : EventArgs +{ + + /// + /// The BoundingClientRect for the first child of the scrolled element + /// + public BoundingClientRect FirstChildBoundingClientRect { get; set; } + + /// + /// The ScrollTop property gets or sets the number of pixels that an element's content is scrolled vertically + /// + public double ScrollTop { get; set; } + + /// + /// The ScrollLeft property gets or sets the number of pixels that an element's content is scrolled from its left edge. + /// + public double ScrollLeft { get; set; } + + /// + /// The ScrollHeight property is a measurement of the height of an element's content, including content not visible on the screen due to overflow + /// + public int ScrollHeight { get; set; } + + /// + /// The ScrollWidth property is a measurement of the width of an element's content, including content not visible on the screen due to overflow + /// + public int ScrollWidth { get; set; } + + /// + /// Node name of the scrolled element + /// + public string NodeName { get; set; } + +} diff --git a/Services/Scroll/ScrollListener.cs b/Services/Scroll/ScrollListener.cs new file mode 100644 index 0000000..357bfe2 --- /dev/null +++ b/Services/Scroll/ScrollListener.cs @@ -0,0 +1,114 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected +{ + + + public interface IScrollListener : IDisposable + { + /// + /// The CSS selector to which the scroll event will be attached + /// + string Selector { get; set; } + + event EventHandler OnScroll; + } + + internal class ScrollListener : IScrollListener, IDisposable + { + private readonly IJSRuntime _js; + private DotNetObjectReference _dotNetRef; + + /// + /// The CSS selector to which the scroll event will be attached + /// + public string Selector { get; set; } = null; + + [DynamicDependency(nameof(RaiseOnScroll))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ScrollEventArgs))] + public ScrollListener(IJSRuntime js) : this(string.Empty, js) + { + } + + public ScrollListener(string selector, IJSRuntime js) + { + _js = js; + Selector = selector; + } + + private EventHandler _onScroll; + + /// + /// OnScroll event. Fired when a element is scrolled + /// + public event EventHandler OnScroll + { + add => Subscribe(value); + remove => Unsubscribe(value); + } + + + private async void Subscribe(EventHandler value) + { + if (_onScroll == null) + { + await Start(); + } + _onScroll += value; + } + + private void Unsubscribe(EventHandler value) + { + _onScroll -= value; + if (_onScroll == null) + { + Cancel().ConfigureAwait(false); + } + } + + /// + /// invoked in JS, in scroll-listener.js + /// + /// The scroll event args + [JSInvokable] + public void RaiseOnScroll(ScrollEventArgs e) + { + _onScroll?.Invoke(this, e); + } + + /// + /// Subscribe to scroll event in JS + /// + private ValueTask Start() + { + _dotNetRef = DotNetObjectReference.Create(this); + return _js.InvokeVoidAsyncWithErrorHandling + ("mudScrollListener.listenForScroll", + _dotNetRef, + Selector); + } + + /// + /// Unsubscribe to scroll event in + /// + private async ValueTask Cancel() + { + try + { + await _js.InvokeVoidAsync( + "mudScrollListener.cancelListener", + Selector); + } + catch { /* ignore */ } + } + + public void Dispose() + { + _dotNetRef?.Dispose(); + } + } +} diff --git a/Services/Scroll/ScrollListenerFactory.cs b/Services/Scroll/ScrollListenerFactory.cs new file mode 100644 index 0000000..4aee153 --- /dev/null +++ b/Services/Scroll/ScrollListenerFactory.cs @@ -0,0 +1,28 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected +{ + public interface IScrollListenerFactory + { + IScrollListener Create(string selector); + } + + public class ScrollListenerFactory : IScrollListenerFactory + { + private readonly IServiceProvider _provider; + + public ScrollListenerFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IScrollListener Create(string selector) => + new ScrollListener(selector, _provider.GetRequiredService()); + } +} diff --git a/Services/Scroll/ScrollManager.cs b/Services/Scroll/ScrollManager.cs new file mode 100644 index 0000000..e6fb3c4 --- /dev/null +++ b/Services/Scroll/ScrollManager.cs @@ -0,0 +1,100 @@ +using Connected.Extensions; +using Microsoft.JSInterop; + +namespace Connected +{ + /// + /// Inject with the AddMudBlazorScrollServices extension + /// + public interface IScrollManager + { + ValueTask ScrollToAsync(string id, int left, int top, ScrollBehavior scrollBehavior); + ValueTask ScrollIntoViewAsync(string selector, ScrollBehavior behavior); + //ValueTask ScrollToFragmentAsync(string id, ScrollBehavior behavior); + ValueTask ScrollToTopAsync(string id, ScrollBehavior scrollBehavior = ScrollBehavior.Auto); + ValueTask ScrollToYearAsync(string elementId); + ValueTask ScrollToListItemAsync(string elementId); + ValueTask LockScrollAsync(string selector = "body", string cssClass = "scroll-locked"); + ValueTask UnlockScrollAsync(string selector = "body", string cssClass = "scroll-locked"); + ValueTask ScrollToBottomAsync(string elementId, ScrollBehavior scrollBehavior = ScrollBehavior.Auto); + } + + public class ScrollManager : IScrollManager + { + [Obsolete] + public string Selector { get; set; } + private readonly IJSRuntime _jSRuntime; + + public ScrollManager(IJSRuntime jSRuntime) + { + _jSRuntime = jSRuntime; + } + + /// + /// Scrolls to the coordinates of the element + /// + /// id of element + /// x coordinate + /// y coordinate + /// smooth or auto + /// + public ValueTask ScrollToAsync(string id, int left, int top, ScrollBehavior behavior) => + _jSRuntime.InvokeVoidAsync("scrollManager.scrollTo", id, left, top, behavior.ToDescriptionString()); + + /// + /// Scrolls the first instance of the selector into view + /// + /// + /// + /// + public ValueTask ScrollIntoViewAsync(string selector, ScrollBehavior behavior) => + _jSRuntime.InvokeVoidAsync("scrollManager.scrollIntoView", selector, behavior.ToDescriptionString()); + + /// + /// Scrolls to the top of the element + /// + /// id of element + /// smooth or auto + /// + public ValueTask ScrollToTopAsync(string id, ScrollBehavior scrollBehavior = ScrollBehavior.Auto) => + ScrollToAsync(id, 0, 0, scrollBehavior); + + public async Task ScrollToTop(ScrollBehavior scrollBehavior = ScrollBehavior.Auto) + { +#pragma warning disable CS0612 // Type or member is obsolete + await ScrollToAsync(Selector, 0, 0, scrollBehavior); +#pragma warning restore CS0612 // Type or member is obsolete + } + + /// + /// Scroll to the bottom of the element (or if not found to the bottom of the page) + /// + /// id of element of null to scroll to page bottom + /// smooth or auto + /// + public ValueTask ScrollToBottomAsync(string id, ScrollBehavior behavior) => + _jSRuntime.InvokeVoidAsync("scrollManager.scrollToBottom", id, behavior.ToDescriptionString()); + + public ValueTask ScrollToYearAsync(string elementId) => + _jSRuntime.InvokeVoidAsync("scrollManager.scrollToYear", elementId); + + public ValueTask ScrollToListItemAsync(string elementId) => + _jSRuntime.InvokeVoidAsync("scrollManager.scrollToListItem", elementId); + + public ValueTask LockScrollAsync(string selector = "body", string cssClass = "scroll-locked") => + _jSRuntime.InvokeVoidAsync("scrollManager.lockScroll", selector, cssClass); + + public ValueTask UnlockScrollAsync(string selector = "body", string cssClass = "scroll-locked") => + _jSRuntime.InvokeVoidAsyncIgnoreErrors("scrollManager.unlockScroll", selector, cssClass); + } + + /// + /// Smooth: scrolls in a smooth fashion; + /// Auto: is immediate + /// + public enum ScrollBehavior + { + Smooth, + Auto + } +} diff --git a/Services/Scroll/ScrollManagerException.cs b/Services/Scroll/ScrollManagerException.cs new file mode 100644 index 0000000..dda1b6b --- /dev/null +++ b/Services/Scroll/ScrollManagerException.cs @@ -0,0 +1,20 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ + + [ExcludeFromCodeCoverage] + [Serializable] + public class ScrollManagerException : Exception + { + public ScrollManagerException() : base() { } + public ScrollManagerException(string message) : base(message) { } + public ScrollManagerException(string message, Exception inner) : base(message, inner) { } + + // A constructor is needed for serialization when an + // exception propagates from a remoting server to the client. + protected ScrollManagerException(System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} diff --git a/Services/Scroll/ScrollOptions.cs b/Services/Scroll/ScrollOptions.cs new file mode 100644 index 0000000..35a2988 --- /dev/null +++ b/Services/Scroll/ScrollOptions.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; + +namespace Connected.Services.Scroll +{ + public class ScrollOptions + { + /// + ///the element to be tracked; + /// + public ElementReference Element { get; set; } + + /// + ///the amount of milliseconds that the event is throttled + /// + public int ReportRate { get; set; } = 300; + + /// + /// Suppress the first OnScroll that is invoked when a new event handler is added. + /// + public bool SuppressInitEvent { get; set; } + } +} diff --git a/Services/Scroll/ScrollSpy.cs b/Services/Scroll/ScrollSpy.cs new file mode 100644 index 0000000..a9c1302 --- /dev/null +++ b/Services/Scroll/ScrollSpy.cs @@ -0,0 +1,112 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Microsoft.JSInterop; + +namespace Connected +{ + public class ScrollSectionCenteredEventArgs + { + public ScrollSectionCenteredEventArgs(string id) + { + Id = id; + } + + public string Id { get; init; } + } + + public interface IScrollSpy : IAsyncDisposable + { + /// + /// Start spying for scroll events for elements with the specified classes + /// + /// the class name (without .) to identify the containers to spy on + /// + public Task StartSpying(string elementsSelector); + + /// + /// Center the viewport to DOM element with the given Id + /// + /// The Id of the DOM element, that should be centered + /// + Task ScrollToSection(string id); + + /// + /// Center the viewport to the DOM element represented by the fragment inside the uri + /// + /// The uri which contains the fragment. If no fragment it scrolls to the top of the page + /// + Task ScrollToSection(Uri uri); + event EventHandler ScrollSectionSectionCentered; + + /// + /// Does the same as ScrollToSection but without the scrolling. This can be used to initially set an value + /// + /// + /// + Task SetSectionAsActive(String id); + + /// + /// Get the current position of the centered section + /// + string CenteredSection { get; } + } + + public class ScrollSpy : IScrollSpy + { + public string CenteredSection { get; private set; } + private readonly IJSRuntime _js; + private DotNetObjectReference _dotNetRef; + + [DynamicDependency(nameof(SectionChangeOccured))] + public ScrollSpy(IJSRuntime js) + { + _js = js; + _dotNetRef = DotNetObjectReference.Create(this); + } + + public async Task StartSpying(string containerSelector) => await _js.InvokeVoidAsync + ("mudScrollSpy.spying", containerSelector, _dotNetRef); + + [JSInvokable] + public void SectionChangeOccured(string id) + { + CenteredSection = id; + ScrollSectionSectionCentered?.Invoke(this, new ScrollSectionCenteredEventArgs(id)); + } + + public event EventHandler ScrollSectionSectionCentered; + + public async Task ScrollToSection(string id) + { + CenteredSection = id; + await _js.InvokeVoidAsyncWithErrorHandling + ("mudScrollSpy.scrollToSection", id.Trim('#')); + } + + public async Task SetSectionAsActive(string id) + { + CenteredSection = id; + await _js.InvokeVoidAsyncWithErrorHandling + ("mudScrollSpy.activateSection", id.Trim('#')); + } + + public async Task ScrollToSection(Uri uri) => await ScrollToSection(uri.Fragment); + + public async ValueTask DisposeAsync() + { + try + { + _dotNetRef?.Dispose(); + await _js.InvokeVoidAsyncWithErrorHandling("mudScrollSpy.unspy"); + } + catch (Exception) + { + } + } + } +} diff --git a/Services/Scroll/ScrollSpyFactory.cs b/Services/Scroll/ScrollSpyFactory.cs new file mode 100644 index 0000000..c1f45cd --- /dev/null +++ b/Services/Scroll/ScrollSpyFactory.cs @@ -0,0 +1,28 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Connected +{ + public interface IScrollSpyFactory + { + IScrollSpy Create(); + } + + public class ScrollSpyFactory : IScrollSpyFactory + { + private readonly IServiceProvider _provider; + + public ScrollSpyFactory(IServiceProvider provider) + { + _provider = provider; + } + + public IScrollSpy Create() => + new ScrollSpy(_provider.GetRequiredService()); + } +} diff --git a/Services/ServiceCollectionExtensions.cs b/Services/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..42253ef --- /dev/null +++ b/Services/ServiceCollectionExtensions.cs @@ -0,0 +1,304 @@ +using System.Diagnostics.CodeAnalysis; +using Connected.Components; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Connected.Services; + +[ExcludeFromCodeCoverage] +public static class ServiceCollectionExtensions +{ + /// + /// Adds a Dialog Service as a Scoped instance. + /// + /// IServiceCollection + /// Continues the IServiceCollection chain. + public static IServiceCollection AddBlazorDialog(this IServiceCollection services) + { + services.TryAddScoped(); + return services; + } + + /// + /// Adds a Snackbar Service as a Scoped instance. + /// + /// IServiceCollection + /// Defines SnackbarConfiguration for this instance. + /// Continues the IServiceCollection chain. + public static IServiceCollection AddBlazorSnackbar(this IServiceCollection services, SnackbarConfiguration configuration = null) + { + configuration ??= new SnackbarConfiguration(); + + services.TryAddScoped(builder => + new SnackbarService(builder.GetService(), configuration)); + return services; + } + + /// + /// Adds a Snackbar Service as a Scoped instance. + /// + /// IServiceCollection + /// Defines SnackbarConfiguration for this instance. + /// Continues the IServiceCollection chain. + public static IServiceCollection AddBlazorSnackbar(this IServiceCollection services, Action configuration) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + var options = new SnackbarConfiguration(); + configuration(options); + return AddBlazorSnackbar(services, options); + } + + /// + /// Adds a ResizeListener as a Scoped instance. + /// + /// IServiceCollection + /// Defines ResizeOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddBlazorResizeListener(this IServiceCollection services, ResizeOptions options = null) + { + options ??= new ResizeOptions(); + services.AddBlazorResizeListener(o => + { + o = options; + }); + return services; + } + + /// + /// Adds a ResizeListener as a Scoped instance. + /// + /// IServiceCollection + /// Defines ResizeOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddBlazorResizeListener(this IServiceCollection services, Action options) + { + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.Configure(options); + return services; + } + + /// + /// Adds a IResizeObserver as a Transient instance. + /// + /// IServiceCollection + /// Defines ResizeObserverOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorResizeObserver(this IServiceCollection services, Action options) + { + services.TryAddTransient(); + services.Configure(options); + return services; + } + + /// + /// Adds a IResizeObserver as a Transient instance. + /// + /// IServiceCollection + /// Defines ResizeObserverOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorResizeObserver(this IServiceCollection services, ResizeObserverOptions options = null) + { + options ??= new ResizeObserverOptions(); + services.AddMudBlazorResizeObserver(o => + { + o = options; + }); + return services; + } + + /// + /// Adds a IResizeObserverFactory as a scoped dependency. + /// + /// IServiceCollection + /// Defines ResizeObserverOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorResizeObserverFactory(this IServiceCollection services, Action options) + { + services.TryAddScoped(); + services.Configure(options); + return services; + } + + /// + /// Adds a IResizeObserverFactory as a scoped dependency. + /// + /// IServiceCollection + /// Defines ResizeObserverOptions for this instance + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorResizeObserverFactory(this IServiceCollection services, ResizeObserverOptions options = null) + { + options ??= new ResizeObserverOptions(); + services.AddMudBlazorResizeObserverFactory(o => + { + o = options; + }); + return services; + } + + /// + /// Adds IKeyInterceptor as a Transient instance. + /// + /// IServiceCollection + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorKeyInterceptor(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddScoped(); + + return services; + } + + /// + /// Adds JsEvent as a Transient instance. + /// + /// IServiceCollection + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudBlazorJsEvent(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddScoped(); + + return services; + } + + /// + /// Adds ScrollManager as a transient instance. + /// + /// IServiceCollection + public static IServiceCollection AddMudBlazorScrollManager(this IServiceCollection services) + { + services.TryAddTransient(); + return services; + } + + /// + /// Adds ScrollManager as a transient instance. + /// + /// IServiceCollection + /// Defines PopoverOptions for the application/user + public static IServiceCollection AddMudPopoverService(this IServiceCollection services, Action options) + { + services.Configure(options); + services.TryAddScoped(); + return services; + } + + /// + /// Adds ScrollManager as a transient instance. + /// + /// IServiceCollection + /// Defines PopoverOptions for the application/user + public static IServiceCollection AddMudPopoverService(this IServiceCollection services, PopoverOptions options) + { + options ??= new PopoverOptions(); + services.AddMudPopoverService(o => + { + o = options; + }); + return services; + } + + /// + /// Adds ScrollListener as a transient instance. + /// + /// IServiceCollection + public static IServiceCollection AddMudBlazorScrollListener(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddScoped(); + + return services; + } + + + /// + /// Adds ScrollSpy as a transient instance. + /// + /// IServiceCollection + public static IServiceCollection AddMudBlazorScrollSpy(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddScoped(); + return services; + } + + /// + /// Adds JsApi as a transient instance. + /// + /// IServiceCollection + public static IServiceCollection AddMudBlazorJsApi(this IServiceCollection services) + { + services.TryAddTransient(); + return services; + } + + /// + /// Adds IEventListener as a transient instance. + /// + /// IServiceCollection + public static IServiceCollection AddMudEventManager(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddScoped(); + + return services; + } + + /// + /// Adds common services required by MudBlazor components + /// + /// IServiceCollection + /// Defines options for all MudBlazor services. + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudServices(this IServiceCollection services, MudServicesConfiguration configuration = null) + { + configuration ??= new MudServicesConfiguration(); + return services + .AddBlazorDialog() + .AddBlazorSnackbar(configuration.SnackbarConfiguration) + .AddBlazorResizeListener(configuration.ResizeOptions) + .AddMudBlazorResizeObserver(configuration.ResizeObserverOptions) + .AddMudBlazorResizeObserverFactory() + .AddMudBlazorKeyInterceptor() + .AddMudBlazorJsEvent() + .AddMudBlazorScrollManager() + .AddMudBlazorScrollListener() + .AddMudBlazorJsApi() + .AddMudBlazorScrollSpy() + .AddMudPopoverService(configuration.PopoverOptions) + .AddMudEventManager(); + } + + /// + /// Adds common services required by MudBlazor components + /// + /// IServiceCollection + /// Defines options for all MudBlazor services. + /// Continues the IServiceCollection chain. + public static IServiceCollection AddMudServices(this IServiceCollection services, Action configuration) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + var options = new MudServicesConfiguration(); + configuration(options); + return services + .AddBlazorDialog() + .AddBlazorSnackbar(options.SnackbarConfiguration) + .AddBlazorResizeListener(options.ResizeOptions) + .AddMudBlazorResizeObserver(options.ResizeObserverOptions) + .AddMudBlazorResizeObserverFactory(options.ResizeObserverOptions) + .AddMudBlazorKeyInterceptor() + .AddMudBlazorJsEvent() + .AddMudBlazorScrollManager() + .AddMudBlazorScrollListener() + .AddMudBlazorJsApi() + .AddMudPopoverService(options.PopoverOptions) + .AddMudBlazorScrollSpy() + .AddMudEventManager(); + } +} diff --git a/Services/ServiceConfiguration.cs b/Services/ServiceConfiguration.cs new file mode 100644 index 0000000..25edef7 --- /dev/null +++ b/Services/ServiceConfiguration.cs @@ -0,0 +1,17 @@ +using Connected.Components; + +namespace Connected.Services +{ + // Add additional configuration objects here when adding new services + + /// + /// Common services configuration required by MudBlazor components + /// + public class MudServicesConfiguration + { + public SnackbarConfiguration SnackbarConfiguration { get; set; } = new SnackbarConfiguration(); + public ResizeOptions ResizeOptions { get; set; } = new ResizeOptions(); + public ResizeObserverOptions ResizeObserverOptions { get; set; } = new ResizeObserverOptions(); + public PopoverOptions PopoverOptions { get; set; } = new PopoverOptions(); + } +} diff --git a/Styles/Components.scss b/Styles/Components.scss new file mode 100644 index 0000000..f18c486 --- /dev/null +++ b/Styles/Components.scss @@ -0,0 +1,88 @@ +/*! + * MudBlazor (https://mudblazor.com/) + * Copyright (c) 2021 MudBlazor + * Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE) + */ + +@import 'abstracts/_colors'; +@import 'abstracts/_variables'; +@import 'abstracts/_mixins'; + +@import 'core/_base'; +@import 'core/_blazor'; +@import 'core/_animations'; +@import 'core/_reset'; +@import 'core/_elevation'; + +@import 'components/_alert'; +@import 'components/_badge'; +@import 'components/_toolbar'; +@import 'components/_tooltip'; +@import 'components/_avatar'; +@import 'components/_breadcrumbs'; +@import 'components/_button'; +@import 'components/_buttongroup'; +@import 'components/_iconbutton'; +@import 'components/_card'; +@import 'components/_carousel'; +@import 'components/_charts'; +@import 'components/_checkbox'; +@import 'components/_chip'; +@import 'components/_collapse'; +@import 'components/_dialog'; +@import 'components/_field'; +@import 'components/_grid'; +@import 'components/_paper'; +@import 'components/_icons'; +@import 'components/_divider'; +@import 'components/_dropzone'; +@import 'components/_expansionpanel'; +@import 'components/_fab'; +@import 'components/_form'; +@import 'components/_list'; +@import 'components/_layout'; +@import 'components/_menu'; +@import 'components/_link'; +@import 'components/_navmenu'; +@import 'components/_pagecontentnavigation'; +@import 'components/_pagination'; +@import 'components/_picker'; +@import 'components/_pickerdate'; +@import 'components/_pickertime'; +@import 'components/_pickercolor'; +@import 'components/_popover'; +@import 'components/_simpletable'; +@import 'components/_skeleton'; +@import 'components/_slider'; +@import 'components/_progresscircular'; +@import 'components/_progresslinear'; +@import 'components/_radio'; +@import 'components/_rating'; +@import 'components/_snackbar'; +@import 'components/_switch'; +@import 'components/_timeline'; +@import 'components/_typography'; +@import 'components/_table'; +@import 'components/_tabs'; +@import 'components/_select'; +@import 'components/_input'; +@import 'components/_inputcontrol'; +@import 'components/_inputlabel'; +@import 'components/_fileupload'; +@import 'components/_image'; +@import 'components/_overlay'; +@import 'components/_treeview'; +@import 'components/_datagrid'; + +@import 'utilities'; + +@import 'layout/_appbar'; +@import 'layout/_drawer'; +@import 'layout/_main'; +@import 'layout/_container'; +@import 'layout/_scroll'; + + +@import 'core/_colors'; +@import 'core/_ripple'; +@import 'core/_rtl'; \ No newline at end of file diff --git a/Styles/abstracts/_colors.scss b/Styles/abstracts/_colors.scss new file mode 100644 index 0000000..986e2d6 --- /dev/null +++ b/Styles/abstracts/_colors.scss @@ -0,0 +1,86 @@ +@import 'variables'; + +@each $color in $palette-colors { + .#{$color} { + background-color: var(--palette-#{$color}) !important; + } + + .#{$color}-text { + color: var(--palette-#{$color}) !important; + } + + .#{$color}-hover { + background-color: var(--palette-#{$color}-hover) !important; + } + + .hover\:#{$color}-hover { + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-hover) !important; + } + } + + .border-#{$color} { + border-color: var(--palette-#{$color}) !important; + } + + .theme-#{$color} { + color: var(--palette-#{$color}-text) !important; + background-color: var(--palette-#{$color}) !important; + } +} + +.inherit-text { + color: inherit !important; +} + +.border-lines-default{ + border-color: var(--palette-lines-default); +} + +.background { + background-color: var(--palette-background) !important; +} + +.background-gray{ + background-color: var(--palette-background-grey) !important; +} + +.theme-transparent { + color: inherit !important; + background-color: transparent !important; +} + +.transparent { + background-color: transparent !important; +} + +.transparent-text { + color: transparent !important; +} + +.text-primary { + color: var(--palette-text-primary); +} + +.text-secondary { + color: var(--palette-text-secondary); +} + +.text-disabled { + color: var(--palette-text-disabled); +} + +.white { + background-color: #FFFFFF !important; +} +.white-text { + color: #FFFFFF !important; +} + +.black { + background-color: #000000 !important; +} + +.black-text { + color: #000000 !important; +} diff --git a/Styles/abstracts/_mixins.scss b/Styles/abstracts/_mixins.scss new file mode 100644 index 0000000..5a960f8 --- /dev/null +++ b/Styles/abstracts/_mixins.scss @@ -0,0 +1,53 @@ +@mixin inputplaceholder { + // CSS Pseudo-Element + &::placeholder { + @content + } + /* - Chrome ≤56, + - Safari 5-10.0 + - iOS Safari 4.2-10.2 + - Opera 15-43 + - Opera Mobile 12-12.1 + - Android Browser 2.1-4.4.4 + - Samsung Internet ≤6.2 + - QQ Browser */ + &::-webkit-input-placeholder { + @content + } + // Firefox 4-18 + &:-moz-placeholder { + @content + } + // Firefox 19-50 + &::-moz-placeholder { + @content + } + // IE 10–11 - IE Mobile 10-11 + &:-ms-input-placeholder { + @content + } + // Edge + &::-ms-input-placeholder { + @content + } +} + +@mixin slider-track { + &::-webkit-slider-runnable-track { + @content + } + // Firefox + &::-moz-range-track { + @content + } +} + +@mixin slider-thumb { + &::-webkit-slider-thumb { + @content + } + // Firefox + &::-moz-range-thumb { + @content + } +} \ No newline at end of file diff --git a/Styles/abstracts/_variables.scss b/Styles/abstracts/_variables.scss new file mode 100644 index 0000000..650f9c5 --- /dev/null +++ b/Styles/abstracts/_variables.scss @@ -0,0 +1,13 @@ +$palette-colors: primary, secondary, tertiary, info, success, warning, error, dark; + +$sizes: small, medium, large; + +$breakpoint-xs: 0px; +$breakpoint-sm: 600px; +$breakpoint-md: 960px; +$breakpoint-lg: 1280px; +$breakpoint-xl: 1920px; +$breakpoint-xxl: 2560px; + +$breakpoints: ( xs: $breakpoint-xs, sm: $breakpoint-sm, md: $breakpoint-md, lg: $breakpoint-lg, xl: $breakpoint-xl, xxl: $breakpoint-xxl ); +$breakpoints-css-utilities-only: ( sm: $breakpoint-sm, md: $breakpoint-md, lg: $breakpoint-lg, xl: $breakpoint-xl, xxl: $breakpoint-xxl ); diff --git a/Styles/components/_alert.scss b/Styles/components/_alert.scss new file mode 100644 index 0000000..c33f82b --- /dev/null +++ b/Styles/components/_alert.scss @@ -0,0 +1,107 @@ +@import '../abstracts/variables'; + +.alert { + display: flex; + padding: 6px 16px; + border-radius: var(--default-borderradius); + background-color: transparent; + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &.square { + border-radius: 0px; + } + + &.dense { + padding: 0px 12px; + } +} + +.alert-text { + &-normal { + color: var(--palette-text-primary); + background-color: var(--palette-dark-hover); + } + + @each $color in $palette-colors { + &-#{$color} { + color: var(--palette-#{$color}-darken); + background-color: var(--palette-#{$color}-hover); + + & .alert-icon { + color: var(--palette-#{$color}); + } + } + } +} + +.alert-outlined { + &-normal { + color: var(--palette-text-primary); + border: 1px solid var(--palette-text-primary); + } + + @each $color in $palette-colors { + &-#{$color} { + color: var(--palette-#{$color}-darken); + border: 1px solid var(--palette-#{$color}); + + & .alert-icon { + color: var(--palette-#{$color}); + } + } + } +} + +.alert-filled { + &-normal { + color: var(--palette-dark-text); + font-weight: 500; + background-color: var(--palette-dark); + } + + @each $color in $palette-colors { + &-#{$color} { + color: var(--palette-#{$color}-text); + font-weight: 500; + background-color: var(--palette-#{$color}); + } + } +} + +.alert-icon { + display: flex; + opacity: 0.9; + padding: 7px 0; + font-size: 22px; + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; + + &.alert-icon-left { + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; + } + + &.alert-icon-right { + margin-left: 12px; + margin-inline-start: 12px; + margin-inline-end: unset; + } +} + +.alert-message { + padding: 9px 0; +} + +.alert-position { + flex: 1; + display: flex; +} + +.alert-close { + display: flex; + flex: 0; + align-items: center; + margin-left: 8px; +} \ No newline at end of file diff --git a/Styles/components/_avatar.scss b/Styles/components/_avatar.scss new file mode 100644 index 0000000..ead9bf5 --- /dev/null +++ b/Styles/components/_avatar.scss @@ -0,0 +1,131 @@ +@import '../abstracts/variables'; + +.avatar { + display: flex; + overflow: hidden; + position: relative; + display: inline-flex; + align-items: center; + flex-shrink: 0; + line-height: 1; + user-select: none; + border-radius: 50%; + justify-content: center; + color: var(--palette-white); + background-color: var(--palette-grey-light); + + &.avatar-small { + width: 24px; + height: 24px; + font-size: .875rem; + } + + &.avatar-medium { + width: 40px; + height: 40px; + font-size: 1.25rem; + } + + &.avatar-large { + width: 56px; + height: 56px; + font-size: 1.75rem; + } +} + + +.avatar-rounded { + border-radius: var(--default-borderradius); +} + +.avatar-square { + border-radius: 0; +} + +.avatar-img { + color: transparent; + width: 100%; + height: 100%; + object-fit: cover; + text-align: center; + text-indent: 10000px; +} + +.avatar-fallback { + width: 75%; + height: 75%; +} + +.avatar-outlined { + color: var(--palette-text-primary); + background-color: unset; + border: 1px solid var(--palette-text-primary); + + @each $color in $palette-colors { + &.avatar-outlined-#{$color} { + color: var(--palette-#{$color}); + border: 1px solid var(--palette-#{$color}); + } + } +} + +.avatar-filled { + color: var(--palette-white); + background-color: var(--palette-grey-light); + + @each $color in $palette-colors { + &.avatar-filled-#{$color} { + background-color: var(--palette-#{$color}); + } + } +} + + +.avatar-group { + display: flex; + + .avatar:first-child { + margin-inline-start: 0px !important; + } + + &.avatar-group-outlined { + &.avatar-group-outlined-transparent { + .avatar:not(.avatar-outlined) { + border-color: transparent; + } + } + + &.avatar-group-outlined-surface { + .avatar:not(.avatar-outlined) { + border-color: var(--palette-surface); + } + } + + @each $color in $palette-colors { + &.avatar-group-outlined-#{$color} { + .avatar:not(.avatar-outlined) { + border-color: var(--palette-#{$color}); + } + } + } + + .avatar { + border: 2px solid; + + &.avatar-small { + width: 28px; + height: 28px; + } + + &.avatar-medium { + width: 44px; + height: 44px; + } + + &.avatar-large { + width: 60px; + height: 60px; + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_badge.scss b/Styles/components/_badge.scss new file mode 100644 index 0000000..819f074 --- /dev/null +++ b/Styles/components/_badge.scss @@ -0,0 +1,204 @@ + +.badge-root { + position: relative; + display: inline-block; + + .badge-wrapper { + top: 0; + left: 0; + flex: 0 1; + width: 100%; + height: 100%; + display: flex; + pointer-events: none; + position: absolute; + + &.badge { + + &-top { + align-items: flex-start; + + &.left { + justify-content: flex-start; + } + + &.center { + justify-content: center; + } + + &.right { + justify-content: flex-end; + } + } + + &-center { + align-items: center; + + &.left { + justify-content: flex-start; + } + + &.center { + justify-content: center + } + + &.right { + justify-content: flex-end; + } + } + + &-bottom { + align-items: flex-end; + + &.left { + justify-content: flex-start; + } + + &.center { + justify-content: center; + } + + &.right { + justify-content: flex-end; + } + } + } + } +} + +.badge { + border-radius: 10px; + font-size: 12px; + height: 20px; + letter-spacing: 0; + min-width: 20px; + padding: 4px 6px; + pointer-events: auto; + line-height: 1; + position: absolute; + text-align: center; + text-indent: 0; + top: auto; + transition: .3s cubic-bezier(.25,.8,.5,1); + white-space: nowrap; + + &.badge-default { + color: var(--palette-text-primary); + background-color: var(--palette-grey-light); + } + + &.badge-bordered { + border-color: var(--palette-surface); + border-style: solid; + border-width: 2px; + padding: 3px 4px; + + &.badge-icon { + padding: 4px 6px; + + & .icon-badge { + margin-left: -4px; + margin-inline-start: -4px; + margin-inline-end: unset; + margin-top: -4px; + } + } + } + + &.badge-icon { + width: 20px; + height: 20px; + + & .icon-badge { + color: inherit; + font-size: 12px; + margin-left: -2px; + margin-inline-start: -2px; + margin-inline-end: unset; + } + } + + &.badge-dot { + border-radius: 50%; + height: 9px; + min-width: 0; + padding: 0; + width: 9px; + } + + &.badge { + + &-top { + &.left { + inset: auto calc(100% - 4px) calc(100% - 4px) auto; + + &.badge-overlap { + inset: auto calc(100% - 12px) calc(100% - 12px) auto; + } + } + + &.center { + bottom: calc(100% - 4px); + + &.badge-overlap { + bottom: calc(100% - 12px); + } + } + + &.right { + inset: auto auto calc(100% - 4px) calc(100% - 4px); + + &.badge-overlap { + inset: auto auto calc(100% - 12px) calc(100% - 12px); + } + } + } + + &-center { + &.left { + right: calc(100% - 4px); + + &.badge-overlap { + right: calc(100% - 12px); + } + } + + &.center { + } + + &.right { + left: calc(100% - 4px); + + &.badge-overlap { + left: calc(100% - 12px); + } + } + } + + &-bottom { + &.left { + inset: calc(100% - 4px) calc(100% - 4px) auto auto; + + &.badge-overlap { + inset: calc(100% - 12px) calc(100% - 12px) auto auto; + } + } + + &.center { + top: calc(100% - 4px); + + &.badge-overlap { + top: calc(100% - 12px); + } + } + + &.right { + inset: calc(100% - 4px) auto auto calc(100% - 4px); + + &.badge-overlap { + inset: calc(100% - 12px) auto auto calc(100% - 12px); + } + } + } + } +} diff --git a/Styles/components/_breadcrumbs.scss b/Styles/components/_breadcrumbs.scss new file mode 100644 index 0000000..cfdb4bc --- /dev/null +++ b/Styles/components/_breadcrumbs.scss @@ -0,0 +1,48 @@ +.breadcrumbs { + display: flex; + flex-wrap: wrap; + flex: 0 1 auto; + align-items: center; + list-style-type: none; + margin: 0; + padding: 16px 12px; +} + +.breadcrumb-separator { + padding: 0 12px; +} + +.breadcrumb-separator > span { + color: var(--palette-text-primary); + opacity: 0.38 +} + +.breadcrumb-item > a { + display: flex; + align-items: center; +} + +.breadcrumb-item > a > svg.icon-root { + margin-right: 4px; + margin-inline-end: 4px; + margin-inline-start: unset; +} + +.breadcrumb-item.disabled > a { + pointer-events: none; + color: var(--palette-action-disabled); +} + +.breadcrumbs-expander { + cursor: pointer; + display: flex; + background-color: #EEEEEE; +} + +.breadcrumbs-expander:hover { + background-color: #E0E0E0; +} + +.breadcrumbs-expander > svg { + width: 26px; +} diff --git a/Styles/components/_button.scss b/Styles/components/_button.scss new file mode 100644 index 0000000..ca8a27a --- /dev/null +++ b/Styles/components/_button.scss @@ -0,0 +1,270 @@ +@import '../abstracts/variables'; + +.button-root { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + display: inline-flex; + outline: 0; + padding: 0; + position: relative; + align-items: center; + user-select: none; + border-radius: 0; + vertical-align: middle; + -moz-appearance: none; + justify-content: center; + text-decoration: none; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; + + &::-moz-focus-inner { + border-style: none; + } + + &:disabled { + color: var(--palette-action-disabled) !important; + cursor: default; + pointer-events: none; + } +} + +.button { + padding: 6px 16px; + font-family: var(--typography-button-family); + font-size: var(--typography-button-size); + font-weight: var(--typography-button-weight); + line-height: var(--typography-button-lineheight); + letter-spacing: var(--typography-button-letterspacing); + text-transform: var(--typography-button-text-transform); + min-width: 64px; + box-sizing: border-box; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: var(--default-borderradius); + color: var(--palette-text-primary); + + &:hover, &:focus-visible { + background-color: var(--palette-action-default-hover); + } +} + +.button-label { + width: 100%; + display: inherit; + align-items: inherit; + justify-content: inherit; +} + +.button-text { + padding: 6px 8px; + + &.button-text-inherit { + color: inherit; + } + + @each $color in $palette-colors { + &.button-text-#{$color} { + color: var(--palette-#{$color}); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-hover); + } + } + } +} + +.button-outlined { + color: var(--palette-text-primary); + border: 1px solid var(--palette-text-primary); + padding: 5px 15px; + + &.button-outlined-inherit { + color: inherit; + border-color: currentColor; + } + + &.icon-button { + padding: 5px; + } + + &:hover, &:focus-visible { + background-color: var(--palette-action-default-hover); + } + + @each $color in $palette-colors { + &.button-outlined-#{$color} { + color: var(--palette-#{$color}); + border: 1px solid var(--palette-#{$color}); + + &:hover, &:focus-visible { + border: 1px solid var(--palette-#{$color}); + background-color: var(--palette-#{$color}-hover); + } + } + } + + &:disabled { + border: 1px solid var(--palette-action-disabled-background); + } +} + +.button-filled { + color: var(--palette-text-primary); + box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12); + background-color: var(--palette-action-default-hover); + + &.icon-button { + padding: 6px; + } + + &:hover, &:focus-visible { + box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0,0,0,.12); + background-color: var(--palette-action-disabled-background); + } + + &:active { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0,0,0,.12); + } + + + &:disabled { + color: var(--palette-action-disabled); + box-shadow: none; + background-color: var(--palette-action-disabled-background) !important; + } + + @each $color in $palette-colors { + &.button-filled-#{$color} { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-darken); + } + } + } +} + +.button-disable-elevation { + box-shadow: none; + + &:hover { + box-shadow: none; + } + + &:active { + box-shadow: none; + } + + &.focus-visible { + box-shadow: none; + } + + &:disabled { + box-shadow: none; + } +} + + +.button-color-inherit { + color: inherit; + border-color: currentColor; +} + +.button-text-size-small { + padding: 4px 5px; + font-size: 0.8125rem; +} + +.button-text-size-large { + padding: 8px 11px; + font-size: 0.9375rem; +} + +.button-outlined-size-small { + padding: 3px 9px; + font-size: 0.8125rem; + + &.icon-button { + padding: 4px; + } +} + +.button-outlined-size-large { + padding: 7px 21px; + font-size: 0.9375rem; + + &.icon-button { + padding: 4px; + } +} + +.button-filled-size-small { + padding: 4px 10px; + font-size: 0.8125rem; + + &.icon-button { + padding: 5px; + } +} + +.button-filled-size-large { + padding: 8px 22px; + font-size: 0.9375rem; + + &.icon-button { + padding: 5px; + } +} + +.button-full-width { + width: 100%; +} + +.button-label { + .button-icon-start { + display: inherit; + margin-left: -4px; + margin-right: 8px; + margin-inline-start: -4px; + margin-inline-end: 8px; + + &.button-icon-size-small { + margin-left: -2px; + margin-inline-start: -2px; + margin-inline-end: 8px; + } + } + + .button-icon-end { + display: inherit; + margin-left: 8px; + margin-right: -4px; + margin-inline-start: 8px; + margin-inline-end: -4px; + + &.button-icon-size-small { + margin-right: -2px; + margin-inline-end: -2px; + margin-inline-start: 8px; + } + } +} + + + + + +.button-icon-size-small > *:first-child { + font-size: 18px; +} + +.button-icon-size-medium > *:first-child { + font-size: 20px; +} + +.button-icon-size-large > *:first-child { + font-size: 22px; +} \ No newline at end of file diff --git a/Styles/components/_buttongroup.scss b/Styles/components/_buttongroup.scss new file mode 100644 index 0000000..378fbb6 --- /dev/null +++ b/Styles/components/_buttongroup.scss @@ -0,0 +1,322 @@ +@import '../abstracts/variables'; + +.button-group-root { + border-radius: var(--default-borderradius); + display: inline-flex; + + .button-root { + border-radius: var(--default-borderradius); + } + + &.button-group-override-styles { + .button { + color: var(--palette-text-primary); + } + + .button-root { + background-color: inherit; + box-shadow: none; + border: none; + + &:hover, &:focus-visible { + background-color: var(--palette-action-default-hover); + } + } + } +} +.button-group-horizontal { + &:not(.button-group-rtl) { + > .button-root:not(:last-child), > :not(:last-child) .button-root { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + > .button-root:not(:first-child), > :not(:first-child) .button-root { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + } + } + + &.button-group-rtl { + > .button-root:not(:last-child), > :not(:last-child) .button-root { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + } + + > .button-root:not(:first-child), > :not(:first-child) .button-root { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } +} + +.button-group-vertical { + flex-direction: column; + .icon-button { + width: 100%; + } + + > .button-root:not(:last-child), > :not(:last-child) .button-root { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + + > .button-root:not(:first-child), > :not(:first-child) .button-root { + border-top-right-radius: 0; + border-top-left-radius: 0; + margin-top: -1px; + } +} + +.button-group-text { + &.button-group-override-styles { + .button-root { + padding: 6px 8px; + } + + &.button-group-horizontal { + &:not(.button-group-rtl) { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-text-primary); + } + } + + &.button-group-rtl { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-text-primary); + } + } + } + + &.button-group-vertical { + .button-root:not(:last-child), > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-text-primary); + } + } + + @each $color in $palette-colors { + &.button-group-text-#{$color} { + .button-root { + color: var(--palette-#{$color}); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-hover); + } + } + + &.button-group-horizontal { + &:not(.button-group-rtl) { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-#{$color}); + } + } + + &.button-group-rtl { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-#{$color}); + } + } + } + + &.button-group-vertical { + .button-root:not(:last-child), > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-#{$color}); + } + } + } + } + } +} + +.button-group-outlined { + &.button-group-override-styles { + .button-root { + padding: 5px 15px; + border: 1px solid var(--palette-text-primary); + } + + @each $color in $palette-colors { + &.button-group-outlined-#{$color} .button-root { + color: var(--palette-#{$color}); + border: 1px solid var(--palette-#{$color}); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-hover); + } + } + } + } +} + +.button-group-filled { + box-shadow: var(--elevation-2); + + .button-root { + box-shadow: none; + + &:hover, &:focus-visible { + box-shadow: var(--elevation-4); + } + } + + &.button-group-override-styles { + .button-root { + background-color: var(--palette-action-default-hover); + padding: 6px 16px; + } + + &.button-group-horizontal { + &:not(.button-group-rtl) { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-divider); + } + } + + &.button-group-rtl { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-divider); + } + } + } + + &.button-group-vertical { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-divider); + } + } + + @each $color in $palette-colors { + &.button-group-filled-#{$color} { + .button-root { + background-color: var(--palette-#{$color}); + color: var(--palette-#{$color}-text); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-darken); + } + } + + &.button-group-horizontal { + &:not(.button-group-rtl) { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-#{$color}-lighten); + } + } + + &.button-group-rtl { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-#{$color}-lighten); + } + } + } + + &.button-group-vertical { + .button-root:not(:first-child), > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-#{$color}-lighten); + } + } + } + } + } +} + +.button-group-disable-elevation { + box-shadow: none; +} + +.button-group-root { + &.button-group-text-size-small .button-root { + padding: 4px 5px; + font-size: 0.8125rem; + + &.icon-button .icon-root { + font-size: 1.422rem; + } + } + + &.button-group-text-size-large .button-root { + padding: 8px 11px; + font-size: 0.9375rem; + + &.icon-button .icon-root { + font-size: 1.641rem; + } + } + + &.button-group-outlined-size-small .button-root { + padding: 3px 9px; + font-size: 0.8125rem; + + &.icon-button { + padding: 3px 9px; + + .icon-root { + font-size: 1.422rem; + } + } + } + + &.button-group-outlined-size-large .button-root { + padding: 7px 21px; + font-size: 0.9375rem; + + &.icon-button { + padding: 7px 15px; + + .icon-root { + font-size: 1.641rem; + } + } + } + + &.button-group-filled-size-small .button-root { + padding: 4px 10px; + font-size: 0.8125rem; + + &.icon-button { + padding: 4px 10px; + + .icon-root { + font-size: 1.422rem; + } + } + } + + &.button-group-filled-size-large .button-root { + padding: 8px 22px; + font-size: 0.9375rem; + + &.icon-button { + padding: 8px 16px; + + .icon-root { + font-size: 1.641rem; + } + } + } +} + +.button-group-root { + .button-root.icon-button { + padding-right: 12px; + padding-left: 12px; + + .icon-root { + font-size: 1.516rem; + } + + &.ripple-icon { + &:after { + transform: scale(10,10); + } + + &:active:after { + transform: scale(0,0); + opacity: 0.1; + transition: 0s; + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_card.scss b/Styles/components/_card.scss new file mode 100644 index 0000000..6aa626b --- /dev/null +++ b/Styles/components/_card.scss @@ -0,0 +1,59 @@ +.card { + +} + +.card-header { + display: flex; + padding: 16px; + align-items: center; + border-top-left-radius: inherit; + border-top-right-radius: inherit; + + & .card-header-avatar { + flex: 0 0 auto; + margin-right: 16px; + margin-inline-end: 16px; + margin-inline-start: unset; + } + + & .card-header-content { + flex: 1 1 auto; + + & .typography { + margin-bottom: 0; + } + } + + & .card-header-actions { + flex: 0 0 auto; + align-self: flex-start; + margin-top: -8px; + margin-right: -8px; + margin-inline-end: -8px; + margin-inline-start: unset; + } +} + +.card-media { + display: block; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} + +.card-header + .card-media { + border-top-left-radius: 0px; + border-top-right-radius: 0px; +} + +.card-content { + padding: 16px; +} + +.card-actions { + display: flex; + padding: 8px; + align-items: center; +} \ No newline at end of file diff --git a/Styles/components/_carousel.scss b/Styles/components/_carousel.scss new file mode 100644 index 0000000..21da256 --- /dev/null +++ b/Styles/components/_carousel.scss @@ -0,0 +1,211 @@ +@import '../abstracts/variables'; + +.carousel { + display: flex !important; + position: relative; + margin: 0px !important; + clip-path: inset(0px 0px 0px 0px); + overflow: hidden; + + @each $color in $palette-colors { + &.carousel-#{$color} { + color: var(--palette-#{$color}-text); + } + } +} + +.carousel-elements-rtl { + transform: rotate(180deg) !important; +} + +.carousel-item { + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + margin: inherit; + padding: inherit; + z-index: 2; + + @each $color in $palette-colors { + &.carousel-item-#{$color} { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + } + } +} + +.carousel-item-exit { + z-index: 1; +} + +/* ### Transitions ### */ + +/*Fade +*/ +@keyframes carousel-transition-fade-in-keyframe { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes carousel-transition-fade-out-keyframe { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} + + +.carousel-transition-fade-in { + animation: 0.5s carousel-transition-fade-in-keyframe +} + +.carousel-transition-fade-out { + animation: 0.5s carousel-transition-fade-out-keyframe; + animation-fill-mode: forwards; +} + +.carousel-transition-none { + display: none; +} + + + +/*Slide +*/ +@keyframes carousel-transition-slide-next-enter-keyframe { + from { + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(0, 0, 0); + } +} + +@keyframes carousel-transition-slide-next-rtl-enter-keyframe { + from { + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(0, 0, 0); + } +} + +@keyframes carousel-transition-slide-next-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes carousel-transition-slide-next-rtl-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(100%, 0, 0); + } +} + +.carousel-transition-slide-next-enter { + animation: 0.5s carousel-transition-slide-next-enter-keyframe +} + +.carousel-transition-slide-next-rtl-enter { + animation: 0.5s carousel-transition-slide-next-rtl-enter-keyframe; +} + +.carousel-transition-slide-next-exit { + animation: 0.5s carousel-transition-slide-next-exit-keyframe; + animation-fill-mode: forwards; + +} + +.carousel-transition-slide-next-rtl-exit { + animation: 0.5s carousel-transition-slide-next-rtl-exit-keyframe; + animation-fill-mode: forwards; +} + + + +@keyframes carousel-transition-slide-prev-enter-keyframe { + from { + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(0, 0, 0); + } +} + +@keyframes carousel-transition-slide-prev-rtl-enter-keyframe { + from { + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(0, 0, 0); + } +} + +@keyframes carousel-transition-slide-prev-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(100%, 0, 0); + } +} + +@keyframes carousel-transition-slide-prev-rtl-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + + to { + transform: translate3d(-100%, 0, 0); + } +} + +.carousel-transition-slide-prev-enter { + animation: 0.5s carousel-transition-slide-prev-enter-keyframe +} + +.carousel-transition-slide-prev-rtl-enter { + animation: 0.5s carousel-transition-slide-prev-rtl-enter-keyframe; +} + +.carousel-transition-slide-prev-exit { + animation: 0.5s carousel-transition-slide-prev-exit-keyframe; + animation-fill-mode: forwards; +} + +.carousel-transition-slide-prev-rtl-exit { + animation: 0.5s carousel-transition-slide-prev-rtl-exit-keyframe; + animation-fill-mode: forwards; +} + diff --git a/Styles/components/_charts.scss b/Styles/components/_charts.scss new file mode 100644 index 0000000..7b2f427 --- /dev/null +++ b/Styles/components/_charts.scss @@ -0,0 +1,135 @@ +.chart { + display: flex; + + &.chart-legend-bottom { + flex-direction: column; + + .chart-legend { + margin-top: 10px; + justify-content: center; + width: 100%; + } + } + + &.chart-legend-top { + flex-direction: column-reverse; + + & .chart-legend { + justify-content: center; + width: 100%; + } + } + + &.chart-legend-right { + flex-direction: row; + + & .chart-legend { + flex-direction: column; + } + } + + &.chart-legend-left { + flex-direction: row-reverse; + + & .chart-legend { + flex-direction: column; + } + } + + + & .chart-donut, .chart-pie, chart-line { + display: flex; + margin: auto; + } + + & .chart-legend { + display: flex; + padding: 10px 0px; + margin: auto; + flex-wrap: wrap; + + & .chart-legend-item { + display: block; + margin: 2px 5px; + + & .chart-legend-marker { + height: 12px; + width: 12px; + border-radius: 50%; + position: relative; + display: inline-flex; + } + + & .chart-legend-text { + display: inline-flex; + } + } + } +} + +.charts-yaxis { + fill: var(--palette-text-primary); +} + +.charts-xaxis { + fill: var(--palette-text-primary); +} + +.chart-donut { + & .donut-hole { + fill: transparent; + user-select: none; + pointer-events: unset; + } + + & .donut-ring { + fill: transparent; + stroke-width: 5; + stroke: white; + pointer-events: unset; + } + + & .donut-segment { + stroke-width: 5; + fill: transparent; + pointer-events: stroke; + -webkit-transition: stroke .2s ease; + -moz-transition: stroke .2s ease; + -o-transition: stroke .2s ease; + transition: stroke .2s ease; + } +} + +.chart-legend-marker { + height: 12px; + width: 12px; + border-radius: 50%; + position: relative; + display: inline-block; +} + + + + + + +.chart-marker-color-0 { + background-color: #008FFB; +} + +.chart-marker-color-1 { + background-color: #00E396; +} + +.chart-marker-color-2 { + background-color: #FEB019; +} + +.chart-marker-color-3 { + background-color: #FF4560; +} + +.chart-marker-color-4 { + background-color: #594ae2; +} + diff --git a/Styles/components/_checkbox.scss b/Styles/components/_checkbox.scss new file mode 100644 index 0000000..a7845af --- /dev/null +++ b/Styles/components/_checkbox.scss @@ -0,0 +1,45 @@ +.checkbox { + cursor: pointer; + display: inline-flex; + align-items: center; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; + + &.disabled, .disabled:hover, .disabled:focus-visible { + cursor: default; + background-color: transparent !important; + + & * { + cursor: default; + color: var(--palette-text-disabled); + } + } + + &.readonly, .readonly:hover { + cursor: default; + } + + & .checkbox-dense { + padding: 4px; + } +} + +.checkbox-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; +} + +.checkbox-span { + display: inline-block; + width: 100%; + cursor: pointer; +} + diff --git a/Styles/components/_chip.scss b/Styles/components/_chip.scss new file mode 100644 index 0000000..5ce8aa1 --- /dev/null +++ b/Styles/components/_chip.scss @@ -0,0 +1,153 @@ +@import '../abstracts/variables'; + +.chip { + border: none; + cursor: default; + display: inline-flex; + max-width: 100%; + outline: 0; + padding: 0 12px; + position: relative; + box-sizing: border-box; + transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: center; + white-space: nowrap; + vertical-align: middle; + justify-content: center; + text-decoration: none; + line-height: normal; + margin: 4px; + + &.disabled { + opacity: 0.5; + pointer-events: none; + } + + &.chip-size-small { + border-radius: 12px; + font-size: 12px; + height: 24px; + } + + &.chip-size-medium { + height: 32px; + font-size: 14px; + border-radius: 16px; + } + + &.chip-size-large { + height: 40px; + font-size: 16px; + border-radius: 20px; + } + + &.chip-label { + border-radius: var(--default-borderradius); + } + + &.clickable { + cursor: pointer; + } + + .chip-icon { + margin-left: -4px; + margin-right: 4px; + margin-inline-start: -4px; + margin-inline-end: 4px; + color: inherit; + } + + .chip-close-button { + padding: 1px; + margin-right: -4px; + margin-left: 6px; + margin-inline-end: -4px; + margin-inline-start: 6px; + height: 18px; + width: 18px; + color: inherit; + transition: .3s cubic-bezier(.25,.8,.5,1),visibility 0s; + + .icon-size-small { + font-size: 1.15rem; + } + + &:hover { + opacity: .70; + } + } + + & > .chip-content { + align-items: center; + display: inline-flex; + height: 100%; + max-width: 100%; + user-select: none; + } +} + +.chip-filled { + color: var(--palette-text-primary); + background-color: var(--palette-action-disabled-background); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: var(--palette-action-disabled); + } + + @each $color in $palette-colors { + &.chip-color-#{$color} { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: var(--palette-#{$color}-darken); + } + } + } +} +.chip-outlined { + color: var(--palette-text-primary); + border: 1px solid var(--palette-lines-inputs); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: var(--palette-action-default-hover); + } + + @each $color in $palette-colors { + &.chip-color-#{$color} { + color: var(--palette-#{$color}); + border: 1px solid var(--palette-#{$color}); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: var(--palette-#{$color}-hover); + } + + &.chip-selected { + background-color: var(--palette-#{$color}-hover); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-#{$color}-rgb), 0.12); + } + } + } + } +} +.chip-text { + color: var(--palette-text-primary); + background-color: var(--palette-action-default-hover); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: var(--palette-action-disabled-background); + } + + @each $color in $palette-colors { + &.chip-color-#{$color} { + color: var(--palette-#{$color}); + background-color: var(--palette-#{$color}-hover); + + &:hover:not(.disabled), &:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-#{$color}-rgb), 0.12); + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_collapse.scss b/Styles/components/_collapse.scss new file mode 100644 index 0000000..22c5a24 --- /dev/null +++ b/Styles/components/_collapse.scss @@ -0,0 +1,48 @@ +.collapse-container { + height: 0px; + overflow: hidden; +} + +@keyframes expand-anim { + from { + height: 0; + } +} + +.collapse-entering { + animation: expand-anim 1s ease-in-out 0ms 1 forwards; + + &.navgroup-collapse { + animation-duration: 300ms !important; + } +} + +.collapse-entered { + overflow: initial; +} + +@keyframes collapse-anim { + to { + height: 0; + } +} + +.collapse-exiting { + animation: collapse-anim 0.5s cubic-bezier(0, 1, 0, 1) 0ms 1 forwards; + + &.navgroup-collapse { + animation-duration: 300ms; + } +} + +.collapse-hidden { + visibility: hidden; +} + +.collapse-wrapper { + display: flex; +} + +.collapse-wrapper-inner { + width: 100%; +} diff --git a/Styles/components/_datagrid.scss b/Styles/components/_datagrid.scss new file mode 100644 index 0000000..62c34c4 --- /dev/null +++ b/Styles/components/_datagrid.scss @@ -0,0 +1,132 @@ +@import '../abstracts/variables'; + +.data-grid { + th { + position: relative; + } + + .table-cell { + &.edit-mode-cell { + //padding: 0 !important; + + .input-control { + margin: 0 !important; + } + + .input { + font-size: inherit; + + &:before { + content: none; + } + + &after { + content: none; + } + + .input-outlined-border { + border: none; + } + } + } + + &.filter-header-cell { + padding: 6px 24px 6px 16px; + padding-inline-start: 16px; + padding-inline-end: 24px; + } + + &.sticky-left { + left: 0px; + position: sticky; + background-color: var(--palette-background-grey); + z-index: 1; + } + + &.sticky-right { + right: 0px; + position: sticky; + background-color: var(--palette-background-grey); + z-index: 1; + } + + .input-text { + margin-top: 0 !important; + } + + .column-header { + display: flex; + justify-content: space-between; + + .sortable-column-header { + width: 100%; + } + + &:hover { + .column-options .sort-direction-icon, .column-options .column-options-icon { + opacity: 0.8; + color: var(--palette-action-default); + } + + .column-options .menu .icon-button-label { + opacity: 1.0; + color: var(--palette-action-default); + } + } + + .column-options { + display: inline-flex; + align-items: center; + flex-direction: inherit; + justify-content: flex-start; + } + + .sort-direction-icon { + font-size: 18px; + margin-left: 4px; + margin-left: 4px; + margin-inline-start: 4px; + margin-inline-end: unset; + user-select: none; + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + opacity: 0; + + &.direction-desc { + opacity: 1; + transform: rotate(180deg); + } + + &.direction-asc { + opacity: 1; + transform: rotate(0deg); + } + } + + .sort-index { + transform: scale(0.9) translate(-2px, -2px); + } + + .column-options .menu .icon-button-label { + /*font-size: 18px;*/ + user-select: none; + /*margin-right: 4px;*/ + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + opacity: 0; + } + } + + .resizer { + position: absolute; + top: 0; + right: 0; + width: 8px; + cursor: col-resize; + user-select: none; + } + + .resizer:hover, + .resizing { + border-right: 2px solid var(--palette-primary); + } + } +} \ No newline at end of file diff --git a/Styles/components/_dialog.scss b/Styles/components/_dialog.scss new file mode 100644 index 0000000..ed28590 --- /dev/null +++ b/Styles/components/_dialog.scss @@ -0,0 +1,201 @@ +.dialog-container { + display: flex; + position: fixed; + top: 0; + width: 100%; + height: 100%; + z-index: var(--zindex-dialog); + + &.dialog-center { + align-items: center; + justify-content: center; + } + + &.dialog-topcenter { + align-items: flex-start; + justify-content: center; + padding-top: 32px; + } + + &.dialog-bottomcenter { + align-items: flex-end; + justify-content: center; + padding-bottom: 32px; + } + + &.dialog-centerright { + align-items: center; + justify-content: flex-end; + padding-right: 32px; + } + + &.dialog-centerleft { + align-items: center; + justify-content: flex-start; + padding-left: 32px; + } + + &.dialog-topleft .dialog { + position: absolute; + top: 32px; + left: 32px; + } + + &.dialog-topright .dialog { + position: absolute; + top: 32px; + right: 32px; + } + + &.dialog-bottomleft .dialog { + position: absolute; + bottom: 32px; + left: 32px; + } + + &.dialog-bottomright .dialog { + position: absolute; + bottom: 32px; + right: 32px; + } +} + +.dialog { + display: flex; + z-index: calc(var(--zindex-dialog) + 2); + flex-direction: column; + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + -webkit-animation: open-dialog-center 0.1s cubic-bezier(0.390, 0.575, 0.565, 1.000) both; + animation: open-dialog-center 0.1s cubic-bezier(0.390, 0.575, 0.565, 1.000) both; + box-shadow: 0px 11px 15px -7px rgba(0,0,0,0.2), 0px 24px 38px 3px rgba(0,0,0,0.14), 0px 9px 46px 8px rgba(0,0,0,0.12); + + &.dialog-rtl .dialog-title .button-root { + right: unset; + left: 8px; + } + + & .dialog-title { + z-index: +1; + flex: 0 0 auto; + margin: 0; + padding: 16px 24px; + border-top-left-radius: var(--default-borderradius); + border-top-right-radius: var(--default-borderradius); + + + * > .dialog-content { + border-radius: 0 + } + & .button-root { + top: 8px; + right: 8px; + position: absolute; + } + } + + & .dialog-content { + position: relative; + flex: 1 1 auto; + padding: 8px 24px; + -webkit-overflow-scrolling: touch; + border-top-left-radius: var(--default-borderradius); + border-top-right-radius: var(--default-borderradius); + + &.dialog-no-side-padding { + padding: 12px 0px; + } + } + + & .dialog-actions { + flex: 0 0 auto; + display: flex; + padding: 8px; + align-items: center; + justify-content: flex-end; + border-bottom-left-radius: var(--default-borderradius); + border-bottom-right-radius: var(--default-borderradius); + + & > :not(:first-child) { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; + } + } +} + + +.dialog-width-false { + max-width: calc(100% - 64px); +} + +.dialog-width-xs { + max-width: 444px; +} + +.dialog-width-sm { + max-width: 600px; +} + +.dialog-width-md { + max-width: 960px; +} + +.dialog-width-lg { + max-width: 1280px; +} + +.dialog-width-xl { + max-width: 1920px; +} + +.dialog-width-xxl { + max-width: 2560px; +} + +.dialog-width-full { + width: calc(100% - 64px); +} + +.dialog-fullscreen { + width: 100%; + height: 100%; + margin: 0; + max-width: 100%; + max-height: none; + border-radius: 0; +} + +@-webkit-keyframes open-dialog-center { + 0% { + opacity: 0; + } + + 1% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 1; + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes open-dialog-center { + 0% { + opacity: 0; + } + + 1% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 1; + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} diff --git a/Styles/components/_divider.scss b/Styles/components/_divider.scss new file mode 100644 index 0000000..1b1ca10 --- /dev/null +++ b/Styles/components/_divider.scss @@ -0,0 +1,39 @@ +.divider { + margin: 0; + flex-shrink: 0; + border-color: var(--palette-divider); + border-width: 1px; + border-style: solid none none none; +} + +.divider-absolute { + left: 0; + width: 100%; + bottom: 0; + position: absolute; +} + +.divider-inset { + margin-left: 72px; + margin-inline-start: 72px; + margin-inline-end: unset; +} + +.divider-light { + border-color: var(--palette-divider-light); +} + +.divider-middle { + margin-left: 16px; + margin-right: 16px; +} + +.divider-vertical { + border-style: none solid none none; + height: 100%; +} + +.divider-flexitem { + height: auto; + align-self: stretch; +} \ No newline at end of file diff --git a/Styles/components/_dropzone.scss b/Styles/components/_dropzone.scss new file mode 100644 index 0000000..496d817 --- /dev/null +++ b/Styles/components/_dropzone.scss @@ -0,0 +1,35 @@ + +.drop-zone { + position:relative; + transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.drop-zone-drag-block > * { + pointer-events: none; +} + +.drop-zone-can-drop { + background-color: var(--palette-success-hover); +} + +.drop-zone-no-drop { + background-color: var(--palette-error-hover); +} + +.drop-item:not(.drop-item-preview-start) { + cursor: grab; + user-select: none; + + &:active { + cursor: grabbing; + } +} + +.drop-item-preview-start { + height: 20px; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: +1; +} \ No newline at end of file diff --git a/Styles/components/_expansionpanel.scss b/Styles/components/_expansionpanel.scss new file mode 100644 index 0000000..572c7c3 --- /dev/null +++ b/Styles/components/_expansionpanel.scss @@ -0,0 +1,125 @@ + +.expansion-panels { + flex: 0 1 auto; + position: relative; + max-width: 100%; + transition: .3s cubic-bezier(.25,.8,.5,1); + border-radius: var(--default-borderradius); + + &.expansion-panels-square { + border-radius: 0px; + } + + &.expansion-panels-borders { + & .expand-panel { + border-bottom: 1px solid var(--palette-lines-default); + } + } +} + +.expand-panel { + flex: 1 0 100%; + max-width: 100%; + position: relative; + transition: margin .3s cubic-bezier(.25,.8,.5,1); + transition-delay: 100ms; + color: var(--palette-text-primary); + background-color: var(--palette-surface); + + &.expand-panel-border { + border-bottom: 1px solid var(--palette-lines-default); + } + + &:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } + + &:last-child { + border-bottom: none; + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; + } + + &.panel-expanded { + margin: 16px 0; + border-radius: inherit; + border-bottom: none; + transition-delay: 0ms; + + &:first-child { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + } + + & + .expand-panel { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } + } + + &.panel-next-expanded { + border-bottom: none; + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; + } + + & .expand-panel-header { + width: 100%; + align-items: center; + display: flex; + font-size: .9375rem; + line-height: 1; + min-height: 48px; + outline: none; + padding: 16px 24px; + position: relative; + transition: min-height .3s cubic-bezier(.25,.8,.5,1); + user-select: none; + + &:hover { + cursor: pointer; + } + + & .expand-panel-text { + flex: 1 1 auto; + } + + & .expand-panel-icon { + transition: .3s cubic-bezier(.25,.8,.5,1),visibility 0s; + + &.transform { + transform: rotate(-180deg); + } + } + } + + & .expand-panel-content { + padding: 0 24px 16px; + flex: 1 1 auto; + max-width: 100%; + + &.expand-panel-gutters { + padding-left: 0px; + padding-right: 0px; + } + + &.expand-panel-dense { + padding-top: 0px; + padding-bottom: 0px; + } + } +} + +.disabled { + & > .expand-panel-header { + color: var(--palette-text-disabled); + + &:hover { + cursor: default; + } + } +} \ No newline at end of file diff --git a/Styles/components/_fab.scss b/Styles/components/_fab.scss new file mode 100644 index 0000000..e9f6049 --- /dev/null +++ b/Styles/components/_fab.scss @@ -0,0 +1,139 @@ +@import '../abstracts/variables'; + +.fab { + padding: 0; + font-family: var(--typography-button-family); + font-size: var(--typography-button-size); + font-weight: var(--typography-button-weight); + line-height: var(--typography-button-lineheight); + letter-spacing: var(--typography-button-letterspacing); + text-transform: var(--typography-button-text-transform); + min-width: 0; + box-shadow: 0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12); + box-sizing: border-box; + min-height: 36px; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 50%; + color: var(--palette-text-primary); + background-color: var(--palette-action-default-hover); + + &:hover, &:focus-visible { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0,0,0,.12); + text-decoration: none; + background-color: var(--palette-action-disabled-background); + } + + &:active { + box-shadow: 0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12); + } + + &:disabled { + color: var(--palette-action-disabled); + box-shadow: none; + background-color: var(--palette-action-disabled-background); + cursor: default; + pointer-events: none; + + &:hover { + background-color: var(--palette-action-disabled-background); + } + } +} + +.fab-disable-elevation { + box-shadow: none; + + &:hover { + box-shadow: none; + } + + &:active { + box-shadow: none; + } + + &.focus-visible { + box-shadow: none; + } + + &:disabled { + box-shadow: none; + } +} + +.fab-label { + width: 100%; + display: inherit; + align-items: inherit; + justify-content: inherit; +} + + +@each $color in $palette-colors { + .fab-#{$color} { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + + &:hover, &:focus-visible { + background-color: var(--palette-#{$color}-darken); + } + } +} + +.fab-extended { + + &.fab-size-large { + width: auto; + height: 48px; + padding: 0 16px; + min-width: 48px; + min-height: auto; + border-radius: 24px; + + .fab-label { + gap: 8px; + } + } + + &.fab-size-small { + width: auto; + height: 34px; + padding: 0 12px; + min-width: 34px; + border-radius: 17px; + + .fab-label { + gap: 4px; + } + } + + &.fab-size-medium { + width: auto; + height: 40px; + padding: 0 16px; + min-width: 40px; + border-radius: 20px; + + .fab-label { + gap: 8px; + } + } +} + +.fab-color-inherit { + color: inherit; +} + +.fab-size-small { + width: 40px; + height: 40px; +} + +.fab-size-medium { + width: 48px; + height: 48px; +} + +.fab-size-large { + width: 56px; + height: 56px; +} diff --git a/Styles/components/_field.scss b/Styles/components/_field.scss new file mode 100644 index 0000000..55db22d --- /dev/null +++ b/Styles/components/_field.scss @@ -0,0 +1,33 @@ +.input-control.field { + .input-slot { + height: auto; + min-height: 19px; + + &.input-root-outlined.input-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 14px; + } + + &.input-root-filled.input-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 12px; + } + + &.input-slot-nopadding { + padding-top: 0px; + padding-bottom: 0px; + + &.input-root-filled { + padding-top: 21px; + padding-bottom: 2px; + } + + &.input-root-outlined { + padding-top: 7px; + padding-bottom: 2px; + } + } + } +} diff --git a/Styles/components/_fileupload.scss b/Styles/components/_fileupload.scss new file mode 100644 index 0000000..1bf458a --- /dev/null +++ b/Styles/components/_fileupload.scss @@ -0,0 +1,7 @@ +.file-upload { + flex-grow: 0; +} + +.file-upload > .input-control-input-container { + display: initial !important; +} diff --git a/Styles/components/_form.scss b/Styles/components/_form.scss new file mode 100644 index 0000000..4850de6 --- /dev/null +++ b/Styles/components/_form.scss @@ -0,0 +1,5 @@ +.form { + +} + + \ No newline at end of file diff --git a/Styles/components/_grid.scss b/Styles/components/_grid.scss new file mode 100644 index 0000000..ad82aa3 --- /dev/null +++ b/Styles/components/_grid.scss @@ -0,0 +1,618 @@ +@import '../abstracts/variables'; + +.grid { + width: 100%; + display: flex; + flex-wrap: wrap; + box-sizing: border-box; +} + +.grid-item { + margin: 0; + box-sizing: border-box; +} + + +.grid-spacing-xs-1 { + width: calc(100% + 8px); + margin: -4px; +} + +.grid-spacing-xs-1 > .grid-item { + padding: 4px; +} + +.grid-spacing-xs-2 { + width: calc(100% + 16px); + margin: -8px; +} + +.grid-spacing-xs-2 > .grid-item { + padding: 8px; +} + +.grid-spacing-xs-3 { + width: calc(100% + 24px); + margin: -12px; +} + +.grid-spacing-xs-3 > .grid-item { + padding: 12px; +} + +.grid-spacing-xs-4 { + width: calc(100% + 32px); + margin: -16px; +} + +.grid-spacing-xs-4 > .grid-item { + padding: 16px; +} + +.grid-spacing-xs-5 { + width: calc(100% + 40px); + margin: -20px; +} + +.grid-spacing-xs-5 > .grid-item { + padding: 20px; +} + +.grid-spacing-xs-6 { + width: calc(100% + 48px); + margin: -24px; +} + +.grid-spacing-xs-6 > .grid-item { + padding: 24px; +} + +.grid-spacing-xs-7 { + width: calc(100% + 56px); + margin: -28px; +} + +.grid-spacing-xs-7 > .grid-item { + padding: 28px; +} + +.grid-spacing-xs-8 { + width: calc(100% + 64px); + margin: -32px; +} + +.grid-spacing-xs-8 > .grid-item { + padding: 32px; +} + +.grid-spacing-xs-9 { + width: calc(100% + 72px); + margin: -36px; +} + +.grid-spacing-xs-9 > .grid-item { + padding: 36px; +} + +.grid-spacing-xs-10 { + width: calc(100% + 80px); + margin: -40px; +} + +.grid-spacing-xs-10 > .grid-item { + padding: 40px; +} + +.grid-item-xs-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; +} + +.grid-item-xs-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; +} + +.grid-item-xs-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; +} + +.grid-item-xs-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; +} + +.grid-item-xs-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; +} + +.grid-item-xs-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; +} + +.grid-item-xs-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; +} + +.grid-item-xs-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; +} + +.grid-item-xs-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; +} + +.grid-item-xs-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; +} + +.grid-item-xs-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; +} + +.grid-item-xs-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; +} + +.grid-item-xs-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; +} + +.grid-item-xs-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; +} + +@media (min-width:$breakpoint-sm) { + .grid-item-sm-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-sm-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-sm-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-sm-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-sm-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-sm-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-sm-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-sm-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-sm-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-sm-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-sm-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-sm-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-sm-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-sm-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} + +@media (min-width:$breakpoint-md) { + .grid-item-md-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-md-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-md-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-md-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-md-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-md-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-md-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-md-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-md-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-md-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-md-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-md-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-md-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-md-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} + +@media (min-width:$breakpoint-lg) { + .grid-item-lg-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-lg-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-lg-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-lg-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-lg-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-lg-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-lg-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-lg-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-lg-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-lg-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-lg-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-lg-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-lg-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-lg-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} + +@media (min-width:$breakpoint-xl) { + .grid-item-xl-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-xl-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-xl-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-xl-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-xl-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-xl-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-xl-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-xl-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-xl-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-xl-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-xl-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-xl-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-xl-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-xl-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} + +@media (min-width:$breakpoint-xxl) { + .grid-item-xxl-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-xxl-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-xxl-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-xxl-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-xxl-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-xxl-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-xxl-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-xxl-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-xxl-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-xxl-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-xxl-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-xxl-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-xxl-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-xxl-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} \ No newline at end of file diff --git a/Styles/components/_iconbutton.scss b/Styles/components/_iconbutton.scss new file mode 100644 index 0000000..3a05d10 --- /dev/null +++ b/Styles/components/_iconbutton.scss @@ -0,0 +1,83 @@ +.icon-button { + flex: 0 0 auto; + padding: 12px; + overflow: visible; + font-size: 1.5rem; + text-align: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 50%; + color: var(--palette-action-default); + + &.button { + min-width: unset; + border-radius: var(--default-borderradius); + } + + &:hover, &:focus-visible { + background-color: var(--palette-action-default-hover); + } + + &:disabled { + color: var(--palette-action-disabled); + background-color: transparent; + } + + &.readonly, .readonly:hover { + cursor: default; + } +} + +.icon-button-color-inherit { + color: inherit; + + &:hover, &:focus-visible { + background-color: var(--palette-action-default-hover); + } +} + +.icon-button-label { + width: 100%; + display: flex; + align-items: inherit; + justify-content: inherit; +} + +.icon-button-edge-start { + margin-left: -12px; + margin-inline-start: -12px; + margin-inline-end: unset; +} + +.icon-button-edge-end { + margin-right: -12px; + margin-inline-end: -12px; + margin-inline-start: unset; +} + +.icon-button-edge-margin-end { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} + +.icon-button-size-small { + padding: 3px; + font-size: 1.125rem; + + &.icon-button-edge-start { + margin-left: -3px; + margin-inline-start: -3px; + margin-inline-end: unset; + } + + &.icon-button-edge-end { + margin-right: -3px; + margin-inline-end: -3px; + margin-inline-start: unset; + } +} + + +.icon-button-size-large.button > .icon-button-label > .icon-size-large { + font-size: 2rem; +} diff --git a/Styles/components/_icons.scss b/Styles/components/_icons.scss new file mode 100644 index 0000000..c1e264b --- /dev/null +++ b/Styles/components/_icons.scss @@ -0,0 +1,39 @@ +.icon-default { + color: var(--palette-text-secondary); +} + + +.disabled { + .icon-root, .svg-icon, .icon-default { + color: var(--palette-text-disabled); + } +} + +.icon-root { + width: 1em; + height: 1em; + display: inline-block; + transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + flex-shrink: 0; + user-select: none; + + &:focus { + outline: none; + } + + &.svg-icon { + fill: currentColor; + } +} + +.icon-size-small { + font-size: 1.25rem; +} + +.icon-size-medium { + font-size: 1.5rem; +} + +.icon-size-large { + font-size: 2.25rem; +} \ No newline at end of file diff --git a/Styles/components/_image.scss b/Styles/components/_image.scss new file mode 100644 index 0000000..2e28a9e --- /dev/null +++ b/Styles/components/_image.scss @@ -0,0 +1,6 @@ +.image { + &.fluid{ + max-width: 100%; + height: auto; + } +} \ No newline at end of file diff --git a/Styles/components/_input.scss b/Styles/components/_input.scss new file mode 100644 index 0000000..9875e87 --- /dev/null +++ b/Styles/components/_input.scss @@ -0,0 +1,496 @@ +.input { + position: relative; + color: var(--palette-text-primary); + cursor: text; + display: inline-flex; + font-size: 1rem; + box-sizing: border-box; + align-items: center; + font-weight: 400; + line-height: 1.1876em; + letter-spacing: 0.00938em; + + &.input-full-width { + width: 100%; + } + + &.disabled { + color: var(--palette-text-disabled); + cursor: default; + } + + &.disabled > .input-adornment { + color: var(--palette-text-disabled); + pointer-events: none; + } + + &.input-underline { + &:before { + left: 0; + right: 0; + bottom: 0; + content: "\00a0"; + position: absolute; + transition: border-bottom 0.2s, background-color 0.2s; + border-bottom: 1px solid var(--palette-lines-inputs); + pointer-events: none; + } + + &:hover:not(.disabled):before { + border-bottom: 1px solid var(--palette-action-default); + } + + &:after { + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + transform: scaleX(0); + transition: transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + border-bottom: 2px solid var(--palette-primary); + pointer-events: none; + } + + &.disabled:before { + border-bottom-style: dotted; + } + + &.input-error:after { + transform: scaleX(1); + border-bottom-color: var(--palette-error); + } + } + + &.input-filled { + position: relative; + transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + background-color: rgba(0, 0, 0, 0.09); + border-top-left-radius: 4px; + border-top-right-radius: 4px; + + &:hover { + background-color: rgba(0, 0, 0, 0.13); + } + + &.focused { + background-color: rgba(0, 0, 0, 0.09); + } + + &.disabled { + background-color: rgba(0, 0, 0, 0.12); + } + + &.input-adorned-start { + padding-left: 12px; + padding-inline-start: 12px; + padding-inline-end: unset; + } + + &.input-adorned-end { + padding-right: 12px; + padding-inline-end: 12px; + padding-inline-start: unset; + } + + &.input-underline { + &:before { + left: 0; + right: 0; + bottom: 0; + content: "\00a0"; + position: absolute; + transition: border-bottom-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-bottom: 1px solid var(--palette-lines-inputs); + pointer-events: none; + } + + &:after { + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + transform: scaleX(0); + transition: transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + border-bottom: 2px solid var(--palette-primary); + pointer-events: none; + } + + &:hover:before { + border-bottom: 1px solid var(--palette-action-default); + } + + &.disabled:before { + border-bottom-style: dotted; + } + + &.input-error:after { + transform: scaleX(1); + border-bottom-color: var(--palette-error); + } + } + } + + &.input-outlined { + position: relative; + border-width: 0px; + + & .input-outlined-border { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + box-sizing: border-box; + width: 100%; + max-width: 100%; + height: 100%; + text-align: start; + pointer-events: none; + border-radius: var(--default-borderradius); + border-color: var(--palette-lines-inputs); + border-width: 1px; + border-style: solid; + transition: border-width,border-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + &:not(.disabled):not(:focus-within):hover .input-outlined-border { + border-color: var(--palette-action-default); + } + + &:focus-within .input-outlined-border { + border-width: 2px; + border-color: var(--palette-primary); + } + + &.disabled .input-outlined-border { + border-color: var(--palette-action-disabled); + } + + &.input-adorned-start { + padding-left: 14px; + padding-inline-start: 14px; + padding-inline-end: unset; + } + + &.input-adorned-end { + padding-right: 14px; + padding-inline-end: 14px; + padding-inline-start: unset; + } + } +} + +.input-error .input-outlined-border { + border-color: var(--palette-error) !important; +} + +.input:focus-within.input-underline:after { + transform: scaleX(1); +} + +.input > input, div.input-slot { + &.input-root { + font: inherit; + color: currentColor; + width: 100%; + border: 0; + height: 1.1876em; + margin: 0; + display: block; + padding: 6px 0 7px; + min-width: 0; + background: none; + position: relative; + box-sizing: content-box; + letter-spacing: inherit; + -webkit-tap-highlight-color: transparent; + + @include inputplaceholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + &.input-root-margin-dense { + padding-top: 3px; + } + + &.input-root-multiline { + height: auto; + resize: none; + padding: 0; + } + + &.input-root-type-search { + -moz-appearance: textfield; + -webkit-appearance: textfield; + } + + &:focus { + outline: 0; + } + + &:invalid { + box-shadow: none; + } + + &:disabled { + opacity: 1; + } + + &.input-root-filled { + padding: 27px 12px 10px; + + &.input-root-margin-dense { + padding-top: 23px; + padding-bottom: 6px; + } + + &:-webkit-autofill { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } + + &.input-root-hidden-label { + padding-top: 18px; + padding-bottom: 19px; + + &.input-root-margin-dense { + padding-top: 10px; + padding-bottom: 11px; + } + } + + &.input-root-multiline { + padding: 0; + } + + &.input-root-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 12px; + } + + &.input-root-adorned-end { + padding-right: 0; + padding-inline-end: 0; + padding-inline-start: 12px; + } + } + } + + &.input-root-outlined { + padding: 18.5px 14px; + + + &.input-root:-webkit-autofill { + border-radius: inherit; + } + + &.input-root-margin-dense { + padding-top: 10.5px; + padding-bottom: 10.5px; + } + + &.input-root-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 14px; + } + + &.input-root-adorned-end { + padding-right: 0; + padding-inline-end: 0; + padding-inline-start: 14px; + } + } + + &::-ms-reveal, &::-ms-clear { + display: none !important; + } +} + +.input > textarea { + &.input-root { + font: inherit; + color: currentColor; + width: 100%; + border: 0; + height: auto; + margin: 6px 0 7px; + padding: 0; + display: block; + min-width: 0; + background: none; + position: relative; + box-sizing: content-box; + letter-spacing: inherit; + -webkit-tap-highlight-color: transparent; + height: auto; + resize: none; + cursor: auto; + + @include inputplaceholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + &.input-root-margin-dense { + margin-top: 3px; + } + + &.input-root-type-search { + -moz-appearance: textfield; + -webkit-appearance: textfield; + } + + &:focus { + outline: 0; + } + + &:invalid { + box-shadow: none; + } + + &:disabled { + opacity: 1; + } + + &.input-root-filled { + margin: 27px 12px 10px; + + &.input-root-margin-dense { + margin-top: 23px; + margin-bottom: 6px; + } + + &:-webkit-autofill { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } + + &.input-root-hidden-label { + margin-top: 18px; + margin-bottom: 19px; + + &.input-root-margin-dense { + margin-top: 10px; + margin-bottom: 11px; + } + } + + &.input-root-adorned-start { + margin-left: 0; + margin-inline-start: 0; + margin-inline-end: 12px; + + } + + &.input-root-adorned-end { + margin-right: 0; + margin-inline-end: unset; + margin-inline-start: 12px; + } + } + + &::-webkit-scrollbar { + width: 8px; + height: 8px; + z-index: 1; + cursor: crosshair; + } + + &::-webkit-scrollbar-thumb { + background: var(--palette-lines-inputs); + border-radius: 1px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + } + + &.input-root-outlined { + margin: 18.5px 14px; + + + &.input-root:-webkit-autofill { + border-radius: inherit; + } + + &.input-root-margin-dense { + margin-top: 10.5px; + margin-bottom: 10.5px; + } + + &.input-root-adorned-start { + margin-left: 0; + margin-inline-start: 0; + margin-inline-end: 14px; + } + + &.input-root-adorned-end { + margin-right: 0; + margin-inline-end: 0; + margin-inline-start: 14px; + } + } +} + +.input-adornment { + height: 0.01em; + display: flex; + max-height: 2em; + align-items: center; + white-space: nowrap; +} + +.input-adornment-start { + &.input-root-filled-shrink { + margin-top: 16px; + } +} + +.input-adornment-start { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} + +.input-adornment-end { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +.input-number-control.input-showspin .input-adornment-end { + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} + +.input-number-control.input-showspin .input-underline:not(.input-filled) .input-adornment-end { + margin-right: 24px; + margin-inline-end: 24px; + margin-inline-start: unset; +} + +.input-adornment-disable-pointerevents { + pointer-events: none; +} + +.range-input-separator { + visibility: hidden; + margin: 0 4px; +} + +.input:focus-within .range-input-separator { + visibility: visible; +} + +.picker .shrink .range-input-separator { + visibility: visible; +} diff --git a/Styles/components/_inputcontrol.scss b/Styles/components/_inputcontrol.scss new file mode 100644 index 0000000..007a970 --- /dev/null +++ b/Styles/components/_inputcontrol.scss @@ -0,0 +1,200 @@ +.input-control { + border: 0; + margin: 0; + padding: 0; + display: flex; + flex: 1 1 auto; + max-width: 100%; + position: relative; + flex-direction: column; + vertical-align: top; + margin-top: 6px; + + &.input-control-margin-normal { + margin-top: 16px; + margin-bottom: 8px; + } + + &.input-control-margin-dense { + margin-top: 3px; + margin-bottom: 2px; + } + + &.input-control-full-width { + width: 100%; + } + + &.input-control-boolean-input { + flex: none; + margin: 0; + } + + & > .input-control-input-container { + position: relative; + display: flex; + flex-direction: column; + + & > div { + &.input.input-text { + margin-top: 16px; + } + + &.input.input-filled { + } + + &.input.input-outlined { + } + } + } + + & > .input-control-input-container > .input-label-outlined { + &.input-label-inputcontrol { + line-height: 18px; + } + } + + & > .input-control-input-container > .input-label-inputcontrol { + color: var(--palette-text-secondary); + padding: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1; + letter-spacing: 0.00938em; + z-index: 0; + pointer-events: none; + + &.disabled { + color: var(--palette-text-disabled); + } + + &.input-error { + color: var(--palette-error) !important; + } + } + + &.input-required > .input-control-input-container > .input-label::after { + content: "*"; + } + + &.input-number-control { + & input::-webkit-outer-spin-button, + & input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + & input[type=number] { + -moz-appearance: textfield; + } + + &.input-showspin .input:not(.input-adorned-end) { + input { + padding-right: 24px; //This must be the same width of the spinners + padding-inline-end: 24px; + + &.input-root-margin-dense { + padding-right: 20px; //This must be the same width of the spinners + padding-inline-end: 20px; + } + } + + &.input-text input { + padding-inline-start: 0; + + &.input-root-margin-dense { + padding-inline-start: 0; + } + } + + &.input-filled input { + padding-inline-start: 12px; + + &.input-root-margin-dense { + padding-inline-start: 12px; + } + } + + &.input-outlined input { + padding-inline-start: 14px; + + &.input-root-margin-dense { + padding-inline-start: 14px; + } + } + } + + & .input-numeric-spin { + display: inline-flex; + flex-direction: column; + justify-content: space-between; + position: absolute; + right: 0; + top: 0; + bottom: 0; + + & button { + padding: 2px; + min-width: unset; + min-height: unset; + } + } + + .input-numeric-spin button { + padding: 2px 0; + } + } +} + +.input-control-helper-container { + overflow: hidden; + margin-top: 3px; +} + +.input-helper-text { + color: var(--palette-text-secondary); + margin: 0; + font-size: 0.75rem; + text-align: start; + font-weight: 400; + line-height: 1.66; + letter-spacing: 0.03333em; + + &.input-helper-onfocus { + transform: translateY(-100%); + transition: color 200ms cubic-bezier(0,0,.2,1) 0ms,transform 200ms cubic-bezier(0,0,.2,1) 0ms; + } +} + +.input-control { + &:focus-within, &.input-error { + .input-helper-text { + &.input-helper-onfocus { + transform: translateY(0); + } + } + } +} + + .input-helper-text.disabled { + color: var(--palette-text-disabled); + } + + .input-helper-text.input-error { + color: var(--palette-error) !important; + } + + .input-helper-text-margin-dense { + margin-top: 4px; + } + + .input-helper-text-contained { + margin-left: 14px; + margin-right: 14px; + } + + .application-layout-rtl { + .input-control.input-number-control .input-numeric-spin { + left: 0; + right: unset; + } + } \ No newline at end of file diff --git a/Styles/components/_inputlabel.scss b/Styles/components/_inputlabel.scss new file mode 100644 index 0000000..ea63077 --- /dev/null +++ b/Styles/components/_inputlabel.scss @@ -0,0 +1,127 @@ +.input-label { + display: block; + transform-origin: top left; +} + +.input-label-inputcontrol { + top: 0; + left: 0; + position: absolute; + transform: translate(0, 24px) scale(1); +} + +.input-label-margindense { + transform: translate(0, 21px) scale(1); +} + +.input-label-shrink { + transform: translate(0, 1.5px) scale(0.75); + transform-origin: top left; +} + +.input-label-animated { + transition: color 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms,transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; +} + +.input-label-filled { + z-index: 1; + transform: translate(12px, 20px) scale(1); + pointer-events: none; + + &.input-label-margin-dense { + transform: translate(12px, 17px) scale(1); + } +} + + +.input-label-outlined { + transform: translate(14px, 20px) scale(1); + pointer-events: none; + background-color: var(--palette-surface); + padding: 0px 5px !important; + + + &.input-label-margin-dense { + transform: translate(14px, 12px) scale(1); + } +} + +label.input-label.input-label-inputcontrol { + .shrink ~ & { + color: var(--palette-text-primary); + } + + .input:focus-within ~ & { + color: var(--palette-primary); + } + + .shrink ~ &, + .input:focus-within ~ & { + transform: translate(0, 1.5px) scale(0.75); + transform-origin: top left; + + &.input-label-filled { + transform: translate(12px, 10px) scale(0.75); + + &.input-label-margin-dense { + transform: translate(12px, 7px) scale(0.75); + } + } + + &.input-label-outlined { + transform: translate(14px, -6px) scale(0.75); + } + } + + .input:focus-within ~ &.input-error { + color: var(--palette-error); + } +} +.application-layout-rtl { + .input-label { + transform-origin: top right; + } + + .input-label-inputcontrol { + left: unset; + right: 0; + } + + .input-label-shrink { + transform-origin: top right; + } + + .input-label-filled { + transform: translate(-12px, 20px) scale(1); + + &.input-label-margin-dense { + transform: translate(-12px, 17px) scale(1); + } + } + + .input-label-outlined { + transform: translate(-14px, 20px) scale(1); + + &.input-label-margin-dense { + transform: translate(-14px, 12px) scale(1); + } + } + + .shrink, .input:focus-within { + ~ label.input-label.input-label-inputcontrol { + transform-origin: top right; + + &.input-label-filled { + transform: translate(-12px, 10px) scale(0.75); + + &.input-label-margin-dense { + transform: translate(-12px, 7px) scale(0.75); + } + } + + &.input-label-outlined { + transform: translate(-14px, -6px) scale(0.75); + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_layout.scss b/Styles/components/_layout.scss new file mode 100644 index 0000000..9d0cdce --- /dev/null +++ b/Styles/components/_layout.scss @@ -0,0 +1,4 @@ + +.application-layout-rtl { + direction: rtl; +} \ No newline at end of file diff --git a/Styles/components/_link.scss b/Styles/components/_link.scss new file mode 100644 index 0000000..c1cf0d8 --- /dev/null +++ b/Styles/components/_link.scss @@ -0,0 +1,27 @@ + +.link { + &.link-underline-none { + text-decoration: none; + } + + &.link-underline-hover { + text-decoration: none; + + &:hover, &:focus-visible { + text-decoration: underline; + } + } + + &.link-underline-always { + text-decoration: underline; + } + + &.link-disabled { + cursor: default; + color: var(--palette-action-disabled) !important; + + &:not(.link-underline-always) { + text-decoration: none; + } + } +} diff --git a/Styles/components/_list.scss b/Styles/components/_list.scss new file mode 100644 index 0000000..2796797 --- /dev/null +++ b/Styles/components/_list.scss @@ -0,0 +1,132 @@ +.list { + margin: 0; + padding: 0; + position: relative; + list-style: none; + + &.list-padding { + padding-top: 8px; + padding-bottom: 8px; + } +} + +.list-item { + width: 100%; + display: flex; + position: relative; + box-sizing: border-box; + text-align: start; + align-items: center; + padding-top: 8px; + padding-bottom: 8px; + justify-content: flex-start; + text-decoration: none; + + &.list-item-dense { + padding-top: 4px; + padding-bottom: 4px; + } + + &.list-item-disabled { + color: var(--palette-action-disabled) !important; + cursor: default !important; + pointer-events: none !important; + + .list-item-icon { + color: var(--palette-action-disabled) !important; + } + } +} + +.list-item-clickable { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + outline: 0; + user-select: none; + border-radius: 0; + vertical-align: middle; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + background-color: var(--palette-action-default-hover); + } + + &:focus:not(.selected-item) { + background-color: var(--palette-action-default-hover); + } +} + +.list-item-gutters { + padding-left: 16px; + padding-right: 16px; +} + + +.list-item-text { + flex: 1 1 auto; + min-width: 0; + margin-top: 4px; + margin-bottom: 4px; +} + + +.list-item-text-inset { + padding-left: 56px; + padding-inline-start: 56px; + padding-inline-end: unset; +} + +.list-item-icon { + color: var(--palette-action-default); + display: inline-flex; + min-width: 56px; + flex-shrink: 0; +} + + +.list-subheader { + color: var(--palette-action-default); + font-size: 0.875rem; + box-sizing: border-box; + list-style: none; + font-weight: 500; + padding-top: 8px; + padding-bottom: 20px; +} + +.list-subheader-gutters { + padding-left: 16px; + padding-right: 16px; +} + +.list-subheader-inset { + padding-left: 72px; + padding-inline-start: 72px; + padding-inline-end: unset; +} + +.list-subheader-sticky { + top: 0; + z-index: 1; + position: sticky; + background-color: inherit; +} + + +.list-item-avatar { + min-width: 56px; + flex-shrink: 0; +} + +.nested-list { + & > .list-item { + padding-left: 32px; + padding-inline-start: 32px; + padding-inline-end: unset; + } +} \ No newline at end of file diff --git a/Styles/components/_markdowncode.scss b/Styles/components/_markdowncode.scss new file mode 100644 index 0000000..1279533 --- /dev/null +++ b/Styles/components/_markdowncode.scss @@ -0,0 +1,36 @@ +.markdown { + margin: 0px; + padding: 15px; + border-radius: var(--default-borderradius); + background-color: var(--palette-dark); + margin-bottom: 1.5rem; + + & .markdown-pre { + white-space: normal; + } + + & .markdown-code { + color: #fff; + font-size: 1em; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + } +} + +.markdown .markdown-pre .markdown-code { + + & mark { + color: #808078; + background-color: none; + } + + & mark { + color: #008080; + font-weight: bold; + background-color: none; + } +} + +.token.attr-value > .punctuation { + color: #d0d0d0; +} + diff --git a/Styles/components/_menu.scss b/Styles/components/_menu.scss new file mode 100644 index 0000000..3f3a3d0 --- /dev/null +++ b/Styles/components/_menu.scss @@ -0,0 +1,21 @@ +.menu { + display: inline-flex; + align-self: center; + position: relative; + + & * { + cursor: pointer; + } + + & > div.disabled { + cursor: default; + + & * { + cursor: default; + } + } + + & > div.menu-activator { + display: contents; + } +} diff --git a/Styles/components/_navmenu.scss b/Styles/components/_navmenu.scss new file mode 100644 index 0000000..899da15 --- /dev/null +++ b/Styles/components/_navmenu.scss @@ -0,0 +1,273 @@ +@import '../abstracts/variables'; + +.navmenu { + margin: 0; + position: relative; + list-style: none; + overscroll-behavior-y: contain; +} + +.nav-group { + width: 100%; + display: block; + justify-content: flex-start; + + & > .nav-link > .nav-link-text { + font-weight: 500; + } + + & * .nav-group { + & > .nav-link > .nav-link-text { + font-weight: 400; + } + } + + & * .nav-group { + & > .nav-link.expanded > .nav-link-text { + font-weight: 500; + } + } + + & * .navmenu .nav-item .nav-link { + padding-left: 36px; + padding-inline-start: 36px; + padding-inline-end: unset; + } +} + +.nav-group-disabled { + &, .nav-link-text, .nav-link-expand-icon, .nav-link-icon { + color: var(--palette-text-disabled) !important; + cursor: default; + pointer-events: none; + } +} + +.nav-item { + width: 100%; + display: flex; + justify-content: flex-start; + text-decoration: none; +} + +.nav-link { + width: 100%; + font-weight: 400; + padding: 8px 16px 8px 16px; + color: inherit; + line-height: 1.75; + display: inline-flex; + align-items: center; + justify-content: flex-start; + text-transform: inherit; + background-color: transparent; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, padding 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: flex-start; + + &.nav-link-disabled { + color: var(--palette-text-disabled) !important; + cursor: default; + pointer-events: none; + } + + &:hover:not(.nav-link-disabled) { + cursor: pointer; + text-decoration: none; + background-color: var(--palette-action-default-hover); + } + + &:focus:not(.nav-link-disabled) { + background-color: var(--palette-action-default-hover); + } + + &.active:not(.nav-link-disabled) { + font-weight: 500 !important; + } + + &:not(.nav-link-disabled) .nav-link-icon.nav-link-icon-default { + color: var(--palette-drawer-icon); + } + + &.nav-link-disabled .nav-link-icon { + color: var(--palette-text-disabled); + } + + & .nav-link-expand-icon { + color: var(--palette-drawer-icon); + transition: .3s cubic-bezier(.25,.8,.5,1),visibility 0s; + + &.transform { + transform: rotate(-180deg); + } + + &.transform-disabled { + transform: rotate(-180deg); + } + } + + & .nav-link-text { + width: 100%; + text-align: start; + margin-left: 12px; + margin-inline-start: 12px; + margin-inline-end: unset; + letter-spacing: 0; + } +} + +.navmenu{ + + &.navmenu-dense{ + .nav-link{ + padding: 4px 16px 4px 16px; + } + } + + &.navmenu-margin-dense{ + .nav-link{ + margin: 2px 0; + } + } + + &.navmenu-margin-normal{ + .nav-link{ + margin: 4px 0; + } + } + + &.navmenu-rounded{ + .nav-link{ + border-radius: var(--default-borderradius); + } + } + + &.navmenu-bordered{ + .nav-link{ + &.active:not(.nav-link-disabled) { + border-inline-end-style: solid; + border-inline-end-width: 2px; + } + } + } + + &.navmenu-default{ + .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-primary); + background-color: var(--palette-action-default-hover); + + &:hover:not(.nav-link-disabled), &:focus-visible:not(.nav-link-disabled) { + background-color: var(--palette-action-default-hover); + } + } + + .nav-link-expand-icon.transform { + fill: var(--palette-primary); + } + } + + @each $color in $palette-colors { + &.navmenu-#{$color} { + .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-#{$color}); + background-color: var(--palette-#{$color}-hover); + + &:hover:not(.nav-link-disabled), &:focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-#{$color}-rgb), 0.12); + } + + .nav-link-icon { + color: var(--palette-#{$color}); + } + } + + .nav-link-expand-icon.transform { + fill: var(--palette-#{$color}); + } + } + } +} + +.nav-group * .navmenu > .nav-group { + & .nav-link { + padding-left: 36px; + padding-inline-start: 36px; + padding-inline-end: 16px; + } + + & * .navmenu .nav-item .nav-link { + padding-left: 48px; + padding-inline-start: 48px; + } + + & * .navmenu > .nav-group { + & .nav-link { + padding-left: 48px; + padding-inline-start: 48px; + padding-inline-end: 16px; + } + + & * .navmenu .nav-item .nav-link { + padding-left: 60px; + padding-inline-start: 60px; + padding-inline-end: 0; + } + + & * .navmenu > .nav-group { + & .nav-link { + padding-left: 60px; + padding-inline-start: 60px; + padding-inline-end: 16px; + } + + & * .navmenu .nav-item .nav-link { + padding-left: 72px; + padding-inline-start: 72px; + padding-inline-end: 0; + } + } + } +} + +.drawer--closed.drawer-mini { + & > .drawer-content > .navmenu { + & .nav-link .icon-root:first-child + .nav-link-text { + display: none; + } + } + + .nav-group { + & * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; + } + } + + .nav-group * .navmenu > .nav-group { + & .nav-link { + padding: 8px 16px 8px 16px; + } + + & * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; + } + + & * .navmenu > .nav-group { + & .nav-link { + padding: 8px 16px 8px 16px; + } + + & * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; + } + + & * .navmenu > .nav-group { + & .nav-link { + padding: 8px 16px 8px 16px; + } + + & * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; + } + } + } + } +} diff --git a/Styles/components/_overlay.scss b/Styles/components/_overlay.scss new file mode 100644 index 0000000..7b5a1c3 --- /dev/null +++ b/Styles/components/_overlay.scss @@ -0,0 +1,64 @@ +.overlay { + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0 !important; + align-items: center; + justify-content: center; + border-radius: inherit; + display: flex; + position: fixed; + transition: .3s cubic-bezier(.25,.8,.5,1),z-index 1ms; + z-index: 5; + + &.overlay-absolute { + position: absolute; + } + + & .overlay-scrim { + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; + position: absolute; + height: 100%; + width: 100%; + border-color: transparent; + background-color: transparent; + animation: animation-fadein ease 0.15s; + -webkit-animation: animation-fadein ease 0.15s; + -moz-animation: animation-fadein ease 0.15s; + -o-animation: animation-fadein ease 0.15s; + + &.overlay-dark { + border-color: var(--palette-overlay-dark); + background-color: var(--palette-overlay-dark); + } + + &.overlay-light { + border-color: var(--palette-overlay-light); + background-color: var(--palette-overlay-light); + } + &:hover { + cursor: default; + } + } + + & .overlay-content { + position: relative; + } + + &.overlay-popover { + z-index: var(--zindex-popover); + } + + &.overlay-dialog { + z-index: calc(var(--zindex-dialog) + 1); + } + + &.overlay-drawer { + z-index: calc(var(--zindex-appbar) + 1); //<-- Yes this is correct we want to display it on top of the Appbar + } +} diff --git a/Styles/components/_pagecontentnavigation.scss b/Styles/components/_pagecontentnavigation.scss new file mode 100644 index 0000000..ae2241b --- /dev/null +++ b/Styles/components/_pagecontentnavigation.scss @@ -0,0 +1,34 @@ +@import '../abstracts/variables'; + +.page-content-navigation { + + .page-content-navigation-navlink { + &.active { + .nav-link { + color: var(--palette-primary); + border-color: var(--palette-primary); + background-color: transparent; + } + } + + .nav-link { + padding: 4px 16px 4px 16px; + color: var(--palette-text-secondary); + border-left: 2px solid var(--palette-action-disabled-background); + + &.active { + color: var(--palette-primary); + border-color: var(--palette-primary); + background-color: transparent; + } + + .nav-link-text { + margin-left: 0px; + margin-inline-start: 0px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} diff --git a/Styles/components/_pagination.scss b/Styles/components/_pagination.scss new file mode 100644 index 0000000..f9b1092 --- /dev/null +++ b/Styles/components/_pagination.scss @@ -0,0 +1,97 @@ +@import '../abstracts/variables'; + +.pagination { + display: inline-flex; + flex-wrap: wrap; + gap: 6px; + align-items: center; + margin: 0; + + .pagination-item { + & > * { + height: 32px; + min-width: 32px; + margin: 0 3px; + padding: 0 6px; + text-align: center; + border-radius: 16px; + } + + :not(pagination-item-selected) > * { + box-shadow: none; + } + + .button { + line-height: normal; + } + + .icon-button { + padding: 0; + } + + &-rectangular .button { + border-radius: var(--default-borderradius); + } + + .typography[disabled] { + color: var(--palette-action-disabled) !important; + } + } + + &-outlined { + .pagination-item-selected { + .button-outlined-default { + background-color: var(--palette-action-default-hover) + } + + @each $color in $palette-colors { + .button-outlined-#{$color} { + background-color: var(--palette-#{$color}-hover); + } + } + } + } + + &-filled { + .pagination-item { + &:not(.pagination-item-selected) .button { + background-color: var(--palette-surface); + } + + .button { + box-shadow: var(--elevation-1); + } + } + } + + &-small { + .pagination-item { + & > * { + height: 26px; + min-width: 26px; + margin: 0 1px; + padding: 0 4px; + border-radius: 13px; + } + } + } + + &-large { + .pagination-item { + & > * { + height: 40px; + min-width: 40px; + padding: 0 10px; + border-radius: 20px; + } + } + } + + &-disable-elevation .pagination-item .button { + box-shadow: none; + } + + &-rtl .pagination-item .icon-root { + transform: scaleX(-1); + } +} \ No newline at end of file diff --git a/Styles/components/_paper.scss b/Styles/components/_paper.scss new file mode 100644 index 0000000..1c2df67 --- /dev/null +++ b/Styles/components/_paper.scss @@ -0,0 +1,15 @@ + +.paper { + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.paper-square { + border-radius: 0px; +} + +.paper-outlined { + border: 1px solid var(--palette-lines-default); +} \ No newline at end of file diff --git a/Styles/components/_picker.scss b/Styles/components/_picker.scss new file mode 100644 index 0000000..733c85d --- /dev/null +++ b/Styles/components/_picker.scss @@ -0,0 +1,198 @@ +.picker { + &.rounded { + border-radius: var(--default-borderradius); + } + + & .picker-actions { + flex: 0 0 auto; + display: flex; + padding: 8px; + align-items: center; + justify-content: flex-end; + + & > :not(:first-child) { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; + } + } +} + +.picker-inline { + display: flex; + flex: 1 1 auto; + position: relative; + max-width: 100%; + + &.picker-input-button { + & .input, .input .input-root { + cursor: pointer + } + + &.disabled { + & .input, .input .input-root { + cursor: default; + } + } + } + + &.picker-input-text { + cursor: text; + + &:hover { + cursor: text; + } + + &.disabled { + cursor: default; + + &:hover { + cursor: default; + } + } + } +} + +.picker-static { + display: flex; + overflow: hidden; + min-width: 310px; + flex-direction: column; +} + +.picker-container { + display: flex; + flex-direction: column; + border-radius: inherit; + + &.picker-container-landscape { + flex-direction: row; + } + + & .toolbar { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } +} + +.picker-popover-paper { + outline: 0; + z-index: calc(var(--zindex-popover) + 1); + position: absolute; + min-width: 16px; + min-height: 16px; + overflow-x: hidden; + overflow-y: auto; +} + +.picker-view { + display: none; + margin-top: 20px; + + &.picker-open { + display: block; + animation: animation-fadein 251ms; + } +} + +.picker-content { + display: flex; + //max-width: 325px; + max-width: 100%; + min-width: 310px; + min-height: 305px; + overflow: hidden; + flex-direction: column; + justify-content: center; + + &.picker-content-landscape { + padding: 0 8px; + } +} + +.picker-toolbar { + height: 100px; + display: flex; + align-items: center; + flex-direction: row; + justify-content: center; + + &.picker-toolbar-landscape { + height: auto; + padding: 8px; + max-width: 150px; + justify-content: flex-start; + } + + + &.button-root { + padding: 0; + min-width: 16px; + text-transform: none; + } +} + +.picker-inline-paper { + .paper { + position: relative !important; + } +} + +.picker-hidden { + visibility: hidden; +} + +.picker-pos-top { + top: 0px; + position: fixed; + visibility: visible; + + &.picker-pos-left { + left: 10px; + } + + &.picker-pos-right { + right: 10px; + } +} + +.picker-pos-above { + bottom: 0px; + visibility: visible; + + &.picker-pos-left { + left: 50%; + transform: translateX(-50%); + } + + &.picker-pos-right { + right: 0px; + } +} + +.picker-pos-bottom { + bottom: 10px; + position: fixed; + visibility: visible; + + &.picker-pos-left { + left: 10px; + } + + &.picker-pos-right { + right: 10px; + } +} + +.picker-pos-below { + visibility: visible; + + &.picker-pos-left { + left: 50%; + transform: translateX(-50%); + } + + &.picker-pos-right { + right: 0px; + } +} diff --git a/Styles/components/_pickercolor.scss b/Styles/components/_pickercolor.scss new file mode 100644 index 0000000..e7eea99 --- /dev/null +++ b/Styles/components/_pickercolor.scss @@ -0,0 +1,242 @@ +.picker-container { + & + .picker-color-toolbar { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } + + & + .picker-color-content { + border-top-left-radius: inherit; + border-top-right-radius: inherit; + } +} + + +.picker-color-toolbar { + height: 32px; + padding-right: 2px; + padding-left: 2px; +} + +.picker-color-content { + min-height: unset; + position: relative; +} + +.picker-color-picker { + width: 312px; + height: 250px; + position: relative; + overflow: hidden; + + .picker-color-overlay { + width: 100%; + height: 100%; + + &.picker-color-overlay-white { + background: linear-gradient(to right, white 0%, rgba(255, 255, 255, 0) 100%); + } + + &.picker-color-overlay-black { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, black 100%); + } + } + + .picker-color-selector { + position: absolute; + top: -13px; + left: -13px; + } +} + +.picker-color-controls { + width: 312px; + padding: 16px; + display: flex; + flex-direction: column; + + .picker-color-controls-row { + display: flex; + align-items: center; + + & + .picker-color-controls-row { + margin-top: 24px; + } + + .picker-color-sliders { + display: flex; + flex: 1 0 auto; + flex-direction: column; + + .picker-color-slider { + min-width: 224px; + border-radius: var(--default-borderradius); + + & .slider-input { + height: 10px; + border-radius: var(--default-borderradius); + + @include slider-track { + background: initial; + } + + @include slider-thumb { + appearance: none; + margin-top: -6px; + height: 14px; + width: 14px; + transform: none; + transition: none; + background: #f0f0f0; + box-shadow: rgba(0, 0, 0, 0.37) 0px 1px 4px 0px; + } + + &:active { + @include slider-thumb { + box-shadow: 0 0 0 2px var(--palette-action-default-hover) !important; + } + } + } + + &.hue + .alpha { + margin-top: 18px; + } + + &.hue .slider-input { + background: linear-gradient( 90deg, #FF0000, #ff0 16.66%, #0f0 33.33%,#0ff 50%, #00f 66.66%, #f0f 83.33%, #FF0000); + } + + &.alpha .slider-input { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGCQwoKxgqGgcJA5h3yFAAs8BRWVSwooAAAAAElFTkSuQmCC) repeat; + } + } + } + + .picker-color-inputs { + display: flex; + flex: 1 1 auto; + + .picker-color-inputfield { + width: 100%; + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; + + &:last-of-type { + margin-right: 0; + margin-inline-end: 0; + margin-inline-start: unset; + } + + .input { + input { + padding: 6px; + height: 1em; + text-align: center; + font-size: 14px; + } + } + + .input-helper-text { + text-align: center; + + & div div { + margin: auto; + } + } + } + } + + .picker-control-switch { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; + padding-bottom: 16px; + } + + .picker-color-collection { + display: flex; + min-width: 230px; + justify-content: space-between; + + .picker-color-dot { + max-width: 38px; + } + } + } +} + +.picker-color-dot { + height: 38px; + min-width: 38px; + width: 100%; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border-radius 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: var(--default-borderradius); + box-shadow: 0 0 6px rgba(127, 130, 134, 0.18); + + &:hover { + cursor: pointer; + box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12); + } + + &.picker-color-dot-current { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGCQwoKxgqGgcJA5h3yFAAs8BRWVSwooAAAAAElFTkSuQmCC) repeat; + } + + .picker-color-fill { + width: 100%; + height: 100%; + border-radius: inherit; + } + + & + .picker-color-sliders { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; + } + + & + .picker-color-collection { + margin-left: 10px; + margin-inline-start: 10px; + margin-inline-end: unset; + } +} + +.picker-color-view { + position: absolute; + width: 100%; + height: 100%; + overflow: auto; + padding: 6px; + background-color: var(--palette-surface); + + .picker-color-view-collection { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + + .picker-color-dot { + max-width: 38px; + margin: 8px; + + &.selected { + border-radius: 50%; + box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12); + } + } + } +} + +.picker-color-picker { + .picker-color-grid { + display: flex; + flex-wrap: wrap; + + .picker-color-dot { + height: 25px; + min-width: 26px; + max-width: 26px; + border-radius: 0px; + box-shadow: none; + } + } +} \ No newline at end of file diff --git a/Styles/components/_pickerdate.scss b/Styles/components/_pickerdate.scss new file mode 100644 index 0000000..893ce15 --- /dev/null +++ b/Styles/components/_pickerdate.scss @@ -0,0 +1,384 @@ +@import '../abstracts/variables'; + +.picker-datepicker-toolbar { + align-items: flex-start; + flex-direction: column; + + .button-year { + font-size: 1rem; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; + } + + .button-date { + font-size: 2.125rem; + font-weight: 400; + line-height: 1.17; + letter-spacing: 0.00735em; + text-transform: none; + } +} + +.picker-datepicker-toolbar-landscape { + padding: 16px; +} + +.picker-datepicker-date-landscape { + margin-right: 16px; + margin-inline-end: 16px; + margin-inline-start: unset; +} + + +.picker-calendar-header-switch { + display: flex; + margin-top: 4px; + align-items: center; + margin-bottom: 8px; + justify-content: space-between; + + & > .icon-button { + z-index: 1; + padding: 8px; + margin: 6px; + background-color: var(--palette-surface); + + &:hover { + background-color: var(--palette-action-default-hover); + } + } + + & .picker-calendar-header-transition { + width: 100%; + height: 23px; + overflow: hidden; + + &:hover { + & .typography { + cursor: pointer; + font-weight: 500; + } + } + } +} + + +.picker-calendar-header-day { + display: flex; + max-height: 16px; + align-items: center; + justify-content: center; + + .day-label { + color: var(--palette-text-secondary); + width: 36px; + margin: 0 2px; + text-align: center; + } +} + +.picker-year-container { + height: 300px; + overflow-y: auto; + + .picker-year { + cursor: pointer; + height: 40px; + display: flex; + outline: none; + align-items: center; + justify-content: center; + user-select: none; + animation: animation-fadein 500ms; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + background-color: var(--palette-action-default-hover); + } + + & .picker-year-selected { + margin: 10px 0; + font-weight: 500; + } + } +} + +.picker-month-container { + width: 310px; + display: flex; + flex-wrap: wrap; + align-content: stretch; + + .picker-month { + flex: 1 0 33.33%; + cursor: pointer; + height: 60px; + display: flex; + outline: none; + transition: font-size 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: center; + justify-content: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + background-color: var(--palette-action-default-hover); + } + + & .picker-month-selected { + font-weight: 500; + } + + &.disabled { + color: var(--palette-text-disabled); + pointer-events: none; + } + } +} + + +.picker-slide-transition { + display: block; + position: relative; +} + +.picker-slide-transition > * { + top: 0; + left: 0; + right: 0; + position: absolute; +} + +.picker-calendar-transition { + margin-top: 12px; + min-height: 216px; +} + +.picker-calendar-progress-container { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.picker-calendar-content { + display: grid; + --selected-day: 0; + grid-column-gap: 10px; + grid-template-columns: auto; +} + +@media(min-width: $breakpoint-sm) { + .picker-calendar-content:not(.picker-calendar-content-1) { + grid-template-columns: repeat(2, minmax(auto, 1fr)); + + .picker-calendar-header-1, + .picker-calendar-header-3, + .picker-calendar-header-5, + .picker-calendar-header-7, + .picker-calendar-header-9, + .picker-calendar-header-11 { + .picker-nav-button-next { + visibility: hidden; + } + + .picker-nav-button-prev { + visibility: visible; + } + } + + .picker-calendar-header-2, + .picker-calendar-header-4, + .picker-calendar-header-6, + .picker-calendar-header-8, + .picker-calendar-header-10, + .picker-calendar-header-12 { + .picker-nav-button-next { + visibility: visible; + } + + .picker-nav-button-prev { + visibility: hidden; + } + } + } +} + +@media(min-width: $breakpoint-md) { + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) { + grid-template-columns: repeat(3, minmax(auto, 1fr)); + + .picker-calendar-header-1, + .picker-calendar-header-4, + .picker-calendar-header-7, + .picker-calendar-header-10 { + .picker-nav-button-next { + visibility: hidden; + } + + .picker-nav-button-prev { + visibility: visible; + } + } + + .picker-calendar-header-2, + .picker-calendar-header-5, + .picker-calendar-header-8, + .picker-calendar-header-11 { + .picker-nav-button-next, .picker-nav-button-prev { + visibility: hidden; + } + } + + .picker-calendar-header-3, + .picker-calendar-header-6, + .picker-calendar-header-9, + .picker-calendar-header-12 { + .picker-nav-button-next { + visibility: visible; + } + + .picker-nav-button-prev { + visibility: hidden; + } + } + } +} + +:not(.picker-hidden) { + .picker-calendar-header-last { + .picker-nav-button-next { + visibility: inherit !important; + } + } +} + +.picker-hidden { + .picker-nav-button-next, .picker-nav-button-prev { + visibility: hidden !important; + } +} + +.picker-calendar-container { + display: flex; + width: 310px; + flex-direction: column; +} + +.picker-calendar { + display: flex; + flex-wrap: wrap; + justify-content: center; + + .day { + color: var(--palette-text-primary); + width: 36px; + height: 36px; + margin: 0 2px; + padding: 0; + font-size: 0.75rem; + font-weight: 500; + + &:hover { + background-color: var(--palette-action-default-hover); + } + + &.hidden { + opacity: 0; + pointer-events: none; + } + + &.current { + font-weight: 600; + } + + &.selected { + font-weight: 500; + } + + .typography { + margin-top: 2px; + } + + &.disabled { + color: var(--palette-text-disabled); + pointer-events: none; + } + + &.range { + margin: 0; + width: 40px; + transition: none; + + &.range-start-selected { + border-radius: 50% 0% 0% 50%; + } + + &.range-end-selected { + border-radius: 0% 50% 50% 0%; + } + + &.range-between { + border-radius: 0; + background-color: var(--palette-action-default-hover); + } + + &.range-selection:hover { + &.range-start-selected { + border-radius: 50%; + } + + &:not(.range-start-selected) { + border-radius: 0% 50% 50% 0%; + } + } + + &.range-selection:not(:hover):not(.range-start-selected) { + border-radius: 0; + background: linear-gradient(var(--palette-action-default-hover) 100%, var(--palette-action-default-hover) 100%, transparent 0%); + background-size: 100% calc(100% * (var(--selected-day) - var(--day-id))); + } + } + } +} + +@each $color in $palette-colors { + .range-selection-#{$color} { + &:hover { + color: var(--palette-#{$color}-text) !important; + background-color: var(--palette-#{$color}) !important; + } + } +} + +.picker-calendar-week { + display: flex; + margin: 0 5px; + justify-content: center; + align-items: center; + + .picker-calendar-week-text { + width: 15px; + margin-top: 2px !important; + color: var(--palette-text-disabled); + } +} + +.application-layout-rtl { + .picker-calendar .day.range { + &.range-start-selected { + border-radius: 0% 50% 50% 0%; + } + + &.range-end-selected { + border-radius: 50% 0% 0% 50%; + } + + &.range-selection:hover { + &:not(.range-start-selected) { + border-radius: 50% 0% 0% 50%; + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_pickertime.scss b/Styles/components/_pickertime.scss new file mode 100644 index 0000000..75fcd25 --- /dev/null +++ b/Styles/components/_pickertime.scss @@ -0,0 +1,285 @@ +.picker-timepicker-toolbar { + + .timepicker-button { + padding: 0; + min-width: 16px; + text-transform: none; + + &.timepicker-toolbar-text { + color: rgba(255, 255, 255, 0.54); + } + + &:hover { + background-color: var(--theme-default-hover); + } + } + + .timepicker-hourminute { + display: flex; + align-items: baseline; + justify-content: flex-end; + + .timepicker-button { + font-size: 3.75rem; + font-weight: 300; + line-height: 1; + letter-spacing: -0.00833em; + } + } + + .timepicker-ampm { + display: flex; + margin-left: 20px; + margin-right: -20px; + margin-inline-start: 20px; + margin-inline-end: -20px; + flex-direction: column; + + .timepicker-button { + font-size: 18px; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; + } + } + + .timepicker-separator { + cursor: default; + margin: 0 4px 0 2px; + margin-inline-start: 2px; + margin-inline-end: 4px; + } + + &.picker-timepicker-toolbar-landscape { + flex-wrap: wrap; + width: 150px; + justify-content: center; + + .timepicker-hourminute { + .timepicker-button { + font-size: 3rem; + font-weight: 400; + line-height: 1.04; + letter-spacing: 0em; + } + } + + .timepicker-ampm { + display: flex; + margin-left: 20px; + margin-right: -20px; + margin-inline-start: 20px; + margin-inline-end: -20px; + flex-direction: column; + + .timepicker-button { + font-size: 18px; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; + } + } + + .timepicker-separator { + font-size: 3rem; + font-weight: 400; + line-height: 1.04; + letter-spacing: 0em; + } + } +} + +.picker-time-container { + margin: 16px 0 8px; + display: flex; + align-items: flex-end; + justify-content: center; + + .picker-time-clock { + width: 260px; + height: 260px; + position: relative; + border-radius: 50%; + pointer-events: none; + background-color: rgba(0,0,0,.07); + + .picker-time-clock-mask { + width: 100%; + height: 100%; + outline: none; + position: absolute; + user-select: none; + touch-actions: none; + pointer-events: auto; + } + + .picker-time-clock-pin { + top: 50%; + left: 50%; + width: 6px; + height: 6px; + position: absolute; + transform: translate(-50%, -50%); + border-radius: 50%; + } + + .picker-stick-inner { + left: calc(50% - 1px); + width: 3px; + height: 35%; + bottom: 0; + position: absolute; + transform-origin: center bottom 0px; + + &.hour { + &:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%,-50%); + height: 48px; + width: 48px; + top: -60%; + border-radius: 50%; + background-color: inherit; + } + } + } + + .picker-stick-outer { + left: calc(50% - 1px); + width: 0; + height: 35%; + bottom: 35%; + position: absolute; + transform-origin: center bottom 0px; + + &.hour { + &:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%,-50%); + height: 48px; + width: 62px; + top: -20px; + border-radius: 50%; + background-color: inherit; + } + } + } + + .picker-stick { + left: calc(50% - 1px); + width: 3px; + height: 50%; + bottom: 50%; + position: absolute; + transform-origin: center bottom 0px; + + &.hour { + &:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%,-50%); + height: 62px; + width: 62px; + top: 20px; + border-radius: 50%; + background-color: inherit; + } + } + + &.minute { + &:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%,-50%); + height: 44px; + width: 15px; + top: 20px; + border-radius: 50%; + background-color: inherit; + } + } + } + + .picker-time-clock-pointer { + left: calc(50% - 1px); + width: 2px; + bottom: 50%; + position: absolute; + transform-origin: center bottom 0px; + + &.picker-time-clock-pointer-animation { + transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,height 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + .picker-time-clock-pointer-thumb { + position: absolute; + border-radius: 100%; + + &.onclock-text { + top: -19px; + left: -13px; + width: 28px; + height: 28px; + border: none; + background-color: inherit + } + + &.onclock-minute { + background: transparent; + border: 2px solid; + width: 10px; + height: 10px; + top: -9px; + left: -4px; + } + } + } + + .clock-number { + left: calc((100% - 32px) / 2); + color: var(--palette-text-primary); + background-color: transparent !important; + width: 32px; + height: 32px; + display: inline-flex; + position: absolute; + align-items: center; + user-select: none; + border-radius: 50%; + justify-content: center; + transition-duration: 120ms; + transition-property: color; + } + } +} + +.time-picker-dial { + width: 100%; + height: 100%; + position: absolute; + transition: transform 350ms,opacity 350ms; +} + +.time-picker-dial-out { + opacity: 0; +} + +.time-picker-hour.time-picker-dial-out { + transform: scale(1.2,1.2); + transform-origin: center; +} + +.time-picker-minute.time-picker-dial-out { + transform: scale(.8,.8); + transform-origin: center; +} + +.time-picker-dial-hidden { + visibility: hidden; +} \ No newline at end of file diff --git a/Styles/components/_popover.scss b/Styles/components/_popover.scss new file mode 100644 index 0000000..ef8a8d4 --- /dev/null +++ b/Styles/components/_popover.scss @@ -0,0 +1,58 @@ +.popover { + outline: 0; + z-index: calc(var(--zindex-popover) + 1); + position: absolute; + opacity: 0; + + &.popover-fixed { + position: fixed; + } + + &.popover-relative-width { + width: 100%; + } + + &.popover-open { + opacity: 1; + transition: opacity; + } + + &:not(.popover-open ) { + pointer-events: none; + transition-duration:0ms !important; + transition-delay:0ms !important; + } +} + +.appbar { + .popover-cascading-value { + z-index: calc(var(--zindex-appbar) + 2); + } +} + +.drawer { + &:not(.drawer-temporary) { + .popover-cascading-value { + z-index: calc(var(--zindex-drawer) + 2); + } + } + + &.drawer-temporary, &.drawer-responsive { + .popover-cascading-value { + z-index: calc(var(--zindex-appbar) + 4); + } + } +} + +.dialog { + .popover-cascading-value { + z-index: calc(var(--zindex-dialog) + 3); + } +} + +.popover { + .list { + max-height: inherit; + overflow-y: auto; + } +} \ No newline at end of file diff --git a/Styles/components/_progresscircular.scss b/Styles/components/_progresscircular.scss new file mode 100644 index 0000000..4b436f0 --- /dev/null +++ b/Styles/components/_progresscircular.scss @@ -0,0 +1,52 @@ + +.progress-circular { + display: inline-block; + color: var(--palette-text-secondary); + + &.progress-indeterminate { + animation: progress-circular-keyframes-circular-rotate 1.4s linear infinite; + } + + &.progress-static { + transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + &.progress-small { + height: 24px; + width: 24px; + } + + &.progress-medium { + height: 40px; + width: 40px; + } + + &.progress-large { + height: 56px; + width: 56px; + } +} + + +.progress-circular-svg { + display: block; + transform: rotate(-90deg); +} + +.progress-circular-circle { + stroke: currentColor; + + &.progress-indeterminate { + animation: progress-circular-keyframes-circular-dash 1.4s ease-in-out infinite; + stroke-dasharray: 80px, 200px; + stroke-dashoffset: 0px; + } + + &.progress-static { + transition: stroke-dashoffset 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } +} + +.progress-circular-disable-shrink { + animation: none; +} \ No newline at end of file diff --git a/Styles/components/_progresslinear.scss b/Styles/components/_progresslinear.scss new file mode 100644 index 0000000..7b533d7 --- /dev/null +++ b/Styles/components/_progresslinear.scss @@ -0,0 +1,262 @@ + +.progress-linear { + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.2; + } + + &.horizontal { + width: 100%; + + &.progress-linear { + &-small { + height: 4px; + } + + &-medium { + height: 8px; + } + + &-large { + height: 12px; + } + } + + .progress-linear-dashed { + animation: progress-linear-horizontal-keyframes-buffer 3s infinite linear; + } + } + + &.vertical { + height: 100%; + + &.progress-linear { + &-small { + width: 4px; + } + + &-medium { + width: 8px; + } + + &-large { + width: 12px; + } + } + } + + .progress-linear-content { + position: absolute; + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .progress-linear-bars { + position: absolute; + height: 100%; + width: 100%; + overflow: hidden; + } + + .progress-linear-bar { + top: 0; + left: 0; + width: 100%; + bottom: 0; + position: absolute; + transition: transform 0.2s linear; + transform-origin: left; + + &.progress-linear-1-indeterminate { + &.horizontal { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + } + + &.vertical { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + } + } + + &.progress-linear-2-indeterminate { + &.horizontal { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; + } + + &.vertical { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; + } + } + } + + &.progress-linear-color-default { + &:not(.progress-linear-buffer) { + &::before { + background-color: var(--palette-action-disabled); + } + + .progress-linear-bar { + background-color: var(--palette-action-default); + } + } + + &.progress-linear-buffer { + .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-action-disabled) 0%, var(--palette-action-disabled) 16%, transparent 42%); + background-position: 0 -23px; + } + + .progress-linear-bar:nth-child(2) { + background-color: var(--palette-action-default); + } + + .progress-linear-bar:last-child { + transition: transform .4s linear; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-action-disabled); + } + } + } + } + + @each $color in $palette-colors { + &.progress-linear-color-#{$color} { + + &:not(.progress-linear-buffer) { + &::before { + background-color: var(--palette-#{$color}); + } + + .progress-linear-bar { + background-color: var(--palette-#{$color}); + } + } + + + &.progress-linear-buffer { + .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-#{$color}) 0%, var(--palette-#{$color}) 16%, transparent 42%); + background-position: 0 -23px; + } + + .progress-linear-bar:nth-child(2) { + background-color: var(--palette-#{$color}); + } + + .progress-linear-bar:last-child { + transition: transform .4s linear; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-#{$color}); + } + } + } + } + } + + &.progress-indeterminate { + &.horizontal { + .progress-linear-bar:first-child { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + } + + .progress-linear-bar:last-child { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; + } + } + + &.vertical { + .progress-linear-bar:first-child { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + } + + .progress-linear-bar:last-child { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; + } + } + } + + &.progress-linear-buffer { + .progress-linear-bar:first-child { + width: 100%; + height: 100%; + position: absolute; + margin-top: 0; + } + + .progress-linear-bar:nth-child(2) { + z-index: 1; + transition: transform .4s linear; + } + + &.horizontal { + .progress-linear-bar:first-child { + animation: progress-linear-horizontal-keyframes-buffer 3s infinite linear; + } + } + + &.vertical { + .progress-linear-bar:first-child { + animation: progress-linear-vertical-keyframes-buffer 3s infinite linear; + } + } + } + + &.progress-linear-striped { + .progress-linear-bar { + background-image: linear-gradient( 135deg,hsla(0,0%,100%,.25) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.25) 0,hsla(0,0%,100%,.25) 75%,transparent 0,transparent); + background-size: 40px 40px; + background-repeat: repeat; + animation: progress-linear-striped-loading 10s linear infinite; + } + } + + &.progress-linear-rounded { + border-radius: var(--default-borderradius); + + .progress-linear-bars { + border-radius: var(--default-borderradius); + } + + .progress-linear-bar { + border-radius: var(--default-borderradius); + } + } +} diff --git a/Styles/components/_radio.scss b/Styles/components/_radio.scss new file mode 100644 index 0000000..9d725fe --- /dev/null +++ b/Styles/components/_radio.scss @@ -0,0 +1,110 @@ +@import '../abstracts/variables'; + +.radio { + cursor: pointer; + display: inline-flex; + align-items: center; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; + color: var(--palette-action-default); + + & > .radio-content { + color: var(--palette-text-primary); + } + + &.disabled, .disabled:hover, .disabled:focus-visible { + cursor: default; + background-color: transparent !important; + + & > .radio-content { + color: var(--palette-text-disabled); + } + + & * { + cursor: default; + color: var(--palette-text-disabled); + } + } + + & .radio-dense { + padding: 4px; + } + + &.checked { + color: var(--palette-action-default); + + &:hover { + background-color: var(--palette-action-default-hover); + } + } +} + +.radio-button { + width: 100%; + display: flex; + align-items: inherit; + justify-content: inherit; + + & .radio-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity:0; + padding: 0; + z-index: 1; + position: absolute; + } + + & .radio-icons { + display: flex; + position: relative; + } +} + + +.radio-icons.checked .radio-icon-checked { + transform: scale(1); + transition: transform 150ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; +} + +.radio-icon-checked { + left: 0; + position: absolute; + transform: scale(0); + transition: transform 150ms cubic-bezier(0.4, 0, 1, 1) 0ms; +} + +.radio-content-placement- { + &start { + margin-left: 16px; + margin-right: -11px; + margin-inline-start: 16px; + margin-inline-end: -11px; + flex-direction: row-reverse; + } + + &end { + margin-left: -11px; + margin-right: 16px; + margin-inline-start: -11px; + margin-inline-end: 16px; + flex-direction: row; + } + + &top { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; + flex-direction: column-reverse; + } + + &bottom { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; + flex-direction: column; + } +} diff --git a/Styles/components/_rating.scss b/Styles/components/_rating.scss new file mode 100644 index 0000000..1300860 --- /dev/null +++ b/Styles/components/_rating.scss @@ -0,0 +1,54 @@ +.rating-root { + display: inline-flex; + color: #ffb400; + + &:focus-visible { + outline: none; + + &:not(.disabled) { + background-color: var(--palette-action-default-hover); + } + } +} + +.rating-item { + cursor: pointer; + transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &.rating-item-active { + transform: scale(1.2); + } + + &.disabled, .disabled:hover { + cursor: default; + pointer-events: none; + + & * { + cursor: default; + color: var(--palette-text-disabled); + } + } + + &.readonly { + cursor: default; + } + + & .rating-input { + clip: rect(0,0,0,0); + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; + cursor: inherit; + overflow: hidden; + } + + & svg { + pointer-events: none; + + & path { + pointer-events: none; + } + } +} diff --git a/Styles/components/_select.scss b/Styles/components/_select.scss new file mode 100644 index 0000000..98359fe --- /dev/null +++ b/Styles/components/_select.scss @@ -0,0 +1,89 @@ +.select { + display: flex; + flex-grow: 1; + position: relative; + + &.autocomplete { + display: block; + + & .select-input { + cursor: text; + } + + & .input-adornment { + cursor: pointer; + } + } + + &.autocomplete--with-progress { + & .select-input input { + padding-right: 3.5rem !important; + } + + & .input-adorned-end input { + padding-right: 4.5rem !important; + } + + & .select-input .icon-button { + display: none !important; + } + + & .progress-indicator-circular { + position: absolute; + width: 100%; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: flex-end; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-right: 1rem; + } + + & .progress-indicator-circular--with-adornment { + padding-right: 3rem; + } + + & .progress-linear { + position: absolute; + bottom: -1px; + height: 2px; + } + } + + .select-input { + cursor: pointer; + + & .input-slot { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + & .input-adornment-end { + margin-left: 0; + } + + &:disabled { + cursor: default; + } + } + + .disabled { + .select-input { + cursor: default; + } + } +} + + +.select > .form-helpertext { + margin-top: -21px; +} + +.select-all { + margin-top: 10px; + border-bottom: 1px solid lightgrey; + padding-bottom: 18px; +} diff --git a/Styles/components/_simpletable.scss b/Styles/components/_simpletable.scss new file mode 100644 index 0000000..f922ad8 --- /dev/null +++ b/Styles/components/_simpletable.scss @@ -0,0 +1,145 @@ + +.simple-table { + + table { + width: 100%; + display: table; + border-spacing: 0; + border-collapse: collapse; + + thead { + display: table-header-group; + } + + tbody { + display: table-row-group; + } + + * tr { + color: inherit; + display: table-row; + outline: 0; + vertical-align: middle; + + > td, th { + display: table-cell; + padding: 16px; + font-size: 0.875rem; + text-align: start; + font-weight: 400; + line-height: 1.43; + border-bottom: 1px solid var(--palette-table-lines); + letter-spacing: 0.01071em; + vertical-align: inherit; + } + + > th { + font-weight: 500; + line-height: 1.5rem; + } + } + + tbody { + tr:last-child { + td { + border-bottom: none; + } + } + } + } +} + +.simple-table.table-dense { + & * tr { + & td, th { + padding: 6px 16px; + } + } +} + +.simple-table.table-hover { + & .table-container table tbody { + & tr:hover { + background-color: var(--palette-table-hover); + } + } +} + +.simple-table.table-bordered { + & .table-container table tbody { + & tr { + td { + border-right: 1px solid var(--palette-table-lines); + } + + td:last-child { + border-right: none; + } + } + } +} + +.simple-table.table-striped { + & .table-container table tbody { + & tr:nth-of-type(odd) { + background-color: var(--palette-table-striped); + } + } +} + +.table-hover.table-striped { + & .table-container table tbody { + & tr:nth-of-type(odd):nth-of-type(odd):hover { + background-color: var(--palette-table-hover); + } + } +} + +.simple-table.table-sticky-header { + .table-container { + overflow-x: auto; + max-height: 100%; + } + + & * table { + border-collapse: separate; + + thead { + & * th:first-child { + border-radius: var(--default-borderradius) 0 0 0; + } + + & * th:last-child { + border-radius: 0 var(--default-borderradius) 0 0; + } + + & * th { + background-color: var(--palette-surface); + position: sticky; + z-index: 1; + top: 0; + } + } + } +} + + +.simple-table.table-sticky-footer { + .table-container { + overflow-x: auto; + max-height: 100%; + } + + & * table { + border-collapse: separate; + + tfoot { + & * td { + background-color: var(--palette-surface); + position: sticky; + z-index: 1; + bottom: 0; + } + } + } +} diff --git a/Styles/components/_skeleton.scss b/Styles/components/_skeleton.scss new file mode 100644 index 0000000..3e7d254 --- /dev/null +++ b/Styles/components/_skeleton.scss @@ -0,0 +1,44 @@ + +.skeleton { + height: 1.2em; + display: block; + background-color: rgba(0, 0, 0, 0.11); +} + +.skeleton-text { + height: auto; + transform: scale(1, 0.60); + margin-top: 0; + border-radius: var(--default-borderradius); + margin-bottom: 0; + transform-origin: 0 60%; +} + +.skeleton-text:empty:before { + content: "\00a0"; +} + +.skeleton-circle { + border-radius: 50%; +} + +.skeleton-pulse { + animation: skeleton-keyframes-pulse 1.5s ease-in-out 0.5s infinite; +} + +.skeleton-wave { + overflow: hidden; + position: relative; +} + +.skeleton-wave::after { + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + animation: skeleton-keyframes-wave 1.6s linear 0.5s infinite; + transform: translateX(-100%); + background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.04), transparent); +} \ No newline at end of file diff --git a/Styles/components/_slider.scss b/Styles/components/_slider.scss new file mode 100644 index 0000000..82a3e3a --- /dev/null +++ b/Styles/components/_slider.scss @@ -0,0 +1,211 @@ +@import '../abstracts/variables'; + +.slider { + color: var(--palette-text-primary); + display: inline-block; + width: 100%; + user-select: none; + + & > .typography { + margin-top: 10px; + } + + &.slider-vertical { + transform: rotate(270deg); + height: 100%; + width: unset; + } + + .slider-input { + -webkit-appearance: none; + -moz-appearance: none; + position: relative; + display: block; + width: 100%; + background-color: transparent; + cursor: pointer; + + &:focus { + outline: none; + } + + &:active { + & + .slider-value-label { + opacity: 1; + } + } + + @include slider-track { + border-radius: var(--default-borderradius); + width: 100%; + } + + + @include slider-thumb { + appearance: none; + -webkit-appearance: none; + border: none; + border-radius: 50%; + cursor: pointer; + transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + } + + &:disabled { + cursor: default; + opacity: 0.38; + + @include slider-track { + background-color: var(--palette-text-disabled); + } + + @include slider-thumb { + background-color: rgb( 0, 0, 0); + color: rgb(255, 255, 255); + box-shadow: 0 0 0 1px rgb( 255, 255, 255) !important; + transform: scale(4, 4); + + &:hover { + box-shadow: 0 0 0 1px rgb( 255, 255, 255) !important; + } + } + } + } + + @each $color in $palette-colors { + &.slider-#{$color} { + .slider-filled { + background-color: var(--palette-#{$color}); + } + + .slider-track-tick { + background-color: var(--palette-#{$color}); + } + + .slider-value-label { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + } + + + .slider-input { + @include slider-track { + background-color: rgba(var(--palette-#{$color}-rgb), 0.30); + } + + @include slider-thumb { + background-color: var(--palette-#{$color}); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-#{$color}-rgb),0.3); + } + + @include slider-thumb { + &:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-#{$color}-rgb),0.3),0 0 0 1px rgba(var(--palette-#{$color}-rgb), 0.24); + } + } + + + &:active, &:focus-visible { + @include slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-#{$color}-rgb),0.3),0 0 0 2px rgba(var(--palette-#{$color}-rgb), 0.24); + } + } + } + } + } + + $slider-sizes: ("small": 2, "medium": 4, "large": 6); + $tickcount: 50; + $margincount: 10; + $thumbscale: 6; + + @each $size, $value in $slider-sizes { + &.slider-#{$size} { + .slider-filled { + height: #{$value}px; + } + + .slider-track-tick { + width: #{$value}px; + height: #{$value}px; + } + + .slider-track-tick-label { + transform: translateX(-50%) translateY(#{$tickcount + "%"}); + } + + .slider-input { + @include slider-track { + height: #{$value}px; + margin: #{$margincount}px 0; + } + + @include slider-thumb { + height: #{$value}px; + width: #{$value}px; + transform: scale(#{$thumbscale}, #{$thumbscale}); + } + } + } + + $tickcount: $tickcount + 30; + $margincount: $margincount + 2; + $thumbscale: $thumbscale - 1; + } + + + + .slider-container { + position: relative; + width: 100%; + display: flex; + align-content: center; + } + + .slider-filled { + border-radius: var(--default-borderradius); + } + + .slider-inner-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + } + + .slider-value-label { + position: absolute; + top: 0; + transform: translateX(-50%) translateY(-125%); + padding: 4px 8px; + text-align: center; + align-items: center; + justify-content: center; + font-size: 12px; + border-radius: 2px; + line-height: normal; + opacity: 0; + transition: opacity .2s ease-in-out; + pointer-events: none; + user-select: none; + } + + .slider-tickmarks { + display: flex; + justify-content: space-between; + flex-grow: 1; + } + + .slider-track-tick { + border-radius: 9999%; + background-color: var(--palette-primary); + } + + .slider-track-tick-label { + position: absolute; + top: 0; + left: 0; + } +} diff --git a/Styles/components/_snackbar.scss b/Styles/components/_snackbar.scss new file mode 100644 index 0000000..045ab05 --- /dev/null +++ b/Styles/components/_snackbar.scss @@ -0,0 +1,105 @@ + +.snackbar { + display: flex; + flex-grow: initial; + padding: 6px 16px; + align-items: center; + position: relative; + pointer-events: auto; + font-weight: 400; + line-height: 1.43; + overflow: hidden; + margin-top: 16px; + min-width: 288px; + max-width: 500px; + border-radius: var(--default-borderradius); + box-shadow: 0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12); + + &.force-cursor{ + cursor:pointer; + } + + &.snackbar-blurred { + backdrop-filter: blur(18px); + } + + &.snackbar-surface { + background: var(--palette-surface); + } + + .snackbar-content-message { + padding: 8px 0; + } + + .snackbar-content-action { + display: flex; + align-items: center; + margin-left: auto; + margin-right: -8px; + padding-left: 16px; + margin-inline-start: auto; + margin-inline-end: -8px; + padding-inline-start: 16px; + padding-inline-end: unset; + + & > button { + color: inherit; + } + } +} + +.snackbar-location { + &-top { + + &-left { + top: 24px; + left: 24px + } + + &-center { + top: 24px; + left: 50%; + transform: translateX(-50%); + } + + &-right { + top: 24px; + right: 24px + } + } + + &-bottom { + + &-right { + right: 24px; + bottom: 24px + } + + &-center { + bottom: 24px; + left: 50%; + transform: translateX(-50%); + } + + &-left { + bottom: 24px; + left: 24px + } + } +} + +#snackbar-container { + position: fixed; + z-index: var(--zindex-snackbar); + pointer-events: none +} + +.snackbar-icon { + display: flex; + opacity: 0.9; + padding: 7px 0; + font-size: 22px; + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} \ No newline at end of file diff --git a/Styles/components/_switch.scss b/Styles/components/_switch.scss new file mode 100644 index 0000000..febe2b9 --- /dev/null +++ b/Styles/components/_switch.scss @@ -0,0 +1,106 @@ +.switch { + cursor: pointer; + display: inline-flex; + align-items: center; + margin-left: -11px; + margin-right: 16px; + margin-inline-start: -11px; + margin-inline-end: 16px; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; + + &.disabled { + color: var(--palette-text-disabled) !important; + cursor: default; + } + + &.readonly, .readonly:hover { + cursor: default; + background-color: transparent !important; + } +} + +.switch-span { + width: 58px; + height: 38px; + display: inline-flex; + padding: 12px; + z-index: 0; + overflow: hidden; + position: relative; + box-sizing: border-box; + flex-shrink: 0; + vertical-align: middle; + + & .switch-track { + width: 100%; + height: 100%; + opacity: 0.48; + z-index: -1; + transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 7px; + background-color: var(--palette-black); + } +} + +.switch-base { + padding: 9px; + top: 0; + left: 0; + color: #fafafa; + z-index: 1; + position: absolute; + transition: left 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &.checked { + transform: translateX(20px); + + & + .switch-track { + opacity: 0.5; + } + } + + &:hover { + background-color: var(--palette-action-default-hover); + } + + &.switch-disabled { + color: var(--palette-grey-default) !important; + + & + .switch-track { + opacity: 0.12 !important; + } + + &:hover, &:focus-visible { + cursor: default; + background-color: transparent !important; + } + } +} + +.switch-button { + display: flex; + align-items: inherit; + justify-content: inherit; + + & .switch-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; + } + + & .switch-thumb { + width: 20px; + height: 20px; + box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2), 0px 1px 1px 0px rgba(0,0,0,0.14), 0px 1px 3px 0px rgba(0,0,0,0.12); + border-radius: 50%; + background-color: currentColor; + } +} \ No newline at end of file diff --git a/Styles/components/_table.scss b/Styles/components/_table.scss new file mode 100644 index 0000000..7e82dd2 --- /dev/null +++ b/Styles/components/_table.scss @@ -0,0 +1,559 @@ +@import '../abstracts/variables'; + +.table { + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &.table-square { + border-radius: 0px; + } + + &.table-outlined { + border: 1px solid var(--palette-lines-default); + } +} + +.table-container { + width: 100%; + overflow-y: auto; +} + +.table-root { + width: 100%; + border-spacing: 0; + + & .table-head { + display: table-header-group; + + & .table-cell { + color: var(--palette-text-primary); + font-weight: 500; + line-height: 1.5rem; + } + } + + & .table-body { + display: table-row-group; + + & .table-cell { + color: var(--palette-text-primary); + } + } + + & .table-body:last-child { + & .table-row:last-child { + & .table-cell { + border-bottom: none; + } + } + } +} + +.table-sort-label { + cursor: pointer; + display: inline-flex; + align-items: center; + flex-direction: inherit; + justify-content: flex-start; + + &:hover { + color: var(--palette-action-default); + + .table-sort-label-icon { + opacity: 0.8; + } + } + + .table-sort-label-icon { + font-size: 18px; + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + margin-left: 4px; + user-select: none; + margin-right: 4px; + opacity: 0; + + &.direction-desc { + opacity: 1; + transform: rotate(180deg); + } + + &.direction-asc { + opacity: 1; + transform: rotate(0deg); + } + } +} + +.table-toolbar { + padding-left: 16px; + padding-right: 8px; + padding-inline-start: 16px; + padding-inline-end: 8px; +} + + + +.table-cell { + display: table-cell; + padding: 16px; + font-size: 0.875rem; + text-align: start; + font-weight: 400; + line-height: 1.43; + border-bottom: 1px solid var(--palette-table-lines); + letter-spacing: 0.01071em; + vertical-align: inherit; + + & .checkbox { + margin: -12px; + } +} + +.table-cell-footer { + color: var(--palette-text-secondary); + font-size: 0.75rem; + line-height: 1.3125rem; +} + +.table-dense { + & * .table-row { + & .table-cell { + padding: 6px 24px 6px 16px; + padding-inline-start: 16px; + padding-inline-end: 24px; + + .table-cell-checkbox { + .button-root { + padding: 4px; + } + } + + .table-row-expander { + padding: 4px; + } + } + + & .table-cell:last-child { + padding-right: 16px; + padding-inline-end: 16px; + } + } +} + +.table-bordered { + & .table-container .table-root .table-body { + & .table-row { + .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); + } + } + } + + & .table-container .table-root .table-head.table-head-bordered { + & .table-row { + .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); + } + } + } + + & .table-container .table-root .table-foot.table-foot-bordered { + & .table-row { + .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); + } + } + } +} + +.table-sticky-header { + .table-container { + overflow-x: auto; + } + + & * .table-root { + + .table-head { + & * .table-cell:first-child { + border-radius: var(--default-borderradius) 0px 0px 0px; + } + + & * .table-cell:last-child { + border-radius: 0px var(--default-borderradius) 0px 0px; + } + + & * .table-cell { + background-color: var(--palette-surface); + position: sticky; + z-index: 2; + top: 0; + } + } + } +} + +.table-sticky-footer { + .table-container { + overflow-x: auto; + } + + & * .table-root { + + .table-foot { + + & * .table-cell { + background-color: var(--palette-surface); + position: sticky; + z-index: 2; + bottom: 0; + } + } + } +} + + +.table-row { + color: inherit; + display: table-row; + outline: 0; + vertical-align: middle; +} + +.table-hover { + & .table-container .table-root .table-body { + & .table-row:hover { + background-color: var(--palette-table-hover); + } + } +} + +.table-striped { + & .table-container .table-root .table-body { + & .table-row:nth-of-type(odd) { + background-color: var(--palette-table-striped); + } + } +} + +.table-hover.table-striped { + & .table-container .table-root .table-body { + & .table-row:nth-of-type(odd):hover { + background-color: var(--palette-table-hover); + } + } +} + + +.table-cell { + & > .input-control { + & > div.input.input-text { + color: var(--theme-on-surface); + font-size: 0.875rem; + margin-top: -14px; + margin-bottom: -8px; + } + } + + & > .select { + & > .input-control { + & > div.input.input-text { + color: var(--theme-on-surface); + font-size: 0.875rem; + margin-top: -14px; + margin-bottom: -8px; + } + } + } +} + +.table-cell-align { + &-left { + text-align: left; + } + + &-center { + text-align: center; + } + + &-right { + text-align: right; + flex-direction: row-reverse; + } + + &-justify { + text-align: justify; + } +} + +.table-pagination-display { + display: flex; + flex-shrink: 0; + + & .tablepager-left { + flex-direction: row !important; + } + + & .tablepager-right { + flex-direction: row-reverse !important; + } +} + +.table-pagination-information { + white-space: nowrap; + direction: initial; +} + +.table-page-number-information { + white-space: nowrap; + direction: initial; +} + +.table-pagination { + color: var(--theme-on-surface); + overflow: auto; + font-size: 0.875rem; + display: initial; +} + +.table-pagination:last-child { + padding: 0; +} + +.table-pagination-toolbar { + border-top: 1px solid var(--palette-table-lines); + height: 52px; + padding-right: 2px; + padding-inline-end: 2px; + padding-inline-start: unset; + + & .tablepager-left { + flex-direction: row !important; + } + + & .tablepager-right { + flex-direction: row-reverse !important; + } +} + +.table-pagination-spacer { + flex: 1 1 100%; +} + +.table-pagination-caption { + display: flex; + flex-shrink: 0; + align-items: center; + padding-left: 10px; + padding-right: 10px; +} + +.table-pagination-select { + cursor: pointer; + margin-left: 10px !important; + margin-right: 10px !important; + margin-top: 0px !important; + min-width: 52px; + + & .select-input { + margin-top: 0px !important; + } + + & .input .input-root { + max-width: 80px; + cursor: pointer; + margin-top: 2px; + border: none; + font-size: .875rem; + font-weight: 400; + line-height: 1.43; + letter-spacing: .01071em; + color: var(--theme-on-surface) + } +} + +.table-pagination-actions { + flex-shrink: 0; + align-items: center; + margin-left: 10px; + margin-inline-start: 10px; + margin-inline-end: unset; +} + +.table-smalldevices-sortselect { + display: none; +} + +.table-loading { + position: relative; + + & .table-loading-progress { + position: absolute; + width: 100%; + } +} + +.table-empty-row { + background-color: var(--palette-surface); + vertical-align: middle; + text-align: center; +} + + +@for $i from 1 through 5 { + tr.table-row-group-indented-#{$i} td:first-child { + padding-left: #{$i * 48}px !important; + } +} + +.table-row-expander { + margin: -12px -2px -12px -12px; +} + +@mixin table-display-smalldevices ($breakpoint) { + .#{$breakpoint}table { + .table-root .table-head, + .table-root .table-foot { + display: none; + } + + .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + + .table-body { + border-top: 1px solid var(--palette-table-lines); + } + + .table-row { + display: initial; + + .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + } + + .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + + &.table-dense { + & .table-cell { + padding: 6px 16px; + } + } + + .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + + &.table-small-alignright .table-cell:before { + margin-right: auto; + } + + .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + + .table-pagination { + + .table-pagination-spacer { + flex: none; + } + + .table-pagination-actions { + .button-root:first-child { + display: none; + } + + .button-root:last-child { + display: none; + } + } + + .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } + } + } +} + +// Table Pagination Flex Wrapper on old as phones +@media (max-width:360px) { + .table { + .table-pagination { + .select { + margin-left: auto; + margin-right: -14px; + margin-inline-start: auto; + margin-inline-end: -14px; + } + + .select ~ .table-pagination-caption { + margin-left: unset !important; + margin-inline-start: unset !important; + } + } + } +} + +@media (max-width:416px) { + .table { + .table-pagination { + .table-pagination-toolbar { + flex-wrap: wrap; + padding-top: 16px; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + min-height: 100px; + + .table-pagination-actions { + margin-left: auto; + margin-right: -14px; + margin-inline-start: auto; + margin-inline-end: -14px; + } + } + } + } +} + +@media (max-width:$breakpoint-sm) { + @include table-display-smalldevices("xs-"); +} + +@media (max-width:$breakpoint-md) { + @include table-display-smalldevices("sm-"); +} + +@media (max-width:$breakpoint-lg) { + @include table-display-smalldevices("md-"); +} + +@media (max-width:$breakpoint-xl) { + @include table-display-smalldevices("lg-"); +} + +@media (max-width:$breakpoint-xxl) { + @include table-display-smalldevices("xl-"); +} + +@media (min-width:$breakpoint-xxl) { + @include table-display-smalldevices("xxl-"); +} diff --git a/Styles/components/_tabs.scss b/Styles/components/_tabs.scss new file mode 100644 index 0000000..83f5d02 --- /dev/null +++ b/Styles/components/_tabs.scss @@ -0,0 +1,303 @@ +@import '../abstracts/variables'; + +.tabs { + display: flex; + flex-direction: column; + + &.tabs-reverse { + flex-direction: column-reverse; + } + + &.tabs-vertical { + flex-direction: row; + } + + &.tabs-vertical-reverse { + flex-direction: row-reverse; + } + + &.tabs-rounded { + border-radius: var(--default-borderradius); + + .tabs-toolbar { + border-radius: var(--default-borderradius); + } + + .tabs-panels { + border-radius: var(--default-borderradius); + } + } +} + +.tabs-toolbar { + position: relative; + background-color: var(--palette-surface); + + &.tabs-border-left { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-right: 1px solid var(--palette-lines-default); + } + + &.tabs-border-right { + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-left: 1px solid var(--palette-lines-default); + } + + &.tabs-border-top { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-bottom: 1px solid var(--palette-lines-default); + } + + &.tabs-border-bottom { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; + border-top: 1px solid var(--palette-lines-default); + } + + &.tabs-rounded { + border-radius: var(--default-borderradius); + } + + &.tabs-vertical { + .tabs-toolbar-inner { + flex-direction: column; + + .tabs-scroll-button { + .button-root { + width: 100%; + border-radius: 0px; + height: 32px; + + .icon-button-label { + .icon-root{ + transform:rotate(90deg); + } + } + } + } + } + } + + & .tabs-toolbar-inner { + display: flex; + min-height: 48px; + } +} + + +.tabs-toolbar-content { + width: 100%; + flex: 1 1 auto; + display: inline-block; + position: relative; + white-space: nowrap; + overflow: hidden; + + & .tabs-toolbar-wrapper { + width: max-content; + position: inherit; + display: flex; + transition: .3s cubic-bezier(.25,.8,.5,1); + + &.tabs-centered { + margin: auto; + } + + &.tabs-vertical { + flex-direction: column; + } + } +} + +.tabs-panels { + position: relative; + transition: .3s cubic-bezier(.25,.8,.5,1); + + &.tabs-vertical { + display: flex; + flex-grow: 1; + } +} + +.tab { + width:100%; + min-width: 160px; + display: inline-flex; + padding: 6px 12px; + min-height: 48px; + flex-shrink: 0; + font-weight: 500; + line-height: 1.75; + user-select: none; + white-space: normal; + letter-spacing: 0.02857em; + text-transform: uppercase; + text-align: center; + align-items: center; + justify-content: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + cursor: pointer; + background-color: var(--palette-action-default-hover); + } + + &.tab-active { + color: var(--palette-primary); + + &:hover { + background-color: var(--palette-primary-hover); + } + } + + &.disabled { + cursor: default; + pointer-events: none; + color: var(--palette-text-disabled); + } + + & .tab-icon-text { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; + } +} + +.tab-slider { + position: absolute; + background: var(--palette-primary); + + &.tab-slider-horizontal { + height: 2px; + left: 0; + bottom: 0; + transition: left .3s cubic-bezier(.64,.09,.08,1); + will-change: left; + + &.tab-slider-horizontal-reverse { + top: 0px; + } + } + + &.tab-slider-vertical { + width: 2px; + right: 0; + transition: top .3s cubic-bezier(.64,.09,.08,1); + will-change: top; + + &.tab-slider-vertical-reverse { + left: 0; + right: unset; + } + } +} + +.tab-badge{ + margin-left:8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +@each $color in $palette-colors { + .tabs-toolbar-#{$color} { + background-color: var(--palette-#{$color}); + color: var(--palette-#{$color}-text); + + .tab-slider { + background: var(--palette-#{$color}-text); + } + + .tab { + &.tab-active { + color: var(--palette-#{$color}-text); + + &:hover { + background-color: var(--palette-#{$color}-lighten); + } + } + } + } +} + + +.tab-transition { + &-enter { + transform: translate(100%, 0); + } + + &-leave, &-leave-active { + position: absolute; + top: 0; + } + + &-leave-to { + position: absolute; + transform: translate(-100%, 0); + } +} + +.tab-reverse-transition { + &-enter { + transform: translate(-100%, 0); + } + + &-leave, &-leave-to { + top: 0; + position: absolute; + transform: translate(100%, 0); + } +} + +.dynamic-tabs { + .tabs-toolbar { + .tab { + padding: 6px 14px; + + .icon-button { + padding: 4px; + margin-right: -4px; + margin-inline-end: -4px; + margin-inline-start: unset; + } + + .tabs-panel-header-before { + padding-right: 8px; + padding-inline-end: 8px; + padding-inline-start: unset; + } + + .tabs-panel-header-after { + padding-left: 8px; + padding-inline-start: 8px; + padding-inline-end: unset; + } + } + } +} + +.tabs-header { + &.tabs-header-before { + display: inherit; + } + + &.tabs-header-after { + display: inherit; + } +} + +.tabs-panel-header { + display: flex; + flex: 1 1 auto; + + &.tabs-panel-header-before { + justify-content: flex-start; + } + + &.tabs-panel-header-after { + justify-content: flex-end; + } +} + diff --git a/Styles/components/_timeline.scss b/Styles/components/_timeline.scss new file mode 100644 index 0000000..49c9bd6 --- /dev/null +++ b/Styles/components/_timeline.scss @@ -0,0 +1,650 @@ + +.timeline { + position: relative; + display: flex; +} + +.timeline-vertical { + padding-top: 24px; + flex-direction: column; + + &::before { + top: 0; + bottom: 0; + content: ""; + height: 100%; + position: absolute; + width: 2px; + background: var(--palette-divider); + } + + .timeline-item { + padding-bottom: 24px; + + .timeline-item-content { + max-width: calc(50% - 48px); + } + + .timeline-item-divider { + min-width: 96px; + } + + .timeline-item-opposite { + flex: 1 1 auto; + max-width: calc(50% - 48px); + } + } +} + +.timeline-horizontal { + flex-direction: row; + + &::before { + top: 0; + bottom: 0; + content: ""; + height: 2px; + position: absolute; + width: 100%; + background: var(--palette-divider); + } + + .timeline-item { + padding-left: 24px; + padding-right: 24px; + width: 100%; + + .timeline-item-content { + max-height: calc(50% - 48px); + } + + .timeline-item-divider { + min-height: 96px; + } + } +} + +.timeline-item { + display: flex; + + .timeline-item-content { + position: relative; + height: 100%; + flex: 1 1 auto; + } + + .timeline-item-divider { + position: relative; + display: flex; + align-items: center; + justify-content: center; + } + + .timeline-item-opposite { + align-self: center; + } +} + + +.timeline-vertical { + &.timeline-align-start { + .timeline-item-divider { + align-items: flex-start; + } + + .timeline-item-opposite { + align-self: flex-start; + } + } + + &.timeline-align-end { + .timeline-item-divider { + align-items: flex-end; + } + + .timeline-item-opposite { + align-self: flex-end; + } + } + + &.timeline-position-alternate { + &::before { + left: auto; + right: calc(50% - 1px); + } + + .timeline-item { + &:nth-child(odd):not(.timeline-item-start), &.timeline-item-end { + flex-direction: row-reverse; + + .timeline-item-opposite { + text-align: end; + } + } + + &:nth-child(2n):not(.timeline-item-end) { + flex-direction: row; + + .timeline-item-opposite { + text-align: start; + } + } + } + + &.timeline-reverse { + .timeline-item { + &:nth-child(odd):not(.timeline-item-end), &.timeline-item-start { + flex-direction: row; + + .timeline-item-opposite { + text-align: start; + } + } + + &:nth-child(2n):not(.timeline-item-start) { + flex-direction: row-reverse; + + .timeline-item-opposite { + text-align: end; + } + } + } + } + } + + &.timeline-position-start { + &::before { + right: auto; + left: 47px; + } + + &.timeline-rtl { + &::before { + right: 47px; + left: auto; + } + } + + .timeline-item { + flex-direction: row-reverse; + } + } + + &.timeline-position-end { + &::before { + right: 47px; + left: auto; + } + + &.timeline-rtl { + &::before { + left: 47px; + right: auto; + } + } + + .timeline-item { + flex-direction: row; + } + } + /* Both Start & End */ + &.timeline-position { + &-start, &-end { + .timeline-item-content { + max-width: calc(100% - 96px); + } + + .timeline-item-opposite { + display: none; + } + } + } +} + +.timeline-horizontal { + &.timeline-align-start { + .timeline-item-divider { + justify-content: flex-start; + } + + .timeline-item-opposite { + align-self: flex-start; + } + } + + &.timeline-align-end { + .timeline-item-divider { + justify-content: flex-end; + } + + .timeline-item-opposite { + align-self: flex-end; + } + } + + &.timeline-position-alternate { + &::before { + top: auto; + bottom: calc(50% - 1px); + } + + .timeline-item { + &:nth-child(odd), &.timeline-item-end { + flex-direction: column-reverse; + + .timeline-item-opposite { + /* I dont know */ + } + } + + &:nth-child(2n), &.timeline-item-start { + flex-direction: column; + + .timeline-item-opposite { + /* I dont know */ + } + } + } + + &.timeline-reverse { + .timeline-item { + &:nth-child(odd), &.timeline-item-end { + flex-direction: column; + + .timeline-item-opposite { + /* I dont know */ + } + } + + &:nth-child(2n), &.timeline-item-start { + flex-direction: column-reverse; + + .timeline-item-opposite { + /* I dont know */ + } + } + } + } + } + + &.timeline-position-top { + &::before { + top: 47px; + bottom: auto; + } + + .timeline-item { + flex-direction: column-reverse; + } + } + + &.timeline-position-bottom { + &::before { + top: auto; + bottom: 47px; + } + + .timeline-item { + flex-direction: column; + } + } + /* Both Top & Bottom */ + &.timeline-position { + &-top, &-bottom { + + .timeline-item-content { + max-height: calc(100% - 96px); + } + + .timeline-item-opposite { + display: none; + } + } + } +} + +/*Dot*/ + +.timeline-item-dot { + display: flex; + justify-content: center; + align-items: center; + background: var(--palette-surface); + border-radius: 50%; + left: calc(50% - 19px); + + &.timeline-dot-size-small { + width: 24px; + height: 24px; + + .timeline-item-dot-inner { + height: 18px; + width: 18px; + } + } + + &.timeline-dot-size-medium { + width: 38px; + height: 38px; + + .timeline-item-dot-inner { + height: 30px; + width: 30px; + } + } + + &.timeline-dot-size-large { + width: 52px; + height: 52px; + + .timeline-item-dot-inner { + height: 42px; + width: 42px; + } + } + + .timeline-item-dot-inner { + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + &.timeline-dot-fill { + height: inherit; + width: inherit; + } + + &.timeline-dot-default { + background-color: var(--palette-grey-light); + } + + @each $color in $palette-colors { + &.timeline-dot-#{$color} { + color: var(--palette-#{$color}-text); + background-color: var(--palette-#{$color}); + } + } + } +} + +/*Modifiers*/ + +.timeline-modifiers { + .timeline-item-content { + .card { + &::before, &::after { + content: ""; + position: absolute; + } + } + } + + &.timeline-vertical { + &.timeline-position-start:not(.timeline-rtl), &.timeline-position-end.timeline-rtl { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(0); + left: -16px; + right: auto; + } + + &.paper-outlined { + &::after { + left: -15px; + } + } + } + } + } + + &.timeline-position-end:not(.timeline-rtl), &.timeline-position-start.timeline-rtl { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(180deg); + right: -16px; + left: auto; + } + + &.paper-outlined { + &::after { + right: -15px; + } + } + } + } + } + + &.timeline-position-alternate { + .timeline-item { + &:nth-child(odd):not(.timeline-item-start), &.timeline-item-end { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(0); + left: -16px; + right: auto; + } + + &.paper-outlined { + &::after { + left: -15px; + } + } + } + } + } + + &:nth-child(2n):not(.timeline-item-end) { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(180deg); + right: -16px; + left: auto; + } + + &.paper-outlined { + &::after { + right: -15px; + } + } + } + } + } + } + } + + &.timeline-reverse:not(.timeline-rtl), &.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) { + .timeline-item { + &:nth-child(odd):not(.timeline-item-end), &.timeline-item-start { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(180deg); + right: -16px; + left: auto; + } + + &.paper-outlined { + &::after { + right: -15px; + } + } + } + } + } + + &:nth-child(2n):not(.timeline-item-start) { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(0); + left: -16px; + right: auto; + } + + &.paper-outlined { + &::after { + left: -15px; + } + } + } + } + } + } + } + } + + &.timeline-horizontal { + &.timeline-position-top { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + top: -23px; + } + } + } + } + } + + &.timeline-position-bottom { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + bottom: -23px; + } + } + } + } + } + + &.timeline-position-alternate { + .timeline-item { + &:nth-child(odd):not(.timeline-item-start), &.timeline-item-end { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + top: -23px; + } + } + } + } + } + + &:nth-child(2n):not(.timeline-item-end) { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + bottom: -23px; + } + } + } + } + } + } + + &.timeline-reverse { + .timeline-item { + &:nth-child(odd):not(.timeline-item-start), &.timeline-item-end { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + bottom: -23px; + } + } + } + } + } + + &:nth-child(2n):not(.timeline-item-end) { + .timeline-item-content { + .card { + &::before, &::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); + } + + &.paper-outlined { + &::after { + top: -23px; + } + } + } + } + } + } + } + } + } + + + + .timeline-item-content { + .card { + &::before { + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + border-right: 16px solid rgba(0,0,0,.10); + top: calc(50% - 14px); + } + + &::after { + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + border-right: 16px solid var(--palette-surface); + top: calc(50% - 16px); + } + + &.paper-outlined { + &::before { + top: calc(50% - 16px); + border-right-color: var(--palette-lines-default); + } + } + } + } +} \ No newline at end of file diff --git a/Styles/components/_toolbar.scss b/Styles/components/_toolbar.scss new file mode 100644 index 0000000..2666ec8 --- /dev/null +++ b/Styles/components/_toolbar.scss @@ -0,0 +1,34 @@ +@import '../abstracts/variables'; + +.toolbar { + display: flex; + position: relative; + align-items: center; + height: 56px; +} + +.toolbar-gutters { + padding-left: 16px; + padding-right: 16px; +} + +@media (min-width:$breakpoint-xs) and (orientation: landscape) { + .toolbar { + height: 48px; + } +} + +@media (min-width:$breakpoint-sm) { + .toolbar { + height: 64px; + } + + .toolbar-gutters { + padding-left: 24px; + padding-right: 24px; + } +} + +.toolbar-dense { + height: 48px; +} diff --git a/Styles/components/_tooltip.scss b/Styles/components/_tooltip.scss new file mode 100644 index 0000000..b29dd30 --- /dev/null +++ b/Styles/components/_tooltip.scss @@ -0,0 +1,76 @@ + +.tooltip-root { + width: fit-content; + + &.tooltip-inline { + display: inline-block; + } +} + +.tooltip { + padding: 4px 8px; + text-align: center; + align-items: center; + justify-content: center; + font-weight: 500; + font-size: 12px; + line-height: 1.4em; + border-radius: var(--default-borderradius); + z-index: var(--zindex-tooltip); + + &.tooltip-default { + color: var(--palette-dark-text); + background-color: var(--palette-grey-darker); + + &.tooltip-arrow::after { + border-color: var(--palette-grey-darker) transparent transparent transparent; + } + } + + &.tooltip { + &-center-left:not([data-mudpopover-flip]), &-center-right[data-mudpopover-flip] { + transform: translateX(-10px); + + &.tooltip-arrow::after { + left: 100%; + transform: rotate(270deg); + } + } + + &-center-right:not([data-mudpopover-flip]), &-center-left[data-mudpopover-flip] { + transform: translateX(10px); + + &.tooltip-arrow::after { + right: 100%; + transform: rotate(90deg); + } + } + + &-top-center:not([data-mudpopover-flip]), &-bottom-center[data-mudpopover-flip] { + transform: translateY(-10px); + + &.tooltip-arrow::after { + top: 100%; + transform: rotate(0deg); + } + } + + &-bottom-center:not([data-mudpopover-flip]), &-top-center[data-mudpopover-flip] { + transform: translateY(10px); + + &.tooltip-arrow::after { + bottom: 100%; + transform: rotate(180deg); + } + } + } + + &.tooltip-arrow::after { + content: ""; + position: absolute; + border-width: 6px; + border-style: solid; + border-color: transparent; + border-top-color: inherit; + } +} \ No newline at end of file diff --git a/Styles/components/_treeview.scss b/Styles/components/_treeview.scss new file mode 100644 index 0000000..b9375ee --- /dev/null +++ b/Styles/components/_treeview.scss @@ -0,0 +1,136 @@ +@import '../abstracts/variables'; + +.treeview { + margin: 0px; + padding: 0px; + list-style: none; + overflow: auto; + + @each $color in $palette-colors { + &.treeview-selected-#{$color} { + .treeview-item-content.treeview-item-selected { + color: var(--palette-#{$color}); + background-color: var(--palette-#{$color}-hover); + } + } + } + + @each $color in $palette-colors { + &.treeview-checked-#{$color} { + .treeview-item-checkbox { + .button-root.icon-button { + color: var(--palette-#{$color}); + } + } + } + } +} + +.treeview-group { + margin: 0px; + padding: 0px; + margin-left: 17px; + margin-inline-start: 17px; + margin-inline-end: unset; + list-style: none; +} + +.treeview-item { + margin: 0; + outline: 0; + padding: 0; + cursor: default; + list-style: none; + min-height: 2rem; + align-items: center; + -webkit-tap-highlight-color: transparent; + + .treeview-item-arrow, .treeview-item-checkbox { + .icon-button { + padding: 4px; + } + } +} + +.treeview-item-content { + width: 100%; + display: flex; + padding: 4px 8px; + align-items: center; + transition: background-color 150ms cubic-bezier(.4,0,.2,1) 0ms; +} + +.treeview-hover .treeview-item-content:hover { + background-color: var(--palette-action-default-hover); +} + +.treeview-item-arrow { + width: 2rem; + display: flex; + flex-shrink: 0; + margin: 0 4px; + min-height: 32px; + justify-content: center; + + .treeview-item-arrow-expand { + transition: .3s cubic-bezier(.25,.8,.5,1),visibility 0s; + + &.transform { + transform: rotate(90deg); + } + } + + .treeview-item-arrow-load { + animation: rotation 1s infinite linear; + } +} + +.treeview-item-icon { + width: 32px; + display: flex; + flex-shrink: 0; + margin-right: 4px; + margin-inline-end: 4px; + margin-inline-start: unset; + justify-content: center; +} + +.treeview-item-label { + flex-grow: 1; + padding-left: 4px; + padding-right: 4px; +} + +.treeview-dense { + .treeview-item { + min-height: unset; + } + + .treeview-item-content { + padding: 1px 4px; + } + + .treeview-item-arrow { + min-height: unset; + } + + .icon-button { + padding: 0; + } +} + +@keyframes rotation { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(359deg); + } +} + +.application-layout-rtl { + .treeview-item-arrow { + transform: scaleX(-1); + } +} \ No newline at end of file diff --git a/Styles/components/_typography.scss b/Styles/components/_typography.scss new file mode 100644 index 0000000..97729c0 --- /dev/null +++ b/Styles/components/_typography.scss @@ -0,0 +1,62 @@ + +.typography{ + margin: 0; +} + +$typography-types: ("body1", "body2", "caption", "button", "h1", "h2", "h3", "h4", "h5", "h6", "subtitle1", "subtitle2", "overline"); + +@each $type in $typography-types { + .typography-#{$type} { + font-size: var(--typography-#{$type}-size); + font-family: var(--typography-#{$type}-family); + font-weight: var(--typography-#{$type}-weight); + line-height: var(--typography-#{$type}-lineheight); + letter-spacing: var(--typography-#{$type}-letterspacing); + text-transform: var(--typography-#{$type}-text-transform);; + } +} + +.typography-srOnly { + width: 1px; + height: 1px; + overflow: hidden; + position: absolute; +} + +.typography-align-left { + text-align: left; +} + +.typography-align-center { + text-align: center; +} + +.typography-align-right { + text-align: right; +} + +.typography-align-justify { + text-align: justify; +} + +.typography-nowrap { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.typography-gutterbottom { + margin-bottom: 0.35em; +} + +.typography-paragraph { + margin-bottom: 16px; +} + +.typography-display-inline { + display: inline; +} + +.typography-display-block { + display: block; +} diff --git a/Styles/core/_animations.scss b/Styles/core/_animations.scss new file mode 100644 index 0000000..811285c --- /dev/null +++ b/Styles/core/_animations.scss @@ -0,0 +1,249 @@ +@keyframes animation-fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-moz-keyframes animation-fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-webkit-keyframes animation-fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-o-keyframes animation-fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-ms-keyframes animation-fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-webkit-keyframes scale-up-center { + 0% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes scale-up-center { + 0% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@-webkit-keyframes skeleton-keyframes-pulse { + 0% { + opacity: 1; + } + + 50% { + opacity: 0.4; + } + + 100% { + opacity: 1; + } +} + +@-webkit-keyframes skeleton-keyframes-wave { + 0% { + transform: translateX(-100%); + } + + 60% { + transform: translateX(100%); + } + + 100% { + transform: translateX(100%); + } +} + +@-webkit-keyframes progress-circular-keyframes-circular-rotate { + 0% { + transform-origin: 50% 50%; + } + + 100% { + transform: rotate(360deg); + } +} + +@-webkit-keyframes progress-circular-keyframes-circular-dash { + 0% { + stroke-dasharray: 1px, 200px; + stroke-dashoffset: 0px; + } + + 50% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -15px; + } + + 100% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -125px; + } +} + +@-webkit-keyframes progress-linear-horizontal-keyframes-indeterminate1 { + 0% { + left: -35%; + right: 100%; + } + + 60% { + left: 100%; + right: -90%; + } + + 100% { + left: 100%; + right: -90%; + } +} + +@-webkit-keyframes progress-linear-horizontal-keyframes-indeterminate2 { + 0% { + left: -200%; + right: 100%; + } + + 60% { + left: 107%; + right: -8%; + } + + 100% { + left: 107%; + right: -8%; + } +} + +@-webkit-keyframes progress-linear-horizontal-keyframes-buffer { + 0% { + opacity: 1; + background-position: 0 -23px; + } + + 50% { + opacity: 0; + background-position: 0 -23px; + } + + 100% { + opacity: 1; + background-position: -200px -23px; + } +} + + + + + + + + + + +@-webkit-keyframes progress-linear-vertical-keyframes-indeterminate1 { + 0% { + bottom: -35%; + top: 100%; + } + + 60% { + bottom: 100%; + top: -90%; + } + + 100% { + bottom: 100%; + top: -90%; + } +} + +@-webkit-keyframes progress-linear-vertical-keyframes-indeterminate2 { + 0% { + bottom: -200%; + top: 100%; + } + + 60% { + bottom: 107%; + top: -8%; + } + + 100% { + bottom: 107%; + top: -8%; + } +} + +@-webkit-keyframes progress-linear-vertical-keyframes-buffer { + 0% { + opacity: 1; + background-position: -23px 0; + } + + 50% { + opacity: 0; + background-position: -23px 0; + } + + 100% { + opacity: 1; + background-position: -23px -200px; + } +} + +@keyframes progress-linear-striped-loading { + 0% { + background-position: 0 0; + } + + 100% { + background-position: 300px 0; + } +} \ No newline at end of file diff --git a/Styles/core/_base.scss b/Styles/core/_base.scss new file mode 100644 index 0000000..db60c8b --- /dev/null +++ b/Styles/core/_base.scss @@ -0,0 +1,34 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; + border-width: 0; + border-style: solid; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +strong, b { + font-weight: 700; +} + +body { + color: var(--palette-text-primary); + font-family: var(--typography-default-family); + font-size: var(--typography-default-size); + font-weight: var(--typography-default-weight); + line-height: var(--typography-default-lineheight); + letter-spacing: var(--typography-default-letterspacing); + text-transform: var(--typography-default-text-transform); + background-color: var(--palette-background); +} + +a { + color: var(--palette-text-primary); +} + +.layout { + height: 100%; + width: 100%; + position: relative; +} \ No newline at end of file diff --git a/Styles/core/_blazor.scss b/Styles/core/_blazor.scss new file mode 100644 index 0000000..6be3610 --- /dev/null +++ b/Styles/core/_blazor.scss @@ -0,0 +1,45 @@ +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 9999; +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} + +#components-reconnect-modal { + z-index: 9999 !important; + + h5 { + font-size: 18px; + } + + button { + color: var(--palette-text-primary); + padding: 8px 16px; + font-size: .875rem; + min-width: 64px; + box-sizing: border-box; + transition: background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms,border 250ms cubic-bezier(.4,0,.2,1) 0ms; + font-weight: 500; + line-height: 1; + border-radius: var(--default-borderradius); + letter-spacing: .02857em; + text-transform: uppercase; + margin: 40px auto !important; + + &:hover { + background-color: var(--palette-action-default-hover); + } + } +} \ No newline at end of file diff --git a/Styles/core/_colors.scss b/Styles/core/_colors.scss new file mode 100644 index 0000000..227833a --- /dev/null +++ b/Styles/core/_colors.scss @@ -0,0 +1,361 @@ +$red: ( + 'base': #F44336, + 'lighten-5': #FFEBEE, + 'lighten-4': #FFCDD2, + 'lighten-3': #EF9A9A, + 'lighten-2': #E57373, + 'lighten-1': #EF5350, + 'darken-1': #E53935, + 'darken-2': #D32F2F, + 'darken-3': #C62828, + 'darken-4': #B71C1C, + 'accent-1': #FF8A80, + 'accent-2': #FF5252, + 'accent-3': #FF1744, + 'accent-4': #D50000 +); + +$pink: ( + 'base': #e91e63, + 'lighten-5': #fce4ec, + 'lighten-4': #f8bbd0, + 'lighten-3': #f48fb1, + 'lighten-2': #f06292, + 'lighten-1': #ec407a, + 'darken-1': #d81b60, + 'darken-2': #c2185b, + 'darken-3': #ad1457, + 'darken-4': #880e4f, + 'accent-1': #ff80ab, + 'accent-2': #ff4081, + 'accent-3': #f50057, + 'accent-4': #c51162 +); + +$purple: ( + 'base': #9c27b0, + 'lighten-5': #f3e5f5, + 'lighten-4': #e1bee7, + 'lighten-3': #ce93d8, + 'lighten-2': #ba68c8, + 'lighten-1': #ab47bc, + 'darken-1': #8e24aa, + 'darken-2': #7b1fa2, + 'darken-3': #6a1b9a, + 'darken-4': #4a148c, + 'accent-1': #ea80fc, + 'accent-2': #e040fb, + 'accent-3': #d500f9, + 'accent-4': #aa00ff +); + +$deep-purple: ( + 'base': #673ab7, + 'lighten-5': #ede7f6, + 'lighten-4': #d1c4e9, + 'lighten-3': #b39ddb, + 'lighten-2': #9575cd, + 'lighten-1': #7e57c2, + 'darken-1': #5e35b1, + 'darken-2': #512da8, + 'darken-3': #4527a0, + 'darken-4': #311b92, + 'accent-1': #b388ff, + 'accent-2': #7c4dff, + 'accent-3': #651fff, + 'accent-4': #6200ea +); + +$indigo: ( + 'base': #3f51b5, + 'lighten-5': #e8eaf6, + 'lighten-4': #c5cae9, + 'lighten-3': #9fa8da, + 'lighten-2': #7986cb, + 'lighten-1': #5c6bc0, + 'darken-1': #3949ab, + 'darken-2': #303f9f, + 'darken-3': #283593, + 'darken-4': #1a237e, + 'accent-1': #8c9eff, + 'accent-2': #536dfe, + 'accent-3': #3d5afe, + 'accent-4': #304ffe +); + +$blue: ( + 'base': #2196F3, + 'lighten-5': #E3F2FD, + 'lighten-4': #BBDEFB, + 'lighten-3': #90CAF9, + 'lighten-2': #64B5F6, + 'lighten-1': #42A5F5, + 'darken-1': #1E88E5, + 'darken-2': #1976D2, + 'darken-3': #1565C0, + 'darken-4': #0D47A1, + 'accent-1': #82B1FF, + 'accent-2': #448AFF, + 'accent-3': #2979FF, + 'accent-4': #2962FF +); + +$light-blue: ( + 'base': #03a9f4, + 'lighten-5': #e1f5fe, + 'lighten-4': #b3e5fc, + 'lighten-3': #81d4fa, + 'lighten-2': #4fc3f7, + 'lighten-1': #29b6f6, + 'darken-1': #039be5, + 'darken-2': #0288d1, + 'darken-3': #0277bd, + 'darken-4': #01579b, + 'accent-1': #80d8ff, + 'accent-2': #40c4ff, + 'accent-3': #00b0ff, + 'accent-4': #0091ea +); + +$cyan: ( + 'base': #00bcd4, + 'lighten-5': #e0f7fa, + 'lighten-4': #b2ebf2, + 'lighten-3': #80deea, + 'lighten-2': #4dd0e1, + 'lighten-1': #26c6da, + 'darken-1': #00acc1, + 'darken-2': #0097a7, + 'darken-3': #00838f, + 'darken-4': #006064, + 'accent-1': #84ffff, + 'accent-2': #18ffff, + 'accent-3': #00e5ff, + 'accent-4': #00b8d4 +); + +$teal: ( + 'base': #009688, + 'lighten-5': #e0f2f1, + 'lighten-4': #b2dfdb, + 'lighten-3': #80cbc4, + 'lighten-2': #4db6ac, + 'lighten-1': #26a69a, + 'darken-1': #00897b, + 'darken-2': #00796b, + 'darken-3': #00695c, + 'darken-4': #004d40, + 'accent-1': #a7ffeb, + 'accent-2': #64ffda, + 'accent-3': #1de9b6, + 'accent-4': #00bfa5 +); + +$green: ( + 'base': #4CAF50, + 'lighten-5': #E8F5E9, + 'lighten-4': #C8E6C9, + 'lighten-3': #A5D6A7, + 'lighten-2': #81C784, + 'lighten-1': #66BB6A, + 'darken-1': #43A047, + 'darken-2': #388E3C, + 'darken-3': #2E7D32, + 'darken-4': #1B5E20, + 'accent-1': #B9F6CA, + 'accent-2': #69F0AE, + 'accent-3': #00E676, + 'accent-4': #00C853 +); + +$light-green: ( + 'base': #8bc34a, + 'lighten-5': #f1f8e9, + 'lighten-4': #dcedc8, + 'lighten-3': #c5e1a5, + 'lighten-2': #aed581, + 'lighten-1': #9ccc65, + 'darken-1': #7cb342, + 'darken-2': #689f38, + 'darken-3': #558b2f, + 'darken-4': #33691e, + 'accent-1': #ccff90, + 'accent-2': #b2ff59, + 'accent-3': #76ff03, + 'accent-4': #64dd17 +); + +$lime: ( + 'base': #cddc39, + 'lighten-5': #f9fbe7, + 'lighten-4': #f0f4c3, + 'lighten-3': #e6ee9c, + 'lighten-2': #dce775, + 'lighten-1': #d4e157, + 'darken-1': #c0ca33, + 'darken-2': #afb42b, + 'darken-3': #9e9d24, + 'darken-4': #827717, + 'accent-1': #f4ff81, + 'accent-2': #eeff41, + 'accent-3': #c6ff00, + 'accent-4': #aeea00 +); + +$yellow: ( + 'base': #ffeb3b, + 'lighten-5': #fffde7, + 'lighten-4': #fff9c4, + 'lighten-3': #fff59d, + 'lighten-2': #fff176, + 'lighten-1': #ffee58, + 'darken-1': #fdd835, + 'darken-2': #fbc02d, + 'darken-3': #f9a825, + 'darken-4': #f57f17, + 'accent-1': #ffff8d, + 'accent-2': #ffff00, + 'accent-3': #ffea00, + 'accent-4': #ffd600 +); + +$amber: ( + 'base': #ffc107, + 'lighten-5': #fff8e1, + 'lighten-4': #ffecb3, + 'lighten-3': #ffe082, + 'lighten-2': #ffd54f, + 'lighten-1': #ffca28, + 'darken-1': #ffb300, + 'darken-2': #ffa000, + 'darken-3': #ff8f00, + 'darken-4': #ff6f00, + 'accent-1': #ffe57f, + 'accent-2': #ffd740, + 'accent-3': #ffc400, + 'accent-4': #ffab00 +); + +$orange: ( + 'base': #ff9800, + 'lighten-5': #fff3e0, + 'lighten-4': #ffe0b2, + 'lighten-3': #ffcc80, + 'lighten-2': #ffb74d, + 'lighten-1': #ffa726, + 'darken-1': #fb8c00, + 'darken-2': #f57c00, + 'darken-3': #ef6c00, + 'darken-4': #e65100, + 'accent-1': #ffd180, + 'accent-2': #ffab40, + 'accent-3': #ff9100, + 'accent-4': #ff6d00 +); + +$deep-orange: ( + 'base': #ff5722, + 'lighten-5': #fbe9e7, + 'lighten-4': #ffccbc, + 'lighten-3': #ffab91, + 'lighten-2': #ff8a65, + 'lighten-1': #ff7043, + 'darken-1': #f4511e, + 'darken-2': #e64a19, + 'darken-3': #d84315, + 'darken-4': #bf360c, + 'accent-1': #ff9e80, + 'accent-2': #ff6e40, + 'accent-3': #ff3d00, + 'accent-4': #dd2c00 +); + +$brown: ( + 'base': #795548, + 'lighten-5': #efebe9, + 'lighten-4': #d7ccc8, + 'lighten-3': #bcaaa4, + 'lighten-2': #a1887f, + 'lighten-1': #8d6e63, + 'darken-1': #6d4c41, + 'darken-2': #5d4037, + 'darken-3': #4e342e, + 'darken-4': #3e2723 +); + +$blue-grey: ( + 'base': #607d8b, + 'lighten-5': #eceff1, + 'lighten-4': #cfd8dc, + 'lighten-3': #b0bec5, + 'lighten-2': #90a4ae, + 'lighten-1': #78909c, + 'darken-1': #546e7a, + 'darken-2': #455a64, + 'darken-3': #37474f, + 'darken-4': #263238 +); + +$grey: ( + 'base': #9e9e9e, + 'lighten-5': #fafafa, + 'lighten-4': #f5f5f5, + 'lighten-3': #eeeeee, + 'lighten-2': #e0e0e0, + 'lighten-1': #bdbdbd, + 'darken-1': #757575, + 'darken-2': #616161, + 'darken-3': #424242, + 'darken-4': #212121 +); + +$shades: ( + 'black': #000000, + 'white': #FFFFFF, + 'transparent': transparent +); + +$colors: ( + 'red': $red, + 'pink': $pink, + 'purple': $purple, + 'deep-purple': $deep-purple, + 'indigo': $indigo, + 'blue': $blue, + 'light-blue': $light-blue, + 'cyan': $cyan, + 'teal': $teal, + 'green': $green, + 'light-green': $light-green, + 'lime': $lime, + 'yellow': $yellow, + 'amber': $amber, + 'orange': $orange, + 'deep-orange': $deep-orange, + 'brown': $brown, + 'blue-grey': $blue-grey, + 'grey': $grey, + 'shades': $shades +); + +@each $name, $color in $colors { + @each $color_type, $color_value in $color { + @if $color_type == "base" { + .#{$name} { + background-color: $color_value; + } + .#{$name}-text { + color: $color_value; + } + } + @else if $name != "base" { + .#{$name}.#{$color_type} { + background-color: $color_value; + } + + .#{$name}-text.text-#{$color_type} { + color: $color_value; + } + } + } +} \ No newline at end of file diff --git a/Styles/core/_elevation.scss b/Styles/core/_elevation.scss new file mode 100644 index 0000000..53f085b --- /dev/null +++ b/Styles/core/_elevation.scss @@ -0,0 +1,5 @@ +@for $i from 0 through 25 { + .elevation-#{$i} { + box-shadow: var(--elevation-#{$i}); + } +} diff --git a/Styles/core/_reset.scss b/Styles/core/_reset.scss new file mode 100644 index 0000000..43802a6 --- /dev/null +++ b/Styles/core/_reset.scss @@ -0,0 +1,81 @@ +a { + text-decoration: none; + + &:focus-visible{ + outline:none; + } +} + +label { + display: inline-block; +} + +button { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + display: inline-flex; + outline: 0; + padding: 0; + position: relative; + align-items: center; + user-select: none; + border-radius: 0; + vertical-align: middle; + -moz-appearance: none; + justify-content: center; + text-decoration: none; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; +} + + +button:focus { + outline: none; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +select { + word-wrap: normal; +} + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +iframe { + border: none; + height: 100%; + width: 100%; +} + +ul { + margin: 0; + padding: 0; + list-style: none; +} \ No newline at end of file diff --git a/Styles/core/_ripple.scss b/Styles/core/_ripple.scss new file mode 100644 index 0000000..42df387 --- /dev/null +++ b/Styles/core/_ripple.scss @@ -0,0 +1,37 @@ +.ripple { + position: relative; + overflow: hidden; + + &:after { + content: ""; + display: block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + pointer-events: none; + background-image: radial-gradient(circle, #000 10%, transparent 10.01%); + background-repeat: no-repeat; + background-position: 50%; + transform: scale(10,10); + opacity: 0; + transition: transform .3s, opacity 1s; + } + + &:active:after { + transform: scale(0,0); + opacity: 0.1; + transition: 0s; + } +} + +.ripple-icon, .ripple-checkbox, .ripple-switch, .ripple-radio { + &:after { + transform: scale(7,7); + } +} + +.ripple-switch { + position: absolute; +} diff --git a/Styles/core/_rtl.scss b/Styles/core/_rtl.scss new file mode 100644 index 0000000..888b083 --- /dev/null +++ b/Styles/core/_rtl.scss @@ -0,0 +1,13 @@ +.rtl { + direction: rtl !important; +} + +.ltr { + direction: ltr !important; +} + +.application-layout-rtl { + .flip-x-rtl { + transform: scaleX(-1); + } +} \ No newline at end of file diff --git a/Styles/layout/_appbar.scss b/Styles/layout/_appbar.scss new file mode 100644 index 0000000..a54dfc5 --- /dev/null +++ b/Styles/layout/_appbar.scss @@ -0,0 +1,166 @@ +@import '../abstracts/variables'; + +.appbar { + width: 100%; + display: flex; + z-index: var(--zindex-appbar); + position: relative; + box-sizing: border-box; + flex-shrink: 0; + flex-direction: column; + color: var(--palette-appbar-text); + background-color: var(--palette-appbar-background); + transition: margin 225ms cubic-bezier(0.0, 0, 0.2, 1) 0ms,width 225ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; + + &.appbar-fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + + .popover-cascading-value { + position: fixed; + } + } + + &.appbar-fixed-bottom { + position: fixed; + bottom: 0; + right: 0; + left: 0; + + .popover-cascading-value { + position: fixed; + } + } + + .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 8); + } + + @media (min-width:$breakpoint-xs) and (orientation: landscape) { + .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 4); + } + } + + @media (min-width:$breakpoint-sm) { + .toolbar-appbar { + height: var(--appbar-height); + } + } + + &.appbar-dense { + .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 4); + } + } +} + +.drawer-open { + &-responsive { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + @media (min-width: map-get($breakpoints, $breakpoint)) { + &-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + + &-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + + &-left.drawer-left-clipped-never#{&}-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } + } + } + } + } + + &-persistent { + &-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + + &-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + + &-left.drawer-left-clipped-never#{&}-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } + } + + &-mini { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + @media (min-width: map-get($breakpoints, $breakpoint)) { + &-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + + &-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + + &-left.drawer-left-clipped-never#{&}-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } + } + } + } + } +} + +.drawer-close-mini { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + &-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + + &-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + + &-left.drawer-left-clipped-never#{&}-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } + + @media (max-width: map-get($breakpoints, $breakpoint)) { + &-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + + &-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + + &-left.drawer-left-clipped-docked#{&}-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } + } + } + } +} diff --git a/Styles/layout/_container.scss b/Styles/layout/_container.scss new file mode 100644 index 0000000..fef0dee --- /dev/null +++ b/Styles/layout/_container.scss @@ -0,0 +1,89 @@ +@import '../abstracts/variables'; + +.container { + width: 100%; + display: block; + box-sizing: border-box; + margin-left: auto; + margin-right: auto; + padding-left: 16px; + padding-right: 16px; +} + +@media (min-width:$breakpoint-sm) { + .container { + padding-left: 24px; + padding-right: 24px; + } +} + +.container-disable-gutters { + padding-left: 0; + padding-right: 0; +} + +@media (min-width:$breakpoint-sm) { + .container-fixed { + max-width: $breakpoint-sm; + } +} + +@media (min-width:$breakpoint-md) { + .container-fixed { + max-width: $breakpoint-md; + } +} + +@media (min-width:$breakpoint-lg) { + .container-fixed { + max-width: $breakpoint-lg; + } +} + +@media (min-width:$breakpoint-xl) { + .container-fixed { + max-width: $breakpoint-xl; + } +} + +@media (min-width:$breakpoint-xxl) { + .container-fixed { + max-width: $breakpoint-xxl; + } +} + +@media (min-width:$breakpoint-xs) { + .container-maxwidth-xs { + max-width: 444px; + } +} + +@media (min-width:$breakpoint-sm) { + .container-maxwidth-sm { + max-width: $breakpoint-sm; + } +} + +@media (min-width:$breakpoint-md) { + .container-maxwidth-md { + max-width: $breakpoint-md; + } +} + +@media (min-width:$breakpoint-lg) { + .container-maxwidth-lg { + max-width: $breakpoint-lg; + } +} + +@media (min-width:$breakpoint-xl) { + .container-maxwidth-xl { + max-width: $breakpoint-xl; + } +} + +@media (min-width:$breakpoint-xxl) { + .container-maxwidth-xxl { + max-width: $breakpoint-xxl; + } +} diff --git a/Styles/layout/_drawer.scss b/Styles/layout/_drawer.scss new file mode 100644 index 0000000..2418add --- /dev/null +++ b/Styles/layout/_drawer.scss @@ -0,0 +1,390 @@ +@import '../abstracts/variables'; + +.drawer { + display: flex; + flex-shrink: 0; + flex-grow: 1; + flex: 0 0 auto; + outline: 0; + position: fixed; + z-index: var(--zindex-drawer); + overflow-y: auto; + flex-direction: column; + color: var(--palette-drawer-text); + background-color: var(--palette-drawer-background); + --drawer-content-height: 0; + + .drawer-content { + height: 100%; + max-height: 100%; + display: flex; + flex-shrink: 0; + flex-grow: 1; + flex: 0 0 auto; + flex-direction: column; + } + + &:not(.drawer-fixed) { + position: absolute; + } + + @each $breakpoint in map-keys($breakpoints) { + &.drawer-mini.drawer-#{$breakpoint}:not(.drawer--closed), &.drawer-responsive.drawer-#{$breakpoint} { + @media (max-width: map-get($breakpoints, $breakpoint) - 1px) { + z-index: calc(var(--zindex-appbar) + 2); + + &.drawer--initial:not(.drawer-mini) { + display: none !important; + } + } + } + } + + &.drawer-responsive, &.drawer-persistent { + height: 100%; + + &.drawer-pos-left { + right: auto; + width: var(--drawer-width, var(--drawer-width-left)); + + &.drawer--open { + left: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-left 225ms cubic-bezier(0, 0, 0.2, 1); + } + } + + &.drawer--closed { + box-shadow: none; + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); + + &:not(.drawer--initial) { + animation: drawer-slide-out-left 225ms cubic-bezier(0, 0, 0.2, 1); + } + } + } + + &.drawer-pos-right { + left: auto; + width: var(--drawer-width, var(--drawer-width-right)); + + &.drawer--open { + right: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-right 225ms cubic-bezier(0, 0, 0.2, 1); + } + } + + &.drawer--closed { + box-shadow: none; + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); + + &:not(.drawer--initial) { + animation: drawer-slide-out-right 225ms cubic-bezier(0, 0, 0.2, 1); + } + } + } + } + + &.drawer-mini { + height: 100%; + transition: width 225ms cubic-bezier(0, 0, 0.2, 1); + + &.drawer-pos-left { + left: 0; + right: auto; + + &.drawer--closed { + width: var(--drawer-width-mini-left); + } + + &.drawer--open { + width: var(--drawer-width-left); + } + } + + &.drawer-pos-right { + left: auto; + right: 0; + + &.drawer--closed { + width: var(--drawer-width-mini-right); + } + + &.drawer--open { + width: var(--drawer-width-right); + } + } + } + + &.drawer-temporary { + margin: 0 !important; + z-index: calc(var(--zindex-appbar) + 2); + transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms; + + &.drawer-pos-left { + right: auto; + top: 0; + height: 100%; + width: var(--drawer-width, var(--drawer-width-left)); + + &.drawer--open { + left: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-left 225ms cubic-bezier(0, 0, 0.2, 1)forwards; + } + } + + &.drawer--closed { + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); + + &:not(.drawer--initial) { + animation: drawer-slide-out-left 225ms cubic-bezier(0, 0, 0.2, 1)forwards; + } + } + } + + &.drawer-pos-right { + left: auto; + top: 0; + height: 100%; + width: var(--drawer-width, var(--drawer-width-right)); + + &.drawer--open { + right: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-right 225ms cubic-bezier(0, 0, 0.2, 1)forwards; + } + } + + &.drawer--closed { + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); + + &:not(.drawer--initial) { + animation: drawer-slide-out-right 225ms cubic-bezier(0, 0, 0.2, 1)forwards; + } + } + } + + &.drawer-pos-bottom { + left: 0; + top: auto; + width: 100%; + + &.drawer--open { + bottom: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-bottom 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; + } + } + + &.drawer--closed { + bottom: calc(-1 * var(--drawer-content-height)); + + &:not(.drawer--initial) { + animation: drawer-slide-out-bottom 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; + } + } + } + + &.drawer-pos-top { + left: 0; + bottom: auto; + width: 100%; + + &.drawer--open { + top: 0; + + &:not(.drawer--initial) { + animation: drawer-slide-in-top 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; + } + } + + &.drawer--closed { + top: calc(-1 * var(--drawer-content-height)); + + &:not(.drawer--initial) { + animation: drawer-slide-out-top 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; + } + } + } + } + + &.drawer-mini.drawer-pos-left ~ div:not(.main-content), + &.drawer-mini.drawer-pos-right ~ div:not(.main-content), + &.drawer-persistent.drawer-pos-left ~ div:not(.main-content), + &.drawer-persistent.drawer-pos-right ~ div:not(.main-content) { + transition: margin 225ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; + } + + &.drawer-mini.drawer-pos-left.drawer--open ~ div:not(.main-content), + &.drawer-persistent.drawer-pos-left.drawer--open ~ div:not(.main-content) { + margin-left: var(--drawer-width, var(--drawer-width-left)); + } + + &.drawer-mini.drawer-pos-right.drawer--open ~ div:not(.main-content), + &.drawer-persistent.drawer-pos-right.drawer--open ~ div:not(.main-content) { + margin-right: var(--drawer-width, var(--drawer-width-right)); + } + + &.drawer-mini.drawer-pos-left.drawer--closed ~ div:not(.main-content) { + margin-left: var(--drawer-width, var(--drawer-width-mini-left)); + } + + &.drawer-mini.drawer-pos-right.drawer--closed ~ div:not(.main-content) { + margin-right: var(--drawer-width, var(--drawer-width-mini-right)); + } +} + +.drawer-header { + display: flex; + min-height: var(--appbar-height); + padding: 12px 24px 12px 24px; + + &.drawer-header-dense { + min-height: calc(var(--appbar-height) - var(--appbar-height) / 4); + padding: 8px 24px 8px 24px; + } +} + +.drawer-fixed { + &.drawer-mini.drawer-clipped-always, + &.drawer-persistent:not(.drawer-clipped-never), + &.drawer-responsive.drawer-clipped-always, + &.drawer-temporary.drawer-clipped-always { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + + @media (max-width:$breakpoint-sm - 1px) and (orientation: landscape) { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - calc(var(--appbar-height) - var(--appbar-height)/4)); + } + + @media (max-width:$breakpoint-sm - 1px) and (orientation: portrait) { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - calc(var(--appbar-height) - var(--appbar-height)/8)); + } + } + + @each $breakpoint in map-keys($breakpoints) { + &.drawer-mini.drawer-clipped-docked.drawer-#{$breakpoint}, + &.drawer-responsive.drawer-clipped-docked.drawer-#{$breakpoint} { + @media (min-width: map-get($breakpoints, $breakpoint)) { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + + @media (max-width:$breakpoint-sm - 1px) and (orientation: landscape) { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } + + @media (max-width:$breakpoint-sm - 1px) and (orientation: portrait) { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } + } + } + } +} + +.appbar-dense ~ .drawer-fixed { + &.drawer-mini:not(.drawer-clipped-never), + &.drawer-persistent:not(.drawer-clipped-never), + &.drawer-responsive.drawer-clipped-always, + &.drawer-temporary.drawer-clipped-always { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } + + @each $breakpoint in map-keys($breakpoints) { + @media (min-width: map-get($breakpoints, $breakpoint)) { + &.drawer-responsive.drawer-clipped-docked.drawer-#{$breakpoint} { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } + } + } +} + +.drawer-overlay { + display: none; + + &.drawer-overlay--open { + @each $breakpoint in map-keys($breakpoints) { + &.drawer-overlay-responsive.drawer-overlay-#{$breakpoint} { + @media (max-width: map-get($breakpoints, $breakpoint) - 1px) { + display: block; + + &.drawer--initial { + display: none; + } + } + } + + &.drawer-overlay-mini.drawer-overlay-#{$breakpoint} { + @media (max-width: map-get($breakpoints, $breakpoint) - 1px) { + display: block; + } + } + } + + &.drawer-overlay-temporary { + display: block; + } + } +} + +/*#region keyframes*/ +@keyframes drawer-slide-in-left { + from { + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); + } +} + +@keyframes drawer-slide-out-left { + from { + left: 0; + } +} + +@keyframes drawer-slide-in-right { + from { + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); + } +} + +@keyframes drawer-slide-out-right { + from { + right: 0; + } +} + +@keyframes drawer-slide-in-bottom { + from { + bottom: calc(-1 * var(--drawer-content-height)); + } +} + +@keyframes drawer-slide-out-bottom { + from { + bottom: 0; + } +} + +@keyframes drawer-slide-in-top { + from { + top: calc(-1 * var(--drawer-content-height)); + } +} + +@keyframes drawer-slide-out-top { + from { + top: 0; + } +} +/*#endregion*/ \ No newline at end of file diff --git a/Styles/layout/_main.scss b/Styles/layout/_main.scss new file mode 100644 index 0000000..a713520 --- /dev/null +++ b/Styles/layout/_main.scss @@ -0,0 +1,136 @@ +@import '../abstracts/variables'; + +.main-content { + margin: 0; + flex: 1 1 auto; + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 8); + transition: margin 225ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; +} + +@media (min-width:$breakpoint-xs) and (orientation: landscape) { + .main-content { + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 4); + } +} + +@media (min-width:$breakpoint-sm) { + .main-content { + padding-top: var(--appbar-height); + } +} + +.appbar-dense { + ~ .main-content { + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 4); + } +} + +.drawer-open { + &-responsive { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + @media (min-width: map-get($breakpoints, $breakpoint)) { + &-left .main-content { + margin-left: var(--drawer-width-left); + } + + &-right .main-content { + margin-right: var(--drawer-width-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } + } + } + } + } + + &-persistent { + &-left:not(&-right) .main-content { + margin-left: var(--drawer-width-left); + } + + &-right:not(&-left) .main-content { + margin-right: var(--drawer-width-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } + } + + &-mini { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + @media (min-width: map-get($breakpoints, $breakpoint)) { + &-left .main-content { + margin-left: var(--drawer-width-left); + } + + &-right .main-content { + margin-right: var(--drawer-width-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } + } + } + } + + &-none, &-always { + &-left .main-content { + margin-left: var(--drawer-width-left); + } + + &-right .main-content { + margin-right: var(--drawer-width-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } + } + } +} + +.drawer-close { + &-mini { + @each $breakpoint in map-keys($breakpoints) { + &-#{$breakpoint} { + &-left .main-content { + margin-left: var(--drawer-width-mini-left); + } + + &-right .main-content { + margin-right: var(--drawer-width-mini-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); + } + } + } + + &-none, &-always { + &-left .main-content { + margin-left: var(--drawer-width-mini-left); + } + + &-right .main-content { + margin-right: var(--drawer-width-mini-right); + } + + &-left#{&}-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); + } + } + } +} diff --git a/Styles/layout/_scroll.scss b/Styles/layout/_scroll.scss new file mode 100644 index 0000000..84e24f0 --- /dev/null +++ b/Styles/layout/_scroll.scss @@ -0,0 +1,69 @@ +.scroll-locked{ + padding-right: 8px; + overflow: hidden; + + .layout { + .appbar { + padding-right: 8px; + } + + .main-content { + .scroll-to-top { + padding-right: 8px; + } + } + } +} + +@-moz-document url-prefix() { + .scroll-locked { + padding-right: 17px; //the width of scroll-bar in firefox + + .layout { + .appbar { + padding-right: 17px; + } + + .main-content { + .scroll-to-top { + padding-right: 17px; + } + } + } + } +} + +.scroll-to-top { + position: fixed; + cursor: pointer; + z-index: 100; + + &.visible { + bottom: 16px; + right: 16px; + opacity: 1; + transition: transform 0.5s; + flex: 1; + } + + &.hidden { + bottom: 16px; + right: 16px; + opacity: 0; + transition: all 0.5s; + visibility: hidden; + transform: scale(0) rotate(180deg); + flex: 0; + } + + &:after { + content: ''; + background: transparent; + top: 0; + bottom: 0; + left: 0; + right: 0; + position: absolute; + z-index: var(--zindex-tooltip); + } +} diff --git a/Styles/utilities/_index.scss b/Styles/utilities/_index.scss new file mode 100644 index 0000000..1c8a337 --- /dev/null +++ b/Styles/utilities/_index.scss @@ -0,0 +1,21 @@ +@import 'borders/border-radius'; +@import 'borders/border-style'; +@import 'borders/border-width'; +@import 'borders/outline'; + +@import 'flexbox'; + +@import 'interactivity/cursor'; +@import 'interactivity/pointerevents'; + +@import 'layout/display'; +@import 'layout/object-fit'; +@import 'layout/object-position'; +@import 'layout/overflow'; +@import 'layout/position'; +@import 'layout/visibility'; +@import 'layout/zindex'; + +@import 'spacing/spacing'; + +@import 'obsolete'; diff --git a/Styles/utilities/_obsolete.scss b/Styles/utilities/_obsolete.scss new file mode 100644 index 0000000..61f8ac7 --- /dev/null +++ b/Styles/utilities/_obsolete.scss @@ -0,0 +1,11 @@ +.width-full{ + width:100%; +} + +.height-full { + height: 100%; +} + +.w-max { + width: max-content; +} \ No newline at end of file diff --git a/Styles/utilities/borders/_border-radius.scss b/Styles/utilities/borders/_border-radius.scss new file mode 100644 index 0000000..7e2dfd8 --- /dev/null +++ b/Styles/utilities/borders/_border-radius.scss @@ -0,0 +1,168 @@ +$border-radiuses: ( "0": 0, "sm": 2px, "lg": 8px, "xl": 24px); + +@each $size, $value in $border-radiuses { + .rounded-#{$size} { + border-radius: $value !important; + } + + .rounded-t-#{$size} { + border-top-left-radius: $value !important; + border-top-right-radius: $value !important; + } + + .rounded-r-#{$size}, .rounded-e-#{$size} { + border-top-right-radius: $value !important; + border-bottom-right-radius: $value !important; + } + + .rounded-b-#{$size} { + border-bottom-right-radius: $value !important; + border-bottom-left-radius: $value !important; + } + + .rounded-l-#{$size}, .rounded-s-#{$size} { + border-top-left-radius: $value !important; + border-bottom-left-radius: $value !important; + } + + .rounded-tl-#{$size}, .rounded-ts-#{$size} { + border-top-left-radius: $value !important; + } + + .rounded-tr-#{$size}, .rounded-te-#{$size} { + border-top-right-radius: $value !important; + } + + .rounded-br-#{$size}, .rounded-be-#{$size} { + border-bottom-right-radius: $value !important; + } + + .rounded-bl-#{$size}, .rounded-bs-#{$size} { + border-bottom-left-radius: $value !important; + } + + //--------------------------- rtl styles --------------------------- + .application-layout-rtl { + .rounded-s-#{$size} { + border-top-right-radius: $value !important; + border-bottom-right-radius: $value !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + } + + .rounded-e-#{$size} { + border-top-left-radius: $value !important; + border-bottom-left-radius: $value !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + } + + .rounded-ts-#{$size} { + border-top-right-radius: $value !important; + border-top-left-radius: 0 !important; + } + + .rounded-te-#{$size} { + border-top-left-radius: $value !important; + border-top-right-radius: 0 !important; + } + + .rounded-bs-#{$size} { + border-bottom-right-radius: $value !important; + border-bottom-left-radius: 0 !important; + } + + .rounded-be-#{$size} { + border-bottom-left-radius: $value !important; + border-bottom-right-radius: 0 !important; + } + } + //------------------------------------------------------------------ +} + +.rounded { + border-radius: var(--default-borderradius) !important; +} + +.rounded-t { + border-top-left-radius: var(--default-borderradius) !important; + border-top-right-radius: var(--default-borderradius) !important; +} + +.rounded-r, .rounded-e { + border-top-right-radius: var(--default-borderradius) !important; + border-bottom-right-radius: var(--default-borderradius) !important; +} + +.rounded-b { + border-bottom-right-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; +} + +.rounded-l, .rounded-s { + border-top-left-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; +} + +.rounded-tl, .rounded-ts { + border-top-left-radius: var(--default-borderradius) !important; +} + +.rounded-tr, .rounded-te { + border-top-right-radius: var(--default-borderradius) !important; +} + +.rounded-br, .rounded-be { + border-bottom-right-radius: var(--default-borderradius) !important; +} + +.rounded-bl, .rounded-bs { + border-bottom-left-radius: var(--default-borderradius) !important; +} + +//--------------------------- rtl styles --------------------------- +.application-layout-rtl { + .rounded-s { + border-top-right-radius: var(--default-borderradius) !important; + border-bottom-right-radius: var(--default-borderradius) !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + } + + .rounded-e { + border-top-left-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + } + + .rounded-ts { + border-top-right-radius: var(--default-borderradius) !important; + border-top-left-radius: 0 !important; + } + + .rounded-te { + border-top-left-radius: var(--default-borderradius) !important; + border-top-right-radius: 0 !important; + } + + .rounded-bs { + border-bottom-right-radius: var(--default-borderradius) !important; + border-bottom-left-radius: 0 !important; + } + + .rounded-be { + border-bottom-left-radius: var(--default-borderradius) !important; + border-bottom-right-radius: 0 !important; + } +} +//------------------------------------------------------------------ + + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 9999px !important; +} \ No newline at end of file diff --git a/Styles/utilities/borders/_border-style.scss b/Styles/utilities/borders/_border-style.scss new file mode 100644 index 0000000..18c23f2 --- /dev/null +++ b/Styles/utilities/borders/_border-style.scss @@ -0,0 +1,7 @@ +$border-styles: ( solid, dashed, dotted, double, hidden, none ); + +@each $value in $border-styles { + .border-#{$value} { + border-style: $value !important; + } +} \ No newline at end of file diff --git a/Styles/utilities/borders/_border-width.scss b/Styles/utilities/borders/_border-width.scss new file mode 100644 index 0000000..58798c3 --- /dev/null +++ b/Styles/utilities/borders/_border-width.scss @@ -0,0 +1,22 @@ +$border-widths: ( "-0": 0px,"": 1px, "-2": 2px, "-4": 4px, "-8": 8px ); +$border-width-directions: ("t": top, "r": right, "b": bottom, "l": left); + +@each $name, $value in $border-widths { + .border#{$name} { + border-width: $value !important; + } + @each $direction, $suffix in $border-width-directions { + .border-#{$direction}#{$name} { + border-#{$suffix}-width: $value !important; + } + } + .border-x#{$name} { + border-left-width: $value !important; + border-right-width: $value !important; + } + .border-y#{$name} { + border-top-width: $value !important; + border-bottom-width: $value !important; + } +} + diff --git a/Styles/utilities/borders/_outline.scss b/Styles/utilities/borders/_outline.scss new file mode 100644 index 0000000..28f52ce --- /dev/null +++ b/Styles/utilities/borders/_outline.scss @@ -0,0 +1,34 @@ +/* Outline Style */ + +.outline-none{ + outline-style: none; +} + +.outline-solid{ + outline-style: solid; +} + +.outline-dashed{ + outline-style: dashed; +} + +.outline-dotted{ + outline-style: dotted; +} + +.outline-double{ + outline-style: double; +} + +.outline-hidden{ + outline-style: hidden; +} + +/* Outline Color */ +/* To Doo */ + +/* Outline Offset */ +/* To Doo */ + +/* Outline Width */ +/* To Doo */ diff --git a/Styles/utilities/flexbox/_align-content.scss b/Styles/utilities/flexbox/_align-content.scss new file mode 100644 index 0000000..5a15026 --- /dev/null +++ b/Styles/utilities/flexbox/_align-content.scss @@ -0,0 +1,29 @@ +@import '../../abstracts/variables'; + +@mixin align-content ($breakpoint) { + .align-content-#{$breakpoint}start { + align-content: flex-start !important; + } + + .align-content-#{$breakpoint}end { + align-content: flex-end !important; + } + + .align-content-#{$breakpoint}center { + align-content: center !important; + } + + .align-content-#{$breakpoint}space-between { + align-content: space-between !important; + } + + .align-content-#{$breakpoint}space-around { + align-content: space-around !important; + } + + .align-content-#{$breakpoint}stretch { + align-content: stretch !important; + } +} + +@include align-content(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_align-items.scss b/Styles/utilities/flexbox/_align-items.scss new file mode 100644 index 0000000..9737794 --- /dev/null +++ b/Styles/utilities/flexbox/_align-items.scss @@ -0,0 +1,25 @@ +@import '../../abstracts/variables'; + +@mixin align-items ($breakpoint) { + .align-#{$breakpoint}start { + align-items: flex-start !important; + } + + .align-#{$breakpoint}end { + align-items: flex-end !important; + } + + .align-#{$breakpoint}center { + align-items: center !important; + } + + .align-#{$breakpoint}baseline { + align-items: baseline !important; + } + + .align-#{$breakpoint}stretch { + align-items: stretch !important; + } +} + +@include align-items(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_align-self.scss b/Styles/utilities/flexbox/_align-self.scss new file mode 100644 index 0000000..462dc67 --- /dev/null +++ b/Styles/utilities/flexbox/_align-self.scss @@ -0,0 +1,25 @@ +@import '../../abstracts/variables'; + +@mixin align-self ($breakpoint) { + .align-self-#{$breakpoint}auto { + align-self: auto !important; + } + + .align-self-#{$breakpoint}start { + align-self: flex-start !important; + } + + .align-self-#{$breakpoint}end { + align-self: flex-end !important; + } + + .align-self-#{$breakpoint}center { + align-self: center !important; + } + + .align-self-#{$breakpoint}stretch { + align-self: stretch !important; + } +} + +@include align-self(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_flex-direction.scss b/Styles/utilities/flexbox/_flex-direction.scss new file mode 100644 index 0000000..ad63c08 --- /dev/null +++ b/Styles/utilities/flexbox/_flex-direction.scss @@ -0,0 +1,21 @@ +@import '../../abstracts/variables'; + +@mixin flex-direction ($breakpoint) { + .flex-#{$breakpoint}row { + flex-direction: row !important; + } + + .flex-#{$breakpoint}row-reverse { + flex-direction: row-reverse !important; + } + + .flex-#{$breakpoint}column { + flex-direction: column !important; + } + + .flex-#{$breakpoint}column-reverse { + flex-direction: column-reverse !important; + } +} + +@include flex-direction(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_flex-grow.scss b/Styles/utilities/flexbox/_flex-grow.scss new file mode 100644 index 0000000..7f2223b --- /dev/null +++ b/Styles/utilities/flexbox/_flex-grow.scss @@ -0,0 +1,13 @@ +@import '../../abstracts/variables'; + +@mixin flex-grow ($breakpoint) { + .flex-#{$breakpoint}grow-0 { + flex-grow: 0 !important; + } + + .flex-#{$breakpoint}grow-1 { + flex-grow: 1 !important; + } +} + +@include flex-grow(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_flex-shrink.scss b/Styles/utilities/flexbox/_flex-shrink.scss new file mode 100644 index 0000000..491b62a --- /dev/null +++ b/Styles/utilities/flexbox/_flex-shrink.scss @@ -0,0 +1,13 @@ +@import '../../abstracts/variables'; + +@mixin flex-shrink ($breakpoint) { + .flex-#{$breakpoint}shrink-0 { + flex-shrink: 0 !important; + } + + .flex-#{$breakpoint}shrink-1 { + flex-shrink: 1 !important; + } +} + +@include flex-shrink(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_flex-wrap.scss b/Styles/utilities/flexbox/_flex-wrap.scss new file mode 100644 index 0000000..c4a682b --- /dev/null +++ b/Styles/utilities/flexbox/_flex-wrap.scss @@ -0,0 +1,17 @@ +@import '../../abstracts/variables'; + +@mixin flex-wrap ($breakpoint) { + .flex-#{$breakpoint}wrap { + flex-wrap: wrap !important; + } + + .flex-#{$breakpoint}nowrap { + flex-wrap: nowrap !important; + } + + .flex-#{$breakpoint}wrap-reverse { + flex-wrap: wrap-reverse !important; + } +} + +@include flex-wrap(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_flex.scss b/Styles/utilities/flexbox/_flex.scss new file mode 100644 index 0000000..59ac171 --- /dev/null +++ b/Styles/utilities/flexbox/_flex.scss @@ -0,0 +1,18 @@ +@import '../../abstracts/variables'; + +@mixin flex($breakpoint) { + .flex-#{$breakpoint}1 { + flex: 1 1 0% !important; + } + .flex-#{$breakpoint}auto { + flex: 1 1 auto !important; + } + .flex-#{$breakpoint}initial { + flex: 0 1 auto !important; + } + .flex-#{$breakpoint}none { + flex: none !important; + } +} + +@include flex(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_gap.scss b/Styles/utilities/flexbox/_gap.scss new file mode 100644 index 0000000..569b344 --- /dev/null +++ b/Styles/utilities/flexbox/_gap.scss @@ -0,0 +1,23 @@ +@import '../../abstracts/variables'; + +$count: 0; +$value: 0; + +@mixin gap($breakpoint) { + + @while $count < 17 { + .gap-#{$breakpoint}#{$count} { + gap: #{$value}px; + } + .gap-x-#{$breakpoint}#{$count} { + column-gap: #{$value}px; + } + .gap-y-#{$breakpoint}#{$count} { + row-gap: #{$value}px; + } + $count: $count + 1; + $value: $value + 4; + } +} + +@include gap(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_index.scss b/Styles/utilities/flexbox/_index.scss new file mode 100644 index 0000000..3769482 --- /dev/null +++ b/Styles/utilities/flexbox/_index.scss @@ -0,0 +1,29 @@ +@import '../../abstracts/variables'; +@import 'flex'; +@import 'flex-direction'; +@import 'flex-grow'; +@import 'flex-shrink'; +@import 'flex-wrap'; +@import 'justify-content'; +@import 'order'; +@import 'align-content'; +@import 'align-items'; +@import 'align-self'; +@import 'gap'; + + +@each $name, $value in $breakpoints-css-utilities-only { + @media (min-width:$value) { + @include flex($name + "-"); + @include flex-direction($name + "-"); + @include flex-grow($name + "-"); + @include flex-shrink($name + "-"); + @include flex-wrap($name + "-"); + @include justify-content($name + "-"); + @include order($name + "-"); + @include align-content($name + "-"); + @include align-items($name + "-"); + @include align-self($name + "-"); + @include gap($name + "-"); + } +} \ No newline at end of file diff --git a/Styles/utilities/flexbox/_justify-content.scss b/Styles/utilities/flexbox/_justify-content.scss new file mode 100644 index 0000000..511bfac --- /dev/null +++ b/Styles/utilities/flexbox/_justify-content.scss @@ -0,0 +1,29 @@ +@import '../../abstracts/variables'; + +@mixin justify-content ($breakpoint) { + .justify-#{$breakpoint}start { + justify-content: flex-start !important; + } + + .justify-#{$breakpoint}end { + justify-content: flex-end !important; + } + + .justify-#{$breakpoint}center { + justify-content: center !important; + } + + .justify-#{$breakpoint}space-between { + justify-content: space-between !important; + } + + .justify-#{$breakpoint}space-around { + justify-content: space-around !important; + } + + .justify-#{$breakpoint}space-evenly { + justify-content: space-evenly !important; + } +} + +@include justify-content(""); \ No newline at end of file diff --git a/Styles/utilities/flexbox/_order.scss b/Styles/utilities/flexbox/_order.scss new file mode 100644 index 0000000..61b9c1a --- /dev/null +++ b/Styles/utilities/flexbox/_order.scss @@ -0,0 +1,21 @@ +@import '../../abstracts/variables'; + +$count: 0; + +@mixin order ($breakpoint) { + .order-#{$breakpoint}first { + order: -9999 !important; + } + .order-#{$breakpoint}last { + order: 9999 !important; + } + @while $count < 13 { + .order-#{$breakpoint}#{$count} { + order: $count !important; + } + $count: $count + 1; + } +} + + +@include order(""); \ No newline at end of file diff --git a/Styles/utilities/interactivity/_cursor.scss b/Styles/utilities/interactivity/_cursor.scss new file mode 100644 index 0000000..ade60af --- /dev/null +++ b/Styles/utilities/interactivity/_cursor.scss @@ -0,0 +1,13 @@ +$cursors: ( + auto, default, pointer, wait, text, move, help, + not-allowed, none, progress, cell, crosshair, + vertical-text, alias, copy, no-drop, grab, grabbing, + all-scroll, col-resize, row-resize, n-resize, w-resize, + zoom-in, zoom-out, url +); + +@each $value in $cursors { + .cursor-#{$value} { + cursor: $value !important; + } +} \ No newline at end of file diff --git a/Styles/utilities/interactivity/_pointerevents.scss b/Styles/utilities/interactivity/_pointerevents.scss new file mode 100644 index 0000000..c4448f7 --- /dev/null +++ b/Styles/utilities/interactivity/_pointerevents.scss @@ -0,0 +1,6 @@ +.pointer-events-none{ + pointer-events: none; +} +.pointer-events-auto{ + pointer-events: auto; +} \ No newline at end of file diff --git a/Styles/utilities/layout/_display.scss b/Styles/utilities/layout/_display.scss new file mode 100644 index 0000000..c1b6910 --- /dev/null +++ b/Styles/utilities/layout/_display.scss @@ -0,0 +1,65 @@ +@import '../../abstracts/variables'; + +@mixin display-mixin ($breakpoint) { + .d-#{$breakpoint}none { + display: none !important; + } + + .d-#{$breakpoint}inline { + display: inline !important; + } + + .d-#{$breakpoint}inline-block { + display: inline-block !important; + } + + .d-#{$breakpoint}block { + display: block !important; + } + + .d-#{$breakpoint}table { + display: table !important; + } + + .d-#{$breakpoint}table-row { + display: table-row !important; + } + + .d-#{$breakpoint}table-cell { + display: table-cell !important; + } + + .d-#{$breakpoint}flex { + display: flex !important; + } + + .d-#{$breakpoint}inline-flex { + display: inline-flex !important; + } +} + + + + +// XS > +@include display-mixin(""); + +@media (min-width:$breakpoint-sm) { + @include display-mixin("sm-"); +} + +@media (min-width:$breakpoint-md) { + @include display-mixin("md-"); +} + +@media (min-width:$breakpoint-lg) { + @include display-mixin("lg-"); +} + +@media (min-width:$breakpoint-xl) { + @include display-mixin("xl-"); +} + +@media (min-width:$breakpoint-xxl) { + @include display-mixin("xxl-"); +} diff --git a/Styles/utilities/layout/_object-fit.scss b/Styles/utilities/layout/_object-fit.scss new file mode 100644 index 0000000..0407df0 --- /dev/null +++ b/Styles/utilities/layout/_object-fit.scss @@ -0,0 +1,15 @@ +.object-none { + object-fit: none; +} +.object-cover { + object-fit: cover; +} +.object-contain { + object-fit: contain; +} +.object-fill { + object-fit: fill; +} +.object-scale-down { + object-fit: scale-down; +} \ No newline at end of file diff --git a/Styles/utilities/layout/_object-position.scss b/Styles/utilities/layout/_object-position.scss new file mode 100644 index 0000000..49bdf23 --- /dev/null +++ b/Styles/utilities/layout/_object-position.scss @@ -0,0 +1,27 @@ +.object-center { + object-position: center; +} +.object-top { + object-position: top; +} +.object-bottom { + object-position: bottom; +} +.object-left { + object-position: left; +} +.object-left-top { + object-position: left top; +} +.object-left-bottom { + object-position: left bottom; +} +.object-right { + object-position: right; +} +.object-right-top { + object-position: right top; +} +.object-right-bottom { + object-position: right bottom; +} \ No newline at end of file diff --git a/Styles/utilities/layout/_overflow.scss b/Styles/utilities/layout/_overflow.scss new file mode 100644 index 0000000..8561246 --- /dev/null +++ b/Styles/utilities/layout/_overflow.scss @@ -0,0 +1,47 @@ +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-visible { + overflow: visible; +} + +.overflow-scroll { + overflow: scroll; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-x-hidden { + overflow-x: hidden; +} + +.overflow-y-hidden { + overflow-y: hidden; +} + +.overflow-x-visible { + overflow-x: visible; +} + +.overflow-y-visible { + overflow-y: visible; +} + +.overflow-x-scroll { + overflow-x: scroll; +} + +.overflow-y-scroll { + overflow-y: scroll; +} diff --git a/Styles/utilities/layout/_position.scss b/Styles/utilities/layout/_position.scss new file mode 100644 index 0000000..67c38a2 --- /dev/null +++ b/Styles/utilities/layout/_position.scss @@ -0,0 +1,19 @@ +.absolute { + position: absolute; +} + +.fixed { + position: fixed; +} + +.relative { + position: relative; +} + +.static { + position: static; +} + +.sticky { + position: sticky; +} \ No newline at end of file diff --git a/Styles/utilities/layout/_visibility.scss b/Styles/utilities/layout/_visibility.scss new file mode 100644 index 0000000..b6f8e26 --- /dev/null +++ b/Styles/utilities/layout/_visibility.scss @@ -0,0 +1,6 @@ +.visible { + visibility: visible; +} +.invisible { + visibility: hidden; +} \ No newline at end of file diff --git a/Styles/utilities/layout/_zindex.scss b/Styles/utilities/layout/_zindex.scss new file mode 100644 index 0000000..bc5074c --- /dev/null +++ b/Styles/utilities/layout/_zindex.scss @@ -0,0 +1,14 @@ +$count: 1; +$value: 0; + +@while $count < 12 { + .z-#{$value} { + z-index: $value; + } + $count: $count + 1; + $value: $value + 10; +} + +.z-auto{ + z-index:auto; +} \ No newline at end of file diff --git a/Styles/utilities/spacing/_spacing.scss b/Styles/utilities/spacing/_spacing.scss new file mode 100644 index 0000000..ae044fd --- /dev/null +++ b/Styles/utilities/spacing/_spacing.scss @@ -0,0 +1,101 @@ +@import '../../abstracts/variables'; + +$spacing-values: ( "0": 0, "1": 4px, "2": 8px, "3": 12px, "4": 16px, "5": 20px, "6": 24px, "7": 28px, "8": 32px, "9": 36px, "10": 40px, "11": 44px, "12": 48px, "13": 52px, "14": 56px, "15": 60px, "16": 64px, "auto": auto ); +$spacing-negative-values: ( "n1": -4px, "n2": -8px, "n3": -12px, "n4": -16px, "n5": -20px, "n6": -24px, "n7": -28px, "n8": -32px, "n9": -36px, "n10": -40px, "n11": -44px, "n12": -48px, "n13": -52px, "n14": -56px, "n15": -60px, "n16": -64px ); + +@mixin spacing-positive-negative ($breakpoint) { + @each $prop, $abbrev in (margin: m, padding: p) { + @each $name, $value in $spacing-values { + .#{$abbrev}t-#{$breakpoint}#{$name}, + .#{$abbrev}y-#{$breakpoint}#{$name} { + #{$prop}-top: $value !important; + } + + .#{$abbrev}r-#{$breakpoint}#{$name}, + .#{$abbrev}x-#{$breakpoint}#{$name} { + #{$prop}-right: $value !important; + } + + .#{$abbrev}l-#{$breakpoint}#{$name}, + .#{$abbrev}x-#{$breakpoint}#{$name} { + #{$prop}-left: $value !important; + } + + .#{$abbrev}b-#{$breakpoint}#{$name}, + .#{$abbrev}y-#{$breakpoint}#{$name} { + #{$prop}-bottom: $value !important; + } + + .#{$abbrev}s-#{$breakpoint}#{$name} { + #{$prop}-inline-start: $value !important; + } + + .#{$abbrev}e-#{$breakpoint}#{$name} { + #{$prop}-inline-end: $value !important; + } + + .#{$abbrev}a-#{$breakpoint}#{$name} { + #{$prop}: $value !important; + } + } + } + + @each $prop, $abbrev in (margin: m) { + @each $name, $value in $spacing-negative-values { + .#{$abbrev}t-#{$breakpoint}#{$name}, + .#{$abbrev}y-#{$breakpoint}#{$name} { + #{$prop}-top: $value !important; + } + + .#{$abbrev}r-#{$breakpoint}#{$name}, + .#{$abbrev}x-#{$breakpoint}#{$name} { + #{$prop}-right: $value !important; + } + + .#{$abbrev}l-#{$breakpoint}#{$name}, + .#{$abbrev}x-#{$breakpoint}#{$name} { + #{$prop}-left: $value !important; + } + + .#{$abbrev}b-#{$breakpoint}#{$name}, + .#{$abbrev}y-#{$breakpoint}#{$name} { + #{$prop}-bottom: $value !important; + } + + .#{$abbrev}s-#{$breakpoint}#{$name} { + #{$prop}-inline-start: $value !important; + } + + .#{$abbrev}e-#{$breakpoint}#{$name} { + #{$prop}-inline-end: $value !important; + } + + .#{$abbrev}a-#{$breakpoint}#{$name} { + #{$prop}: $value !important; + } + } + } +} + +// XS > +@include spacing-positive-negative(""); + +@media screen and (min-width:$breakpoint-sm) { + @include spacing-positive-negative("sm-"); +} + +@media screen and (min-width:$breakpoint-md) { + @include spacing-positive-negative("md-"); +} + +@media screen and (min-width:$breakpoint-lg) { + @include spacing-positive-negative("lg-"); +} + +@media screen and (min-width:$breakpoint-xl) { + @include spacing-positive-negative("xl-"); +} + +@media screen and (min-width:$breakpoint-xxl) { + @include spacing-positive-negative("xxl-"); +} \ No newline at end of file diff --git a/TScripts/mudAAAlicense.js b/TScripts/mudAAAlicense.js new file mode 100644 index 0000000..cea4e9a --- /dev/null +++ b/TScripts/mudAAAlicense.js @@ -0,0 +1,5 @@ +/*! + * MudBlazor (https://mudblazor.com/) + * Copyright (c) 2021 MudBlazor + * Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE) + */ \ No newline at end of file diff --git a/TScripts/mudDragAndDrop.js b/TScripts/mudDragAndDrop.js new file mode 100644 index 0000000..abef412 --- /dev/null +++ b/TScripts/mudDragAndDrop.js @@ -0,0 +1,12 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +window.mudDragAndDrop = { + + initDropZone: (id) => { + const elem = document.getElementById('mud-drop-zone-' + id); + elem.addEventListener('dragover',() => event.preventDefault()); + elem.addEventListener('dragstart', () => event.dataTransfer.setData('', event.target.id)); + } +}; \ No newline at end of file diff --git a/TScripts/mudElementReference.js b/TScripts/mudElementReference.js new file mode 100644 index 0000000..1695bbd --- /dev/null +++ b/TScripts/mudElementReference.js @@ -0,0 +1,146 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudElementReference { + constructor() { + this.listenerId = 0; + this.eventListeners = {}; + } + + focus (element) { + if (element) + { + element.focus(); + } + } + + blur(element) { + if (element) { + element.blur(); + } + } + + focusFirst (element, skip = 0, min = 0) { + if (element) + { + let tabbables = getTabbableElements(element); + if (tabbables.length <= min) + element.focus(); + else + tabbables[skip].focus(); + } + } + + focusLast (element, skip = 0, min = 0) { + if (element) + { + let tabbables = getTabbableElements(element); + if (tabbables.length <= min) + element.focus(); + else + tabbables[tabbables.length - skip - 1].focus(); + } + } + + saveFocus (element) { + if (element) + { + element['mudblazor_savedFocus'] = document.activeElement; + } + } + + restoreFocus (element) { + if (element) + { + let previous = element['mudblazor_savedFocus']; + delete element['mudblazor_savedFocus'] + if (previous) + previous.focus(); + } + } + + selectRange(element, pos1, pos2) { + if (element) + { + if (element.createTextRange) { + let selRange = element.createTextRange(); + selRange.collapse(true); + selRange.moveStart('character', pos1); + selRange.moveEnd('character', pos2); + selRange.select(); + } else if (element.setSelectionRange) { + element.setSelectionRange(pos1, pos2); + } else if (element.selectionStart) { + element.selectionStart = pos1; + element.selectionEnd = pos2; + } + element.focus(); + } + } + + select(element) { + if (element) + { + element.select(); + } + } + + getBoundingClientRect(element) { + if (!element) return; + + var rect = JSON.parse(JSON.stringify(element.getBoundingClientRect())); + + rect.scrollY = window.scrollY || document.documentElement.scrollTop; + rect.scrollX = window.scrollX || document.documentElement.scrollLeft; + + rect.windowHeight = window.innerHeight; + rect.windowWidth = window.innerWidth; + return rect; + } + + changeCss (element, css) { + if (element) + { + element.className = css; + } + } + + removeEventListener (element, event, eventId) { + element.removeEventListener(event, this.eventListeners[eventId]); + delete this.eventListeners[eventId]; + } + + addDefaultPreventingHandler(element, eventName) { + let listener = function(e) { + e.preventDefault(); + } + element.addEventListener(eventName, listener, { passive: false }); + this.eventListeners[++this.listenerId] = listener; + return this.listenerId; + } + + removeDefaultPreventingHandler(element, eventName, listenerId) { + this.removeEventListener(element, eventName, listenerId); + } + + addDefaultPreventingHandlers(element, eventNames) { + let listeners = []; + + for (const eventName of eventNames) { + let listenerId = this.addDefaultPreventingHandler(element, eventName); + listeners.push(listenerId); + } + + return listeners; + } + + removeDefaultPreventingHandlers(element, eventNames, listenerIds) { + for (let index = 0; index < eventNames.length; ++index) { + const eventName = eventNames[index]; + const listenerId = listenerIds[index]; + this.removeDefaultPreventingHandler(element, eventName, listenerId); + } + } +}; +window.mudElementRef = new MudElementReference(); diff --git a/TScripts/mudEventManager.js b/TScripts/mudEventManager.js new file mode 100644 index 0000000..5e3ebb8 --- /dev/null +++ b/TScripts/mudEventManager.js @@ -0,0 +1,140 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//Functions related to MudThrottledEventManager +class MudThrottledEventManager { + constructor() { + this.mapper = {}; + } + + subscribe(eventName, elementId, projection, throotleInterval, key, properties, dotnetReference) { + const handlerRef = this.throttleEventHandler.bind(this, key); + + let elem = document.getElementById(elementId); + if (elem) { + elem.addEventListener(eventName, handlerRef, false); + + let projector = null; + if (projection) { + const parts = projection.split('.'); + let functionPointer = window; + let functionReferenceFound = true; + if (parts.length == 0 || parts.length == 1) { + functionPointer = functionPointer[projection]; + } + else { + for (let i = 0; i < parts.length; i++) { + functionPointer = functionPointer[parts[i]]; + if (!functionPointer) { + functionReferenceFound = false; + break; + } + } + } + + if (functionReferenceFound === true) { + projector = functionPointer; + } + } + + this.mapper[key] = { + eventName: eventName, + handler: handlerRef, + delay: throotleInterval, + timerId: -1, + reference: dotnetReference, + elementId: elementId, + properties: properties, + projection: projector, + }; + } + } + + subscribeGlobal(eventName, throotleInterval, key, properties, dotnetReference) { + let handlerRef = throotleInterval > 0 ? + this.throttleEventHandler.bind(this, key) : + this.eventHandler.bind(this, key); + + document.addEventListener(eventName, handlerRef, false); + + this.mapper[key] = { + eventName: eventName, + handler: handlerRef, + delay: throotleInterval, + timerId: -1, + reference: dotnetReference, + elementId: document, + properties: properties, + projection: null, + }; + } + + throttleEventHandler(key, event) { + const entry = this.mapper[key]; + if (!entry) { + return; + } + + clearTimeout(entry.timerId); + entry.timerId = window.setTimeout( + this.eventHandler.bind(this, key, event), + entry.delay + ); + } + + eventHandler(key, event) { + const entry = this.mapper[key]; + if (!entry) { + return; + } + + var elem = document.getElementById(entry.elementId); + if (elem != event.srcElement && entry.elementId != document) { + return; + } + + const eventEntry = {}; + for (var i = 0; i < entry.properties.length; i++) { + eventEntry[entry.properties[i]] = event[entry.properties[i]]; + } + + if (entry.projection) { + if (typeof entry.projection === "function") { + entry.projection.apply(null, [eventEntry, event]); + } + } + + entry.reference.invokeMethodAsync('OnEventOccur', key, JSON.stringify(eventEntry)); + } + + unsubscribe(key) { + const entry = this.mapper[key]; + if (!entry) { + return; + } + + entry.reference = null; + + if (document == entry.elementId) { + document.removeEventListener(entry.eventName, entry.handler, false); + } else { + const elem = document.getElementById(entry.elementId); + if (elem) { + elem.removeEventListener(entry.eventName, entry.handler, false); + } + } + + delete this.mapper[key]; + } +}; + +window.mudThrottledEventManager = new MudThrottledEventManager(); + +window.mudEventProjections = { + correctOffset: function (eventEntry, event) { + var target = event.target.getBoundingClientRect(); + eventEntry.offsetX = event.clientX - target.x; + eventEntry.offsetY = event.clientY - target.y; + } +}; \ No newline at end of file diff --git a/TScripts/mudHelpers.js b/TScripts/mudHelpers.js new file mode 100644 index 0000000..7bebfcd --- /dev/null +++ b/TScripts/mudHelpers.js @@ -0,0 +1,87 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +window.getTabbableElements = (element) => { + return element.querySelectorAll( + "a[href]:not([tabindex='-1'])," + + "area[href]:not([tabindex='-1'])," + + "button:not([disabled]):not([tabindex='-1'])," + + "input:not([disabled]):not([tabindex='-1']):not([type='hidden'])," + + "select:not([disabled]):not([tabindex='-1'])," + + "textarea:not([disabled]):not([tabindex='-1'])," + + "iframe:not([tabindex='-1'])," + + "details:not([tabindex='-1'])," + + "[tabindex]:not([tabindex='-1'])," + + "[contentEditable=true]:not([tabindex='-1']" + ); +}; + +//from: https://github.com/RemiBou/BrowserInterop +window.serializeParameter = (data, spec) => { + if (typeof data == "undefined" || + data === null) { + return null; + } + if (typeof data === "number" || + typeof data === "string" || + typeof data == "boolean") { + return data; + } + + let res = (Array.isArray(data)) ? [] : {}; + if (!spec) { + spec = "*"; + } + + for (let i in data) { + let currentMember = data[i]; + + if (typeof currentMember === 'function' || currentMember === null) { + continue; + } + + let currentMemberSpec; + if (spec != "*") { + currentMemberSpec = Array.isArray(data) ? spec : spec[i]; + if (!currentMemberSpec) { + continue; + } + } else { + currentMemberSpec = "*" + } + + if (typeof currentMember === 'object') { + if (Array.isArray(currentMember) || currentMember.length) { + res[i] = []; + for (let j = 0; j < currentMember.length; j++) { + const arrayItem = currentMember[j]; + if (typeof arrayItem === 'object') { + res[i].push(this.serializeParameter(arrayItem, currentMemberSpec)); + } else { + res[i].push(arrayItem); + } + } + } else { + //the browser provides some member (like plugins) as hash with index as key, if length == 0 we shall not convert it + if (currentMember.length === 0) { + res[i] = []; + } else { + res[i] = this.serializeParameter(currentMember, currentMemberSpec); + } + } + + + } else { + // string, number or boolean + if (currentMember === Infinity) { //inifity is not serialized by JSON.stringify + currentMember = "Infinity"; + } + if (currentMember !== null) { //needed because the default json serializer in jsinterop serialize null values + res[i] = currentMember; + } + } + } + + return res; +}; diff --git a/TScripts/mudJsEvent.js b/TScripts/mudJsEvent.js new file mode 100644 index 0000000..89069fa --- /dev/null +++ b/TScripts/mudJsEvent.js @@ -0,0 +1,221 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudJsEventFactory { + connect(dotNetRef, elementId, options) { + //console.log('[MudBlazor | MudJsEventFactory] connect ', { dotNetRef, elementId, options }); + if (!elementId) + throw "[MudBlazor | JsEvent] elementId: expected element id!"; + var element = document.getElementById(elementId); + if (!element) + throw "[MudBlazor | JsEvent] no element found for id: " + elementId; + if (!element.mudJsEvent) + element.mudJsEvent = new MudJsEvent(dotNetRef, options); + element.mudJsEvent.connect(element); + } + + disconnect(elementId) { + var element = document.getElementById(elementId); + if (!element || !element.mudJsEvent) + return; + element.mudJsEvent.disconnect(); + } + + subscribe(elementId, eventName) { + //console.log('[MudBlazor | MudJsEventFactory] subscribe ', { elementId, eventName}); + if (!elementId) + throw "[MudBlazor | JsEvent] elementId: expected element id!"; + var element = document.getElementById(elementId); + if (!element) + throw "[MudBlazor | JsEvent] no element found for id: " +elementId; + if (!element.mudJsEvent) + throw "[MudBlazor | JsEvent] please connect before subscribing" + element.mudJsEvent.subscribe(eventName); + } + + unsubscribe(elementId, eventName) { + var element = document.getElementById(elementId); + if (!element || !element.mudJsEvent) + return; + element.mudJsEvent.unsubscribe(element, eventName); + } +} +window.mudJsEvent = new MudJsEventFactory(); + + +class MudJsEvent { + + constructor(dotNetRef, options) { + this._dotNetRef = dotNetRef; + this._options = options || {}; + this.logger = options.enableLogging ? console.log : (message) => { }; + this.logger('[MudBlazor | JsEvent] Initialized', { options }); + this._subscribedEvents = {}; + } + + connect(element) { + if (!this._options) + return; + if (!this._options.targetClass) + throw "_options.targetClass: css class name expected"; + if (this._observer) { + // don't do double registration + return; + } + var targetClass = this._options.targetClass; + this.logger('[MudBlazor | JsEvent] Start observing DOM of element for changes to child with class ', { element, targetClass }); + this._element = element; + this._observer = new MutationObserver(this.onDomChanged); + this._observer.mudJsEvent = this; + this._observer.observe(this._element, { attributes: false, childList: true, subtree: true }); + this._observedChildren = []; + } + + disconnect() { + if (!this._observer) + return; + this.logger('[MudBlazor | JsEvent] disconnect mutation observer and event handler '); + this._observer.disconnect(); + this._observer = null; + for (const child of this._observedChildren) + this.detachHandlers(child); + } + + subscribe(eventName) { + // register handlers + if (this._subscribedEvents[eventName]) { + //console.log("... already attached"); + return; + } + var element = this._element; + var targetClass = this._options.targetClass; + //this.logger('[MudBlazor | JsEvent] Subscribe event ' + eventName, { element, targetClass }); + this._subscribedEvents[eventName]=true; + for (const child of element.getElementsByClassName(targetClass)) { + this.attachHandlers(child); + } + } + + unsubscribe(eventName) { + if (!this._observer) + return; + this.logger('[MudBlazor | JsEvent] unsubscribe event handler ' + eventName ); + this._observer.disconnect(); + this._observer = null; + this._subscribedEvents[eventName] = false; + for (const child of this._observedChildren) { + this.detachHandler(child, eventName); + } + } + + attachHandlers(child) { + child.mudJsEvent = this; + //this.logger('[MudBlazor | JsEvent] attachHandlers ', this._subscribedEvents, child); + for (var eventName of Object.getOwnPropertyNames(this._subscribedEvents)) { + if (!this._subscribedEvents[eventName]) + continue; + // note: multiple registration of the same event not possible due to the use of the same handler func + this.logger('[MudBlazor | JsEvent] attaching event ' + eventName, child); + child.addEventListener(eventName, this.eventHandler); + } + if(this._observedChildren.indexOf(child) < 0) + this._observedChildren.push(child); + } + + detachHandler(child, eventName) { + this.logger('[MudBlazor | JsEvent] detaching handler ' + eventName, child); + child.removeEventListener(eventName, this.eventHandler); + } + + detachHandlers(child) { + this.logger('[MudBlazor | JsEvent] detaching handlers ', child); + for (var eventName of Object.getOwnPropertyNames(this._subscribedEvents)) { + if (!this._subscribedEvents[eventName]) + continue; + child.removeEventListener(eventName, this.eventHandler); + } + this._observedChildren = this._observedChildren.filter(x=>x!==child); + } + + onDomChanged(mutationsList, observer) { + var self = this.mudJsEvent; // func is invoked with this == _observer + //self.logger('[MudBlazor | JsEvent] onDomChanged: ', { self }); + var targetClass = self._options.targetClass; + for (const mutation of mutationsList) { + //self.logger('[MudBlazor | JsEvent] Subtree mutation: ', { mutation }); + for (const element of mutation.addedNodes) { + if (element.classList && element.classList.contains(targetClass)) { + if (!self._options.TagName || element.tagName == self._options.TagName) + self.attachHandlers(element); + } + } + for (const element of mutation.removedNodes) { + if (element.classList && element.classList.contains(targetClass)) { + if (!self._options.tagName || element.tagName == self._options.tagName) + self.detachHandlers(element); + } + } + } + } + + eventHandler(e) { + var self = this.mudJsEvent; // func is invoked with this == child + var eventName = e.type; + self.logger('[MudBlazor | JsEvent] "' + eventName + '"', e); + // call specific handler + self["on" + eventName](self, e); + } + + onkeyup(self, e) { + const caretPosition = e.target.selectionStart; + const invoke = self._subscribedEvents["keyup"]; + if (invoke) { + //self.logger('[MudBlazor | JsEvent] caret pos: ' + caretPosition); + self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged', caretPosition); + } + } + + onclick(self, e) { + const caretPosition = e.target.selectionStart; + const invoke = self._subscribedEvents["click"]; + if (invoke) { + //self.logger('[MudBlazor | JsEvent] caret pos: ' + caretPosition); + self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged', caretPosition); + } + } + + //oncopy(self, e) { + // const invoke = self._subscribedEvents["copy"]; + // if (invoke) { + // //self.logger('[MudBlazor | JsEvent] copy (preventing default and stopping propagation)'); + // e.preventDefault(); + // e.stopPropagation(); + // self._dotNetRef.invokeMethodAsync('OnCopy'); + // } + //} + + onpaste(self, e) { + const invoke = self._subscribedEvents["paste"]; + if (invoke) { + //self.logger('[MudBlazor | JsEvent] paste (preventing default and stopping propagation)'); + e.preventDefault(); + e.stopPropagation(); + const text = (e.originalEvent || e).clipboardData.getData('text/plain'); + self._dotNetRef.invokeMethodAsync('OnPaste', text); + } + } + + onselect(self, e) { + const invoke = self._subscribedEvents["select"]; + if (invoke) { + const start = e.target.selectionStart; + const end = e.target.selectionEnd; + if (start === end) + return; // <-- we have caret position changed for that. + //self.logger('[MudBlazor | JsEvent] select ' + start + "-" + end); + self._dotNetRef.invokeMethodAsync('OnSelect', start, end); + } + } +} + diff --git a/TScripts/mudKeyInterceptor.js b/TScripts/mudKeyInterceptor.js new file mode 100644 index 0000000..f483ba7 --- /dev/null +++ b/TScripts/mudKeyInterceptor.js @@ -0,0 +1,258 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudKeyInterceptorFactory { + + connect(dotNetRef, elementId, options) { + //console.log('[MudBlazor | MudKeyInterceptorFactory] connect ', { dotNetRef, element, options }); + if (!elementId) + throw "elementId: expected element id!"; + var element = document.getElementById(elementId); + if (!element) + throw "no element found for id: " +elementId; + if (!element.mudKeyInterceptor) + element.mudKeyInterceptor = new MudKeyInterceptor(dotNetRef, options); + element.mudKeyInterceptor.connect(element); + } + + updatekey(elementId, option) { + var element = document.getElementById(elementId); + if (!element || !element.mudKeyInterceptor) + return; + element.mudKeyInterceptor.updatekey(option); + } + + disconnect(elementId) { + var element = document.getElementById(elementId); + if (!element || !element.mudKeyInterceptor) + return; + element.mudKeyInterceptor.disconnect(); + } +} +window.mudKeyInterceptor = new MudKeyInterceptorFactory(); + + +class MudKeyInterceptor { + + constructor(dotNetRef, options) { + this._dotNetRef = dotNetRef; + this._options = options; + this.logger = options.enableLogging ? console.log : (message) => { }; + this.logger('[MudBlazor | KeyInterceptor] Interceptor initialized', { options }); + } + + + connect(element) { + if (!this._options) + return; + if (!this._options.keys) + throw "_options.keys: array of KeyOptions expected"; + if (!this._options.targetClass) + throw "_options.targetClass: css class name expected"; + if (this._observer) { + // don't do double registration + return; + } + var targetClass = this._options.targetClass; + this.logger('[MudBlazor | KeyInterceptor] Start observing DOM of element for changes to child with class ', { element, targetClass}); + this._element = element; + this._observer = new MutationObserver(this.onDomChanged); + this._observer.mudKeyInterceptor = this; + this._observer.observe(this._element, { attributes: false, childList: true, subtree: true }); + this._observedChildren = []; + // transform key options into a key lookup + this._keyOptions = {}; + this._regexOptions = []; + for (const keyOption of this._options.keys) { + if (!keyOption || !keyOption.key) { + this.logger('[MudBlazor | KeyInterceptor] got invalid key options: ', keyOption); + continue; + } + this.setKeyOption(keyOption) + } + this.logger('[MudBlazor | KeyInterceptor] key options: ', this._keyOptions); + if (this._regexOptions.size > 0) + this.logger('[MudBlazor | KeyInterceptor] regex options: ', this._regexOptions); + // register handlers + for (const child of this._element.getElementsByClassName(targetClass)) { + this.attachHandlers(child); + } + } + + setKeyOption(keyOption) { + if (keyOption.key.length > 2 && keyOption.key.startsWith('/') && keyOption.key.endsWith('/')) { + // JS regex key options such as "/[a-z]/" or "/a|b/" but NOT "/[a-z]/g" or "/[a-z]/i" + keyOption.regex = new RegExp(keyOption.key.substring(1, keyOption.key.length - 1)); // strip the / from start and end + this._regexOptions.push(keyOption); + } + else + this._keyOptions[keyOption.key.toLowerCase()] = keyOption; + // remove whitespace and enforce lowercase + var whitespace = new RegExp("\\s", "g"); + keyOption.preventDown = (keyOption.preventDown || "none").replace(whitespace, "").toLowerCase(); + keyOption.preventUp = (keyOption.preventUp || "none").replace(whitespace, "").toLowerCase(); + keyOption.stopDown = (keyOption.stopDown || "none").replace(whitespace, "").toLowerCase(); + keyOption.stopUp = (keyOption.stopUp || "none").replace(whitespace, "").toLowerCase(); + } + + updatekey(updatedOption) { + var option = this._keyOptions[updatedOption.key.toLowerCase()]; + option || this.logger('[MudBlazor | KeyInterceptor] updating option failed: key not registered'); + this.setKeyOption(updatedOption); + this.logger('[MudBlazor | KeyInterceptor] updated option ', { option, updatedOption }); + } + + disconnect() { + if (!this._observer) + return; + this.logger('[MudBlazor | KeyInterceptor] disconnect mutation observer and event handlers'); + this._observer.disconnect(); + this._observer = null; + for (const child of this._observedChildren) + this.detachHandlers(child); + } + + attachHandlers(child) { + this.logger('[MudBlazor | KeyInterceptor] attaching handlers ', { child }); + if (this._observedChildren.indexOf(child) > -1) { + //console.log("... already attached"); + return; + } + child.mudKeyInterceptor = this; + child.addEventListener('keydown', this.onKeyDown); + child.addEventListener('keyup', this.onKeyUp); + this._observedChildren.push(child); + } + + detachHandlers(child) { + this.logger('[MudBlazor | KeyInterceptor] detaching handlers ', { child }); + child.removeEventListener('keydown', this.onKeyDown); + child.removeEventListener('keyup', this.onKeyUp); + this._observedChildren = this._observedChildren.filter(x=>x!==child); + } + + onDomChanged(mutationsList, observer) { + var self = this.mudKeyInterceptor; // func is invoked with this == _observer + //self.logger('[MudBlazor | KeyInterceptor] onDomChanged: ', { self }); + var targetClass = self._options.targetClass; + for (const mutation of mutationsList) { + //self.logger('[MudBlazor | KeyInterceptor] Subtree mutation: ', { mutation }); + for (const element of mutation.addedNodes) { + if (element.classList && element.classList.contains(targetClass)) + self.attachHandlers(element); + } + for (const element of mutation.removedNodes) { + if (element.classList && element.classList.contains(targetClass)) + self.detachHandlers(element); + } + } + } + + matchesKeyCombination(option, args) { + if (!option || option=== "none") + return false; + if (option === "any") + return true; + var shift = args.shiftKey; + var ctrl = args.ctrlKey; + var alt = args.altKey; + var meta = args.metaKey; + var any = shift || ctrl || alt || meta; + if (any && option === "key+any") + return true; + if (!any && option.includes("key+none")) + return true; + if (!any) + return false; + var combi = `key${shift ? "+shift" : ""}${ctrl ? "+ctrl" : ""}${alt ? "+alt" : ""}${meta ? "+meta" : ""}`; + return option.includes(combi); + } + + onKeyDown(args) { + var self = this.mudKeyInterceptor; // func is invoked with this == child + var key = args.key.toLowerCase(); + self.logger('[MudBlazor | KeyInterceptor] down "' + key + '"', args); + var invoke = false; + if (self._keyOptions.hasOwnProperty(key)) { + var keyOptions = self._keyOptions[key]; + self.logger('[MudBlazor | KeyInterceptor] options for "' + key + '"', keyOptions); + self.processKeyDown(args, keyOptions); + if (keyOptions.subscribeDown) + invoke = true; + } + for (const keyOptions of self._regexOptions) { + if (keyOptions.regex.test(key)) { + self.logger('[MudBlazor | KeyInterceptor] regex options for "' + key + '"', keyOptions); + self.processKeyDown(args, keyOptions); + if (keyOptions.subscribeDown) + invoke = true; + } + } + if (invoke) { + var eventArgs = self.toKeyboardEventArgs(args); + eventArgs.Type = "keydown"; + // we'd like to pass a reference to the child element back to dotnet but we can't + // https://github.com/dotnet/aspnetcore/issues/16110 + // if we ever need it we'll pass the id up and users need to id the observed elements + self._dotNetRef.invokeMethodAsync('OnKeyDown', eventArgs); + } + } + + processKeyDown(args, keyOptions) { + if (this.matchesKeyCombination(keyOptions.preventDown, args)) + args.preventDefault(); + if (this.matchesKeyCombination(keyOptions.stopDown, args)) + args.stopPropagation(); + } + + onKeyUp(args) { + var self = this.mudKeyInterceptor; // func is invoked with this == child + var key = args.key.toLowerCase(); + self.logger('[MudBlazor | KeyInterceptor] up "' + key + '"', args); + var invoke = false; + if (self._keyOptions.hasOwnProperty(key)) { + var keyOptions = self._keyOptions[key]; + self.processKeyUp(args, keyOptions); + if (keyOptions.subscribeUp) + invoke = true; + } + for (const keyOptions of self._regexOptions) { + if (keyOptions.regex.test(key)) { + self.processKeyUp(args, keyOptions); + if (keyOptions.subscribeUp) + invoke = true; + } + } + if (invoke) { + var eventArgs = self.toKeyboardEventArgs(args); + eventArgs.Type = "keyup"; + // we'd like to pass a reference to the child element back to dotnet but we can't + // https://github.com/dotnet/aspnetcore/issues/16110 + // if we ever need it we'll pass the id up and users need to id the observed elements + self._dotNetRef.invokeMethodAsync('OnKeyUp', eventArgs); + } + } + + processKeyUp(args, keyOptions) { + if (this.matchesKeyCombination(keyOptions.preventUp, args)) + args.preventDefault(); + if (this.matchesKeyCombination(keyOptions.stopUp, args)) + args.stopPropagation(); + } + + toKeyboardEventArgs(args) { + return { + Key: args.key, + Code: args.code, + Location: args.location, + Repeat: args.repeat, + CtrlKey: args.ctrlKey, + ShiftKey: args.shiftKey, + AltKey: args.altKey, + MetaKey: args.metaKey + }; + } + +} + diff --git a/TScripts/mudPopover.js b/TScripts/mudPopover.js new file mode 100644 index 0000000..6a70591 --- /dev/null +++ b/TScripts/mudPopover.js @@ -0,0 +1,494 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +window.mudpopoverHelper = { + + calculatePopoverPosition: function (list, boundingRect, selfRect) { + let top = 0; + let left = 0; + if (list.indexOf('mud-popover-anchor-top-left') >= 0) { + left = boundingRect.left; + top = boundingRect.top; + } else if (list.indexOf('mud-popover-anchor-top-center') >= 0) { + left = boundingRect.left + boundingRect.width / 2; + top = boundingRect.top; + } else if (list.indexOf('mud-popover-anchor-top-right') >= 0) { + left = boundingRect.left + boundingRect.width; + top = boundingRect.top; + + } else if (list.indexOf('mud-popover-anchor-center-left') >= 0) { + left = boundingRect.left; + top = boundingRect.top + boundingRect.height / 2; + } else if (list.indexOf('mud-popover-anchor-center-center') >= 0) { + left = boundingRect.left + boundingRect.width / 2; + top = boundingRect.top + boundingRect.height / 2; + } else if (list.indexOf('mud-popover-anchor-center-right') >= 0) { + left = boundingRect.left + boundingRect.width; + top = boundingRect.top + boundingRect.height / 2; + + } else if (list.indexOf('mud-popover-anchor-bottom-left') >= 0) { + left = boundingRect.left; + top = boundingRect.top + boundingRect.height; + } else if (list.indexOf('mud-popover-anchor-bottom-center') >= 0) { + left = boundingRect.left + boundingRect.width / 2; + top = boundingRect.top + boundingRect.height; + } else if (list.indexOf('mud-popover-anchor-bottom-right') >= 0) { + left = boundingRect.left + boundingRect.width; + top = boundingRect.top + boundingRect.height; + } + + let offsetX = 0; + let offsetY = 0; + + if (list.indexOf('mud-popover-top-left') >= 0) { + offsetX = 0; + offsetY = 0; + } else if (list.indexOf('mud-popover-top-center') >= 0) { + offsetX = -selfRect.width / 2; + offsetY = 0; + } else if (list.indexOf('mud-popover-top-right') >= 0) { + offsetX = -selfRect.width; + offsetY = 0; + } + + else if (list.indexOf('mud-popover-center-left') >= 0) { + offsetX = 0; + offsetY = -selfRect.height / 2; + } else if (list.indexOf('mud-popover-center-center') >= 0) { + offsetX = -selfRect.width / 2; + offsetY = -selfRect.height / 2; + } else if (list.indexOf('mud-popover-center-right') >= 0) { + offsetX = -selfRect.width; + offsetY = -selfRect.height / 2; + } + + else if (list.indexOf('mud-popover-bottom-left') >= 0) { + offsetX = 0; + offsetY = -selfRect.height; + } else if (list.indexOf('mud-popover-bottom-center') >= 0) { + offsetX = -selfRect.width / 2; + offsetY = -selfRect.height; + } else if (list.indexOf('mud-popover-bottom-right') >= 0) { + offsetX = -selfRect.width; + offsetY = -selfRect.height; + } + + return { + top: top, left: left, offsetX: offsetX, offsetY: offsetY + }; + }, + + flipClassReplacements: { + 'top': { + 'mud-popover-top-left': 'mud-popover-bottom-left', + 'mud-popover-top-center': 'mud-popover-bottom-center', + 'mud-popover-anchor-bottom-center': 'mud-popover-anchor-top-center', + 'mud-popover-top-right': 'mud-popover-bottom-right', + }, + 'left': { + 'mud-popover-top-left': 'mud-popover-top-right', + 'mud-popover-center-left': 'mud-popover-center-right', + 'mud-popover-anchor-center-right': 'mud-popover-anchor-center-left', + 'mud-popover-bottom-left': 'mud-popover-bottom-right', + }, + 'right': { + 'mud-popover-top-right': 'mud-popover-top-left', + 'mud-popover-center-right': 'mud-popover-center-left', + 'mud-popover-anchor-center-left': 'mud-popover-anchor-center-right', + 'mud-popover-bottom-right': 'mud-popover-bottom-left', + }, + 'bottom': { + 'mud-popover-bottom-left': 'mud-popover-top-left', + 'mud-popover-bottom-center': 'mud-popover-top-center', + 'mud-popover-anchor-top-center': 'mud-popover-anchor-bottom-center', + 'mud-popover-bottom-right': 'mud-popover-top-right', + }, + 'top-and-left': { + 'mud-popover-top-left': 'mud-popover-bottom-right', + }, + 'top-and-right': { + 'mud-popover-top-right': 'mud-popover-bottom-left', + }, + 'bottom-and-left': { + 'mud-popover-bottom-left': 'mud-popover-top-right', + }, + 'bottom-and-right': { + 'mud-popover-bottom-right': 'mud-popover-top-left', + }, + + }, + + flipMargin: 0, + + getPositionForFlippedPopver: function (inputArray, selector, boundingRect, selfRect) { + const classList = []; + for (var i = 0; i < inputArray.length; i++) { + const item = inputArray[i]; + const replacments = window.mudpopoverHelper.flipClassReplacements[selector][item]; + if (replacments) { + classList.push(replacments); + } + else { + classList.push(item); + } + } + + return window.mudpopoverHelper.calculatePopoverPosition(classList, boundingRect, selfRect); + }, + + placePopover: function (popoverNode, classSelector) { + + if (popoverNode && popoverNode.parentNode) { + const id = popoverNode.id.substr(8); + const popoverContentNode = document.getElementById('popovercontent-' + id); + if (popoverContentNode.classList.contains('mud-popover-open') == false) { + return; + } + + if (!popoverContentNode) { + return; + } + + if (classSelector) { + if (popoverContentNode.classList.contains(classSelector) == false) { + return; + } + } + const boundingRect = popoverNode.parentNode.getBoundingClientRect(); + + if (popoverContentNode.classList.contains('mud-popover-relative-width')) { + popoverContentNode.style['max-width'] = (boundingRect.width) + 'px'; + } + + const selfRect = popoverContentNode.getBoundingClientRect(); + const classList = popoverContentNode.classList; + const classListArray = Array.from(popoverContentNode.classList); + + const postion = window.mudpopoverHelper.calculatePopoverPosition(classListArray, boundingRect, selfRect); + let left = postion.left; + let top = postion.top; + let offsetX = postion.offsetX; + let offsetY = postion.offsetY; + + if (classList.contains('mud-popover-overflow-flip-onopen') || classList.contains('mud-popover-overflow-flip-always')) { + + const appBarElements = document.getElementsByClassName("mud-appbar mud-appbar-fixed-top"); + let appBarOffset = 0; + if (appBarElements.length > 0) { + appBarOffset = appBarElements[0].getBoundingClientRect().height; + } + + const graceMargin = window.mudpopoverHelper.flipMargin; + const deltaToLeft = left + offsetX; + const deltaToRight = window.innerWidth - left - selfRect.width; + const deltaTop = top - selfRect.height - appBarOffset; + const spaceToTop = top - appBarOffset; + const deltaBottom = window.innerHeight - top - selfRect.height; + //console.log('self-width: ' + selfRect.width + ' | self-height: ' + selfRect.height); + //console.log('left: ' + deltaToLeft + ' | rigth:' + deltaToRight + ' | top: ' + deltaTop + ' | bottom: ' + deltaBottom + ' | spaceToTop: ' + spaceToTop); + + let selector = popoverContentNode.mudPopoverFliped; + + if (!selector) { + if (classList.contains('mud-popover-top-left')) { + if (deltaBottom < graceMargin && deltaToRight < graceMargin && spaceToTop >= selfRect.height && deltaToLeft >= selfRect.width) { + selector = 'top-and-left'; + } else if (deltaBottom < graceMargin && spaceToTop >= selfRect.height) { + selector = 'top'; + } else if (deltaToRight < graceMargin && deltaToLeft >= selfRect.width) { + selector = 'left'; + } + } else if (classList.contains('mud-popover-top-center')) { + if (deltaBottom < graceMargin && spaceToTop >= selfRect.height) { + selector = 'top'; + } + } else if (classList.contains('mud-popover-top-right')) { + if (deltaBottom < graceMargin && deltaToLeft < graceMargin && spaceToTop >= selfRect.height && deltaToRight >= selfRect.width) { + selector = 'top-and-right'; + } else if (deltaBottom < graceMargin && spaceToTop >= selfRect.height) { + selector = 'top'; + } else if (deltaToLeft < graceMargin && deltaToRight >= selfRect.width) { + selector = 'right'; + } + } + + else if (classList.contains('mud-popover-center-left')) { + if (deltaToRight < graceMargin && deltaToLeft >= selfRect.width) { + selector = 'left'; + } + } + else if (classList.contains('mud-popover-center-right')) { + if (deltaToLeft < graceMargin && deltaToRight >= selfRect.width) { + selector = 'right'; + } + } + else if (classList.contains('mud-popover-bottom-left')) { + if (deltaTop < graceMargin && deltaToRight < graceMargin && deltaBottom >= 0 && deltaToLeft >= selfRect.width) { + selector = 'bottom-and-left'; + } else if (deltaTop < graceMargin && deltaBottom >= 0) { + selector = 'bottom'; + } else if (deltaToRight < graceMargin && deltaToLeft >= selfRect.width) { + selector = 'left'; + } + } else if (classList.contains('mud-popover-bottom-center')) { + if (deltaTop < graceMargin && deltaBottom >= 0) { + selector = 'bottom'; + } + } else if (classList.contains('mud-popover-bottom-right')) { + if (deltaTop < graceMargin && deltaToLeft < graceMargin && deltaBottom >= 0 && deltaToRight >= selfRect.width) { + selector = 'bottom-and-right'; + } else if (deltaTop < graceMargin && deltaBottom >= 0) { + selector = 'bottom'; + } else if (deltaToLeft < graceMargin && deltaToRight >= selfRect.width) { + selector = 'right'; + } + } + } + + if (selector && selector != 'none') { + const newPosition = window.mudpopoverHelper.getPositionForFlippedPopver(classListArray, selector, boundingRect, selfRect); + left = newPosition.left; + top = newPosition.top; + offsetX = newPosition.offsetX; + offsetY = newPosition.offsetY; + + popoverContentNode.setAttribute('data-mudpopover-flip', 'flipped'); + } + else { + popoverContentNode.removeAttribute('data-mudpopover-flip'); + } + + if (classList.contains('mud-popover-overflow-flip-onopen')) { + if (!popoverContentNode.mudPopoverFliped) { + popoverContentNode.mudPopoverFliped = selector || 'none'; + } + } + } + + if (popoverContentNode.classList.contains('mud-popover-fixed')) { + } + else if (window.getComputedStyle(popoverNode).position == 'fixed') { + popoverContentNode.style['position'] = 'fixed'; + } + else { + offsetX += window.scrollX; + offsetY += window.scrollY + } + + popoverContentNode.style['left'] = (left + offsetX) + 'px'; + popoverContentNode.style['top'] = (top + offsetY) + 'px'; + + if (window.getComputedStyle(popoverNode).getPropertyValue('z-index') != 'auto') { + popoverContentNode.style['z-index'] = window.getComputedStyle(popoverNode).getPropertyValue('z-index'); + popoverContentNode.skipZIndex = true; + } + } + }, + + placePopoverByClassSelector: function (classSelector = null) { + var items = window.mudPopover.getAllObservedContainers(); + + for (let i = 0; i < items.length; i++) { + const popoverNode = document.getElementById('popover-' + items[i]); + window.mudpopoverHelper.placePopover(popoverNode, classSelector); + } + }, + + placePopoverByNode: function (target) { + const id = target.id.substr(15); + const popoverNode = document.getElementById('popover-' + id); + window.mudpopoverHelper.placePopover(popoverNode); + }, + + countProviders: function () { + return document.querySelectorAll(".mud-popover-provider").length; + } +} + +class MudPopover { + + constructor() { + this.map = {}; + this.contentObserver = null; + this.mainContainerClass = null; + } + + callback(id, mutationsList, observer) { + for (const mutation of mutationsList) { + if (mutation.type === 'attributes') { + const target = mutation.target + if (mutation.attributeName == 'class') { + if (target.classList.contains('mud-popover-overflow-flip-onopen') && + target.classList.contains('mud-popover-open') == false) { + target.mudPopoverFliped = null; + target.removeAttribute('data-mudpopover-flip'); + } + + window.mudpopoverHelper.placePopoverByNode(target); + } + else if (mutation.attributeName == 'data-ticks') { + const tickAttribute = target.getAttribute('data-ticks'); + + const parent = target.parentElement; + const tickValues = []; + let max = -1; + for (let i = 0; i < parent.children.length; i++) { + const childNode = parent.children[i]; + const tickValue = parseInt(childNode.getAttribute('data-ticks')); + if (tickValue == 0) { + continue; + } + + if (tickValues.indexOf(tickValue) >= 0) { + continue; + } + + tickValues.push(tickValue); + + if (tickValue > max) { + max = tickValue; + } + } + + if (tickValues.length == 0) { + continue; + } + + const sortedTickValues = tickValues.sort((x, y) => x - y); + + for (let i = 0; i < parent.children.length; i++) { + const childNode = parent.children[i]; + const tickValue = parseInt(childNode.getAttribute('data-ticks')); + if (tickValue == 0) { + continue; + } + + if (childNode.skipZIndex == true) { + continue; + } + + childNode.style['z-index'] = 'calc(var(--mud-zindex-popover) + ' + (sortedTickValues.indexOf(tickValue) + 3).toString() + ')'; + } + } + } + } + } + + initialize(containerClass, flipMargin) { + const mainContent = document.getElementsByClassName(containerClass); + if (mainContent.length == 0) { + return; + } + + if (flipMargin) { + window.mudpopoverHelper.flipMargin = flipMargin; + } + + this.mainContainerClass = containerClass; + + if (!mainContent[0].mudPopoverMark) { + mainContent[0].mudPopoverMark = "mudded"; + if (this.contentObserver != null) { + this.contentObserver.disconnect(); + this.contentObserver = null; + } + + this.contentObserver = new ResizeObserver(entries => { + window.mudpopoverHelper.placePopoverByClassSelector(); + }); + + this.contentObserver.observe(mainContent[0]); + } + } + + connect(id) { + this.initialize(this.mainContainerClass); + + const popoverNode = document.getElementById('popover-' + id); + const popoverContentNode = document.getElementById('popovercontent-' + id); + if (popoverNode && popoverNode.parentNode && popoverContentNode) { + + window.mudpopoverHelper.placePopover(popoverNode); + + const config = { attributeFilter: ['class', 'data-ticks'] }; + + const observer = new MutationObserver(this.callback.bind(this, id)); + + observer.observe(popoverContentNode, config); + + const resizeObserver = new ResizeObserver(entries => { + for (let entry of entries) { + const target = entry.target; + + for (var i = 0; i < target.childNodes.length; i++) { + const childNode = target.childNodes[i]; + if (childNode.id && childNode.id.startsWith('popover-')) { + window.mudpopoverHelper.placePopover(childNode); + } + } + } + }); + + resizeObserver.observe(popoverNode.parentNode); + + const contentNodeObserver = new ResizeObserver(entries => { + for (let entry of entries) { + var target = entry.target; + window.mudpopoverHelper.placePopoverByNode(target); + + + } + }); + + contentNodeObserver.observe(popoverContentNode); + + this.map[id] = { + mutationObserver: observer, + resizeObserver: resizeObserver, + contentNodeObserver: contentNodeObserver + }; + } + } + + disconnect(id) { + if (this.map[id]) { + + const item = this.map[id] + item.mutationObserver.disconnect(); + item.resizeObserver.disconnect(); + item.contentNodeObserver.disconnect(); + + delete this.map[id]; + } + } + + dispose() { + for (var i in this.map) { + disconnect(i); + } + + this.contentObserver.disconnect(); + this.contentObserver = null; + } + + getAllObservedContainers() { + const result = []; + for (var i in this.map) { + result.push(i); + } + + return result; + } +} + +window.mudPopover = new MudPopover(); + +window.addEventListener('scroll', () => { + window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-fixed'); + window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-overflow-flip-always'); +}); + +window.addEventListener('resize', () => { + window.mudpopoverHelper.placePopoverByClassSelector(); +}); \ No newline at end of file diff --git a/TScripts/mudResizeListener.js b/TScripts/mudResizeListener.js new file mode 100644 index 0000000..1506de9 --- /dev/null +++ b/TScripts/mudResizeListener.js @@ -0,0 +1,139 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudResizeListener { + + constructor(id) { + this.logger = function (message) { }; + this.options = {}; + this.throttleResizeHandlerId = -1; + this.dotnet = undefined; + this.breakpoint = -1; + this.id = id; + } + + listenForResize(dotnetRef, options) { + if (this.dotnet) { + this.options = options; + return; + } + //this.logger("[MudBlazor] listenForResize:", { options, dotnetRef }); + this.options = options; + this.dotnet = dotnetRef; + this.logger = options.enableLogging ? console.log : (message) => { }; + this.logger(`[MudBlazor] Reporting resize events at rate of: ${(this.options || {}).reportRate || 100}ms`); + window.addEventListener("resize", this.throttleResizeHandler.bind(this), false); + if (!this.options.suppressInitEvent) { + this.resizeHandler(); + } + this.breakpoint = this.getBreakpoint(window.innerWidth); + } + + throttleResizeHandler() { + clearTimeout(this.throttleResizeHandlerId); + //console.log("[MudBlazor] throttleResizeHandler ", {options:this.options}); + this.throttleResizeHandlerId = window.setTimeout(this.resizeHandler.bind(this), ((this.options || {}).reportRate || 100)); + } + + resizeHandler() { + if (this.options.notifyOnBreakpointOnly) { + let bp = this.getBreakpoint(window.innerWidth); + if (bp == this.breakpoint) { + return; + } + this.breakpoint = bp; + } + + try { + //console.log("[MudBlazor] RaiseOnResized invoked"); + if (this.id) { + this.dotnet.invokeMethodAsync('RaiseOnResized', + { + height: window.innerHeight, + width: window.innerWidth + }, + this.getBreakpoint(window.innerWidth), + this.id); + } + else { + this.dotnet.invokeMethodAsync('RaiseOnResized', + { + height: window.innerHeight, + width: window.innerWidth + }, + this.getBreakpoint(window.innerWidth)); + } + + //this.logger("[MudBlazor] RaiseOnResized invoked"); + } catch (error) { + this.logger("[MudBlazor] Error in resizeHandler:", { error }); + } + } + + cancelListener() { + this.dotnet = undefined; + //console.log("[MudBlazor] cancelListener"); + window.removeEventListener("resize", this.throttleResizeHandler); + } + + matchMedia(query) { + let m = window.matchMedia(query).matches; + //this.logger(`[MudBlazor] matchMedia "${query}": ${m}`); + return m; + } + + getBrowserWindowSize() { + //this.logger("[MudBlazor] getBrowserWindowSize"); + return { + height: window.innerHeight, + width: window.innerWidth + }; + } + + getBreakpoint(width) { + if (width >= this.options.breakpointDefinitions["Xl"]) + return 4; + else if (width >= this.options.breakpointDefinitions["Lg"]) + return 3; + else if (width >= this.options.breakpointDefinitions["Md"]) + return 2; + else if (width >= this.options.breakpointDefinitions["Sm"]) + return 1; + else //Xs + return 0; + } +}; + +window.mudResizeListener = new MudResizeListener(); +window.mudResizeListenerFactory = { + mapping: {}, + listenForResize: (dotnetRef, options, id) => { + var map = window.mudResizeListenerFactory.mapping; + if (map[id]) { + return; + } + + var listener = new MudResizeListener(id); + listener.listenForResize(dotnetRef, options); + map[id] = listener; + }, + + cancelListener: (id) => { + var map = window.mudResizeListenerFactory.mapping; + + if (!map[id]) { + return; + } + + var listener = map[id]; + listener.cancelListener(); + delete map[id]; + }, + + cancelListeners: (ids) => { + for (let i = 0; i < ids.length; i++) { + window.mudResizeListenerFactory.cancelListener(ids[i]); + } + } +} diff --git a/TScripts/mudResizeObserver.js b/TScripts/mudResizeObserver.js new file mode 100644 index 0000000..a2d0d63 --- /dev/null +++ b/TScripts/mudResizeObserver.js @@ -0,0 +1,143 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudResizeObserverFactory { + constructor() { + this._maps = {}; + } + + connect(id, dotNetRef, elements, elementIds, options) { + var existingEntry = this._maps[id]; + if (!existingEntry) { + var observer = new MudResizeObserver(dotNetRef, options); + this._maps[id] = observer; + } + + var result = this._maps[id].connect(elements, elementIds); + return result; + } + + disconnect(id, element) { + //I can't think about a case, where this can be called, without observe has been called before + //however, a check is not harmful either + var existingEntry = this._maps[id]; + if (existingEntry) { + existingEntry.disconnect(element); + } + } + + cancelListener(id) { + //cancelListener is called during dispose of .net instance + //in rare cases it could be possible, that no object has been connect so far + //and no entry exists. Therefore, a little check to prevent an error in this case + var existingEntry = this._maps[id]; + if (existingEntry) { + existingEntry.cancelListener(); + delete this._maps[id]; + } + } +} + +class MudResizeObserver { + + constructor(dotNetRef, options) { + this.logger = options.enableLogging ? console.log : (message) => { }; + this.options = options; + this._dotNetRef = dotNetRef + + var delay = (this.options || {}).reportRate || 200; + + this.throttleResizeHandlerId = -1; + + var observervedElements = []; + this._observervedElements = observervedElements; + + this.logger('[MudBlazor | ResizeObserver] Observer initialized'); + + this._resizeObserver = new ResizeObserver(entries => { + var changes = []; + this.logger('[MudBlazor | ResizeObserver] changes detected'); + for (let entry of entries) { + var target = entry.target; + var affectedObservedElement = observervedElements.find((x) => x.element == target); + if (affectedObservedElement) { + + var size = entry.target.getBoundingClientRect(); + if (affectedObservedElement.isInitialized == true) { + + changes.push({ id: affectedObservedElement.id, size: size }); + } + else { + affectedObservedElement.isInitialized = true; + } + } + } + + if (changes.length > 0) { + if (this.throttleResizeHandlerId >= 0) { + clearTimeout(this.throttleResizeHandlerId); + } + + this.throttleResizeHandlerId = window.setTimeout(this.resizeHandler.bind(this, changes), delay); + + } + }); + } + + resizeHandler(changes) { + try { + this.logger("[MudBlazor | ResizeObserver] OnSizeChanged handler invoked"); + this._dotNetRef.invokeMethodAsync("OnSizeChanged", changes); + } catch (error) { + this.logger("[MudBlazor | ResizeObserver] Error in OnSizeChanged handler:", { error }); + } + } + + connect(elements, ids) { + var result = []; + this.logger('[MudBlazor | ResizeObserver] Start observing elements...'); + + for (var i = 0; i < elements.length; i++) { + var newEntry = { + element: elements[i], + id: ids[i], + isInitialized: false, + }; + + this.logger("[MudBlazor | ResizeObserver] Start observing element:", { newEntry }); + + result.push(elements[i].getBoundingClientRect()); + + this._observervedElements.push(newEntry); + this._resizeObserver.observe(elements[i]); + } + + return result; + } + + disconnect(elementId) { + this.logger('[MudBlazor | ResizeObserver] Try to unobserve element with id', { elementId }); + + var affectedObservedElement = this._observervedElements.find((x) => x.id == elementId); + if (affectedObservedElement) { + + var element = affectedObservedElement.element; + this._resizeObserver.unobserve(element); + this.logger('[MudBlazor | ResizeObserver] Element found. Ubobserving size changes of element', { element }); + + var index = this._observervedElements.indexOf(affectedObservedElement); + this._observervedElements.splice(index, 1); + } + } + + cancelListener() { + this.logger('[MudBlazor | ResizeObserver] Closing ResizeObserver. Detaching all observed elements'); + + this._resizeObserver.disconnect(); + this._dotNetRef = undefined; + } +} + + +window.mudResizeObserver = new MudResizeObserverFactory(); \ No newline at end of file diff --git a/TScripts/mudScrollListener.js b/TScripts/mudScrollListener.js new file mode 100644 index 0000000..609a115 --- /dev/null +++ b/TScripts/mudScrollListener.js @@ -0,0 +1,83 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//Functions related to scroll events +class MudScrollListener { + + constructor() { + this.throttleScrollHandlerId = -1; + //needed as variable to remove the event listeners + this.handlerRef = null; + } + + // subscribe to throttled scroll event + listenForScroll(dotnetReference, selector) { + //if selector is null, attach to document + let element = selector + ? document.querySelector(selector) + : document; + + this.handlerRef = this.throttleScrollHandler.bind(this, dotnetReference); + // add the event listener + element.addEventListener( + 'scroll', + this.handlerRef, + false + ); + } + + // fire the event just once each 100 ms, **it's hardcoded** + throttleScrollHandler(dotnetReference, event) { + clearTimeout(this.throttleScrollHandlerId); + + this.throttleScrollHandlerId = window.setTimeout( + this.scrollHandler.bind(this, dotnetReference, event), + 100 + ); + } + + // when scroll event is fired, pass this information to + // the RaiseOnScroll C# method of the ScrollListener + // We pass the scroll coordinates of the element and + // the boundingClientRect of the first child, because + // scrollTop of body is always 0. With this information, + // we can trigger C# events on different scroll situations + scrollHandler(dotnetReference, event) { + try { + let element = event.target; + + //data to pass + let scrollTop = element.scrollTop; + let scrollHeight = element.scrollHeight; + let scrollWidth = element.scrollWidth; + let scrollLeft = element.scrollLeft; + let nodeName = element.nodeName; + + //data to pass + let firstChild = element.firstElementChild; + let firstChildBoundingClientRect = firstChild.getBoundingClientRect(); + //invoke C# method + dotnetReference.invokeMethodAsync('RaiseOnScroll', { + firstChildBoundingClientRect, + scrollLeft, + scrollTop, + scrollHeight, + scrollWidth, + nodeName, + }); + } catch (error) { + console.log('[MudBlazor] Error in scrollHandler:', { error }); + } + } + + //remove event listener + cancelListener(selector) { + let element = selector + ? document.querySelector(selector) + : document; + + element.removeEventListener('scroll', this.handlerRef); + } +}; +window.mudScrollListener = new MudScrollListener(); \ No newline at end of file diff --git a/TScripts/mudScrollManager.js b/TScripts/mudScrollManager.js new file mode 100644 index 0000000..991d727 --- /dev/null +++ b/TScripts/mudScrollManager.js @@ -0,0 +1,65 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudScrollManager { + //scrolls to year in MudDatePicker + scrollToYear(elementId, offset) { + let element = document.getElementById(elementId); + + if (element) { + element.parentNode.scrollTop = element.offsetTop - element.parentNode.offsetTop - element.scrollHeight * 3; + } + } + + // sets the scroll position of the elements container, + // to the position of the element with the given element id + scrollToListItem(elementId) { + let element = document.getElementById(elementId); + if (element) { + let parent = element.parentElement; + if (parent) { + parent.scrollTop = element.offsetTop; + } + } + } + + //scrolls to the selected element. Default is documentElement (i.e., html element) + scrollTo(selector, left, top, behavior) { + let element = document.querySelector(selector) || document.documentElement; + element.scrollTo({ left, top, behavior }); + } + + //scrolls the provided selector into view + scrollIntoView(selector, behavior) { + let element = document.querySelector(selector) || document.documentElement; + if (element) + element.scrollIntoView({ behavior, block: 'center', inline: 'start' }); + } + + scrollToBottom(selector, behavior) { + let element = document.querySelector(selector); + if (element) + element.scrollTop = element.scrollHeight; + else + window.scrollTo(0, document.body.scrollHeight); + } + + //locks the scroll of the selected element. Default is body + lockScroll(selector, lockclass) { + let element = document.querySelector(selector) || document.body; + + //if the body doesn't have a scroll bar, don't add the lock class + let hasScrollBar = window.innerWidth > document.body.clientWidth; + if (hasScrollBar) { + element.classList.add(lockclass); + } + } + + //unlocks the scroll. Default is body + unlockScroll(selector, lockclass) { + let element = document.querySelector(selector) || document.body; + element.classList.remove(lockclass); + } +}; +window.mudScrollManager = new MudScrollManager(); \ No newline at end of file diff --git a/TScripts/mudScrollSpy.js b/TScripts/mudScrollSpy.js new file mode 100644 index 0000000..3e11637 --- /dev/null +++ b/TScripts/mudScrollSpy.js @@ -0,0 +1,109 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//Functions related to the scroll spy +class MudScrollSpy { + + constructor() { + this.scrollToSectionRequested = null; + this.lastKnowElement = null; + //needed as variable to remove the event listeners + this.handlerRef = null; + } + + // subscribe to relevant events + spying(dotnetReference, selector) { + this.scrollToSectionRequested = null; + this.lastKnowElement = null; + + this.handlerRef = this.handleScroll.bind(this, selector, dotnetReference); + + // add the event for scroll. In case of zooming this event is also fired + document.addEventListener('scroll', this.handlerRef, true); + + // a window resize could change the size of the relevant viewport + window.addEventListener('resize', this.handlerRef, true); + } + + // handle the document scroll event and if needed, fires the .NET event + handleScroll(dotnetReference, selector, event) { + + const elements = document.getElementsByClassName(selector); + if (elements.length === 0) { + return; + } + + const center = window.innerHeight / 2.0; + + let minDifference = Number.MAX_SAFE_INTEGER; + let elementId = ''; + for (let i = 0; i < elements.length; i++) { + const element = elements[i]; + + const rect = element.getBoundingClientRect(); + + const diff = Math.abs(rect.top - center); + + if (diff < minDifference) { + minDifference = diff; + elementId = element.id; + } + } + + if (document.getElementById(elementId).getBoundingClientRect().top < window.innerHeight * 0.8 === false) { + return; + } + + if (this.scrollToSectionRequested != null) { + if (this.scrollToSectionRequested == ' ' && window.scrollY == 0) { + this.scrollToSectionRequested = null; + } + else { + if (elementId === this.scrollToSectionRequested) { + this.scrollToSectionRequested = null; + } + } + + return; + } + + if (elementId != this.lastKnowElement) { + this.lastKnowElement = elementId; + history.replaceState(null, '', window.location.pathname + "#" + elementId); + dotnetReference.invokeMethodAsync('SectionChangeOccured', elementId); + } + } + + activateSection(sectionId) { + const element = document.getElementById(sectionId); + if (element) { + this.lastKnowElement = sectionId; + history.replaceState(null, '', window.location.pathname + "#" + sectionId); + } + } + + scrollToSection(sectionId) { + if (sectionId) { + let element = document.getElementById(sectionId); + if (element) { + this.scrollToSectionRequested = sectionId; + + element.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'start' }); + } + } + else { + window.scrollTo({ top: 0, behavior: 'smooth' }); + + this.scrollToSectionRequested = ' '; + } + } + + //remove event listeners + unspy() { + document.removeEventListener('scroll', this.handlerRef, true); + window.removeEventListener('resize', this.handlerRef, true); + } +}; + +window.mudScrollSpy = new MudScrollSpy(); diff --git a/TScripts/mudThemeProvider.js b/TScripts/mudThemeProvider.js new file mode 100644 index 0000000..4119ad7 --- /dev/null +++ b/TScripts/mudThemeProvider.js @@ -0,0 +1,5 @@ +const darkThemeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + +window.darkModeChange = (dotNetHelper) => { + return darkThemeMediaQuery.matches; +}; \ No newline at end of file diff --git a/TScripts/mudWindow.js b/TScripts/mudWindow.js new file mode 100644 index 0000000..f9db489 --- /dev/null +++ b/TScripts/mudWindow.js @@ -0,0 +1,26 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class MudWindow { + copyToClipboard (text) { + navigator.clipboard.writeText(text); + } + + changeCssById (id, css) { + var element = document.getElementById(id); + if (element) { + element.className = css; + } + } + + changeGlobalCssVariable (name, newValue) { + document.documentElement.style.setProperty(name, newValue); + } + + // Needed as per https://stackoverflow.com/questions/62769031/how-can-i-open-a-new-window-without-using-js + open (args) { + window.open(args); + } +}; +window.mudWindow = new MudWindow(); \ No newline at end of file diff --git a/Themes/Models/Breakpoints.cs b/Themes/Models/Breakpoints.cs new file mode 100644 index 0000000..74f20f5 --- /dev/null +++ b/Themes/Models/Breakpoints.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Connected +{ +#pragma warning disable IDE1006 // must being with upper case + [ExcludeFromCodeCoverage] + public class Breakpoints + { + public string xs { get; set; } = "0px"; + public string sm { get; set; } = "600px"; + public string md { get; set; } = "960px"; + public string lg { get; set; } = "1280px"; + public string xl { get; set; } = "1920px"; + public string xxl { get; set; } = "2560px"; + } +} diff --git a/Themes/Models/LayoutProperties.cs b/Themes/Models/LayoutProperties.cs new file mode 100644 index 0000000..d1a7d5c --- /dev/null +++ b/Themes/Models/LayoutProperties.cs @@ -0,0 +1,21 @@ + +using System; + +namespace Connected +{ + public class LayoutProperties + { + public string DefaultBorderRadius { get; set; } = "4px"; + [Obsolete("DrawerWidth has been removed.", true)] + public string DrawerWidth { get; set; } = null; + public string DrawerMiniWidthLeft { get; set; } = "56px"; + public string DrawerMiniWidthRight { get; set; } = "56px"; + public string DrawerWidthLeft { get; set; } = "240px"; + public string DrawerWidthRight { get; set; } = "240px"; + public string DrawerHeightTop { get; set; } = "320px"; + public string DrawerHeightBottom { get; set; } = "320px"; + [Obsolete("AppbarMinHeight has been removed.", true)] + public string AppbarMinHeight { get; set; } = null; + public string AppbarHeight { get; set; } = "64px"; + } +} diff --git a/Themes/Models/Palette.cs b/Themes/Models/Palette.cs new file mode 100644 index 0000000..ddc4a00 --- /dev/null +++ b/Themes/Models/Palette.cs @@ -0,0 +1,156 @@ +using Connected.Utilities; +using C = Connected.Colors; +using Clr = Connected.Utilities.Color; +namespace Connected; + +public class Palette +{ + private Clr _primaryDarken = null; + private Clr _primaryLighten = null; + private Clr _secondaryDarken = null; + private Clr _secondaryLighten = null; + private Clr _tertiaryDarken = null; + private Clr _tertiaryLighten = null; + private Clr _infoDarken = null; + private Clr _infoLighten = null; + private Clr _successDarken = null; + private Clr _successLighten = null; + private Clr _warningDarken = null; + private Clr _warningLighten = null; + private Clr _errorDarken = null; + private Clr _errorLighten = null; + private Clr _darkDarken = null; + private Clr _darkLighten = null; + + public virtual Clr Black { get; set; } = "#272c34"; + public Clr White { get; set; } = C.Shades.White; + public virtual Clr Primary { get; set; } = "#594AE2"; + public Clr PrimaryContrastText { get; set; } = C.Shades.White; + public Clr Secondary { get; set; } = C.Pink.Accent2; + public Clr SecondaryContrastText { get; set; } = C.Shades.White; + public Clr Tertiary { get; set; } = "#1EC8A5"; + public Clr TertiaryContrastText { get; set; } = C.Shades.White; + public virtual Clr Info { get; set; } = C.Blue.Default; + public Clr InfoContrastText { get; set; } = C.Shades.White; + public virtual Clr Success { get; set; } = C.Green.Accent4; + public Clr SuccessContrastText { get; set; } = C.Shades.White; + public virtual Clr Warning { get; set; } = C.Orange.Default; + public Clr WarningContrastText { get; set; } = C.Shades.White; + public virtual Clr Error { get; set; } = C.Red.Default; + public Clr ErrorContrastText { get; set; } = C.Shades.White; + public virtual Clr Dark { get; set; } = C.Grey.Darken3; + public Clr DarkContrastText { get; set; } = C.Shades.White; + public virtual Clr TextPrimary { get; set; } = C.Grey.Darken3; + public virtual Clr TextSecondary { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.54).ToString(ColorOutputFormats.RGBA); + public virtual Clr TextDisabled { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.38).ToString(ColorOutputFormats.RGBA); + public virtual Clr ActionDefault { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.54).ToString(ColorOutputFormats.RGBA); + public virtual Clr ActionDisabled { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.26).ToString(ColorOutputFormats.RGBA); + public virtual Clr ActionDisabledBackground { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.12).ToString(ColorOutputFormats.RGBA); + public virtual Clr Background { get; set; } = C.Shades.White; + public virtual Clr BackgroundGrey { get; set; } = C.Grey.Lighten4; + public virtual Clr Surface { get; set; } = C.Shades.White; + public virtual Clr DrawerBackground { get; set; } = C.Shades.White; + public virtual Clr DrawerText { get; set; } = C.Grey.Darken3; + public virtual Clr DrawerIcon { get; set; } = C.Grey.Darken2; + public virtual Clr AppbarBackground { get; set; } = "#594AE2"; + public virtual Clr AppbarText { get; set; } = C.Shades.White; + public virtual Clr LinesDefault { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.12).ToString(ColorOutputFormats.RGBA); + public virtual Clr LinesInputs { get; set; } = C.Grey.Lighten1; + public virtual Clr TableLines { get; set; } = new Clr(C.Grey.Lighten2).SetAlpha(1.0).ToString(ColorOutputFormats.RGBA); + public virtual Clr TableStriped { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.02).ToString(ColorOutputFormats.RGBA); + public Clr TableHover { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.04).ToString(ColorOutputFormats.RGBA); + public virtual Clr Divider { get; set; } = C.Grey.Lighten2; + public virtual Clr DividerLight { get; set; } = new Clr(C.Shades.Black).SetAlpha(0.8).ToString(ColorOutputFormats.RGBA); + + public string PrimaryDarken + { + get => (_primaryDarken ??= Primary.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _primaryDarken = value; + } + public string PrimaryLighten + { + get => (_primaryLighten ??= Primary.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _primaryLighten = value; + } + public string SecondaryDarken + { + get => (_secondaryDarken ??= Secondary.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _secondaryDarken = value; + } + public string SecondaryLighten + { + get => (_secondaryLighten ??= Secondary.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _secondaryLighten = value; + } + public string TertiaryDarken + { + get => (_tertiaryDarken ??= Tertiary.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _tertiaryDarken = value; + } + public string TertiaryLighten + { + get => (_tertiaryLighten ??= Tertiary.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _tertiaryLighten = value; + } + public string InfoDarken + { + get => (_infoDarken ??= Info.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _infoDarken = value; + } + public string InfoLighten + { + get => (_infoLighten ??= Info.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _infoLighten = value; + } + public string SuccessDarken + { + get => (_successDarken ??= Success.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _successDarken = value; + } + public string SuccessLighten + { + get => (_successLighten ??= Success.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _successLighten = value; + } + public string WarningDarken + { + get => (_warningDarken ??= Warning.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _warningDarken = value; + } + public string WarningLighten + { + get => (_warningLighten ??= Warning.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _warningLighten = value; + } + public string ErrorDarken + { + get => (_errorDarken ??= Error.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _errorDarken = value; + } + public string ErrorLighten + { + get => (_errorLighten ??= Error.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _errorLighten = value; + } + public string DarkDarken + { + get => (_darkDarken ??= Dark.ColorRgbDarken()).ToString(ColorOutputFormats.RGB); + set => _darkDarken = value; + } + public string DarkLighten + { + get => (_darkLighten ??= Dark.ColorRgbLighten()).ToString(ColorOutputFormats.RGB); + set => _darkLighten = value; + } + + public double HoverOpacity { get; set; } = 0.06; + + public string GrayDefault { get; set; } = C.Grey.Default; + public string GrayLight { get; set; } = C.Grey.Lighten1; + public string GrayLighter { get; set; } = C.Grey.Lighten2; + public string GrayDark { get; set; } = C.Grey.Darken1; + public string GrayDarker { get; set; } = C.Grey.Darken2; + + public string OverlayDark { get; set; } = new Clr("#212121").SetAlpha(0.5).ToString(ColorOutputFormats.RGBA); + public string OverlayLight { get; set; } = new Clr(C.Shades.White).SetAlpha(0.5).ToString(ColorOutputFormats.RGBA); +} diff --git a/Themes/Models/PaletteDark.cs b/Themes/Models/PaletteDark.cs new file mode 100644 index 0000000..823d645 --- /dev/null +++ b/Themes/Models/PaletteDark.cs @@ -0,0 +1,34 @@ +using Connected.Utilities; + +namespace Connected; + +public class PaletteDark : Palette +{ + public override Color Black { get; set; } = "#27272f"; + public override Color Primary { get; set; } = "#776be7"; + public override Color Info { get; set; } = "#3299ff"; + public override Color Success { get; set; } = "#0bba83"; + public override Color Warning { get; set; } = "#ffa800"; + public override Color Error { get; set; } = "#f64e62"; + public override Color Dark { get; set; } = "#27272f"; + public override Color TextPrimary { get; set; } = "rgba(255,255,255, 0.70)"; + public override Color TextSecondary { get; set; } = "rgba(255,255,255, 0.50)"; + public override Color TextDisabled { get; set; } = "rgba(255,255,255, 0.2)"; + public override Color ActionDefault { get; set; } = "#adadb1"; + public override Color ActionDisabled { get; set; } = "rgba(255,255,255, 0.26)"; + public override Color ActionDisabledBackground { get; set; } = "rgba(255,255,255, 0.12)"; + public override Color Background { get; set; } = "#32333d"; + public override Color BackgroundGrey { get; set; } = "#27272f"; + public override Color Surface { get; set; } = "#373740"; + public override Color DrawerBackground { get; set; } = "#27272f"; + public override Color DrawerText { get; set; } = "rgba(255,255,255, 0.50)"; + public override Color DrawerIcon { get; set; } = "rgba(255,255,255, 0.50)"; + public override Color AppbarBackground { get; set; } = "#27272f"; + public override Color AppbarText { get; set; } = "rgba(255,255,255, 0.70)"; + public override Color LinesDefault { get; set; } = "rgba(255,255,255, 0.12)"; + public override Color LinesInputs { get; set; } = "rgba(255,255,255, 0.3)"; + public override Color TableLines { get; set; } = "rgba(255,255,255, 0.12)"; + public override Color TableStriped { get; set; } = "rgba(255,255,255, 0.2)"; + public override Color Divider { get; set; } = "rgba(255,255,255, 0.12)"; + public override Color DividerLight { get; set; } = "rgba(255,255,255, 0.06)"; +} diff --git a/Themes/Models/Shadow.cs b/Themes/Models/Shadow.cs new file mode 100644 index 0000000..5967b28 --- /dev/null +++ b/Themes/Models/Shadow.cs @@ -0,0 +1,36 @@ + +namespace Connected +{ + public class Shadow + { + public string[] Elevation { get; set; } = + { + "none", + "0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)", + "0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)", + "0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)", + "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)", + "0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)", + "0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)", + "0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)", + "0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)", + "0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)", + "0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)", + "0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)", + "0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)", + "0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)", + "0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)", + "0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)", + "0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)", + "0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)", + "0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)", + "0 5px 5px -3px rgba(0,0,0,.06), 0 8px 10px 1px rgba(0,0,0,.042), 0 3px 14px 2px rgba(0,0,0,.036)" + }; + } +} diff --git a/Themes/Models/Typography.cs b/Themes/Models/Typography.cs new file mode 100644 index 0000000..f26d189 --- /dev/null +++ b/Themes/Models/Typography.cs @@ -0,0 +1,174 @@ + +namespace Connected +{ + public class Typography + { + public Default Default { get; set; } = new Default(); + public H1 H1 { get; set; } = new H1(); + public H2 H2 { get; set; } = new H2(); + public H3 H3 { get; set; } = new H3(); + public H4 H4 { get; set; } = new H4(); + public H5 H5 { get; set; } = new H5(); + public H6 H6 { get; set; } = new H6(); + public Subtitle1 Subtitle1 { get; set; } = new Subtitle1(); + public Subtitle2 Subtitle2 { get; set; } = new Subtitle2(); + public Body1 Body1 { get; set; } = new Body1(); + public Body2 Body2 { get; set; } = new Body2(); + public Button Button { get; set; } = new Button(); + public Caption Caption { get; set; } = new Caption(); + public Overline Overline { get; set; } = new Overline(); + } + + public class Default : BaseTypography + { + public Default() + { + FontFamily = new[] { "Roboto", "Helvetica", "Arial", "sans-serif" }; + FontSize = ".875rem"; + FontWeight = 400; + LineHeight = 1.43; + LetterSpacing = ".01071em"; + } + } + public class H1 : BaseTypography + { + public H1() + { + FontSize = "6rem"; + FontWeight = 300; + LineHeight = 1.167; + LetterSpacing = "-.01562em"; + } + } + public class H2 : BaseTypography + { + public H2() + { + FontSize = "3.75rem"; + FontWeight = 300; + LineHeight = 1.2; + LetterSpacing = "-.00833em"; + } + } + public class H3 : BaseTypography + { + public H3() + { + FontSize = "3rem"; + FontWeight = 400; + LineHeight = 1.167; + LetterSpacing = "0"; + } + } + public class H4 : BaseTypography + { + public H4() + { + FontSize = "2.125rem"; + FontWeight = 400; + LineHeight = 1.235; + LetterSpacing = ".00735em"; + } + } + public class H5 : BaseTypography + { + public H5() + { + FontSize = "1.5rem"; + FontWeight = 400; + LineHeight = 1.334; + LetterSpacing = "0"; + } + } + public class H6 : BaseTypography + { + public H6() + { + FontSize = "1.25rem"; + FontWeight = 500; + LineHeight = 1.6; + LetterSpacing = ".0075em"; + } + } + public class Subtitle1 : BaseTypography + { + public Subtitle1() + { + FontSize = "1rem"; + FontWeight = 400; + LineHeight = 1.75; + LetterSpacing = ".00938em"; + } + } + public class Subtitle2 : BaseTypography + { + public Subtitle2() + { + FontSize = ".875rem"; + FontWeight = 500; + LineHeight = 1.57; + LetterSpacing = ".00714em"; + } + } + public class Body1 : BaseTypography + { + public Body1() + { + FontSize = "1rem"; + FontWeight = 400; + LineHeight = 1.5; + LetterSpacing = ".00938em"; + } + } + public class Body2 : BaseTypography + { + public Body2() + { + FontSize = ".875rem"; + FontWeight = 400; + LineHeight = 1.43; + LetterSpacing = ".01071em"; + } + } + public class Button : BaseTypography + { + public Button() + { + FontSize = ".875rem"; + FontWeight = 500; + LineHeight = 1.75; + LetterSpacing = ".02857em"; + TextTransform = "uppercase"; + } + } + public class Caption : BaseTypography + { + public Caption() + { + FontSize = ".75rem"; + FontWeight = 400; + LineHeight = 1.66; + LetterSpacing = ".03333em"; + } + } + public class Overline : BaseTypography + { + public Overline() + { + FontSize = ".75rem"; + FontWeight = 400; + LineHeight = 2.66; + LetterSpacing = ".08333em"; + } + } + + public class BaseTypography + { + public string[] FontFamily { get; set; } + public int FontWeight { get; set; } + public string FontSize { get; set; } + public double LineHeight { get; set; } + public string LetterSpacing { get; set; } + public string TextTransform { get; set; } = "none"; + } +} diff --git a/Themes/Models/Z-Index.cs b/Themes/Models/Z-Index.cs new file mode 100644 index 0000000..c073234 --- /dev/null +++ b/Themes/Models/Z-Index.cs @@ -0,0 +1,13 @@ + +namespace Connected +{ + public class ZIndex + { + public int Drawer { get; set; } = 1100; + public int Popover { get; set; } = 1200; + public int AppBar { get; set; } = 1300; + public int Dialog { get; set; } = 1400; + public int Snackbar { get; set; } = 1500; + public int Tooltip { get; set; } = 1600; + } +} diff --git a/Themes/Theme.cs b/Themes/Theme.cs new file mode 100644 index 0000000..632a764 --- /dev/null +++ b/Themes/Theme.cs @@ -0,0 +1,23 @@ +namespace Connected +{ + public class Theme + { + //public Breakpoints Breakpoints { get; set; } + public Palette Palette { get; set; } + public Palette PaletteDark { get; set; } + public Shadow Shadows { get; set; } + public Typography Typography { get; set; } + public LayoutProperties LayoutProperties { get; set; } + public ZIndex ZIndex { get; set; } + + public Theme() + { + Palette = new Palette(); + PaletteDark = new PaletteDark(); + Shadows = new Shadow(); + Typography = new Typography(); + LayoutProperties = new LayoutProperties(); + ZIndex = new ZIndex(); + } + } +} diff --git a/Utilities/ActivatableCallback.cs b/Utilities/ActivatableCallback.cs new file mode 100644 index 0000000..facf666 --- /dev/null +++ b/Utilities/ActivatableCallback.cs @@ -0,0 +1,15 @@ +using Connected.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Connected +{ + public class ActivatableCallback : IActivatable + { + public Action ActivateCallback { get; set; } + + public void Activate(object sender, MouseEventArgs args) + { + ActivateCallback?.Invoke(sender, args); + } + } +} diff --git a/Utilities/BindingConverters/BoolConverter.cs b/Utilities/BindingConverters/BoolConverter.cs new file mode 100644 index 0000000..6294d2f --- /dev/null +++ b/Utilities/BindingConverters/BoolConverter.cs @@ -0,0 +1,84 @@ +using System; + +namespace Connected +{ + + /// + /// A universal T to bool? binding converter + /// + public class BoolConverter : Converter + { + + public BoolConverter() + { + SetFunc = OnSet; + GetFunc = OnGet; + } + + private T OnGet(bool? value) + { + try + { + if (typeof(T) == typeof(bool)) + return (T)(object)(value == true); + else if (typeof(T) == typeof(bool?)) + return (T)(object)value; + else if (typeof(T) == typeof(string)) + return (T)(object)(value == true ? "on" : (value == false ? "off" : null)); + else if (typeof(T) == typeof(int)) + return (T)(object)(value == true ? 1 : 0); + else if (typeof(T) == typeof(int?)) + return (T)(object)(value == true ? 1 : (value == false ? (int?)0 : null)); + else + { + UpdateGetError($"Conversion to type {typeof(T)} not implemented"); + } + } + catch (Exception e) + { + UpdateGetError("Conversion error: " + e.Message); + return default(T); + } + return default(T); + } + + private bool? OnSet(T arg) + { + if (arg == null) + return null; // <-- this catches all nullable values which are null. no nullchecks necessary below! + try + { + if (arg is bool) + return (bool)(object)arg; + else if (arg is bool?) + return (bool?)(object)arg; + else if (arg is int) + return ((int)(object)arg) > 0; + else if (arg is string) + { + var s = (string)(object)arg; + if (string.IsNullOrWhiteSpace(s)) + return null; + if (bool.TryParse(s, out var b)) + return b; + if (s.ToLowerInvariant() == "on") + return true; + if (s.ToLowerInvariant() == "off") + return false; + return null; + } + else + { + UpdateSetError("Unable to convert to bool? from type " + typeof(T).Name); + return null; + } + } + catch (FormatException e) + { + UpdateSetError("Conversion error: " + e.Message); + return null; + } + } + + } +} diff --git a/Utilities/BindingConverters/Converter.cs b/Utilities/BindingConverters/Converter.cs new file mode 100644 index 0000000..6610817 --- /dev/null +++ b/Utilities/BindingConverters/Converter.cs @@ -0,0 +1,88 @@ +using System; +using System.Globalization; + +namespace Connected +{ + public class Converter + { + public Func SetFunc { get; set; } + public Func GetFunc { get; set; } + + /// + /// The culture info being used for decimal points, date and time format, etc. + /// + public CultureInfo Culture { get; set; } = Converters.DefaultCulture; + + public Action OnError { get; set; } + public bool SetError { get; set; } + public bool GetError { get; set; } + public string SetErrorMessage { get; set; } + public string GetErrorMessage { get; set; } + + public U Set(T value) + { + SetError = false; + SetErrorMessage = null; + if (SetFunc == null) + return default(U); + try + { + return SetFunc(value); + } + catch (Exception e) + { + SetError = true; + SetErrorMessage = $"Conversion from {typeof(T).Name} to {typeof(U).Name} failed: {e.Message}"; + } + return default(U); + } + + public T Get(U value) + { + GetError = false; + GetErrorMessage = null; + if (GetFunc == null) + return default(T); + try + { + return GetFunc(value); + } + catch (Exception e) + { + GetError = true; + GetErrorMessage = $"Conversion from {typeof(U).Name} to {typeof(T).Name} failed: {e.Message}"; + } + return default(T); + } + + protected void UpdateSetError(string msg) + { + SetError = true; + SetErrorMessage = msg; + OnError?.Invoke(msg); + } + + protected void UpdateGetError(string msg) + { + GetError = true; + GetErrorMessage = msg; + OnError?.Invoke(msg); + } + } + + /// + /// Converter from T to string + /// + /// Set converts to string + /// Get converts from string + /// + public class Converter : Converter + { + + /// + /// Custom Format to be applied on bidirectional way. + /// + public string Format { get; set; } = null; + + } +} diff --git a/Utilities/BindingConverters/Converters.cs b/Utilities/BindingConverters/Converters.cs new file mode 100644 index 0000000..505e242 --- /dev/null +++ b/Utilities/BindingConverters/Converters.cs @@ -0,0 +1,55 @@ +using System.Globalization; + +namespace Connected +{ + public static class Converters + { + public static CultureInfo DefaultCulture = CultureInfo.CurrentUICulture; + + #region --> Date converters + public static Converter IsoDate + => new() + { SetFunc = SetIsoDate, GetFunc = GetIsoDate }; + + private static DateTime GetIsoDate(string value) + { + if (DateTime.TryParse(value, out var dateTime)) + return dateTime; + return DateTime.MinValue; + } + + private static string SetIsoDate(DateTime value) + { + return value.ToIsoDateString(); + } + + public static Converter NullableIsoDate + => new() + { SetFunc = SetNullableIsoDate, GetFunc = GetNullableIsoDate }; + + private static DateTime? GetNullableIsoDate(string value) + { + if (DateTime.TryParse(value, out var dateTime)) + return dateTime; + return null; + } + + private static string SetNullableIsoDate(DateTime? value) + { + return value.ToIsoDateString(); + } + + public static DateConverter DateFormat(string format) + { + format ??= "yyyy-MM-dd"; + return new DateConverter(format); + } + + public static DateConverter DateFormat(string format, CultureInfo culture) + { + return new DateConverter(format) { Culture = culture }; + } + + #endregion + } +} diff --git a/Utilities/BindingConverters/DateConverter.cs b/Utilities/BindingConverters/DateConverter.cs new file mode 100644 index 0000000..5712ba1 --- /dev/null +++ b/Utilities/BindingConverters/DateConverter.cs @@ -0,0 +1,90 @@ +using System; + +namespace Connected +{ + + /// + /// A ready made DateTime? to string binding converter with configurable date format and culture + /// + public class NullableDateConverter : Converter + { + public string DateFormat { get; set; } + + public NullableDateConverter(string format = "yyyy-MM-dd") + { + DateFormat = format; + SetFunc = OnSet; + GetFunc = OnGet; + } + + private DateTime? OnGet(string arg) + { + try + { + return DateTime.ParseExact(arg, DateFormat, Culture); + } + catch (FormatException e) + { + UpdateGetError(e.Message); + return null; + } + } + + private string OnSet(DateTime? arg) + { + if (arg == null) + return null; + try + { + return arg.Value.ToString(DateFormat, Culture); + } + catch (FormatException e) + { + UpdateSetError(e.Message); + return null; + } + } + } + + /// + /// A ready made DateTime to string binding converter with configurable date format and culture + /// + public class DateConverter : Converter + { + public string DateFormat { get; set; } = "yyyy-MM-dd"; + + public DateConverter(string format) + { + DateFormat = format; + SetFunc = OnSet; + GetFunc = OnGet; + } + + private DateTime OnGet(string arg) + { + try + { + return DateTime.ParseExact(arg, DateFormat, Culture); + } + catch (FormatException e) + { + UpdateGetError(e.Message); + return default; + } + } + + private string OnSet(DateTime arg) + { + try + { + return arg.ToString(DateFormat, Culture); + } + catch (FormatException e) + { + UpdateSetError(e.Message); + return null; + } + } + } + +} diff --git a/Utilities/BindingConverters/DefaultConverter.cs b/Utilities/BindingConverters/DefaultConverter.cs new file mode 100644 index 0000000..09f7173 --- /dev/null +++ b/Utilities/BindingConverters/DefaultConverter.cs @@ -0,0 +1,315 @@ +using System; +using System.Globalization; + +namespace Connected +{ + + /// + /// A universal T to string binding converter + /// + public class DefaultConverter : Converter + { + + public DefaultConverter() + { + SetFunc = ConvertToString; + GetFunc = ConvertFromString; + } + + public string DefaultTimeSpanFormat { get; set; } = "c"; + + protected virtual T ConvertFromString(string value) + { + try + { + // string + if (typeof(T) == typeof(string)) + return (T)(object)value; + + // this is important, or otherwise all the TryParse down there might fail. + if (string.IsNullOrEmpty(value)) + return default(T); + // char + else if (typeof(T) == typeof(char) || typeof(T) == typeof(char?)) + { + return (T)(object)value[0]; + } + // bool + else if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?)) + { + var lowerValue = value.ToLowerInvariant(); + if (lowerValue is "true" or "on") + return (T)(object)true; + if (lowerValue is "false" or "off") + return (T)(object)false; + UpdateGetError("Not a valid boolean"); + } + // sbyte + else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) + { + if (sbyte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // byte + else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) + { + if (byte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // short + else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) + { + if (short.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // ushort + else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) + { + if (ushort.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // int + else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) + { + if (int.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // uint + else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) + { + if (uint.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // long + else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) + { + if (long.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // ulong + else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) + { + if (ulong.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // float + else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) + { + if (float.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // double + else if (typeof(T) == typeof(double) || typeof(T) == typeof(double?)) + { + if (double.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // decimal + else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) + { + if (decimal.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid number"); + } + // guid + else if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?)) + { + if (Guid.TryParse(value, out var parsedValue)) + return (T)(object)parsedValue; + UpdateGetError("Not a valid GUID"); + } + // enum + else if (IsNullableEnum(typeof(T))) + { + var enum_type = Nullable.GetUnderlyingType(typeof(T)); + if (Enum.TryParse(enum_type, value, out var parsedValue)) + return (T)parsedValue; + UpdateGetError("Not a value of " + enum_type.Name); + } + else if (typeof(T).IsEnum) + { + if (Enum.TryParse(typeof(T), value, out var parsedValue)) + return (T)parsedValue; + UpdateGetError("Not a value of " + typeof(T).Name); + } + // datetime + else if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?)) + { + try + { + return (T)(object)DateTime.ParseExact(value, Format ?? Culture.DateTimeFormat.ShortDatePattern, Culture); + } + catch (FormatException) + { + UpdateGetError("Not a valid date time"); + } + } + // timespan + else if (typeof(T) == typeof(TimeSpan) || typeof(T) == typeof(TimeSpan?)) + { + try + { + return (T)(object)TimeSpan.ParseExact(value, Format ?? DefaultTimeSpanFormat, Culture); + } + catch (FormatException) + { + UpdateGetError("Not a valid time span"); + } + } + else + { + UpdateGetError($"Conversion to type {typeof(T)} not implemented"); + } + } + catch (Exception e) + { + UpdateGetError("Conversion error: " + e.Message); + } + + return default(T); + } + + protected virtual string ConvertToString(T arg) + { + if (arg == null) + return null; // <-- this catches all nullable values which are null. no nullchecks necessary below! + try + { + // string + if (typeof(T) == typeof(string)) + return (string)(object)arg; + // char + if (typeof(T) == typeof(char)) + return ((char)(object)arg).ToString(Culture); + if (typeof(T) == typeof(char?)) + return ((char?)(object)arg).Value.ToString(Culture); + // bool + if (typeof(T) == typeof(bool)) + return ((bool)(object)arg).ToString(CultureInfo.InvariantCulture); + if (typeof(T) == typeof(bool?)) + return ((bool?)(object)arg).Value.ToString(CultureInfo.InvariantCulture); + // sbyte + if (typeof(T) == typeof(sbyte)) + return ((sbyte)(object)arg).ToString(Format, Culture); + if (typeof(T) == typeof(sbyte?)) + return ((sbyte?)(object)arg).Value.ToString(Format, Culture); + // byte + if (typeof(T) == typeof(byte)) + return ((byte)(object)arg).ToString(Format, Culture); + if (typeof(T) == typeof(byte?)) + return ((byte?)(object)arg).Value.ToString(Format, Culture); + // short + if (typeof(T) == typeof(short)) + return ((short)(object)arg).ToString(Format, Culture); + if (typeof(T) == typeof(short?)) + return ((short?)(object)arg).Value.ToString(Format, Culture); + // ushort + if (typeof(T) == typeof(ushort)) + return ((ushort)(object)arg).ToString(Format, Culture); + if (typeof(T) == typeof(ushort?)) + return ((ushort?)(object)arg).Value.ToString(Format, Culture); + // int + else if (typeof(T) == typeof(int)) + return ((int)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(int?)) + return ((int?)(object)arg).Value.ToString(Format, Culture); + // uint + else if (typeof(T) == typeof(uint)) + return ((uint)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(uint?)) + return ((uint?)(object)arg).Value.ToString(Format, Culture); + // long + else if (typeof(T) == typeof(long)) + return ((long)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(long?)) + return ((long?)(object)arg).Value.ToString(Format, Culture); + // ulong + else if (typeof(T) == typeof(ulong)) + return ((ulong)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(ulong?)) + return ((ulong?)(object)arg).Value.ToString(Format, Culture); + // float + else if (typeof(T) == typeof(float)) + return ((float)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(float?)) + return ((float?)(object)arg).Value.ToString(Format, Culture); + // double + else if (typeof(T) == typeof(double)) + return ((double)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(double?)) + return ((double?)(object)arg).Value.ToString(Format, Culture); + // decimal + else if (typeof(T) == typeof(decimal)) + return ((decimal)(object)arg).ToString(Format, Culture); + else if (typeof(T) == typeof(decimal?)) + return ((decimal?)(object)arg).Value.ToString(Format, Culture); + // guid + else if (typeof(T) == typeof(Guid)) + { + var value = (Guid)(object)arg; + return value.ToString(); + } + else if (typeof(T) == typeof(Guid?)) + { + var value = (Guid?)(object)arg; + return value.Value.ToString(); + } + // enum + else if (IsNullableEnum(typeof(T))) + { + var value = (Enum)(object)arg; + return value.ToString(); + } + else if (typeof(T).IsEnum) + { + var value = (Enum)(object)arg; + return value.ToString(); + } + // datetime + else if (typeof(T) == typeof(DateTime)) + { + var value = (DateTime)(object)arg; + return value.ToString(Format ?? Culture.DateTimeFormat.ShortDatePattern, Culture); + } + else if (typeof(T) == typeof(DateTime?)) + { + var value = (DateTime?)(object)arg; + return value.Value.ToString(Format ?? Culture.DateTimeFormat.ShortDatePattern, Culture); + } + // timespan + else if (typeof(T) == typeof(TimeSpan)) + { + var value = (TimeSpan)(object)arg; + return value.ToString(Format ?? DefaultTimeSpanFormat, Culture); + } + else if (typeof(T) == typeof(TimeSpan?)) + { + var value = (TimeSpan?)(object)arg; + return value.Value.ToString(Format ?? DefaultTimeSpanFormat, Culture); + } + return arg.ToString(); + } + catch (FormatException e) + { + UpdateSetError("Conversion error: " + e.Message); + return null; + } + } + + public static bool IsNullableEnum(Type t) + { + var u = Nullable.GetUnderlyingType(t); + return (u != null) && u.IsEnum; + } + } +} diff --git a/Utilities/BindingConverters/NumericConverter.cs b/Utilities/BindingConverters/NumericConverter.cs new file mode 100644 index 0000000..9db5016 --- /dev/null +++ b/Utilities/BindingConverters/NumericConverter.cs @@ -0,0 +1,285 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +namespace Connected +{ + + /// + /// A universal T to double binding converter + /// + /// Note: currently not in use. Should we ever use it, remove + /// the [ExcludeFromCodeCoverage] attribute + /// + [ExcludeFromCodeCoverage] + public class NumericConverter : Converter + { + + public NumericConverter() + { + SetFunc = OnSet; + GetFunc = OnGet; + } + + private T OnGet(double value) + { + try + { + // double + if (typeof(T) == typeof(double) || typeof(T) == typeof(double?)) + return (T)(object)value; + // string + else if (typeof(T) == typeof(string)) + return (T)(object)value.ToString(Culture); + // sbyte + else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) + return (T)(object)Convert.ToSByte(value); + // byte + else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) + return (T)(object)Convert.ToByte(value); + // short + else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) + return (T)(object)Convert.ToInt16(value); + // ushort + else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) + return (T)(object)Convert.ToUInt16(value); + // int + else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) + return (T)(object)Convert.ToInt32(value); + // uint + else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) + return (T)(object)Convert.ToUInt32(value); + // long + else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) + return (T)(object)Convert.ToInt64(value); + // ulong + else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) + return (T)(object)Convert.ToUInt64(value); + // float + else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) + return (T)(object)Convert.ToSingle(value); + // decimal + else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) + return (T)(object)Convert.ToDecimal(value); + else + { + UpdateGetError($"Conversion to type {typeof(T)} not implemented"); + } + } + catch (Exception e) + { + UpdateGetError("Conversion error: " + e.Message); + return default(T); + } + return default(T); + } + + private double OnSet(T arg) + { + if (arg == null) + return double.NaN; // <-- this catches all nullable values which are null. no nullchecks necessary below! + try + { + // double + if (typeof(T) == typeof(double)) + return (double)(object)arg; + else if (typeof(T) == typeof(double?)) + return ((double?)(object)arg).Value; + // string + if (typeof(T) == typeof(string)) + return double.Parse((string)(object)arg, NumberStyles.Any, Culture); + // sbyte + if (typeof(T) == typeof(sbyte)) + return Convert.ToDouble((sbyte)(object)arg); + if (typeof(T) == typeof(sbyte?)) + return Convert.ToDouble(((sbyte?)(object)arg).Value); + // byte + if (typeof(T) == typeof(byte)) + return Convert.ToDouble((byte)(object)arg); + if (typeof(T) == typeof(byte?)) + return Convert.ToDouble(((byte?)(object)arg).Value); + // short + if (typeof(T) == typeof(short)) + return Convert.ToDouble((short)(object)arg); + if (typeof(T) == typeof(short?)) + return Convert.ToDouble(((short?)(object)arg).Value); + // ushort + if (typeof(T) == typeof(ushort)) + return Convert.ToDouble((ushort)(object)arg); + if (typeof(T) == typeof(ushort?)) + return Convert.ToDouble(((ushort?)(object)arg).Value); + // int + else if (typeof(T) == typeof(int)) + return Convert.ToDouble((int)(object)arg); + else if (typeof(T) == typeof(int?)) + return Convert.ToDouble(((int?)(object)arg).Value); + // uint + else if (typeof(T) == typeof(uint)) + return Convert.ToDouble((uint)(object)arg); + else if (typeof(T) == typeof(uint?)) + return Convert.ToDouble(((uint?)(object)arg).Value); + // long + else if (typeof(T) == typeof(long)) + return Convert.ToDouble((long)(object)arg); + else if (typeof(T) == typeof(long?)) + return Convert.ToDouble(((long?)(object)arg).Value); + // ulong + else if (typeof(T) == typeof(ulong)) + return Convert.ToDouble((ulong)(object)arg); + else if (typeof(T) == typeof(ulong?)) + return Convert.ToDouble(((ulong?)(object)arg).Value); + // float + else if (typeof(T) == typeof(float)) + return Convert.ToDouble((float)(object)arg); + else if (typeof(T) == typeof(float?)) + return Convert.ToDouble(((float?)(object)arg).Value); + // decimal + else if (typeof(T) == typeof(decimal)) + return Convert.ToDouble((decimal)(object)arg); + else if (typeof(T) == typeof(decimal?)) + return Convert.ToDouble(((decimal?)(object)arg).Value); + else + { + UpdateSetError("Unable to convert to double from type " + typeof(T).Name); + return double.NaN; + } + } + catch (FormatException e) + { + UpdateSetError("Conversion error: " + e.Message); + return double.NaN; + } + } + + + #region --> Floating Point comparison + + const double MinNormal = 2.2250738585072014E-308d; + + public static bool AreEqual(double a, double b, double epsilon = MinNormal) + { + // Copyright (c) Michael Borgwardt + var absA = Math.Abs(a); + var absB = Math.Abs(b); + var diff = Math.Abs(a - b); + + if (a.Equals(b)) + { // shortcut, handles infinities + return true; + } + else if (a == 0 || b == 0 || absA + absB < MinNormal) + { + // a or b is zero or both are extremely close to it + // relative error is less meaningful here + return diff < (epsilon * MinNormal); + } + else + { // use relative error + return diff / (absA + absB) < epsilon; + } + } + + #endregion + } + + [ExcludeFromCodeCoverage] + internal static class Num + { + public static T To(double d) + { + if (typeof(T) == typeof(sbyte) && d >= sbyte.MinValue && sbyte.MaxValue >= d) + return (T)(object)Convert.ToSByte(d); + if (typeof(T) == typeof(byte) && d >= byte.MinValue && byte.MaxValue >= d) + return (T)(object)Convert.ToByte(d); + if (typeof(T) == typeof(short) && d >= short.MinValue && short.MaxValue >= d) + return (T)(object)Convert.ToInt16(d); + if (typeof(T) == typeof(ushort) && d >= ushort.MinValue && ushort.MaxValue >= d) + return (T)(object)Convert.ToUInt16(d); + if (typeof(T) == typeof(int) && d >= int.MinValue && int.MaxValue >= d) + return (T)(object)Convert.ToInt32(d); + if (typeof(T) == typeof(uint) && d >= uint.MinValue && uint.MaxValue >= d) + return (T)(object)Convert.ToUInt32(d); + if (typeof(T) == typeof(long) && d >= long.MinValue && long.MaxValue >= d) + return (T)(object)Convert.ToInt64(d); + if (typeof(T) == typeof(ulong) && d >= ulong.MinValue && ulong.MaxValue >= d) + return (T)(object)Convert.ToUInt64(d); + if (typeof(T) == typeof(float) && d >= float.MinValue && float.MaxValue >= d) + return (T)(object)Convert.ToSingle(d); + if (typeof(T) == typeof(double) && d >= double.MinValue && double.MaxValue >= d) + return (T)(object)Convert.ToDouble(d); + if (typeof(T) == typeof(decimal) && (decimal)d >= decimal.MinValue && decimal.MaxValue >= (decimal)d) + return (T)(object)Convert.ToDecimal(d); + if (typeof(T) == typeof(sbyte?) && d >= sbyte.MinValue && sbyte.MaxValue >= d) + return (T)(object)Convert.ToSByte(d); + if (typeof(T) == typeof(byte?) && d >= byte.MinValue && byte.MaxValue >= d) + return (T)(object)Convert.ToByte(d); + if (typeof(T) == typeof(short?) && d >= short.MinValue && short.MaxValue >= d) + return (T)(object)Convert.ToInt16(d); + if (typeof(T) == typeof(ushort?) && d >= ushort.MinValue && ushort.MaxValue >= d) + return (T)(object)Convert.ToUInt16(d); + if (typeof(T) == typeof(int?) && d >= int.MinValue && int.MaxValue >= d) + return (T)(object)Convert.ToInt32(d); + if (typeof(T) == typeof(uint?) && d >= uint.MinValue && uint.MaxValue >= d) + return (T)(object)Convert.ToUInt32(d); + if (typeof(T) == typeof(long?) && d >= long.MinValue && long.MaxValue >= d) + return (T)(object)Convert.ToInt64(d); + if (typeof(T) == typeof(ulong?) && d >= ulong.MinValue && ulong.MaxValue >= d) + return (T)(object)Convert.ToUInt64(d); + if (typeof(T) == typeof(float?) && d >= float.MinValue && float.MaxValue >= d) + return (T)(object)Convert.ToSingle(d); + if (typeof(T) == typeof(double?) && d >= double.MinValue && double.MaxValue >= d) + return (T)(object)Convert.ToDouble(d); + if (typeof(T) == typeof(decimal?) && (decimal)d >= decimal.MinValue && decimal.MaxValue >= (decimal)d) + return (T)(object)Convert.ToDecimal(d); + return default; + } + public static double From(T v) + { + if (typeof(T) == typeof(sbyte)) + return Convert.ToDouble((sbyte)(object)v); + if (typeof(T) == typeof(byte)) + return Convert.ToDouble((byte)(object)v); + if (typeof(T) == typeof(short)) + return Convert.ToDouble((short)(object)v); + if (typeof(T) == typeof(ushort)) + return Convert.ToDouble((ushort)(object)v); + if (typeof(T) == typeof(int)) + return Convert.ToDouble((int)(object)v); + if (typeof(T) == typeof(uint)) + return Convert.ToDouble((uint)(object)v); + if (typeof(T) == typeof(long)) + return Convert.ToDouble((long)(object)v); + if (typeof(T) == typeof(ulong)) + return Convert.ToDouble((ulong)(object)v); + if (typeof(T) == typeof(float)) + return Convert.ToDouble((float)(object)v); + if (typeof(T) == typeof(double)) + return Convert.ToDouble((double)(object)v); + if (typeof(T) == typeof(decimal)) + return Convert.ToDouble((decimal)(object)v); + if (typeof(T) == typeof(sbyte?)) + return Convert.ToDouble((sbyte?)(object)v); + if (typeof(T) == typeof(byte?)) + return Convert.ToDouble((byte?)(object)v); + if (typeof(T) == typeof(short?)) + return Convert.ToDouble((short?)(object)v); + if (typeof(T) == typeof(ushort?)) + return Convert.ToDouble((ushort?)(object)v); + if (typeof(T) == typeof(int?)) + return Convert.ToDouble((int?)(object)v); + if (typeof(T) == typeof(uint?)) + return Convert.ToDouble((uint?)(object)v); + if (typeof(T) == typeof(long?)) + return Convert.ToDouble((long?)(object)v); + if (typeof(T) == typeof(ulong?)) + return Convert.ToDouble((ulong?)(object)v); + if (typeof(T) == typeof(float?)) + return Convert.ToDouble((float?)(object)v); + if (typeof(T) == typeof(double?)) + return Convert.ToDouble((double?)(object)v); + if (typeof(T) == typeof(decimal?)) + return Convert.ToDouble((decimal?)(object)v); + return default; + } + } +} diff --git a/Utilities/BindingConverters/RangeConverter.cs b/Utilities/BindingConverters/RangeConverter.cs new file mode 100644 index 0000000..5fd067b --- /dev/null +++ b/Utilities/BindingConverters/RangeConverter.cs @@ -0,0 +1,61 @@ +namespace Connected +{ + public class RangeConverter : Converter> + { + readonly DefaultConverter _converter; + + public RangeConverter() + { + _converter = new DefaultConverter(); + + SetFunc = OnSet; + GetFunc = OnGet; + } + + private Components.Range OnGet(string value) + { + if (!Split(value, out var valueStart, out var valueEnd)) + return null; + + return new Components.Range(_converter.Get(valueStart), _converter.Get(valueEnd)); + } + + private string OnSet(Components.Range arg) + { + if (arg == null) + return string.Empty; + + return Join(_converter.Set(arg.Start), _converter.Set(arg.End)); + } + + public static string Join(string valueStart, string valueEnd) + { + if (string.IsNullOrEmpty(valueStart) && string.IsNullOrEmpty(valueEnd)) + return string.Empty; + + return $"[{valueStart};{valueEnd}]"; + } + + public static bool Split(string value, out string valueStart, out string valueEnd) + { + valueStart = valueEnd = string.Empty; + + if (string.IsNullOrEmpty(value) || value[0] != '[' || value[^1] != ']') + { + return false; + } + + var idx = value.IndexOf(';'); + + if (idx < 1) + { + return false; + } + + valueStart = value[1..idx]; + valueEnd = value[(idx + 1)..^1]; + + return true; + } + } +} diff --git a/Utilities/CodeMessage.cs b/Utilities/CodeMessage.cs new file mode 100644 index 0000000..9fdcda5 --- /dev/null +++ b/Utilities/CodeMessage.cs @@ -0,0 +1,10 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Connected.Utilities; + +internal class CodeMessage +{ + internal const string SerializationUnreferencedCodeMessage = "Serialization and deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved. If you sure that your type is preserved use UnconditionalSuppressMessage to ignore error."; +} diff --git a/Utilities/Color.cs b/Utilities/Color.cs new file mode 100644 index 0000000..a1cf147 --- /dev/null +++ b/Utilities/Color.cs @@ -0,0 +1,383 @@ +//// Copyright (c) Steven Coco +//// https://stackoverflow.com/questions/4087581/creating-a-c-sharp-color-from-hsl-values/4087601#4087601 +//// Stripped and adapted by Meinrad Recheis and Benjamin Kappel for MudBlazor + +using System.Globalization; +using Connected.Extensions; + +namespace Connected.Utilities; + +public enum ColorOutputFormats +{ + /// + /// Output will be starting with a # and include r,g and b but no alpha values. Example #ab2a3d + /// + Hex, + /// + /// Output will be starting with a # and include r,g and b and alpha values. Example #ab2a3dff + /// + HexA, + /// + /// Will output css like output for value. Example rgb(12,15,40) + /// + RGB, + /// + /// Will output css like output for value with alpha. Example rgba(12,15,40,0.42) + /// + RGBA, + /// + /// Will output the color elements without any decorator and without alpha. Example 12,15,26 + /// + ColorElements +} + +public class Color : IEquatable +{ + #region Fields and Properties + + private const double EPSILON = 0.000000000000001; + + private byte[] _valuesAsByte; + + public string Value => $"#{R:x2}{G:x2}{B:x2}{A:x2}"; + + public byte R => _valuesAsByte[0]; + public byte G => _valuesAsByte[1]; + public byte B => _valuesAsByte[2]; + public byte A => _valuesAsByte[3]; + public double APercentage => Math.Round((A / 255.0), 2); + + public double H { get; private set; } + public double L { get; private set; } + public double S { get; private set; } + + #endregion + + #region Constructor + + public Color(double h, double s, double l, double a) + : this(h, s, l, (int)((a * 255.0).EnsureRange(255))) + { + + } + + public Color(double h, double s, double l, int a) + { + _valuesAsByte = new byte[4]; + + h = Math.Round(h.EnsureRange(360), 0); + s = Math.Round(s.EnsureRange(1), 2); + l = Math.Round(l.EnsureRange(1), 2); + a = a.EnsureRange(255); + + // achromatic argb (gray scale) + if (Math.Abs(s) < EPSILON) + { + _valuesAsByte[0] = (byte)Math.Max(0, Math.Min(255, (int)Math.Ceiling(l * 255D))); + _valuesAsByte[1] = (byte)Math.Max(0, Math.Min(255, (int)Math.Ceiling(l * 255D))); + _valuesAsByte[2] = (byte)Math.Max(0, Math.Min(255, (int)Math.Ceiling(l * 255D))); + _valuesAsByte[3] = (byte)a; + } + else + { + + var q = l < .5D + ? l * (1D + s) + : (l + s) - (l * s); + var p = (2D * l) - q; + + var hk = h / 360D; + var T = new double[3]; + T[0] = hk + (1D / 3D); // Tr + T[1] = hk; // Tb + T[2] = hk - (1D / 3D); // Tg + + for (var i = 0; i < 3; i++) + { + if (T[i] < 0D) + T[i] += 1D; + if (T[i] > 1D) + T[i] -= 1D; + + if ((T[i] * 6D) < 1D) + T[i] = p + ((q - p) * 6D * T[i]); + else if ((T[i] * 2D) < 1) + T[i] = q; + else if ((T[i] * 3D) < 2) + T[i] = p + ((q - p) * ((2D / 3D) - T[i]) * 6D); + else + T[i] = p; + } + + _valuesAsByte[0] = ((int)Math.Round(T[0] * 255D)).EnsureRangeToByte(); + _valuesAsByte[1] = ((int)Math.Round(T[1] * 255D)).EnsureRangeToByte(); + _valuesAsByte[2] = ((int)Math.Round(T[2] * 255D)).EnsureRangeToByte(); + _valuesAsByte[3] = (byte)a; + } + + H = Math.Round(h, 0); + S = Math.Round(s, 2); + L = Math.Round(l, 2); + } + + public Color(byte r, byte g, byte b, byte a) + { + _valuesAsByte = new byte[4]; + + _valuesAsByte[0] = r; + _valuesAsByte[1] = g; + _valuesAsByte[2] = b; + _valuesAsByte[3] = a; + + CalculateHSL(); + } + + /// + /// initialize a new MudColor with new RGB values but keeps the hue value from the color + /// + /// R + /// G + /// B + /// Existing color to copy hue value from + public Color(byte r, byte g, byte b, Color color) : this(r, g, b, color.A) + { + H = color.H; + } + + public Color(int r, int g, int b, double alpha) : + this(r, g, b, (byte)((alpha * 255.0).EnsureRange(255))) + { + + } + + public Color(int r, int g, int b, int alpha) : + this((byte)r.EnsureRange(255), (byte)g.EnsureRange(255), (byte)b.EnsureRange(255), (byte)alpha.EnsureRange(255)) + { + + } + + public Color(string value) + { + value = value.Trim().ToLower(); + + if (value.StartsWith("rgba") == true) + { + var parts = SplitInputIntoParts(value); + if (parts.Length != 4) + { + throw new ArgumentException("invalid color format"); + } + + _valuesAsByte = new byte[] + { + byte.Parse(parts[0],CultureInfo.InvariantCulture), + byte.Parse(parts[1],CultureInfo.InvariantCulture), + byte.Parse(parts[2],CultureInfo.InvariantCulture), + (byte)Math.Max(0, Math.Min(255, 255 * double.Parse(parts[3],CultureInfo.InvariantCulture))), + }; + } + else if (value.StartsWith("rgb") == true) + { + var parts = SplitInputIntoParts(value); + if (parts.Length != 3) + { + throw new ArgumentException("invalid color format"); + } + _valuesAsByte = new byte[] + { + byte.Parse(parts[0],CultureInfo.InvariantCulture), + byte.Parse(parts[1],CultureInfo.InvariantCulture), + byte.Parse(parts[2],CultureInfo.InvariantCulture), + 255 + }; + } + else + { + + if (value.StartsWith("#")) + { + value = value.Substring(1); + } + + switch (value.Length) + { + case 3: + value = new string(new char[8] { value[0], value[0], value[1], value[1], value[2], value[2], 'F', 'F' }); + break; + case 4: + value = new string(new char[8] { value[0], value[0], value[1], value[1], value[2], value[2], value[3], value[3] }); + break; + case 6: + value += "FF"; + break; + case 8: + break; + default: + throw new ArgumentException("not a valid color", nameof(value)); + } + + _valuesAsByte = new byte[] + { + GetByteFromValuePart(value,0), + GetByteFromValuePart(value,2), + GetByteFromValuePart(value,4), + GetByteFromValuePart(value,6), + }; + + CalculateHSL(); + } + } + + + + #endregion + + #region Methods + + private void CalculateHSL() + { + var h = 0D; + var s = 0D; + double l; + + // normalize red, green, blue values + var r = R / 255D; + var g = G / 255D; + var b = B / 255D; + + var max = Math.Max(r, Math.Max(g, b)); + var min = Math.Min(r, Math.Min(g, b)); + + // hue + if (Math.Abs(max - min) < EPSILON) + h = 0D; // undefined + else if ((Math.Abs(max - r) < EPSILON) + && (g >= b)) + h = (60D * (g - b)) / (max - min); + else if ((Math.Abs(max - r) < EPSILON) + && (g < b)) + h = ((60D * (g - b)) / (max - min)) + 360D; + else if (Math.Abs(max - g) < EPSILON) + h = ((60D * (b - r)) / (max - min)) + 120D; + else if (Math.Abs(max - b) < EPSILON) + h = ((60D * (r - g)) / (max - min)) + 240D; + + // luminance + l = (max + min) / 2D; + + // saturation + if ((Math.Abs(l) < EPSILON) + || (Math.Abs(max - min) < EPSILON)) + s = 0D; + else if ((0D < l) + && (l <= .5D)) + s = (max - min) / (max + min); + else if (l > .5D) + s = (max - min) / (2D - (max + min)); //(max-min > 0)? + + H = Math.Round(h.EnsureRange(360), 0); + S = Math.Round(s.EnsureRange(1), 2); + L = Math.Round(l.EnsureRange(1), 2); + } + + public Color SetH(double h) => new(h, S, L, A); + public Color SetS(double s) => new(H, s, L, A); + public Color SetL(double l) => new(H, S, l, A); + + public Color SetR(int r) => new(r, G, B, A); + public Color SetG(int g) => new(R, g, B, A); + public Color SetB(int b) => new(R, G, b, A); + + public Color SetAlpha(int a) => new(R, G, B, a); + public Color SetAlpha(double a) => new(R, G, B, a); + + public Color ChangeLightness(double amount) => new(H, S, Math.Max(0, Math.Min(1, L + amount)), A); + public Color ColorLighten(double amount) => ChangeLightness(+amount); + public Color ColorDarken(double amount) => ChangeLightness(-amount); + public Color ColorRgbLighten() => ColorLighten(0.075); + public Color ColorRgbDarken() => ColorDarken(0.075); + + #endregion + + #region Helper + + private static string[] SplitInputIntoParts(string value) + { + var startIndex = value.IndexOf('('); + var lastIndex = value.LastIndexOf(')'); + var subString = value[(startIndex + 1)..lastIndex]; + var parts = subString.Split(',', StringSplitOptions.RemoveEmptyEntries); + for (var i = 0; i < parts.Length; i++) + { + parts[i] = parts[i].Trim(); + } + return parts; + } + + private byte GetByteFromValuePart(string input, int index) => byte.Parse(new string(new char[] { input[index], input[index + 1] }), NumberStyles.HexNumber); + + public bool HslChanged(Color value) => this.H != value.H || this.S != value.S || this.L != value.L; + + #endregion + + #region operators and object members + + public static implicit operator Color(string input) => new(input); + //public static implicit operator string(MudColor input) => input == null ? string.Empty : input.Value; + + public static explicit operator string(Color color) => color == null ? string.Empty : color.Value; + + public override string ToString() => ToString(ColorOutputFormats.HexA); + + public string ToString(ColorOutputFormats format) => format switch + { + ColorOutputFormats.Hex => Value.Substring(0, 7), + ColorOutputFormats.HexA => Value, + ColorOutputFormats.RGB => $"rgb({R},{G},{B})", + ColorOutputFormats.RGBA => $"rgba({R},{G},{B},{(A / 255.0).ToString(CultureInfo.InvariantCulture)})", + ColorOutputFormats.ColorElements => $"{R},{G},{B}", + _ => Value, + }; + + public override bool Equals(object obj) => obj is Color color && Equals(color); + + public bool Equals(Color other) + { + if (ReferenceEquals(other, null) == true) { return false; } + + return + _valuesAsByte[0] == other._valuesAsByte[0] && + _valuesAsByte[1] == other._valuesAsByte[1] && + _valuesAsByte[2] == other._valuesAsByte[2] && + _valuesAsByte[3] == other._valuesAsByte[3]; + } + + public override int GetHashCode() => _valuesAsByte[0] + _valuesAsByte[1] + _valuesAsByte[2] + _valuesAsByte[3]; + + public static bool operator ==(Color lhs, Color rhs) + { + var lhsIsNull = ReferenceEquals(null, lhs); + var rhsIsNull = ReferenceEquals(null, rhs); + if (lhsIsNull == true && rhsIsNull == true) + { + return true; + } + else + { + if ((lhsIsNull || rhsIsNull) == true) + { + return false; + } + else + { + return lhs.Equals(rhs); + } + } + } + + public static bool operator !=(Color lhs, Color rhs) => !(lhs == rhs); + + #endregion + + +} diff --git a/Utilities/ColorManager.cs b/Utilities/ColorManager.cs new file mode 100644 index 0000000..7f063ff --- /dev/null +++ b/Utilities/ColorManager.cs @@ -0,0 +1,113 @@ +using System; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +namespace Connected.Utilities +{ + [ExcludeFromCodeCoverage] + [Obsolete("Use MudColor instead.", true)] + public class ColorManager + { + public static System.Drawing.Color FromHex(string hex) + { + FromHex(hex, out var a, out var r, out var g, out var b); + + return System.Drawing.Color.FromArgb(a, r, g, b); + } + + // amount is between 0.0 and 1.0 + public static System.Drawing.Color ColorLighten(System.Drawing.Color rgbColor, double amount) + { + var hsl = ColorTransformation.RgBtoHsl(rgbColor); + hsl.L = Math.Max(0, Math.Min(1, hsl.L + amount)); + return ColorTransformation.HsLtoRgb(hsl, rgbColor.A); + } + + // amount is between 0.0 and 1.0 + public static System.Drawing.Color ColorDarken(System.Drawing.Color rgbColor, double amount) + { + var hsl = ColorTransformation.RgBtoHsl(rgbColor); + hsl.L = Math.Max(0, Math.Min(1, hsl.L - amount)); + return ColorTransformation.HsLtoRgb(hsl, rgbColor.A); + } + + public static void FromHex(string hex, out byte a, out byte r, out byte g, out byte b) + { + hex = ToRgbaHex(hex); + if (hex == null || !uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var packedValue)) + { + throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex)); + } + + a = (byte)(packedValue >> 0); + r = (byte)(packedValue >> 24); + g = (byte)(packedValue >> 16); + b = (byte)(packedValue >> 8); + } + + public static string ToRgbaFromHex(string hex, double alpha) + { + var color = FromHex(hex); + return $"rgba({color.R},{color.G},{color.B}, {alpha.ToString(CultureInfo.InvariantCulture)})"; + } + + + private static string ToRgbaHex(string hex) + { + hex = hex.StartsWith("#") ? hex.Substring(1) : hex; + + if (hex.Length == 8) + { + return hex; + } + + if (hex.Length == 6) + { + return hex + "FF"; + } + + if (hex.Length is < 3 or > 4) + { + return null; + } + + var red = char.ToString(hex[0]); + var green = char.ToString(hex[1]); + var blue = char.ToString(hex[2]); + var alpha = hex.Length == 3 ? "F" : char.ToString(hex[3]); + + return string.Concat(red, red, green, green, blue, blue, alpha, alpha); + } + + public static string ColorRgbDarken(string hex) + { + var color = FromHex(hex); + color = ColorDarken(color, 0.075); + return $"rgb({color.R},{color.G},{color.B})"; + } + public static string ColorRgbLighten(string hex) + { + var color = FromHex(hex); + color = ColorLighten(color, 0.075); + return $"rgb({color.R},{color.G},{color.B})"; + } + + public static string ColorRgb(string hex) + { + var color = FromHex(hex); + return $"rgb({color.R},{color.G},{color.B})"; + } + + public static string ColorRgbElements(string hex) + { + var color = FromHex(hex); + return $"{color.R},{color.G},{color.B}"; + } + + public static string ColorRgba(string hex, double alpha) + { + var color = FromHex(hex); + return $"rgba({color.R},{color.G},{color.B}, {alpha.ToString(CultureInfo.InvariantCulture)})"; + } + } +} diff --git a/Utilities/ColorTransformation.cs b/Utilities/ColorTransformation.cs new file mode 100644 index 0000000..7d6c9cf --- /dev/null +++ b/Utilities/ColorTransformation.cs @@ -0,0 +1,144 @@ +// Copyright (c) Steven Coco +// https://stackoverflow.com/questions/4087581/creating-a-c-sharp-color-from-hsl-values/4087601#4087601 +// Stripped and adapted by Meinrad Recheis for MudBlazor + +using System; +using System.Diagnostics.CodeAnalysis; +using SystemMath = System.Math; + +namespace Connected.Utilities +{ + /// + /// Static methods for transforming argb spaces and argb values. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use MudColor instead.", true)] + public static class ColorTransformation + { + private static double EPSILON => 0.000000000000001; + + public class HSLColor + { + public double H { get; set; } + public double S { get; set; } + public double L { get; set; } + } + + /// + /// Converts RGB to HSL. Alpha is ignored. + /// Output is: { H: [0, 360], S: [0, 1], L: [0, 1] }. + /// + /// The color to convert. + public static HSLColor RgBtoHsl(System.Drawing.Color color) + { + var h = 0D; + var s = 0D; + double l; + + // normalize red, green, blue values + var r = color.R / 255D; + var g = color.G / 255D; + var b = color.B / 255D; + + var max = SystemMath.Max(r, SystemMath.Max(g, b)); + var min = SystemMath.Min(r, SystemMath.Min(g, b)); + + // hue + if (SystemMath.Abs(max - min) < EPSILON) + h = 0D; // undefined + else if ((SystemMath.Abs(max - r) < EPSILON) + && (g >= b)) + h = (60D * (g - b)) / (max - min); + else if ((SystemMath.Abs(max - r) < EPSILON) + && (g < b)) + h = ((60D * (g - b)) / (max - min)) + 360D; + else if (SystemMath.Abs(max - g) < EPSILON) + h = ((60D * (b - r)) / (max - min)) + 120D; + else if (SystemMath.Abs(max - b) < EPSILON) + h = ((60D * (r - g)) / (max - min)) + 240D; + + // luminance + l = (max + min) / 2D; + + // saturation + if ((SystemMath.Abs(l) < EPSILON) + || (SystemMath.Abs(max - min) < EPSILON)) + s = 0D; + else if ((0D < l) + && (l <= .5D)) + s = (max - min) / (max + min); + else if (l > .5D) + s = (max - min) / (2D - (max + min)); //(max-min > 0)? + + return new HSLColor + { + H = SystemMath.Max(0D, SystemMath.Min(360D, h)), + S = SystemMath.Max(0D, SystemMath.Min(1D, s)), + L = SystemMath.Max(0D, SystemMath.Min(1D, l)) + }; + } + + /// + /// Converts HSL to RGB, with a specified output Alpha. + /// Arguments are limited to the defined range: + /// does not raise exceptions. + /// + /// HSL comprising of - + /// hsl.H (Hue), must be in [0, 360] - + /// hsl.S (Saturation), must be in [0, 1] - + /// hsl.L (Luminance), must be in [0, 1]. + /// Output Alpha, must be in [0, 255]. + public static System.Drawing.Color HsLtoRgb(HSLColor hsl, int a = 255) + { + var h = SystemMath.Max(0D, SystemMath.Min(360D, hsl.H)); + var s = SystemMath.Max(0D, SystemMath.Min(1D, hsl.S)); + var l = SystemMath.Max(0D, SystemMath.Min(1D, hsl.L)); + a = SystemMath.Max(0, SystemMath.Min(255, a)); + + // achromatic argb (gray scale) + if (SystemMath.Abs(s) < EPSILON) + { + return System.Drawing.Color.FromArgb( + a, + SystemMath.Max(0, SystemMath.Min(255, Convert.ToInt32(double.Parse($"{l * 255D:0.00}")))), + SystemMath.Max(0, SystemMath.Min(255, Convert.ToInt32(double.Parse($"{l * 255D:0.00}")))), + SystemMath.Max(0, SystemMath.Min(255, Convert.ToInt32(double.Parse($"{l * 255D:0.00}"))))); + } + + var q = l < .5D + ? l * (1D + s) + : (l + s) - (l * s); + var p = (2D * l) - q; + + var hk = h / 360D; + var T = new double[3]; + T[0] = hk + (1D / 3D); // Tr + T[1] = hk; // Tb + T[2] = hk - (1D / 3D); // Tg + + for (var i = 0; i < 3; i++) + { + if (T[i] < 0D) + T[i] += 1D; + if (T[i] > 1D) + T[i] -= 1D; + + if ((T[i] * 6D) < 1D) + T[i] = p + ((q - p) * 6D * T[i]); + else if ((T[i] * 2D) < 1) + T[i] = q; + else if ((T[i] * 3D) < 2) + T[i] = p + ((q - p) * ((2D / 3D) - T[i]) * 6D); + else + T[i] = p; + } + + return System.Drawing.Color.FromArgb( + a, + SystemMath.Max(0, SystemMath.Min(255, (int)Math.Round(T[0] * 255D))), + SystemMath.Max(0, SystemMath.Min(255, (int)Math.Round(T[1] * 255D))), + SystemMath.Max(0, SystemMath.Min(255, (int)Math.Round(T[2] * 255D)))); + } + + } +} diff --git a/Utilities/CssBuilder.cs b/Utilities/CssBuilder.cs new file mode 100644 index 0000000..2c675c1 --- /dev/null +++ b/Utilities/CssBuilder.cs @@ -0,0 +1,135 @@ +// Copyright (c) 2011 - 2019 Ed Charbeneau +// License: MIT +// See https://github.com/EdCharbeneau + +namespace Connected.Utilities +{ + public struct CssBuilder + { + private string stringBuffer; + + /// + /// Creates a CssBuilder used to define conditional CSS classes used in a component. + /// Call Build() to return the completed CSS Classes as a string. + /// + /// + public static CssBuilder Default(string value) => new(value); + + /// + /// Creates an Empty CssBuilder used to define conditional CSS classes used in a component. + /// Call Build() to return the completed CSS Classes as a string. + /// + public static CssBuilder Empty() => new(); + + /// + /// Creates a CssBuilder used to define conditional CSS classes used in a component. + /// Call Build() to return the completed CSS Classes as a string. + /// + /// + public CssBuilder(string value) => stringBuffer = value; + + /// + /// Adds a raw string to the builder that will be concatenated with the next class or value added to the builder. + /// + /// + /// CssBuilder + public CssBuilder AddValue(string value) + { + stringBuffer += value; + return this; + } + + /// + /// Adds a CSS Class to the builder with space separator. + /// + /// CSS Class to add + /// CssBuilder + public CssBuilder AddClass(string? value) + { + if (value is null) + return this; + + return AddValue($" {value}"); + } + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(string value, bool when = true) => when ? this.AddClass(value) : this; + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Nullable condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(string value, bool? when = true) => when == true ? this.AddClass(value) : this; + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(string value, Func when = null) => this.AddClass(value, when != null && when()); + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// Function that returns a CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(Func value, bool when = true) => when ? this.AddClass(value()) : this; + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// Function that returns a CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(Func value, Func when = null) => this.AddClass(value, when != null && when()); + + /// + /// Adds a conditional nested CssBuilder to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(CssBuilder builder, bool when = true) => when ? this.AddClass(builder.Build()) : this; + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddClass(CssBuilder builder, Func when = null) => this.AddClass(builder, when != null && when()); + + /// + /// Adds a conditional CSS Class when it exists in a dictionary to the builder with space separator. + /// Null safe operation. + /// + /// Additional Attribute splat parameters + /// CssBuilder + public CssBuilder AddClassFromAttributes(IReadOnlyDictionary additionalAttributes) => + additionalAttributes == null ? this : + additionalAttributes.TryGetValue("class", out var c) ? AddClass(c.ToString()) : this; + + /// + /// Finalize the completed CSS Classes as a string. + /// + /// string + public string Build() + { + // String buffer finalization code + return stringBuffer != null ? stringBuffer.Trim() : string.Empty; + } + + // ToString should only and always call Build to finalize the rendered string. + public override string ToString() => Build(); + + } +} diff --git a/Utilities/EventUtil.cs b/Utilities/EventUtil.cs new file mode 100644 index 0000000..c03efa4 --- /dev/null +++ b/Utilities/EventUtil.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; + +namespace Connected +{ + /// + /// This class enables calling events as Non-rendering + /// https://learn.microsoft.com/en-us/aspnet/core/blazor/performance?view=aspnetcore-6.0#avoid-rerendering-after-handling-events-without-state-changes + /// + + public static class EventUtil + { + public static Action AsNonRenderingEventHandler(Action callback) + => new SyncReceiver(callback).Invoke; + public static Action AsNonRenderingEventHandler( + Action callback) + => new SyncReceiver(callback).Invoke; + public static Func AsNonRenderingEventHandler(Func callback) + => new AsyncReceiver(callback).Invoke; + public static Func AsNonRenderingEventHandler( + Func callback) + => new AsyncReceiver(callback).Invoke; + + private record SyncReceiver(Action callback) + : ReceiverBase { public void Invoke() => callback(); } + private record SyncReceiver(Action callback) + : ReceiverBase { public void Invoke(T arg) => callback(arg); } + private record AsyncReceiver(Func callback) + : ReceiverBase { public Task Invoke() => callback(); } + private record AsyncReceiver(Func callback) + : ReceiverBase { public Task Invoke(T arg) => callback(arg); } + + private record ReceiverBase : IHandleEvent + { + public Task HandleEventAsync(EventCallbackWorkItem item, object arg) => + item.InvokeAsync(arg); + } + } +} \ No newline at end of file diff --git a/Utilities/Exceptions/GenericTypeMismatchException.cs b/Utilities/Exceptions/GenericTypeMismatchException.cs new file mode 100644 index 0000000..1a4e9f9 --- /dev/null +++ b/Utilities/Exceptions/GenericTypeMismatchException.cs @@ -0,0 +1,13 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Connected.Utilities.Exceptions +{ + [ExcludeFromCodeCoverage] + public class GenericTypeMismatchException : Exception + { + public GenericTypeMismatchException(string parent, string child, Type t1, Type t2) : base($"{parent}<{t1.Name}> has a child {child}<{t2}> with mismatching generic type.") + { + } + } +} diff --git a/Utilities/FormFieldChangedEventArgs.cs b/Utilities/FormFieldChangedEventArgs.cs new file mode 100644 index 0000000..53078a9 --- /dev/null +++ b/Utilities/FormFieldChangedEventArgs.cs @@ -0,0 +1,13 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Connected.Components; + +namespace Connected.Utilities; + +public class FormFieldChangedEventArgs +{ + public IFormComponent Field { get; set; } + public object NewValue { get; set; } +} diff --git a/Utilities/HashSetExtensions.cs b/Utilities/HashSetExtensions.cs new file mode 100644 index 0000000..bbb748f --- /dev/null +++ b/Utilities/HashSetExtensions.cs @@ -0,0 +1,31 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Connected.Utilities +{ + public static class HashSetExtensions + { + public static bool IsEqualTo(this HashSet self, ICollection other) + { + if (object.ReferenceEquals(self, other)) + return true; + if (self == null && other !=null || self != null && other == null) + return false; + if (self.Count != other.Count) + return false; + foreach (var value in other) + { + if (!self.Contains(value)) + return false; + } + return true; + } + } +} diff --git a/Utilities/MaskAlgorithms/BaseMask.cs b/Utilities/MaskAlgorithms/BaseMask.cs new file mode 100644 index 0000000..16fa4ef --- /dev/null +++ b/Utilities/MaskAlgorithms/BaseMask.cs @@ -0,0 +1,268 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Connected; + +public abstract class BaseMask : IMask +{ + protected bool _initialized; + protected Dictionary _maskDict; + + protected MaskChar[] _maskChars = new MaskChar[] + { + MaskChar.Letter('a'), MaskChar.Digit('0'), MaskChar.LetterOrDigit('*'), + }; + + // per definition (unless defined otherwise in subclasses) delimiters are chars + // in the mask which do not match any MaskChar + protected HashSet _delimiters; + + /// + /// Initialize all internal data structures. Can be called multiple times, + /// will initialize only once. To re-initialize set _initialized to false. + /// + protected void Init() + { + if (_initialized) + return; + _initialized = true; + InitInternals(); + } + + protected virtual void InitInternals() + { + _maskDict = _maskChars.ToDictionary(x => x.Char); + if (Mask == null) + _delimiters = new(); + else + _delimiters = + new HashSet(Mask.Where(c => _maskChars.All(maskDef => maskDef.Char != c))); + } + + /// + /// The mask defining the structure of the accepted input. + /// The mask format depends on the implementation. + /// + public string Mask { get; protected set; } + + /// + /// The current text as it is displayed in the component + /// + public string Text { get; protected set; } + + /// + /// Get the Text without delimiters or placeholders. Depends on the implementation entirely. + /// Clean text will usually be used for the Value property of a mask field. + /// + public virtual string GetCleanText() => Text; + + /// + /// The current caret position + /// + public int CaretPos { get; set; } + + /// + /// The currently selected sub-section of the Text + /// + public (int, int)? Selection { get; set; } + + /// + /// Allow showing a text consisting only of delimiters + /// + public bool AllowOnlyDelimiters { get; set; } + + /// + /// The mask chars define the meaning of single mask characters such as 'a', '0' + /// + public MaskChar[] MaskChars + { + get => _maskChars; + set + { + _maskChars = value; + // force re-initialization + _initialized = false; + } + } + + /// + /// Implements user input at the current caret position (single key strokes or pasting longer text) + /// + /// + public abstract void Insert(string input); + + /// + /// Implements the effect of the Del key at the current cursor position + /// + public abstract void Delete(); + + /// + /// Implements the effect of the Backspace key at the current cursor position + /// + public abstract void Backspace(); + + /// + /// Reset the mask as if the whole textfield was cleared + /// + public void Clear() + { + Init(); + Text = ""; + CaretPos = 0; + Selection = null; + } + + /// + /// Overwrite the mask text from the outside without losing caret position + /// + /// + public void SetText(string text) + { + Clear(); + Insert(text); + } + + /// + /// Update Text from the inside + /// + /// + protected virtual void UpdateText(string text) + { + // don't show a text consisting only of delimiters and placeholders (no actual input) + if (!AllowOnlyDelimiters && text.All(c => _delimiters.Contains(c))) + { + Text = ""; + return; + } + Text = text; + CaretPos = ConsolidateCaret(Text, CaretPos); + } + + protected abstract void DeleteSelection(bool align); + + protected virtual bool IsDelimiter(char maskChar) + { + return _delimiters.Contains(maskChar); + } + + public virtual void UpdateFrom(IMask o) + { + var other = o as BaseMask; + if (other == null) + return; + if (other.Mask != Mask) + { + Mask = other.Mask; + _initialized = false; + } + if (other.MaskChars != null) + { + var maskChars = new HashSet(_maskChars ?? new MaskChar[0]); + if (other.MaskChars.Length != MaskChars.Length || other.MaskChars.Any(x => !maskChars.Contains(x))) + { + _maskChars = other.MaskChars; + _initialized = false; + } + } + Refresh(); + } + + /// + /// Re-applies parameters (i.e. after they changed) without loosing internal state + /// such as Text, CaretPos and Selection + /// + protected virtual void Refresh() + { + var caret = CaretPos; + var sel = Selection; + SetText(Text); + CaretPos = ConsolidateCaret(Text, caret); + Selection = sel; + if (sel != null) + ConsolidateSelection(); + } + + internal static (string, string) SplitAt(string text, int pos) + { + if (pos <= 0) + return ("", text); + if (pos >= text.Length) + return (text, ""); + return (text.Substring(0, pos), text.Substring(pos)); + } + + /// + /// Performs simple border checks and corrections to the caret position + /// + protected static int ConsolidateCaret(string text, int caretPos) + { + if (string.IsNullOrEmpty(text) || caretPos < 0) + return 0; + if (caretPos < text.Length) + return caretPos; + return text.Length; + } + + /// + /// Performs simple border checks and corrections to the selection + /// and removes zero-width selections + /// + protected void ConsolidateSelection() + { + if (Selection == null) + return; + var sel = Selection.Value; + if (sel.Item1 == sel.Item2) + { + CaretPos = sel.Item1; + Selection = null; + return; + } + if (sel.Item1 < 0) + sel.Item1 = 0; + if (sel.Item2 >= Text.Length) + sel.Item2 = Text.Length; + } + + internal static (string, string, string) SplitSelection(string text, (int, int) selection) + { + var start = ConsolidateCaret(text, selection.Item1); + var end = ConsolidateCaret(text, selection.Item2); + (var s1, var rest) = SplitAt(text, start); + (var s2, var s3) = SplitAt(rest, end - start); + return (s1, s2, s3); + } + + /// + /// Prints a representation of the input including markers for caret and selection + /// Used heavily by the tests + /// + /// + public override string ToString() + { + var text = Text ?? ""; + ConsolidateSelection(); + if (Selection == null) + { + var pos = ConsolidateCaret(text, CaretPos); + if (pos < text.Length) + return text.Insert(pos, "|"); + return text + "|"; + } + else + { + var sel = Selection.Value; + var start = ConsolidateCaret(text, sel.Item1); + var end = ConsolidateCaret(text, sel.Item2); + (var s1, var rest) = SplitAt(text, start); + (var s2, var s3) = SplitAt(rest, end - start); + return s1 + "[" + s2 + "]" + s3; + } + } + +} diff --git a/Utilities/MaskAlgorithms/BlockMask.cs b/Utilities/MaskAlgorithms/BlockMask.cs new file mode 100644 index 0000000..2c1c8fd --- /dev/null +++ b/Utilities/MaskAlgorithms/BlockMask.cs @@ -0,0 +1,116 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace Connected; + +public record struct Block(char MaskChar, int Min = 1, int Max = 1); + +public class BlockMask : RegexMask +{ + public BlockMask(params Block[] blocks) : base(null) + { + if (blocks.Length == 0) + throw new ArgumentException("supply at least one block", nameof(blocks)); + Blocks = blocks; + Delimiters = ""; + } + + public BlockMask(string delimiters, params Block[] blocks) : this(blocks) + { + Delimiters = delimiters ?? ""; + } + + public Block[] Blocks { get; protected set; } + + protected override void InitInternals() + { + base.InitInternals(); + Blocks ??= new Block[0]; + Mask = BuildRegex(Blocks); + _regex = new Regex(Mask); + } + + protected override void InitRegex() + { + // BlockMask inits regex itself (but after base init), no need to do it twice + // so don't call base init here + //base.InitRegex(); + } + + /// + /// Build the progressive working regex from the block and delimiter definitions + /// Note: a progressive regex must match partial input!!!! + /// + /// + /// + protected virtual string BuildRegex(Block[] blocks) + { + var s = new StringBuilder(); + int i = 0; + int blockIndex = 0; + s.Append("^"); + foreach (var b in blocks) + { + for (int j = 0; j < b.Min; j++) + { + if (i > 0) + s.Append("("); + if (_maskDict.TryGetValue(b.MaskChar, out var maskDef)) + s.Append(maskDef.Regex); + else + s.Append(Regex.Escape(b.MaskChar.ToString())); + } + + i += b.Min; + if (b.Max > b.Min) + { + for (int j = b.Min; j < b.Max; j++) + { + s.Append("("); + if (_maskDict.TryGetValue(b.MaskChar, out var maskDef)) + s.Append(maskDef.Regex); + else + s.Append(Regex.Escape(b.MaskChar.ToString())); + } + + for (int j = b.Min; j < b.Max; j++) + s.Append(")?"); + } + + if (_delimiters.Count > 0 && blockIndex < blocks.Length - 1) + { + s.Append("(["); + foreach (var d in _delimiters) + s.Append(Regex.Escape(d.ToString())); + s.Append("]"); + i++; + } + + blockIndex++; + } + + for (int j = 0; j < i - 1; j++) + s.Append(")?"); + s.Append("$"); + return s.ToString(); + } + + public override void UpdateFrom(IMask other) + { + base.UpdateFrom(other); + var o = other as BlockMask; + if (o == null) + return; + Blocks = o.Blocks ?? new Block[0]; + Delimiters = o.Delimiters; + _initialized = false; + Refresh(); + } +} diff --git a/Utilities/MaskAlgorithms/DateMask.cs b/Utilities/MaskAlgorithms/DateMask.cs new file mode 100644 index 0000000..d9d6e09 --- /dev/null +++ b/Utilities/MaskAlgorithms/DateMask.cs @@ -0,0 +1,232 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace Connected; + +public class DateMask : PatternMask +{ + + public DateMask(string mask, char year = 'y', char month = 'M', char day = 'd') : base(mask) + { + _y = year; + _M = month; + _d = day; + _maskChars = _maskChars.Concat(new[] { MaskChar.Digit(year), MaskChar.Digit(month), MaskChar.Digit(day), }) + .ToArray(); + } + + private char _y; + private char _M; + private char _d; + + private int _year = 0; + private int _month = 0; + private int _day = 0; + + protected override void ModifyPartiallyAlignedMask(string mask, string text, int maskOffset, ref int textIndex, ref int maskIndex, ref string alignedText) + { + if (alignedText.IsEmpty()) + return; + var y = ExtractYear(mask, alignedText, maskOffset); + if (y >= 0) + _year = y; + MonthLogic(mask, text, maskOffset, ref textIndex, ref maskIndex, ref alignedText); + DayLogic(mask, text, maskOffset, ref textIndex, ref maskIndex, ref alignedText); + } + + private int ExtractYear(string mask, string alignedText, int maskOffset) + { + var yyyy = new string(_y, 4); + var yy = new string(_y, 2); + if (mask.Contains(yyyy)) + { + var (yearString, _) = Extract(yyyy, mask, maskOffset, alignedText); + if (yearString == null || yearString.Length < 4) + return -1; + if (int.TryParse(yearString, out var year)) + return year; + } + else if (mask.Contains(yy)) + { + var (yearString, _) = Extract(yy, mask, maskOffset, alignedText); + if (yearString == null || yearString.Length < 2) + return -1; + if (int.TryParse(yearString, out var y)) + return (DateTime.Today.Year / 100 * 100) + y; // this code will still work in 2100 until 2900. I guess in a thousand years we'll have to update this line ;) + } + return -1; + } + + private void MonthLogic(string mask, string text, int maskOffset, ref int textIndex, ref int maskIndex, ref string alignedText) + { + var MM = new string(_M, 2); + var (monthString, index) = Extract(MM, mask, maskOffset, alignedText); + if (monthString == null) + return; + if (!int.TryParse(monthString, out var month)) + return; + if (monthString.Length == 1) + { + // we are at the first digit of MM, only 0 and 1 are allowed + if (month > 1) + { + alignedText = alignedText.Insert(index, "0"); + maskIndex++; + } + } + else if (monthString.Length == 2) + { + var fixedMonth = FixMonth(month); + _month = fixedMonth; + if (fixedMonth != month) + alignedText = alignedText.Remove(index, 2).Insert(index, $"{fixedMonth:D2}"); + } + } + + private void DayLogic(string mask, string text, int maskOffset, ref int textIndex, ref int maskIndex, ref string alignedText) + { + var dd = new string(_d, 2); + var (dayString, index) = Extract(dd, mask, maskOffset, alignedText); + if (dayString == null) + return; + if (!int.TryParse(dayString, out var day)) + return; + if (dayString.Length == 1) + { + // we are at the first digit of dd, only 0..3 are allowed except if month is February. + if (day > 3 || day == 3 && _month == 2) + { + // by inserting a 0 we make 09 out of 9 + alignedText = alignedText.Insert(index, "0"); + maskIndex++; + _day = day; + } + } + else if (dayString.Length == 2) + { + var fixedDay = FixDay(_year, _month, day); + if (fixedDay != day) + alignedText = alignedText.Remove(index, 2).Insert(index, $"{fixedDay:D2}"); + _day = fixedDay; + } + } + + /// + /// Note: this is required for special cases where the date becomes invalid after the last character has been input + /// For instance: MM/dd/yyyy from 02/29/000| to 02/29/0001| + /// The year 0001 is not a leap year so the day needs to be corrected to 28 + /// Or this 0[3]/31/2000 input "4" => 04/31/2000 + /// But we do this only for a complete date! + /// + protected override string ModifyFinalText(string text) + { + try + { + var yyyy = new string(_y, 4); + var yy = new string(_y, 2); + var dd = new string(_d, 2); + var MM = new string(_M, 2); + var maskHasDay = Mask.Contains(dd); + var maskHasMonth = Mask.Contains(MM); + var maskHasYear = Mask.Contains(yy) || Mask.Contains(yyyy); + var (dayString, dayIndex) = Extract(dd, Mask, 0, text); + var (monthString, monthIndex) = Extract(MM, Mask, 0, text); + var dayFound = dayIndex >= 0; + var dayComplete = dayString?.Length == 2; + var monthFound = monthIndex >= 0; + var monthComplete = monthString?.Length == 2; + var y = ExtractYear(Mask, text, 0); + //if (maskHasYear && y < 0 || maskHasMonth && (!monthFound || !monthComplete) || maskHasDay && (!dayFound || !dayComplete)) + // return text; // we have incomplete input, no final check necessary/possible + int.TryParse(dayString ?? "", out var d); + int.TryParse(monthString ?? "", out var m); + if (!maskHasYear) + y = 0; + if (y < 0) + y = _year; + if (maskHasMonth && (monthFound || monthComplete)) + { + var m1 = FixMonth(m); + if (m1 != m) + text = text.Remove(monthIndex, 2).Insert(monthIndex, $"{m1:D2}"); + } + + if (maskHasDay && (dayFound || dayComplete)) + { + var d1 = FixDay(y, m, d); + text = text.Remove(dayIndex, 2).Insert(dayIndex, $"{d1:D2}"); + } + } + catch (Exception e) + { + Console.WriteLine("Error in ModifyFinalText: " +e.Message); + return text; + } + return text; + } + + private int FixDay(int year, int month, int day) + { + if (day == 0) + return 1; + if (day > 28) + { + var daysInMonth = GetDaysInMonth(year, month); + if (day > daysInMonth) + return daysInMonth; + } + return day; + } + + private int FixMonth(int month) + { + if (month == 0) + return 1; + if (month > 12) + return 12; + return month; + } + + private int GetDaysInMonth(int year, int month) + { + if (month <= 0 || month > 12) // we don't know yet which month the user means, so assume 31 + return 31; + if (year == 0) // DateTime.DaysInMonth does not support year 0 but we just use 4 instead because it was a leap year too + year = 4; + return DateTime.DaysInMonth(year, Math.Min(12, Math.Max(1, month))); + } + + private (string, int) Extract(string maskPart, string mask, int maskOffset, string alignedText) + { + var maskIndex = mask.IndexOf(maskPart); + var index = maskIndex - maskOffset; + if (index < 0 || index >= alignedText.Length) + return (null, -1); + var subString = alignedText.Substring(index, Math.Min(maskPart.Length, alignedText.Length - index)); + if (!Regex.IsMatch(subString, @"^\d+$")) + return (null, -1); + return (subString, index); + } + + public override void UpdateFrom(IMask other) + { + base.UpdateFrom(other); + var o = other as DateMask; + if (o == null) + return; + _y = o._y; + _M = o._M; + _d = o._d; + } +} + diff --git a/Utilities/MaskAlgorithms/IMask.cs b/Utilities/MaskAlgorithms/IMask.cs new file mode 100644 index 0000000..db99937 --- /dev/null +++ b/Utilities/MaskAlgorithms/IMask.cs @@ -0,0 +1,76 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Connected +{ + public interface IMask + { + /// + /// The mask defining the structure of the accepted input. + /// Its format depends on the implementation. + /// + string Mask { get; } + + /// + /// The current text as it is displayed in the component + /// + string Text { get; } + + /// + /// Get the Text without delimiters or placeholders. Depends on the implementation entirely. + /// Clean text will usually be used for the Value property of a mask field. + /// + string GetCleanText() => Text; + + /// + /// The current caret position + /// + int CaretPos { get; set; } + + /// + /// The currently selected sub-section of the Text + /// + (int, int)? Selection { get; set; } + + /// + /// Implements user input at the current caret position (single key strokes or pasting longer text) + /// + /// + void Insert(string input); + + /// + /// Implements the effect of the Del key at the current cursor position + /// + void Delete(); + + /// + /// Implements the effect of the Backspace key at the current cursor position + /// + void Backspace(); + + /// + /// Reset the mask as if the whole textfield was cleared + /// + void Clear(); + + /// + /// Overwrite the mask text without losing caret position + /// + /// + void SetText(string text); + + /// + /// Copy config from other mask but preserve own state. + /// + /// + void UpdateFrom(IMask other); + + } +} diff --git a/Utilities/MaskAlgorithms/MaskChar.cs b/Utilities/MaskAlgorithms/MaskChar.cs new file mode 100644 index 0000000..d589b97 --- /dev/null +++ b/Utilities/MaskAlgorithms/MaskChar.cs @@ -0,0 +1,27 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Connected; + +public struct MaskChar +{ + public MaskChar(char c, string regex) + { + Char = c; + Regex = regex; + } + + public char Char { get; set; } + public string Regex { get; set; } + + public static MaskChar Letter(char c) => new MaskChar { Char = c, Regex = @"\p{L}" }; + public static MaskChar Digit(char c) => new MaskChar { Char = c, Regex = @"\d" }; + public static MaskChar LetterOrDigit(char c) => new MaskChar { Char = c, Regex = @"\p{L}|\d" }; +} diff --git a/Utilities/MaskAlgorithms/MultiMask.cs b/Utilities/MaskAlgorithms/MultiMask.cs new file mode 100644 index 0000000..55448b8 --- /dev/null +++ b/Utilities/MaskAlgorithms/MultiMask.cs @@ -0,0 +1,100 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Connected +{ + public record struct MaskOption(string Id, string Mask, string Regex); + + public class MultiMask : PatternMask + { + public MultiMask(string defaultMask, params MaskOption[] options) : base(defaultMask) + { + _defaultMask = defaultMask; + _options = options ?? new MaskOption[0]; + } + + private string _defaultMask; + private MaskOption[] _options; + public Action OptionDetected { get; set; } + + public MaskOption? DetectedOption { get; private set; } = null; + + public override void Insert(string input) + { + DoCheckAndRedo(() => base.Insert(input)); + } + + public override void Delete() + { + DoCheckAndRedo(base.Delete); + } + + public override void Backspace() + { + DoCheckAndRedo(base.Backspace); + } + + /// + /// This is a nifty trick to avoid writing three times the same code for Insert, Delete and Backspace. + /// This backs up the state. Executes the action, checks if option changed. If so, apply saved state and + /// re-apply the action. + /// + /// + protected void DoCheckAndRedo(Action action) + { + // backup state + var text = Text; + var pos = CaretPos; + var sel = Selection; + // do it! + action(); + var newOption = CheckOption(); + if (newOption == DetectedOption) + return; + // detected a different option + DetectedOption = newOption; + // revert saved state + Text = text; + CaretPos = pos; + Selection = sel; + Mask = newOption != null ? newOption.Value.Mask : _defaultMask; + // when mask changes we need to re-initialize! + _initialized = false; + // do it again! + action(); + OptionDetected?.Invoke(newOption, Text); + } + + protected virtual MaskOption? CheckOption() + { + var text = Text ?? ""; + foreach (var option in _options) + { + if (option.Regex != null && Regex.IsMatch(text, option.Regex)) + return option; + } + return null; + } + + public override void UpdateFrom(IMask other) + { + base.UpdateFrom(other); + var o = other as MultiMask; + if (o == null) + return; + // no need to re-initialize, just update the options + _defaultMask = o._defaultMask; + _options = o._options ?? new MaskOption[0]; + OptionDetected = o.OptionDetected; + Refresh(); + } + } +} diff --git a/Utilities/MaskAlgorithms/PatternMask.cs b/Utilities/MaskAlgorithms/PatternMask.cs new file mode 100644 index 0000000..2e6f6f5 --- /dev/null +++ b/Utilities/MaskAlgorithms/PatternMask.cs @@ -0,0 +1,269 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Connected; + +public class PatternMask : BaseMask +{ + public PatternMask(string mask) + { + Mask = mask; + } + + /// + /// If set, the mask will print placeholders for all non-delimiters that haven't yet been typed. + /// For instance a mask "000-000" with input "1" will show "1__-___" as Text. + /// + public char? Placeholder { get; set; } + + /// + /// A function for changing input characters after they were typed, i.e. lower-case to upper-case, etc. + /// + public Func Transformation { get; set; } + + /// + /// Inserts given text at caret position + /// + /// One or multiple characters of input + public override void Insert(string input) + { + Init(); + DeleteSelection(align: false); + var text = Text ?? ""; + var pos = ConsolidateCaret(text, CaretPos); + (var beforeText, var afterText) = SplitAt(text, pos); + var alignedBefore = AlignAgainstMask(beforeText, 0); + CaretPos = pos = alignedBefore.Length; + var alignedInput = AlignAgainstMask(input, pos); + CaretPos = pos += alignedInput.Length; + if (Placeholder != null) + { + var p = Placeholder.Value; + if (afterText.Take(alignedInput.Length).All(c => IsDelimiter(c) || c==p)) + afterText = new string(afterText.Skip(alignedInput.Length).ToArray()); + } + var alignedAfter = AlignAgainstMask(afterText, pos); + UpdateText( FillWithPlaceholder(alignedBefore + alignedInput + alignedAfter)); + } + + protected override void DeleteSelection(bool align) + { + ConsolidateSelection(); + if (Selection == null) + return; + var sel = Selection.Value; + (var s1, _, var s3) = SplitSelection(Text, sel); + Selection = null; + CaretPos = sel.Item1; + if (!align) + UpdateText( s1 + s3); + else + UpdateText( FillWithPlaceholder( s1 + AlignAgainstMask(s3, CaretPos))); + } + + /// + /// Implements the effect of the Del key at the current cursor position + /// + public override void Delete() + { + Init(); + if (Selection != null) + { + DeleteSelection(align: true); + return; + } + var text = Text ?? ""; + var pos = CaretPos = ConsolidateCaret(text, CaretPos); + if (pos >= text.Length) + return; + (var beforeText, var afterText) = SplitAt(text, pos); + // delete as many delimiters as there are plus one char + var restText = new string(afterText.SkipWhile(IsDelimiter).Skip(1).ToArray()); + var alignedAfter = AlignAgainstMask(restText, pos); + var numDeleted = afterText.Length - restText.Length; + if (numDeleted > 1) + { + // since we just auto-deleted delimiters which were re-created by AlignAgainstMask we can just as well + // adjust the cursor position to after the delimiters + CaretPos += (numDeleted - 1); + } + UpdateText( FillWithPlaceholder(beforeText + alignedAfter)); + } + + /// + /// Implements the effect of the Backspace key at the current cursor position + /// + public override void Backspace() + { + Init(); + if (Selection != null) + { + DeleteSelection(align: true); + return; + } + var text = Text ?? ""; + var pos = CaretPos = ConsolidateCaret(text, CaretPos); + if (pos == 0) + return; + (var beforeText, var afterText) = SplitAt(text, pos); + // backspace as many delimiters as there are plus one char + var restText = new string(beforeText.Reverse().SkipWhile(IsDelimiter).Skip(1).Reverse().ToArray()); + var numDeleted = beforeText.Length - restText.Length; + CaretPos -= numDeleted; + var alignedAfter = AlignAgainstMask(afterText, CaretPos); + UpdateText( FillWithPlaceholder(restText + alignedAfter)); + } + + /// + /// Fill the rest of the text with Placeholder but only if it is set + /// + /// + /// + protected virtual string FillWithPlaceholder(string text) + { + if (Placeholder == null) + return text; + // fill the rest with placeholder + // don't fill if text is still empty + var filledText = text; + var len = text.Length; + var mask = Mask ?? ""; + if (len == 0 || len >= mask.Length) + return text; + for (var maskIndex = len; maskIndex < mask.Length; maskIndex++) + { + var maskChar = mask[maskIndex]; + if (IsDelimiter(maskChar)) + filledText += maskChar; + else + filledText += Placeholder.Value; + } + return filledText; + } + + /// + /// Applies the mask to the given text starting at the given offset and returns the masked text. + /// + /// + /// + protected virtual string AlignAgainstMask(string text, int maskOffset = 0) + { + text ??= ""; + var mask = Mask ?? ""; + var alignedText = ""; + var maskIndex = maskOffset; // index in mask + var textIndex = 0; // index in text + while (textIndex < text.Length) + { + if (maskIndex >= mask.Length) + break; + var maskChar = mask[maskIndex]; + var textChar = text[textIndex]; + if (IsDelimiter(maskChar)) + { + alignedText += maskChar; + maskIndex++; + ModifyPartiallyAlignedMask(mask, text, maskOffset, ref textIndex, ref maskIndex, ref alignedText); + continue; + } + var isPlaceholder = Placeholder != null && textChar == Placeholder.Value; + if (IsMatch(maskChar, textChar) || isPlaceholder) + { + var c = Transformation == null ? textChar : Transformation(textChar); + alignedText += c; + maskIndex++; + } + textIndex++; + ModifyPartiallyAlignedMask(mask, text, maskOffset, ref textIndex, ref maskIndex, ref alignedText); + } + // fill any delimiters if possible + for (int i = maskIndex; i < mask.Length; i++) + { + var maskChar = mask[i]; + if (!IsDelimiter(maskChar)) + break; + alignedText += maskChar; + } + return alignedText; + } + + protected virtual void ModifyPartiallyAlignedMask(string mask, string text, int maskOffset, ref int textIndex, ref int maskIndex, ref string alignedText) + { + /* this is an override hook for more specialized mask implementations deriving from this*/ + } + + protected virtual bool IsMatch(char maskChar, char textChar) + { + var maskDef = _maskDict[maskChar]; + return Regex.IsMatch(textChar.ToString(), maskDef.Regex); + } + + /// + /// If true, all characters which are not defined in the mask (delimiters) are stripped + /// from text. + /// + public bool CleanDelimiters { get; set; } + + /// + /// Return the Text without Placeholders. If CleanDelimiters is enabled, then also strip all + /// undefined characters. For instance, for a mask "0000 0000 0000 0000" the space would be + /// an undefined character (a delimiter) unless it were defined as a mask character in MaskChars. + /// + public override string GetCleanText() + { + Init(); + var cleanText = Text; + if (string.IsNullOrEmpty(cleanText)) + return cleanText; + if (CleanDelimiters) + cleanText=new string(cleanText.Where((c,i)=>_maskDict.ContainsKey(Mask[i])).ToArray()); + if (Placeholder != null) + cleanText = cleanText.Replace(Placeholder.Value.ToString(), ""); + return cleanText; + } + + protected override void InitInternals() + { + base.InitInternals(); + if (Placeholder!=null) + _delimiters.Add(Placeholder.Value); + } + + protected override void UpdateText(string text) + { + // don't show a text consisting only of delimiters and placeholders (no actual input) + if (text.All(c => _delimiters.Contains(c) || (Placeholder!=null && c==Placeholder.Value))) + { + Text = ""; + CaretPos = 0; + return; + } + Text = ModifyFinalText(text); + CaretPos = ConsolidateCaret(Text, CaretPos); + } + + protected virtual string ModifyFinalText(string text) + { + /* this can be overridden in derived classes to apply any necessary changes to the resulting text */ + return text; + } + + public override void UpdateFrom(IMask other) + { + base.UpdateFrom(other); + var o = other as PatternMask; + if (o == null) + return; + Placeholder = o.Placeholder; + CleanDelimiters = o.CleanDelimiters; + Transformation = o.Transformation; + _initialized = false; + Refresh(); + } +} diff --git a/Utilities/MaskAlgorithms/RegexMask.cs b/Utilities/MaskAlgorithms/RegexMask.cs new file mode 100644 index 0000000..c72d642 --- /dev/null +++ b/Utilities/MaskAlgorithms/RegexMask.cs @@ -0,0 +1,271 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace Connected; + +public class RegexMask : BaseMask +{ + /// + /// Add this filter to the end of a mask to block any space, tab or newline character. + /// + private const string WhiteSpaceFilter = "(?!\\s)"; + + /// + /// Create a mask that uses a regex to restrict input. + /// + /// + /// The general or progressive regex to be used for input checking. + /// + /// Note: a general regex must match every possible input, i.e. ^[0-9]+$. + /// Note: a progressive regex must match even partial input successfully! The + /// progressive regex must start with ^ and end with $ to work correctly! + /// + /// Example: to match input "abc" a progressive regex must match "a" or "ab" or "abc". The + /// progressive regex would look like this: ^a(b(c)?)?$ or like this ^(a|ab|abc)$ + /// It is best to generate the progressive regex automatically like BlockMask does. + /// + /// + /// The mask defining the structure of the accepted input. + /// + /// Note: if not included the regex will be the mask. + /// + public RegexMask(string regex, string mask = null) + { + _regexPattern = regex; + Mask = mask ?? regex; + } + + protected string _regexPattern; + protected Regex _regex; + + /// + /// Optional delimiter chars which will be jumped over if the caret is + /// in front of one and the user inputs the next non-delimiter + /// + public string Delimiters { get; protected set; } + + protected override void InitInternals() + { + base.InitInternals(); + Delimiters ??= ""; + _delimiters = new HashSet(Delimiters); + InitRegex(); + } + + protected virtual void InitRegex() + { + _regex = new Regex(_regexPattern); + } + + /// + /// Inserts given text at caret position + /// + /// One or multiple characters of input + public override void Insert(string input) + { + Init(); + DeleteSelection(align: false); + var text = Text ?? ""; + var pos = ConsolidateCaret(text, CaretPos); + (var beforeText, var afterText) = SplitAt(text, pos); + var alignedInput = AlignAgainstMask(beforeText + input); + CaretPos = alignedInput.Length; + UpdateText(AlignAgainstMask(alignedInput + afterText)); + } + + protected override void DeleteSelection(bool align) + { + ConsolidateSelection(); + if (Selection == null) + return; + var sel = Selection.Value; + (var s1, _, var s3) = SplitSelection(Text, sel); + Selection = null; + CaretPos = sel.Item1; + if (!align) + UpdateText(s1 + s3); + else + UpdateText(AlignAgainstMask(s1 + s3)); + } + + /// + /// Implements the effect of the Del key at the current cursor position + /// + public override void Delete() + { + Init(); + if (Selection != null) + { + DeleteSelection(align: true); + return; + } + var text = Text ?? ""; + var pos = ConsolidateCaret(text, CaretPos); + if (pos >= text.Length) + return; + (var beforeText, var afterText) = SplitAt(text, pos); + // delete as many delimiters as there are plus one char + var restText = new string(afterText.SkipWhile(IsDelimiter).Skip(1).ToArray()); + UpdateText( AlignAgainstMask(beforeText + restText)); + var numDeleted = afterText.Length - restText.Length; + if (numDeleted > 1) + { + // since we just auto-deleted delimiters which were re-created by AlignAgainstMask we can just as well + // adjust the cursor position to after the delimiters + CaretPos += (numDeleted - 1); + } + } + + /// + /// Implements the effect of the Backspace key at the current cursor position + /// + public override void Backspace() + { + Init(); + if (Selection != null) + { + DeleteSelection(align: true); + return; + } + var text = Text ?? ""; + var pos = ConsolidateCaret(text, CaretPos); + if (pos == 0) + return; + (var beforeText, var afterText) = SplitAt(text, pos); + // backspace as many delimiters as there are plus one char + var restText = new string(beforeText.Reverse().SkipWhile(IsDelimiter).Skip(1).Reverse().ToArray()); + var numDeleted = beforeText.Length - restText.Length; + CaretPos -= numDeleted; + UpdateText(AlignAgainstMask(restText + afterText)); + } + + /// + /// Applies the mask to the given text starting at the given offset and returns the masked text. + /// + /// + protected virtual string AlignAgainstMask(string text) + { + text ??= ""; + var alignedText = ""; + var textIndex = 0; // index in text + while (textIndex < text.Length) + { + var textChar = text[textIndex]; + if (_regex.IsMatch(alignedText + textChar)) + alignedText += textChar; + // try to skip over a delimiter (input of values only i.e. 31122021 => 31.12.2021) + else if (Delimiters.Length > 0) + { + foreach (var d in Delimiters) + { + if (_regex.IsMatch(alignedText + d + textChar)) + { + alignedText += (d.ToString() + textChar); + break; + } + } + } + textIndex++; + } + return alignedText; + } + + public override void UpdateFrom(IMask other) + { + base.UpdateFrom(other); + var o = other as RegexMask; + if (o == null) + return; + if (Delimiters != o.Delimiters) + { + Delimiters = o.Delimiters; + _initialized = false; + } + Refresh(); + } + + /// + /// Creates a predefined RegexMask for an IPv4 Address with or without port masking. + /// + /// + /// Set to true to include port to the mask. + /// + /// + /// Set the IPv4 maskChar. Default is '0' + /// + public static RegexMask IPv4(bool includePort = false, char maskChar = '0') + { + const string Octet = "25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{0,2}"; + + var ipv4 = $"(?:{Octet})(?:\\.(?:{Octet})){{0,3}}"; + var delimiters = "."; + var octetMask = new string(maskChar, 3); + var mask = string.Join(delimiters, Enumerable.Repeat(octetMask, 4)); + if (includePort) + { + const string IpPort = + "(:|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?"; + ipv4 = $"{ipv4}{IpPort}"; + mask = $"{mask}:{new string(maskChar, 5)}"; + delimiters += ":"; + } + + var regex = $"^{ipv4}{WhiteSpaceFilter}$"; + var regexMask = new RegexMask(regex, mask) { Delimiters = delimiters }; + return regexMask; + } + + /// + /// Creates a predefined RegexMask for an IPv6 Address with or without port masking. + /// + /// + /// Set to true to include port to the mask. + /// + /// + /// Set the IPv6 maskChar. Default is 'X' + /// + /// + /// Set the IPv6 portMask. Default is '0' + /// + public static RegexMask IPv6(bool includePort = false, char maskChar = 'X', char portMaskChar = '0') + { + const string Hex = "[0-9A-Fa-f]{0,4}"; + const string IPv6Filter = "(?!.*?[:]{2}?:)"; + var ipv6 = $"{Hex}(:{Hex}){{0,7}}"; + var delimiters = ":"; + var hexMask = new string(maskChar, 4); + var mask = string.Join(delimiters, Enumerable.Repeat(hexMask, 8)); + if (includePort) + { + const string IpPort = + "(\\]|\\]:|\\]:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?"; + ipv6 = $"((\\[{ipv6}){IpPort})"; + mask = $"[{mask}]:{new(portMaskChar, 5)}"; + delimiters += "[]"; + } + + var regex = $"^{IPv6Filter}{ipv6}{WhiteSpaceFilter}$"; + var regexMask = new RegexMask(regex, mask) { Delimiters = delimiters, AllowOnlyDelimiters = true }; + return regexMask; + } + + /// + /// Creates a predefined RegexMask for Email Address. + /// + /// + /// Set the email mask. Default is "Ex. user@domain.com" + /// + public static RegexMask Email(string mask = "Ex. user@domain.com") + { + const string Regex = $"^(?>[\\w\\-\\+]+\\.?)+(?>@?|@)(?\\w+\\.)*(\\w+)?{WhiteSpaceFilter}$"; + const string Delimiters = "@."; + var regexMask = new RegexMask(Regex, mask) { Delimiters = Delimiters }; + return regexMask; + } +} diff --git a/Utilities/RuntimeLocation.cs b/Utilities/RuntimeLocation.cs new file mode 100644 index 0000000..22e9eb7 --- /dev/null +++ b/Utilities/RuntimeLocation.cs @@ -0,0 +1,13 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Connected.Utilities +{ + [ExcludeFromCodeCoverage] + public class RuntimeLocation + { + public static bool IsClientSide => RuntimeInformation.OSDescription == "Browser"; // WASM + public static bool IsServerSide => RuntimeInformation.OSDescription != "Browser"; + } + +} diff --git a/Utilities/SortingAssistent.cs b/Utilities/SortingAssistent.cs new file mode 100644 index 0000000..a2fb3d4 --- /dev/null +++ b/Utilities/SortingAssistent.cs @@ -0,0 +1,46 @@ +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq.Expressions; +using System.Reflection; +using Connected.Components; + +namespace Connected.Utilities; + +public static class SortingAssistent +{ + public static void UpdateOrder(this IEnumerable items, ItemDropInfo dropInfo, Expression> valueUpdater, int zoneOffset = 0) + { + var memberSelectorExpression = valueUpdater.Body as MemberExpression; + if (memberSelectorExpression == null) { throw new InvalidOperationException(); } + + var property = memberSelectorExpression.Member as PropertyInfo; + + if (property == null) { throw new InvalidOperationException(); } + + var newIndex = dropInfo.IndexInZone + zoneOffset; + + var item = dropInfo.Item; + + int index = 0; + foreach (var _item in items.OrderBy(x => (int)property.GetValue(x))) + { + if (_item.Equals(item) == true) + { + property.SetValue(item, newIndex); + } + else + { + if (index == newIndex) + { + index++; + } + + property.SetValue(_item, index); + + index++; + } + } + } +} diff --git a/Utilities/StyleBuilder.cs b/Utilities/StyleBuilder.cs new file mode 100644 index 0000000..a8fa3a6 --- /dev/null +++ b/Utilities/StyleBuilder.cs @@ -0,0 +1,162 @@ +// Copyright (c) 2011 - 2019 Ed Charbeneau +// License: MIT +// See https://github.com/EdCharbeneau + +using System; +using System.Collections.Generic; + +namespace Connected.Utilities +{ + public struct StyleBuilder + { + private string stringBuffer; + + /// + /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. + /// + /// + /// + public static StyleBuilder Default(string prop, string value) => new(prop, value); + + /// + /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. + /// + /// + public static StyleBuilder Default(string style) => Empty().AddStyle(style); + + /// + /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. + /// + public static StyleBuilder Empty() => new(); + + /// + /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. + /// + /// + /// + public StyleBuilder(string prop, string value) => stringBuffer = $"{prop}:{value};"; + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon. + /// + /// + public StyleBuilder AddStyle(string style) => !string.IsNullOrWhiteSpace(style) ? AddRaw($"{style};") : this; + + /// + /// Adds a raw string to the builder that will be concatenated with the next style or value added to the builder. + /// + /// + /// StyleBuilder + private StyleBuilder AddRaw(string style) + { + stringBuffer += style; + return this; + } + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// + /// Style to add + /// StyleBuilder + public StyleBuilder AddStyle(string prop, string value) => AddRaw($"{prop}:{value};"); + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// + /// Style to conditionally add. + /// Condition in which the style is added. + /// StyleBuilder + public StyleBuilder AddStyle(string prop, string value, bool when = true) => when ? this.AddStyle(prop, value) : this; + + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// + /// Style to conditionally add. + /// Condition in which the style is added. + /// + public StyleBuilder AddStyle(string prop, Func value, bool when = true) => when ? this.AddStyle(prop, value()) : this; + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// + /// Style to conditionally add. + /// Condition in which the style is added. + /// StyleBuilder + public StyleBuilder AddStyle(string prop, string value, Func when = null) => this.AddStyle(prop, value, when != null && when()); + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// + /// Style to conditionally add. + /// Condition in which the style is added. + /// StyleBuilder + public StyleBuilder AddStyle(string prop, Func value, Func when = null) => this.AddStyle(prop, value(), when != null && when()); + + /// + /// Adds a conditional nested StyleBuilder to the builder with separator and closing semicolon. + /// + /// Style Builder to conditionally add. + /// StyleBuilder + public StyleBuilder AddStyle(StyleBuilder builder) => this.AddRaw(builder.Build()); + + /// + /// Adds a conditional nested StyleBuilder to the builder with separator and closing semicolon. + /// + /// Style Builder to conditionally add. + /// Condition in which the style is added. + /// StyleBuilder + public StyleBuilder AddStyle(StyleBuilder builder, bool when = true) => when ? this.AddRaw(builder.Build()) : this; + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// + /// Style Builder to conditionally add. + /// Condition in which the styles are added. + /// StyleBuilder + public StyleBuilder AddStyle(StyleBuilder builder, Func when = null) => this.AddStyle(builder, when != null && when()); + + /// + /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. + /// A ValueBuilder action defines a complex set of values for the property. + /// + /// + /// + /// + public StyleBuilder AddStyle(string prop, Action builder, bool when = true) + { + var values = new ValueBuilder(); + builder(values); + return AddStyle(prop, values.ToString(), when && values.HasValue); + } + + /// + /// Adds a conditional in-line style when it exists in a dictionary to the builder with separator. + /// Null safe operation. + /// + /// Additional Attribute splat parameters + /// StyleBuilder + public StyleBuilder AddStyleFromAttributes(IReadOnlyDictionary additionalAttributes) => + additionalAttributes == null ? this : + additionalAttributes.TryGetValue("style", out var c) ? AddRaw(c.ToString()) : this; + + + /// + /// Finalize the completed Style as a string. + /// + /// string + public string Build() + { + // String buffer finalization code + return stringBuffer != null ? stringBuffer.Trim() : string.Empty; + } + + // ToString should only and always call Build to finalize the rendered string. + public override string ToString() => Build(); + } +} diff --git a/Utilities/ValueBuilder.cs b/Utilities/ValueBuilder.cs new file mode 100644 index 0000000..784102d --- /dev/null +++ b/Utilities/ValueBuilder.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2011 - 2019 Ed Charbeneau +// License: MIT +// See https://github.com/EdCharbeneau + +using System; + +namespace Connected.Utilities +{ + public class ValueBuilder + { + private string stringBuffer; + + public bool HasValue => !string.IsNullOrWhiteSpace(stringBuffer); + /// + /// Adds a space separated conditional value to a property. + /// + /// + /// + /// + public ValueBuilder AddValue(string value, bool when = true) => when ? AddRaw($"{value} ") : this; + public ValueBuilder AddValue(Func value, bool when = true) => when ? AddRaw($"{value()} ") : this; + + private ValueBuilder AddRaw(string style) + { + stringBuffer += style; + return this; + } + + public override string ToString() => stringBuffer != null ? stringBuffer.Trim() : string.Empty; + } +} diff --git a/_Imports.razor b/_Imports.razor new file mode 100644 index 0000000..b4ebe05 --- /dev/null +++ b/_Imports.razor @@ -0,0 +1,6 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.JSInterop \ No newline at end of file diff --git a/compilerconfig.json b/compilerconfig.json new file mode 100644 index 0000000..2f43d70 --- /dev/null +++ b/compilerconfig.json @@ -0,0 +1,10 @@ +[ + { + "outputFile": "wwwroot/Styles.css", + "inputFile": "wwwroot/Styles.scss" + }, + { + "outputFile": "wwwroot/Components.css", + "inputFile": "Styles/Components.scss" + } +] \ No newline at end of file diff --git a/compilerconfig.json.defaults b/compilerconfig.json.defaults new file mode 100644 index 0000000..41870cc --- /dev/null +++ b/compilerconfig.json.defaults @@ -0,0 +1,71 @@ +{ + "compilers": { + "less": { + "autoPrefix": "", + "cssComb": "none", + "ieCompat": true, + "math": null, + "strictMath": false, + "strictUnits": false, + "relativeUrls": true, + "rootPath": "", + "sourceMapRoot": "", + "sourceMapBasePath": "", + "sourceMap": false + }, + "sass": { + "autoPrefix": "", + "loadPaths": "", + "style": "expanded", + "relativeUrls": true, + "sourceMap": false + }, + "nodesass": { + "autoPrefix": "", + "includePath": "", + "indentType": "space", + "indentWidth": 2, + "outputStyle": "nested", + "precision": 5, + "relativeUrls": true, + "sourceMapRoot": "", + "lineFeed": "", + "sourceMap": false + }, + "stylus": { + "sourceMap": false + }, + "babel": { + "sourceMap": false + }, + "coffeescript": { + "bare": false, + "runtimeMode": "node", + "sourceMap": false + }, + "handlebars": { + "root": "", + "noBOM": false, + "name": "", + "namespace": "", + "knownHelpersOnly": false, + "forcePartial": false, + "knownHelpers": [], + "commonjs": "", + "amd": false, + "sourceMap": false + } + }, + "minifiers": { + "css": { + "enabled": true, + "termSemicolons": true, + "gzip": false + }, + "javascript": { + "enabled": true, + "termSemicolons": true, + "gzip": false + } + } +} \ No newline at end of file diff --git a/excubowebcompiler.json b/excubowebcompiler.json new file mode 100644 index 0000000..a481495 --- /dev/null +++ b/excubowebcompiler.json @@ -0,0 +1,56 @@ +{ + "Minifiers": { + "GZip": false, + "Enabled": true, + "Css": { + "CommentMode": "Important", + "ColorNames": "Hex", + "TermSemicolons": true, + "OutputMode": "SingleLine", + "IndentSize": 2 + }, + "Javascript": { + "RenameLocals": false, + "PreserveImportantComments": true, + "EvalTreatment": "Ignore", + "TermSemicolons": true, + "OutputMode": "SingleLine", + "IndentSize": 2 + } + }, + "Autoprefix": { + "Enabled": false, + "ProcessingOptions": { + "Browsers": [ + "last 4 versions" + ], + "Cascade": true, + "Add": true, + "Remove": true, + "Supports": true, + "Flexbox": "All", + "Grid": "None", + "IgnoreUnknownVersions": false, + "Stats": "", + "SourceMap": true, + "InlineSourceMap": false, + "SourceMapIncludeContents": false, + "OmitSourceMapUrl": false + } + }, + "CompilerSettings": { + "Sass": { + "IndentType": "Space", + "IndentWidth": 2, + "OutputStyle": "Nested", + "Precision": 5, + "RelativeUrls": true, + "LineFeed": "Lf", + "SourceMap": false + } + }, + "Output": { + "Preserve": true, + "Directory": "./wwwroot" + } +} diff --git a/wwwroot/Components.css b/wwwroot/Components.css new file mode 100644 index 0000000..c246191 --- /dev/null +++ b/wwwroot/Components.css @@ -0,0 +1,27037 @@ +@charset "UTF-8"; +/*! + * MudBlazor (https://mudblazor.com/) + * Copyright (c) 2021 MudBlazor + * Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE) + */ +.primary { + background-color: var(--palette-primary) !important; +} + +.primary-text { + color: var(--palette-primary) !important; +} + +.primary-hover { + background-color: var(--palette-primary-hover) !important; +} + +.hover\:primary-hover:hover, .hover\:primary-hover:focus-visible { + background-color: var(--palette-primary-hover) !important; +} + +.border-primary { + border-color: var(--palette-primary) !important; +} + +.theme-primary { + color: var(--palette-primary-text) !important; + background-color: var(--palette-primary) !important; +} + +.secondary { + background-color: var(--palette-secondary) !important; +} + +.secondary-text { + color: var(--palette-secondary) !important; +} + +.secondary-hover { + background-color: var(--palette-secondary-hover) !important; +} + +.hover\:secondary-hover:hover, .hover\:secondary-hover:focus-visible { + background-color: var(--palette-secondary-hover) !important; +} + +.border-secondary { + border-color: var(--palette-secondary) !important; +} + +.theme-secondary { + color: var(--palette-secondary-text) !important; + background-color: var(--palette-secondary) !important; +} + +.tertiary { + background-color: var(--palette-tertiary) !important; +} + +.tertiary-text { + color: var(--palette-tertiary) !important; +} + +.tertiary-hover { + background-color: var(--palette-tertiary-hover) !important; +} + +.hover\:tertiary-hover:hover, .hover\:tertiary-hover:focus-visible { + background-color: var(--palette-tertiary-hover) !important; +} + +.border-tertiary { + border-color: var(--palette-tertiary) !important; +} + +.theme-tertiary { + color: var(--palette-tertiary-text) !important; + background-color: var(--palette-tertiary) !important; +} + +.info { + background-color: var(--palette-info) !important; +} + +.info-text { + color: var(--palette-info) !important; +} + +.info-hover { + background-color: var(--palette-info-hover) !important; +} + +.hover\:info-hover:hover, .hover\:info-hover:focus-visible { + background-color: var(--palette-info-hover) !important; +} + +.border-info { + border-color: var(--palette-info) !important; +} + +.theme-info { + color: var(--palette-info-text) !important; + background-color: var(--palette-info) !important; +} + +.success { + background-color: var(--palette-success) !important; +} + +.success-text { + color: var(--palette-success) !important; +} + +.success-hover { + background-color: var(--palette-success-hover) !important; +} + +.hover\:success-hover:hover, .hover\:success-hover:focus-visible { + background-color: var(--palette-success-hover) !important; +} + +.border-success { + border-color: var(--palette-success) !important; +} + +.theme-success { + color: var(--palette-success-text) !important; + background-color: var(--palette-success) !important; +} + +.warning { + background-color: var(--palette-warning) !important; +} + +.warning-text { + color: var(--palette-warning) !important; +} + +.warning-hover { + background-color: var(--palette-warning-hover) !important; +} + +.hover\:warning-hover:hover, .hover\:warning-hover:focus-visible { + background-color: var(--palette-warning-hover) !important; +} + +.border-warning { + border-color: var(--palette-warning) !important; +} + +.theme-warning { + color: var(--palette-warning-text) !important; + background-color: var(--palette-warning) !important; +} + +.error { + background-color: var(--palette-error) !important; +} + +.error-text { + color: var(--palette-error) !important; +} + +.error-hover { + background-color: var(--palette-error-hover) !important; +} + +.hover\:error-hover:hover, .hover\:error-hover:focus-visible { + background-color: var(--palette-error-hover) !important; +} + +.border-error { + border-color: var(--palette-error) !important; +} + +.theme-error { + color: var(--palette-error-text) !important; + background-color: var(--palette-error) !important; +} + +.dark { + background-color: var(--palette-dark) !important; +} + +.dark-text { + color: var(--palette-dark) !important; +} + +.dark-hover { + background-color: var(--palette-dark-hover) !important; +} + +.hover\:dark-hover:hover, .hover\:dark-hover:focus-visible { + background-color: var(--palette-dark-hover) !important; +} + +.border-dark { + border-color: var(--palette-dark) !important; +} + +.theme-dark { + color: var(--palette-dark-text) !important; + background-color: var(--palette-dark) !important; +} + +.inherit-text { + color: inherit !important; +} + +.border-lines-default { + border-color: var(--palette-lines-default); +} + +.background { + background-color: var(--palette-background) !important; +} + +.background-gray { + background-color: var(--palette-background-grey) !important; +} + +.theme-transparent { + color: inherit !important; + background-color: transparent !important; +} + +.transparent { + background-color: transparent !important; +} + +.transparent-text { + color: transparent !important; +} + +.text-primary { + color: var(--palette-text-primary); +} + +.text-secondary { + color: var(--palette-text-secondary); +} + +.text-disabled { + color: var(--palette-text-disabled); +} + +.white { + background-color: #FFFFFF !important; +} + +.white-text { + color: #FFFFFF !important; +} + +.black { + background-color: #000000 !important; +} + +.black-text { + color: #000000 !important; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; + border-width: 0; + border-style: solid; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +strong, b { + font-weight: 700; +} + +body { + color: var(--palette-text-primary); + font-family: var(--typography-default-family); + font-size: var(--typography-default-size); + font-weight: var(--typography-default-weight); + line-height: var(--typography-default-lineheight); + letter-spacing: var(--typography-default-letterspacing); + text-transform: var(--typography-default-text-transform); + background-color: var(--palette-background); +} + +a { + color: var(--palette-text-primary); +} + +.layout { + height: 100%; + width: 100%; + position: relative; +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 9999; +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} + +#components-reconnect-modal { + z-index: 9999 !important; +} +#components-reconnect-modal h5 { + font-size: 18px; +} +#components-reconnect-modal button { + color: var(--palette-text-primary); + padding: 8px 16px; + font-size: 0.875rem; + min-width: 64px; + box-sizing: border-box; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + font-weight: 500; + line-height: 1; + border-radius: var(--default-borderradius); + letter-spacing: 0.02857em; + text-transform: uppercase; + margin: 40px auto !important; +} +#components-reconnect-modal button:hover { + background-color: var(--palette-action-default-hover); +} + +@keyframes animation-fadein { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-moz-keyframes animation-fadein { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-webkit-keyframes animation-fadein { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-o-keyframes animation-fadein { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-ms-keyframes animation-fadein { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-webkit-keyframes scale-up-center { + 0% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@keyframes scale-up-center { + 0% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes skeleton-keyframes-pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.4; + } + 100% { + opacity: 1; + } +} +@-webkit-keyframes skeleton-keyframes-wave { + 0% { + transform: translateX(-100%); + } + 60% { + transform: translateX(100%); + } + 100% { + transform: translateX(100%); + } +} +@-webkit-keyframes progress-circular-keyframes-circular-rotate { + 0% { + transform-origin: 50% 50%; + } + 100% { + transform: rotate(360deg); + } +} +@-webkit-keyframes progress-circular-keyframes-circular-dash { + 0% { + stroke-dasharray: 1px, 200px; + stroke-dashoffset: 0px; + } + 50% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -15px; + } + 100% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -125px; + } +} +@-webkit-keyframes progress-linear-horizontal-keyframes-indeterminate1 { + 0% { + left: -35%; + right: 100%; + } + 60% { + left: 100%; + right: -90%; + } + 100% { + left: 100%; + right: -90%; + } +} +@-webkit-keyframes progress-linear-horizontal-keyframes-indeterminate2 { + 0% { + left: -200%; + right: 100%; + } + 60% { + left: 107%; + right: -8%; + } + 100% { + left: 107%; + right: -8%; + } +} +@-webkit-keyframes progress-linear-horizontal-keyframes-buffer { + 0% { + opacity: 1; + background-position: 0 -23px; + } + 50% { + opacity: 0; + background-position: 0 -23px; + } + 100% { + opacity: 1; + background-position: -200px -23px; + } +} +@-webkit-keyframes progress-linear-vertical-keyframes-indeterminate1 { + 0% { + bottom: -35%; + top: 100%; + } + 60% { + bottom: 100%; + top: -90%; + } + 100% { + bottom: 100%; + top: -90%; + } +} +@-webkit-keyframes progress-linear-vertical-keyframes-indeterminate2 { + 0% { + bottom: -200%; + top: 100%; + } + 60% { + bottom: 107%; + top: -8%; + } + 100% { + bottom: 107%; + top: -8%; + } +} +@-webkit-keyframes progress-linear-vertical-keyframes-buffer { + 0% { + opacity: 1; + background-position: -23px 0; + } + 50% { + opacity: 0; + background-position: -23px 0; + } + 100% { + opacity: 1; + background-position: -23px -200px; + } +} +@keyframes progress-linear-striped-loading { + 0% { + background-position: 0 0; + } + 100% { + background-position: 300px 0; + } +} +a { + text-decoration: none; +} +a:focus-visible { + outline: none; +} + +label { + display: inline-block; +} + +button { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + display: inline-flex; + outline: 0; + padding: 0; + position: relative; + align-items: center; + user-select: none; + border-radius: 0; + vertical-align: middle; + -moz-appearance: none; + justify-content: center; + text-decoration: none; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; +} + +button:focus { + outline: none; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +select { + word-wrap: normal; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} + +iframe { + border: none; + height: 100%; + width: 100%; +} + +ul { + margin: 0; + padding: 0; + list-style: none; +} + +.elevation-0 { + box-shadow: var(--elevation-0); +} + +.elevation-1 { + box-shadow: var(--elevation-1); +} + +.elevation-2 { + box-shadow: var(--elevation-2); +} + +.elevation-3 { + box-shadow: var(--elevation-3); +} + +.elevation-4 { + box-shadow: var(--elevation-4); +} + +.elevation-5 { + box-shadow: var(--elevation-5); +} + +.elevation-6 { + box-shadow: var(--elevation-6); +} + +.elevation-7 { + box-shadow: var(--elevation-7); +} + +.elevation-8 { + box-shadow: var(--elevation-8); +} + +.elevation-9 { + box-shadow: var(--elevation-9); +} + +.elevation-10 { + box-shadow: var(--elevation-10); +} + +.elevation-11 { + box-shadow: var(--elevation-11); +} + +.elevation-12 { + box-shadow: var(--elevation-12); +} + +.elevation-13 { + box-shadow: var(--elevation-13); +} + +.elevation-14 { + box-shadow: var(--elevation-14); +} + +.elevation-15 { + box-shadow: var(--elevation-15); +} + +.elevation-16 { + box-shadow: var(--elevation-16); +} + +.elevation-17 { + box-shadow: var(--elevation-17); +} + +.elevation-18 { + box-shadow: var(--elevation-18); +} + +.elevation-19 { + box-shadow: var(--elevation-19); +} + +.elevation-20 { + box-shadow: var(--elevation-20); +} + +.elevation-21 { + box-shadow: var(--elevation-21); +} + +.elevation-22 { + box-shadow: var(--elevation-22); +} + +.elevation-23 { + box-shadow: var(--elevation-23); +} + +.elevation-24 { + box-shadow: var(--elevation-24); +} + +.elevation-25 { + box-shadow: var(--elevation-25); +} + +.alert { + display: flex; + padding: 6px 16px; + border-radius: var(--default-borderradius); + background-color: transparent; + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.alert.square { + border-radius: 0px; +} +.alert.dense { + padding: 0px 12px; +} + +.alert-text-normal { + color: var(--palette-text-primary); + background-color: var(--palette-dark-hover); +} +.alert-text-primary { + color: var(--palette-primary-darken); + background-color: var(--palette-primary-hover); +} +.alert-text-primary .alert-icon { + color: var(--palette-primary); +} +.alert-text-secondary { + color: var(--palette-secondary-darken); + background-color: var(--palette-secondary-hover); +} +.alert-text-secondary .alert-icon { + color: var(--palette-secondary); +} +.alert-text-tertiary { + color: var(--palette-tertiary-darken); + background-color: var(--palette-tertiary-hover); +} +.alert-text-tertiary .alert-icon { + color: var(--palette-tertiary); +} +.alert-text-info { + color: var(--palette-info-darken); + background-color: var(--palette-info-hover); +} +.alert-text-info .alert-icon { + color: var(--palette-info); +} +.alert-text-success { + color: var(--palette-success-darken); + background-color: var(--palette-success-hover); +} +.alert-text-success .alert-icon { + color: var(--palette-success); +} +.alert-text-warning { + color: var(--palette-warning-darken); + background-color: var(--palette-warning-hover); +} +.alert-text-warning .alert-icon { + color: var(--palette-warning); +} +.alert-text-error { + color: var(--palette-error-darken); + background-color: var(--palette-error-hover); +} +.alert-text-error .alert-icon { + color: var(--palette-error); +} +.alert-text-dark { + color: var(--palette-dark-darken); + background-color: var(--palette-dark-hover); +} +.alert-text-dark .alert-icon { + color: var(--palette-dark); +} + +.alert-outlined-normal { + color: var(--palette-text-primary); + border: 1px solid var(--palette-text-primary); +} +.alert-outlined-primary { + color: var(--palette-primary-darken); + border: 1px solid var(--palette-primary); +} +.alert-outlined-primary .alert-icon { + color: var(--palette-primary); +} +.alert-outlined-secondary { + color: var(--palette-secondary-darken); + border: 1px solid var(--palette-secondary); +} +.alert-outlined-secondary .alert-icon { + color: var(--palette-secondary); +} +.alert-outlined-tertiary { + color: var(--palette-tertiary-darken); + border: 1px solid var(--palette-tertiary); +} +.alert-outlined-tertiary .alert-icon { + color: var(--palette-tertiary); +} +.alert-outlined-info { + color: var(--palette-info-darken); + border: 1px solid var(--palette-info); +} +.alert-outlined-info .alert-icon { + color: var(--palette-info); +} +.alert-outlined-success { + color: var(--palette-success-darken); + border: 1px solid var(--palette-success); +} +.alert-outlined-success .alert-icon { + color: var(--palette-success); +} +.alert-outlined-warning { + color: var(--palette-warning-darken); + border: 1px solid var(--palette-warning); +} +.alert-outlined-warning .alert-icon { + color: var(--palette-warning); +} +.alert-outlined-error { + color: var(--palette-error-darken); + border: 1px solid var(--palette-error); +} +.alert-outlined-error .alert-icon { + color: var(--palette-error); +} +.alert-outlined-dark { + color: var(--palette-dark-darken); + border: 1px solid var(--palette-dark); +} +.alert-outlined-dark .alert-icon { + color: var(--palette-dark); +} + +.alert-filled-normal { + color: var(--palette-dark-text); + font-weight: 500; + background-color: var(--palette-dark); +} +.alert-filled-primary { + color: var(--palette-primary-text); + font-weight: 500; + background-color: var(--palette-primary); +} +.alert-filled-secondary { + color: var(--palette-secondary-text); + font-weight: 500; + background-color: var(--palette-secondary); +} +.alert-filled-tertiary { + color: var(--palette-tertiary-text); + font-weight: 500; + background-color: var(--palette-tertiary); +} +.alert-filled-info { + color: var(--palette-info-text); + font-weight: 500; + background-color: var(--palette-info); +} +.alert-filled-success { + color: var(--palette-success-text); + font-weight: 500; + background-color: var(--palette-success); +} +.alert-filled-warning { + color: var(--palette-warning-text); + font-weight: 500; + background-color: var(--palette-warning); +} +.alert-filled-error { + color: var(--palette-error-text); + font-weight: 500; + background-color: var(--palette-error); +} +.alert-filled-dark { + color: var(--palette-dark-text); + font-weight: 500; + background-color: var(--palette-dark); +} + +.alert-icon { + display: flex; + opacity: 0.9; + padding: 7px 0; + font-size: 22px; + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} +.alert-icon.alert-icon-left { + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} +.alert-icon.alert-icon-right { + margin-left: 12px; + margin-inline-start: 12px; + margin-inline-end: unset; +} + +.alert-message { + padding: 9px 0; +} + +.alert-position { + flex: 1; + display: flex; +} + +.alert-close { + display: flex; + flex: 0; + align-items: center; + margin-left: 8px; +} + +.badge-root { + position: relative; + display: inline-block; +} +.badge-root .badge-wrapper { + top: 0; + left: 0; + flex: 0 1; + width: 100%; + height: 100%; + display: flex; + pointer-events: none; + position: absolute; +} +.badge-root .badge-wrapper.badge-top { + align-items: flex-start; +} +.badge-root .badge-wrapper.badge-top.left { + justify-content: flex-start; +} +.badge-root .badge-wrapper.badge-top.center { + justify-content: center; +} +.badge-root .badge-wrapper.badge-top.right { + justify-content: flex-end; +} +.badge-root .badge-wrapper.badge-center { + align-items: center; +} +.badge-root .badge-wrapper.badge-center.left { + justify-content: flex-start; +} +.badge-root .badge-wrapper.badge-center.center { + justify-content: center; +} +.badge-root .badge-wrapper.badge-center.right { + justify-content: flex-end; +} +.badge-root .badge-wrapper.badge-bottom { + align-items: flex-end; +} +.badge-root .badge-wrapper.badge-bottom.left { + justify-content: flex-start; +} +.badge-root .badge-wrapper.badge-bottom.center { + justify-content: center; +} +.badge-root .badge-wrapper.badge-bottom.right { + justify-content: flex-end; +} + +.badge { + border-radius: 10px; + font-size: 12px; + height: 20px; + letter-spacing: 0; + min-width: 20px; + padding: 4px 6px; + pointer-events: auto; + line-height: 1; + position: absolute; + text-align: center; + text-indent: 0; + top: auto; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); + white-space: nowrap; +} +.badge.badge-default { + color: var(--palette-text-primary); + background-color: var(--palette-grey-light); +} +.badge.badge-bordered { + border-color: var(--palette-surface); + border-style: solid; + border-width: 2px; + padding: 3px 4px; +} +.badge.badge-bordered.badge-icon { + padding: 4px 6px; +} +.badge.badge-bordered.badge-icon .icon-badge { + margin-left: -4px; + margin-inline-start: -4px; + margin-inline-end: unset; + margin-top: -4px; +} +.badge.badge-icon { + width: 20px; + height: 20px; +} +.badge.badge-icon .icon-badge { + color: inherit; + font-size: 12px; + margin-left: -2px; + margin-inline-start: -2px; + margin-inline-end: unset; +} +.badge.badge-dot { + border-radius: 50%; + height: 9px; + min-width: 0; + padding: 0; + width: 9px; +} +.badge.badge-top.left { + inset: auto calc(100% - 4px) calc(100% - 4px) auto; +} +.badge.badge-top.left.badge-overlap { + inset: auto calc(100% - 12px) calc(100% - 12px) auto; +} +.badge.badge-top.center { + bottom: calc(100% - 4px); +} +.badge.badge-top.center.badge-overlap { + bottom: calc(100% - 12px); +} +.badge.badge-top.right { + inset: auto auto calc(100% - 4px) calc(100% - 4px); +} +.badge.badge-top.right.badge-overlap { + inset: auto auto calc(100% - 12px) calc(100% - 12px); +} +.badge.badge-center.left { + right: calc(100% - 4px); +} +.badge.badge-center.left.badge-overlap { + right: calc(100% - 12px); +} +.badge.badge-center.right { + left: calc(100% - 4px); +} +.badge.badge-center.right.badge-overlap { + left: calc(100% - 12px); +} +.badge.badge-bottom.left { + inset: calc(100% - 4px) calc(100% - 4px) auto auto; +} +.badge.badge-bottom.left.badge-overlap { + inset: calc(100% - 12px) calc(100% - 12px) auto auto; +} +.badge.badge-bottom.center { + top: calc(100% - 4px); +} +.badge.badge-bottom.center.badge-overlap { + top: calc(100% - 12px); +} +.badge.badge-bottom.right { + inset: calc(100% - 4px) auto auto calc(100% - 4px); +} +.badge.badge-bottom.right.badge-overlap { + inset: calc(100% - 12px) auto auto calc(100% - 12px); +} + +.toolbar { + display: flex; + position: relative; + align-items: center; + height: 56px; +} + +.toolbar-gutters { + padding-left: 16px; + padding-right: 16px; +} + +@media (min-width: 0px) and (orientation: landscape) { + .toolbar { + height: 48px; + } +} +@media (min-width: 600px) { + .toolbar { + height: 64px; + } + + .toolbar-gutters { + padding-left: 24px; + padding-right: 24px; + } +} +.toolbar-dense { + height: 48px; +} + +.tooltip-root { + width: fit-content; +} +.tooltip-root.tooltip-inline { + display: inline-block; +} + +.tooltip { + padding: 4px 8px; + text-align: center; + align-items: center; + justify-content: center; + font-weight: 500; + font-size: 12px; + line-height: 1.4em; + border-radius: var(--default-borderradius); + z-index: var(--zindex-tooltip); +} +.tooltip.tooltip-default { + color: var(--palette-dark-text); + background-color: var(--palette-grey-darker); +} +.tooltip.tooltip-default.tooltip-arrow::after { + border-color: var(--palette-grey-darker) transparent transparent transparent; +} +.tooltip.tooltip-center-left:not([data-mudpopover-flip]), .tooltip.tooltip-center-right[data-mudpopover-flip] { + transform: translateX(-10px); +} +.tooltip.tooltip-center-left:not([data-mudpopover-flip]).tooltip-arrow::after, .tooltip.tooltip-center-right[data-mudpopover-flip].tooltip-arrow::after { + left: 100%; + transform: rotate(270deg); +} +.tooltip.tooltip-center-right:not([data-mudpopover-flip]), .tooltip.tooltip-center-left[data-mudpopover-flip] { + transform: translateX(10px); +} +.tooltip.tooltip-center-right:not([data-mudpopover-flip]).tooltip-arrow::after, .tooltip.tooltip-center-left[data-mudpopover-flip].tooltip-arrow::after { + right: 100%; + transform: rotate(90deg); +} +.tooltip.tooltip-top-center:not([data-mudpopover-flip]), .tooltip.tooltip-bottom-center[data-mudpopover-flip] { + transform: translateY(-10px); +} +.tooltip.tooltip-top-center:not([data-mudpopover-flip]).tooltip-arrow::after, .tooltip.tooltip-bottom-center[data-mudpopover-flip].tooltip-arrow::after { + top: 100%; + transform: rotate(0deg); +} +.tooltip.tooltip-bottom-center:not([data-mudpopover-flip]), .tooltip.tooltip-top-center[data-mudpopover-flip] { + transform: translateY(10px); +} +.tooltip.tooltip-bottom-center:not([data-mudpopover-flip]).tooltip-arrow::after, .tooltip.tooltip-top-center[data-mudpopover-flip].tooltip-arrow::after { + bottom: 100%; + transform: rotate(180deg); +} +.tooltip.tooltip-arrow::after { + content: ""; + position: absolute; + border-width: 6px; + border-style: solid; + border-color: transparent; + border-top-color: inherit; +} + +.avatar { + display: flex; + overflow: hidden; + position: relative; + display: inline-flex; + align-items: center; + flex-shrink: 0; + line-height: 1; + user-select: none; + border-radius: 50%; + justify-content: center; + color: var(--palette-white); + background-color: var(--palette-grey-light); +} +.avatar.avatar-small { + width: 24px; + height: 24px; + font-size: 0.875rem; +} +.avatar.avatar-medium { + width: 40px; + height: 40px; + font-size: 1.25rem; +} +.avatar.avatar-large { + width: 56px; + height: 56px; + font-size: 1.75rem; +} + +.avatar-rounded { + border-radius: var(--default-borderradius); +} + +.avatar-square { + border-radius: 0; +} + +.avatar-img { + color: transparent; + width: 100%; + height: 100%; + object-fit: cover; + text-align: center; + text-indent: 10000px; +} + +.avatar-fallback { + width: 75%; + height: 75%; +} + +.avatar-outlined { + color: var(--palette-text-primary); + background-color: unset; + border: 1px solid var(--palette-text-primary); +} +.avatar-outlined.avatar-outlined-primary { + color: var(--palette-primary); + border: 1px solid var(--palette-primary); +} +.avatar-outlined.avatar-outlined-secondary { + color: var(--palette-secondary); + border: 1px solid var(--palette-secondary); +} +.avatar-outlined.avatar-outlined-tertiary { + color: var(--palette-tertiary); + border: 1px solid var(--palette-tertiary); +} +.avatar-outlined.avatar-outlined-info { + color: var(--palette-info); + border: 1px solid var(--palette-info); +} +.avatar-outlined.avatar-outlined-success { + color: var(--palette-success); + border: 1px solid var(--palette-success); +} +.avatar-outlined.avatar-outlined-warning { + color: var(--palette-warning); + border: 1px solid var(--palette-warning); +} +.avatar-outlined.avatar-outlined-error { + color: var(--palette-error); + border: 1px solid var(--palette-error); +} +.avatar-outlined.avatar-outlined-dark { + color: var(--palette-dark); + border: 1px solid var(--palette-dark); +} + +.avatar-filled { + color: var(--palette-white); + background-color: var(--palette-grey-light); +} +.avatar-filled.avatar-filled-primary { + background-color: var(--palette-primary); +} +.avatar-filled.avatar-filled-secondary { + background-color: var(--palette-secondary); +} +.avatar-filled.avatar-filled-tertiary { + background-color: var(--palette-tertiary); +} +.avatar-filled.avatar-filled-info { + background-color: var(--palette-info); +} +.avatar-filled.avatar-filled-success { + background-color: var(--palette-success); +} +.avatar-filled.avatar-filled-warning { + background-color: var(--palette-warning); +} +.avatar-filled.avatar-filled-error { + background-color: var(--palette-error); +} +.avatar-filled.avatar-filled-dark { + background-color: var(--palette-dark); +} + +.avatar-group { + display: flex; +} +.avatar-group .avatar:first-child { + margin-inline-start: 0px !important; +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-transparent .avatar:not(.avatar-outlined) { + border-color: transparent; +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-surface .avatar:not(.avatar-outlined) { + border-color: var(--palette-surface); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-primary .avatar:not(.avatar-outlined) { + border-color: var(--palette-primary); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-secondary .avatar:not(.avatar-outlined) { + border-color: var(--palette-secondary); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-tertiary .avatar:not(.avatar-outlined) { + border-color: var(--palette-tertiary); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-info .avatar:not(.avatar-outlined) { + border-color: var(--palette-info); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-success .avatar:not(.avatar-outlined) { + border-color: var(--palette-success); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-warning .avatar:not(.avatar-outlined) { + border-color: var(--palette-warning); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-error .avatar:not(.avatar-outlined) { + border-color: var(--palette-error); +} +.avatar-group.avatar-group-outlined.avatar-group-outlined-dark .avatar:not(.avatar-outlined) { + border-color: var(--palette-dark); +} +.avatar-group.avatar-group-outlined .avatar { + border: 2px solid; +} +.avatar-group.avatar-group-outlined .avatar.avatar-small { + width: 28px; + height: 28px; +} +.avatar-group.avatar-group-outlined .avatar.avatar-medium { + width: 44px; + height: 44px; +} +.avatar-group.avatar-group-outlined .avatar.avatar-large { + width: 60px; + height: 60px; +} + +.breadcrumbs { + display: flex; + flex-wrap: wrap; + flex: 0 1 auto; + align-items: center; + list-style-type: none; + margin: 0; + padding: 16px 12px; +} + +.breadcrumb-separator { + padding: 0 12px; +} + +.breadcrumb-separator > span { + color: var(--palette-text-primary); + opacity: 0.38; +} + +.breadcrumb-item > a { + display: flex; + align-items: center; +} + +.breadcrumb-item > a > svg.icon-root { + margin-right: 4px; + margin-inline-end: 4px; + margin-inline-start: unset; +} + +.breadcrumb-item.disabled > a { + pointer-events: none; + color: var(--palette-action-disabled); +} + +.breadcrumbs-expander { + cursor: pointer; + display: flex; + background-color: #EEEEEE; +} + +.breadcrumbs-expander:hover { + background-color: #E0E0E0; +} + +.breadcrumbs-expander > svg { + width: 26px; +} + +.button-root { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + display: inline-flex; + outline: 0; + padding: 0; + position: relative; + align-items: center; + user-select: none; + border-radius: 0; + vertical-align: middle; + -moz-appearance: none; + justify-content: center; + text-decoration: none; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; +} +.button-root::-moz-focus-inner { + border-style: none; +} +.button-root:disabled { + color: var(--palette-action-disabled) !important; + cursor: default; + pointer-events: none; +} + +.button { + padding: 6px 16px; + font-family: var(--typography-button-family); + font-size: var(--typography-button-size); + font-weight: var(--typography-button-weight); + line-height: var(--typography-button-lineheight); + letter-spacing: var(--typography-button-letterspacing); + text-transform: var(--typography-button-text-transform); + min-width: 64px; + box-sizing: border-box; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: var(--default-borderradius); + color: var(--palette-text-primary); +} +.button:hover, .button:focus-visible { + background-color: var(--palette-action-default-hover); +} + +.button-label { + width: 100%; + display: inherit; + align-items: inherit; + justify-content: inherit; +} + +.button-text { + padding: 6px 8px; +} +.button-text.button-text-inherit { + color: inherit; +} +.button-text.button-text-primary { + color: var(--palette-primary); +} +.button-text.button-text-primary:hover, .button-text.button-text-primary:focus-visible { + background-color: var(--palette-primary-hover); +} +.button-text.button-text-secondary { + color: var(--palette-secondary); +} +.button-text.button-text-secondary:hover, .button-text.button-text-secondary:focus-visible { + background-color: var(--palette-secondary-hover); +} +.button-text.button-text-tertiary { + color: var(--palette-tertiary); +} +.button-text.button-text-tertiary:hover, .button-text.button-text-tertiary:focus-visible { + background-color: var(--palette-tertiary-hover); +} +.button-text.button-text-info { + color: var(--palette-info); +} +.button-text.button-text-info:hover, .button-text.button-text-info:focus-visible { + background-color: var(--palette-info-hover); +} +.button-text.button-text-success { + color: var(--palette-success); +} +.button-text.button-text-success:hover, .button-text.button-text-success:focus-visible { + background-color: var(--palette-success-hover); +} +.button-text.button-text-warning { + color: var(--palette-warning); +} +.button-text.button-text-warning:hover, .button-text.button-text-warning:focus-visible { + background-color: var(--palette-warning-hover); +} +.button-text.button-text-error { + color: var(--palette-error); +} +.button-text.button-text-error:hover, .button-text.button-text-error:focus-visible { + background-color: var(--palette-error-hover); +} +.button-text.button-text-dark { + color: var(--palette-dark); +} +.button-text.button-text-dark:hover, .button-text.button-text-dark:focus-visible { + background-color: var(--palette-dark-hover); +} + +.button-outlined { + color: var(--palette-text-primary); + border: 1px solid var(--palette-text-primary); + padding: 5px 15px; +} +.button-outlined.button-outlined-inherit { + color: inherit; + border-color: currentColor; +} +.button-outlined.icon-button { + padding: 5px; +} +.button-outlined:hover, .button-outlined:focus-visible { + background-color: var(--palette-action-default-hover); +} +.button-outlined.button-outlined-primary { + color: var(--palette-primary); + border: 1px solid var(--palette-primary); +} +.button-outlined.button-outlined-primary:hover, .button-outlined.button-outlined-primary:focus-visible { + border: 1px solid var(--palette-primary); + background-color: var(--palette-primary-hover); +} +.button-outlined.button-outlined-secondary { + color: var(--palette-secondary); + border: 1px solid var(--palette-secondary); +} +.button-outlined.button-outlined-secondary:hover, .button-outlined.button-outlined-secondary:focus-visible { + border: 1px solid var(--palette-secondary); + background-color: var(--palette-secondary-hover); +} +.button-outlined.button-outlined-tertiary { + color: var(--palette-tertiary); + border: 1px solid var(--palette-tertiary); +} +.button-outlined.button-outlined-tertiary:hover, .button-outlined.button-outlined-tertiary:focus-visible { + border: 1px solid var(--palette-tertiary); + background-color: var(--palette-tertiary-hover); +} +.button-outlined.button-outlined-info { + color: var(--palette-info); + border: 1px solid var(--palette-info); +} +.button-outlined.button-outlined-info:hover, .button-outlined.button-outlined-info:focus-visible { + border: 1px solid var(--palette-info); + background-color: var(--palette-info-hover); +} +.button-outlined.button-outlined-success { + color: var(--palette-success); + border: 1px solid var(--palette-success); +} +.button-outlined.button-outlined-success:hover, .button-outlined.button-outlined-success:focus-visible { + border: 1px solid var(--palette-success); + background-color: var(--palette-success-hover); +} +.button-outlined.button-outlined-warning { + color: var(--palette-warning); + border: 1px solid var(--palette-warning); +} +.button-outlined.button-outlined-warning:hover, .button-outlined.button-outlined-warning:focus-visible { + border: 1px solid var(--palette-warning); + background-color: var(--palette-warning-hover); +} +.button-outlined.button-outlined-error { + color: var(--palette-error); + border: 1px solid var(--palette-error); +} +.button-outlined.button-outlined-error:hover, .button-outlined.button-outlined-error:focus-visible { + border: 1px solid var(--palette-error); + background-color: var(--palette-error-hover); +} +.button-outlined.button-outlined-dark { + color: var(--palette-dark); + border: 1px solid var(--palette-dark); +} +.button-outlined.button-outlined-dark:hover, .button-outlined.button-outlined-dark:focus-visible { + border: 1px solid var(--palette-dark); + background-color: var(--palette-dark-hover); +} +.button-outlined:disabled { + border: 1px solid var(--palette-action-disabled-background); +} + +.button-filled { + color: var(--palette-text-primary); + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); + background-color: var(--palette-action-default-hover); +} +.button-filled.icon-button { + padding: 6px; +} +.button-filled:hover, .button-filled:focus-visible { + box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12); + background-color: var(--palette-action-disabled-background); +} +.button-filled:active { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); +} +.button-filled:disabled { + color: var(--palette-action-disabled); + box-shadow: none; + background-color: var(--palette-action-disabled-background) !important; +} +.button-filled.button-filled-primary { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.button-filled.button-filled-primary:hover, .button-filled.button-filled-primary:focus-visible { + background-color: var(--palette-primary-darken); +} +.button-filled.button-filled-secondary { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.button-filled.button-filled-secondary:hover, .button-filled.button-filled-secondary:focus-visible { + background-color: var(--palette-secondary-darken); +} +.button-filled.button-filled-tertiary { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.button-filled.button-filled-tertiary:hover, .button-filled.button-filled-tertiary:focus-visible { + background-color: var(--palette-tertiary-darken); +} +.button-filled.button-filled-info { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.button-filled.button-filled-info:hover, .button-filled.button-filled-info:focus-visible { + background-color: var(--palette-info-darken); +} +.button-filled.button-filled-success { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.button-filled.button-filled-success:hover, .button-filled.button-filled-success:focus-visible { + background-color: var(--palette-success-darken); +} +.button-filled.button-filled-warning { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.button-filled.button-filled-warning:hover, .button-filled.button-filled-warning:focus-visible { + background-color: var(--palette-warning-darken); +} +.button-filled.button-filled-error { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.button-filled.button-filled-error:hover, .button-filled.button-filled-error:focus-visible { + background-color: var(--palette-error-darken); +} +.button-filled.button-filled-dark { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} +.button-filled.button-filled-dark:hover, .button-filled.button-filled-dark:focus-visible { + background-color: var(--palette-dark-darken); +} + +.button-disable-elevation { + box-shadow: none; +} +.button-disable-elevation:hover { + box-shadow: none; +} +.button-disable-elevation:active { + box-shadow: none; +} +.button-disable-elevation.focus-visible { + box-shadow: none; +} +.button-disable-elevation:disabled { + box-shadow: none; +} + +.button-color-inherit { + color: inherit; + border-color: currentColor; +} + +.button-text-size-small { + padding: 4px 5px; + font-size: 0.8125rem; +} + +.button-text-size-large { + padding: 8px 11px; + font-size: 0.9375rem; +} + +.button-outlined-size-small { + padding: 3px 9px; + font-size: 0.8125rem; +} +.button-outlined-size-small.icon-button { + padding: 4px; +} + +.button-outlined-size-large { + padding: 7px 21px; + font-size: 0.9375rem; +} +.button-outlined-size-large.icon-button { + padding: 4px; +} + +.button-filled-size-small { + padding: 4px 10px; + font-size: 0.8125rem; +} +.button-filled-size-small.icon-button { + padding: 5px; +} + +.button-filled-size-large { + padding: 8px 22px; + font-size: 0.9375rem; +} +.button-filled-size-large.icon-button { + padding: 5px; +} + +.button-full-width { + width: 100%; +} + +.button-label .button-icon-start { + display: inherit; + margin-left: -4px; + margin-right: 8px; + margin-inline-start: -4px; + margin-inline-end: 8px; +} +.button-label .button-icon-start.button-icon-size-small { + margin-left: -2px; + margin-inline-start: -2px; + margin-inline-end: 8px; +} +.button-label .button-icon-end { + display: inherit; + margin-left: 8px; + margin-right: -4px; + margin-inline-start: 8px; + margin-inline-end: -4px; +} +.button-label .button-icon-end.button-icon-size-small { + margin-right: -2px; + margin-inline-end: -2px; + margin-inline-start: 8px; +} + +.button-icon-size-small > *:first-child { + font-size: 18px; +} + +.button-icon-size-medium > *:first-child { + font-size: 20px; +} + +.button-icon-size-large > *:first-child { + font-size: 22px; +} + +.button-group-root { + border-radius: var(--default-borderradius); + display: inline-flex; +} +.button-group-root .button-root { + border-radius: var(--default-borderradius); +} +.button-group-root.button-group-override-styles .button { + color: var(--palette-text-primary); +} +.button-group-root.button-group-override-styles .button-root { + background-color: inherit; + box-shadow: none; + border: none; +} +.button-group-root.button-group-override-styles .button-root:hover, .button-group-root.button-group-override-styles .button-root:focus-visible { + background-color: var(--palette-action-default-hover); +} + +.button-group-horizontal:not(.button-group-rtl) > .button-root:not(:last-child), .button-group-horizontal:not(.button-group-rtl) > :not(:last-child) .button-root { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.button-group-horizontal:not(.button-group-rtl) > .button-root:not(:first-child), .button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; +} +.button-group-horizontal.button-group-rtl > .button-root:not(:last-child), .button-group-horizontal.button-group-rtl > :not(:last-child) .button-root { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; +} +.button-group-horizontal.button-group-rtl > .button-root:not(:first-child), .button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.button-group-vertical { + flex-direction: column; +} +.button-group-vertical .icon-button { + width: 100%; +} +.button-group-vertical > .button-root:not(:last-child), .button-group-vertical > :not(:last-child) .button-root { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.button-group-vertical > .button-root:not(:first-child), .button-group-vertical > :not(:first-child) .button-root { + border-top-right-radius: 0; + border-top-left-radius: 0; + margin-top: -1px; +} + +.button-group-text.button-group-override-styles .button-root { + padding: 6px 8px; +} +.button-group-text.button-group-override-styles.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-text-primary); +} +.button-group-text.button-group-override-styles.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-text-primary); +} +.button-group-text.button-group-override-styles.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-text-primary); +} +.button-group-text.button-group-override-styles.button-group-text-primary .button-root { + color: var(--palette-primary); +} +.button-group-text.button-group-override-styles.button-group-text-primary .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-primary .button-root:focus-visible { + background-color: var(--palette-primary-hover); +} +.button-group-text.button-group-override-styles.button-group-text-primary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-primary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-primary); +} +.button-group-text.button-group-override-styles.button-group-text-primary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-primary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-primary); +} +.button-group-text.button-group-override-styles.button-group-text-primary.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-primary.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-primary); +} +.button-group-text.button-group-override-styles.button-group-text-secondary .button-root { + color: var(--palette-secondary); +} +.button-group-text.button-group-override-styles.button-group-text-secondary .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-secondary .button-root:focus-visible { + background-color: var(--palette-secondary-hover); +} +.button-group-text.button-group-override-styles.button-group-text-secondary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-secondary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-secondary); +} +.button-group-text.button-group-override-styles.button-group-text-secondary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-secondary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-secondary); +} +.button-group-text.button-group-override-styles.button-group-text-secondary.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-secondary.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-secondary); +} +.button-group-text.button-group-override-styles.button-group-text-tertiary .button-root { + color: var(--palette-tertiary); +} +.button-group-text.button-group-override-styles.button-group-text-tertiary .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-tertiary .button-root:focus-visible { + background-color: var(--palette-tertiary-hover); +} +.button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-tertiary); +} +.button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-tertiary); +} +.button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-tertiary.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-tertiary); +} +.button-group-text.button-group-override-styles.button-group-text-info .button-root { + color: var(--palette-info); +} +.button-group-text.button-group-override-styles.button-group-text-info .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-info .button-root:focus-visible { + background-color: var(--palette-info-hover); +} +.button-group-text.button-group-override-styles.button-group-text-info.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-info.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-info); +} +.button-group-text.button-group-override-styles.button-group-text-info.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-info.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-info); +} +.button-group-text.button-group-override-styles.button-group-text-info.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-info.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-info); +} +.button-group-text.button-group-override-styles.button-group-text-success .button-root { + color: var(--palette-success); +} +.button-group-text.button-group-override-styles.button-group-text-success .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-success .button-root:focus-visible { + background-color: var(--palette-success-hover); +} +.button-group-text.button-group-override-styles.button-group-text-success.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-success.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-success); +} +.button-group-text.button-group-override-styles.button-group-text-success.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-success.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-success); +} +.button-group-text.button-group-override-styles.button-group-text-success.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-success.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-success); +} +.button-group-text.button-group-override-styles.button-group-text-warning .button-root { + color: var(--palette-warning); +} +.button-group-text.button-group-override-styles.button-group-text-warning .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-warning .button-root:focus-visible { + background-color: var(--palette-warning-hover); +} +.button-group-text.button-group-override-styles.button-group-text-warning.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-warning.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-warning); +} +.button-group-text.button-group-override-styles.button-group-text-warning.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-warning.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-warning); +} +.button-group-text.button-group-override-styles.button-group-text-warning.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-warning.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-warning); +} +.button-group-text.button-group-override-styles.button-group-text-error .button-root { + color: var(--palette-error); +} +.button-group-text.button-group-override-styles.button-group-text-error .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-error .button-root:focus-visible { + background-color: var(--palette-error-hover); +} +.button-group-text.button-group-override-styles.button-group-text-error.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-error.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-error); +} +.button-group-text.button-group-override-styles.button-group-text-error.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-error.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-error); +} +.button-group-text.button-group-override-styles.button-group-text-error.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-error.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-error); +} +.button-group-text.button-group-override-styles.button-group-text-dark .button-root { + color: var(--palette-dark); +} +.button-group-text.button-group-override-styles.button-group-text-dark .button-root:hover, .button-group-text.button-group-override-styles.button-group-text-dark .button-root:focus-visible { + background-color: var(--palette-dark-hover); +} +.button-group-text.button-group-override-styles.button-group-text-dark.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-dark.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-dark); +} +.button-group-text.button-group-override-styles.button-group-text-dark.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-text.button-group-override-styles.button-group-text-dark.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-dark); +} +.button-group-text.button-group-override-styles.button-group-text-dark.button-group-vertical .button-root:not(:last-child), .button-group-text.button-group-override-styles.button-group-text-dark.button-group-vertical > :not(:last-child) .button-root { + border-bottom: 1px solid var(--palette-dark); +} + +.button-group-outlined.button-group-override-styles .button-root { + padding: 5px 15px; + border: 1px solid var(--palette-text-primary); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-primary .button-root { + color: var(--palette-primary); + border: 1px solid var(--palette-primary); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-primary .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-primary .button-root:focus-visible { + background-color: var(--palette-primary-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-secondary .button-root { + color: var(--palette-secondary); + border: 1px solid var(--palette-secondary); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-secondary .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-secondary .button-root:focus-visible { + background-color: var(--palette-secondary-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-tertiary .button-root { + color: var(--palette-tertiary); + border: 1px solid var(--palette-tertiary); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-tertiary .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-tertiary .button-root:focus-visible { + background-color: var(--palette-tertiary-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-info .button-root { + color: var(--palette-info); + border: 1px solid var(--palette-info); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-info .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-info .button-root:focus-visible { + background-color: var(--palette-info-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-success .button-root { + color: var(--palette-success); + border: 1px solid var(--palette-success); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-success .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-success .button-root:focus-visible { + background-color: var(--palette-success-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-warning .button-root { + color: var(--palette-warning); + border: 1px solid var(--palette-warning); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-warning .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-warning .button-root:focus-visible { + background-color: var(--palette-warning-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-error .button-root { + color: var(--palette-error); + border: 1px solid var(--palette-error); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-error .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-error .button-root:focus-visible { + background-color: var(--palette-error-hover); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-dark .button-root { + color: var(--palette-dark); + border: 1px solid var(--palette-dark); +} +.button-group-outlined.button-group-override-styles.button-group-outlined-dark .button-root:hover, .button-group-outlined.button-group-override-styles.button-group-outlined-dark .button-root:focus-visible { + background-color: var(--palette-dark-hover); +} + +.button-group-filled { + box-shadow: var(--elevation-2); +} +.button-group-filled .button-root { + box-shadow: none; +} +.button-group-filled .button-root:hover, .button-group-filled .button-root:focus-visible { + box-shadow: var(--elevation-4); +} +.button-group-filled.button-group-override-styles .button-root { + background-color: var(--palette-action-default-hover); + padding: 6px 16px; +} +.button-group-filled.button-group-override-styles.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-divider); +} +.button-group-filled.button-group-override-styles.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-divider); +} +.button-group-filled.button-group-override-styles.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-divider); +} +.button-group-filled.button-group-override-styles.button-group-filled-primary .button-root { + background-color: var(--palette-primary); + color: var(--palette-primary-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-primary .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-primary .button-root:focus-visible { + background-color: var(--palette-primary-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-primary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-primary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-primary.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-primary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-secondary .button-root { + background-color: var(--palette-secondary); + color: var(--palette-secondary-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-secondary .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-secondary .button-root:focus-visible { + background-color: var(--palette-secondary-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-secondary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-secondary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-secondary.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-secondary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-tertiary .button-root { + background-color: var(--palette-tertiary); + color: var(--palette-tertiary-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-tertiary .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-tertiary .button-root:focus-visible { + background-color: var(--palette-tertiary-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-tertiary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-tertiary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-tertiary.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-tertiary-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-info .button-root { + background-color: var(--palette-info); + color: var(--palette-info-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-info .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-info .button-root:focus-visible { + background-color: var(--palette-info-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-info.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-info.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-info-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-info.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-info.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-info-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-info.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-info.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-info-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-success .button-root { + background-color: var(--palette-success); + color: var(--palette-success-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-success .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-success .button-root:focus-visible { + background-color: var(--palette-success-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-success.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-success.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-success-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-success.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-success.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-success-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-success.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-success.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-success-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-warning .button-root { + background-color: var(--palette-warning); + color: var(--palette-warning-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-warning .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-warning .button-root:focus-visible { + background-color: var(--palette-warning-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-warning-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-warning-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-warning.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-warning-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-error .button-root { + background-color: var(--palette-error); + color: var(--palette-error-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-error .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-error .button-root:focus-visible { + background-color: var(--palette-error-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-error.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-error.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-error-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-error.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-error.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-error-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-error.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-error.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-error-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-dark .button-root { + background-color: var(--palette-dark); + color: var(--palette-dark-text); +} +.button-group-filled.button-group-override-styles.button-group-filled-dark .button-root:hover, .button-group-filled.button-group-override-styles.button-group-filled-dark .button-root:focus-visible { + background-color: var(--palette-dark-darken); +} +.button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-horizontal:not(.button-group-rtl) .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-horizontal:not(.button-group-rtl) > :not(:first-child) .button-root { + border-left: 1px solid var(--palette-dark-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-horizontal.button-group-rtl .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-horizontal.button-group-rtl > :not(:first-child) .button-root { + border-right: 1px solid var(--palette-dark-lighten); +} +.button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-vertical .button-root:not(:first-child), .button-group-filled.button-group-override-styles.button-group-filled-dark.button-group-vertical > :not(:first-child) .button-root { + border-top: 1px solid var(--palette-dark-lighten); +} + +.button-group-disable-elevation { + box-shadow: none; +} + +.button-group-root.button-group-text-size-small .button-root { + padding: 4px 5px; + font-size: 0.8125rem; +} +.button-group-root.button-group-text-size-small .button-root.icon-button .icon-root { + font-size: 1.422rem; +} +.button-group-root.button-group-text-size-large .button-root { + padding: 8px 11px; + font-size: 0.9375rem; +} +.button-group-root.button-group-text-size-large .button-root.icon-button .icon-root { + font-size: 1.641rem; +} +.button-group-root.button-group-outlined-size-small .button-root { + padding: 3px 9px; + font-size: 0.8125rem; +} +.button-group-root.button-group-outlined-size-small .button-root.icon-button { + padding: 3px 9px; +} +.button-group-root.button-group-outlined-size-small .button-root.icon-button .icon-root { + font-size: 1.422rem; +} +.button-group-root.button-group-outlined-size-large .button-root { + padding: 7px 21px; + font-size: 0.9375rem; +} +.button-group-root.button-group-outlined-size-large .button-root.icon-button { + padding: 7px 15px; +} +.button-group-root.button-group-outlined-size-large .button-root.icon-button .icon-root { + font-size: 1.641rem; +} +.button-group-root.button-group-filled-size-small .button-root { + padding: 4px 10px; + font-size: 0.8125rem; +} +.button-group-root.button-group-filled-size-small .button-root.icon-button { + padding: 4px 10px; +} +.button-group-root.button-group-filled-size-small .button-root.icon-button .icon-root { + font-size: 1.422rem; +} +.button-group-root.button-group-filled-size-large .button-root { + padding: 8px 22px; + font-size: 0.9375rem; +} +.button-group-root.button-group-filled-size-large .button-root.icon-button { + padding: 8px 16px; +} +.button-group-root.button-group-filled-size-large .button-root.icon-button .icon-root { + font-size: 1.641rem; +} + +.button-group-root .button-root.icon-button { + padding-right: 12px; + padding-left: 12px; +} +.button-group-root .button-root.icon-button .icon-root { + font-size: 1.516rem; +} +.button-group-root .button-root.icon-button.ripple-icon:after { + transform: scale(10, 10); +} +.button-group-root .button-root.icon-button.ripple-icon:active:after { + transform: scale(0, 0); + opacity: 0.1; + transition: 0s; +} + +.icon-button { + flex: 0 0 auto; + padding: 12px; + overflow: visible; + font-size: 1.5rem; + text-align: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 50%; + color: var(--palette-action-default); +} +.icon-button.button { + min-width: unset; + border-radius: var(--default-borderradius); +} +.icon-button:hover, .icon-button:focus-visible { + background-color: var(--palette-action-default-hover); +} +.icon-button:disabled { + color: var(--palette-action-disabled); + background-color: transparent; +} +.icon-button.readonly, .icon-button .readonly:hover { + cursor: default; +} + +.icon-button-color-inherit { + color: inherit; +} +.icon-button-color-inherit:hover, .icon-button-color-inherit:focus-visible { + background-color: var(--palette-action-default-hover); +} + +.icon-button-label { + width: 100%; + display: flex; + align-items: inherit; + justify-content: inherit; +} + +.icon-button-edge-start { + margin-left: -12px; + margin-inline-start: -12px; + margin-inline-end: unset; +} + +.icon-button-edge-end { + margin-right: -12px; + margin-inline-end: -12px; + margin-inline-start: unset; +} + +.icon-button-edge-margin-end { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} + +.icon-button-size-small { + padding: 3px; + font-size: 1.125rem; +} +.icon-button-size-small.icon-button-edge-start { + margin-left: -3px; + margin-inline-start: -3px; + margin-inline-end: unset; +} +.icon-button-size-small.icon-button-edge-end { + margin-right: -3px; + margin-inline-end: -3px; + margin-inline-start: unset; +} + +.icon-button-size-large.button > .icon-button-label > .icon-size-large { + font-size: 2rem; +} + +.card-header { + display: flex; + padding: 16px; + align-items: center; + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.card-header .card-header-avatar { + flex: 0 0 auto; + margin-right: 16px; + margin-inline-end: 16px; + margin-inline-start: unset; +} +.card-header .card-header-content { + flex: 1 1 auto; +} +.card-header .card-header-content .typography { + margin-bottom: 0; +} +.card-header .card-header-actions { + flex: 0 0 auto; + align-self: flex-start; + margin-top: -8px; + margin-right: -8px; + margin-inline-end: -8px; + margin-inline-start: unset; +} + +.card-media { + display: block; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} + +.card-header + .card-media { + border-top-left-radius: 0px; + border-top-right-radius: 0px; +} + +.card-content { + padding: 16px; +} + +.card-actions { + display: flex; + padding: 8px; + align-items: center; +} + +.carousel { + display: flex !important; + position: relative; + margin: 0px !important; + clip-path: inset(0px 0px 0px 0px); + overflow: hidden; +} +.carousel.carousel-primary { + color: var(--palette-primary-text); +} +.carousel.carousel-secondary { + color: var(--palette-secondary-text); +} +.carousel.carousel-tertiary { + color: var(--palette-tertiary-text); +} +.carousel.carousel-info { + color: var(--palette-info-text); +} +.carousel.carousel-success { + color: var(--palette-success-text); +} +.carousel.carousel-warning { + color: var(--palette-warning-text); +} +.carousel.carousel-error { + color: var(--palette-error-text); +} +.carousel.carousel-dark { + color: var(--palette-dark-text); +} + +.carousel-elements-rtl { + transform: rotate(180deg) !important; +} + +.carousel-item { + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + margin: inherit; + padding: inherit; + z-index: 2; +} +.carousel-item.carousel-item-primary { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.carousel-item.carousel-item-secondary { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.carousel-item.carousel-item-tertiary { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.carousel-item.carousel-item-info { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.carousel-item.carousel-item-success { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.carousel-item.carousel-item-warning { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.carousel-item.carousel-item-error { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.carousel-item.carousel-item-dark { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} + +.carousel-item-exit { + z-index: 1; +} + +/* ### Transitions ### */ +/*Fade +*/ +@keyframes carousel-transition-fade-in-keyframe { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes carousel-transition-fade-out-keyframe { + from { + opacity: 1; + } + to { + opacity: 0; + } +} +.carousel-transition-fade-in { + animation: 0.5s carousel-transition-fade-in-keyframe; +} + +.carousel-transition-fade-out { + animation: 0.5s carousel-transition-fade-out-keyframe; + animation-fill-mode: forwards; +} + +.carousel-transition-none { + display: none; +} + +/*Slide +*/ +@keyframes carousel-transition-slide-next-enter-keyframe { + from { + transform: translate3d(100%, 0, 0); + visibility: visible; + } + to { + transform: translate3d(0, 0, 0); + } +} +@keyframes carousel-transition-slide-next-rtl-enter-keyframe { + from { + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + to { + transform: translate3d(0, 0, 0); + } +} +@keyframes carousel-transition-slide-next-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + to { + transform: translate3d(-100%, 0, 0); + } +} +@keyframes carousel-transition-slide-next-rtl-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + to { + transform: translate3d(100%, 0, 0); + } +} +.carousel-transition-slide-next-enter { + animation: 0.5s carousel-transition-slide-next-enter-keyframe; +} + +.carousel-transition-slide-next-rtl-enter { + animation: 0.5s carousel-transition-slide-next-rtl-enter-keyframe; +} + +.carousel-transition-slide-next-exit { + animation: 0.5s carousel-transition-slide-next-exit-keyframe; + animation-fill-mode: forwards; +} + +.carousel-transition-slide-next-rtl-exit { + animation: 0.5s carousel-transition-slide-next-rtl-exit-keyframe; + animation-fill-mode: forwards; +} + +@keyframes carousel-transition-slide-prev-enter-keyframe { + from { + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + to { + transform: translate3d(0, 0, 0); + } +} +@keyframes carousel-transition-slide-prev-rtl-enter-keyframe { + from { + transform: translate3d(100%, 0, 0); + visibility: visible; + } + to { + transform: translate3d(0, 0, 0); + } +} +@keyframes carousel-transition-slide-prev-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + to { + transform: translate3d(100%, 0, 0); + } +} +@keyframes carousel-transition-slide-prev-rtl-exit-keyframe { + from { + transform: translate3d(0, 0, 0); + visibility: visible; + } + to { + transform: translate3d(-100%, 0, 0); + } +} +.carousel-transition-slide-prev-enter { + animation: 0.5s carousel-transition-slide-prev-enter-keyframe; +} + +.carousel-transition-slide-prev-rtl-enter { + animation: 0.5s carousel-transition-slide-prev-rtl-enter-keyframe; +} + +.carousel-transition-slide-prev-exit { + animation: 0.5s carousel-transition-slide-prev-exit-keyframe; + animation-fill-mode: forwards; +} + +.carousel-transition-slide-prev-rtl-exit { + animation: 0.5s carousel-transition-slide-prev-rtl-exit-keyframe; + animation-fill-mode: forwards; +} + +.chart { + display: flex; +} +.chart.chart-legend-bottom { + flex-direction: column; +} +.chart.chart-legend-bottom .chart-legend { + margin-top: 10px; + justify-content: center; + width: 100%; +} +.chart.chart-legend-top { + flex-direction: column-reverse; +} +.chart.chart-legend-top .chart-legend { + justify-content: center; + width: 100%; +} +.chart.chart-legend-right { + flex-direction: row; +} +.chart.chart-legend-right .chart-legend { + flex-direction: column; +} +.chart.chart-legend-left { + flex-direction: row-reverse; +} +.chart.chart-legend-left .chart-legend { + flex-direction: column; +} +.chart .chart-donut, .chart .chart-pie, .chart chart-line { + display: flex; + margin: auto; +} +.chart .chart-legend { + display: flex; + padding: 10px 0px; + margin: auto; + flex-wrap: wrap; +} +.chart .chart-legend .chart-legend-item { + display: block; + margin: 2px 5px; +} +.chart .chart-legend .chart-legend-item .chart-legend-marker { + height: 12px; + width: 12px; + border-radius: 50%; + position: relative; + display: inline-flex; +} +.chart .chart-legend .chart-legend-item .chart-legend-text { + display: inline-flex; +} + +.charts-yaxis { + fill: var(--palette-text-primary); +} + +.charts-xaxis { + fill: var(--palette-text-primary); +} + +.chart-donut .donut-hole { + fill: transparent; + user-select: none; + pointer-events: unset; +} +.chart-donut .donut-ring { + fill: transparent; + stroke-width: 5; + stroke: white; + pointer-events: unset; +} +.chart-donut .donut-segment { + stroke-width: 5; + fill: transparent; + pointer-events: stroke; + -webkit-transition: stroke 0.2s ease; + -moz-transition: stroke 0.2s ease; + -o-transition: stroke 0.2s ease; + transition: stroke 0.2s ease; +} + +.chart-legend-marker { + height: 12px; + width: 12px; + border-radius: 50%; + position: relative; + display: inline-block; +} + +.chart-marker-color-0 { + background-color: #008FFB; +} + +.chart-marker-color-1 { + background-color: #00E396; +} + +.chart-marker-color-2 { + background-color: #FEB019; +} + +.chart-marker-color-3 { + background-color: #FF4560; +} + +.chart-marker-color-4 { + background-color: #594ae2; +} + +.checkbox { + cursor: pointer; + display: inline-flex; + align-items: center; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; +} +.checkbox.disabled, .checkbox .disabled:hover, .checkbox .disabled:focus-visible { + cursor: default; + background-color: transparent !important; +} +.checkbox.disabled *, .checkbox .disabled:hover *, .checkbox .disabled:focus-visible * { + cursor: default; + color: var(--palette-text-disabled); +} +.checkbox.readonly, .checkbox .readonly:hover { + cursor: default; +} +.checkbox .checkbox-dense { + padding: 4px; +} + +.checkbox-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; +} + +.checkbox-span { + display: inline-block; + width: 100%; + cursor: pointer; +} + +.chip { + border: none; + cursor: default; + display: inline-flex; + max-width: 100%; + outline: 0; + padding: 0 12px; + position: relative; + box-sizing: border-box; + transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: center; + white-space: nowrap; + vertical-align: middle; + justify-content: center; + text-decoration: none; + line-height: normal; + margin: 4px; +} +.chip.disabled { + opacity: 0.5; + pointer-events: none; +} +.chip.chip-size-small { + border-radius: 12px; + font-size: 12px; + height: 24px; +} +.chip.chip-size-medium { + height: 32px; + font-size: 14px; + border-radius: 16px; +} +.chip.chip-size-large { + height: 40px; + font-size: 16px; + border-radius: 20px; +} +.chip.chip-label { + border-radius: var(--default-borderradius); +} +.chip.clickable { + cursor: pointer; +} +.chip .chip-icon { + margin-left: -4px; + margin-right: 4px; + margin-inline-start: -4px; + margin-inline-end: 4px; + color: inherit; +} +.chip .chip-close-button { + padding: 1px; + margin-right: -4px; + margin-left: 6px; + margin-inline-end: -4px; + margin-inline-start: 6px; + height: 18px; + width: 18px; + color: inherit; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), visibility 0s; +} +.chip .chip-close-button .icon-size-small { + font-size: 1.15rem; +} +.chip .chip-close-button:hover { + opacity: 0.7; +} +.chip > .chip-content { + align-items: center; + display: inline-flex; + height: 100%; + max-width: 100%; + user-select: none; +} + +.chip-filled { + color: var(--palette-text-primary); + background-color: var(--palette-action-disabled-background); +} +.chip-filled:hover:not(.disabled), .chip-filled:focus-visible:not(.disabled) { + background-color: var(--palette-action-disabled); +} +.chip-filled.chip-color-primary { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.chip-filled.chip-color-primary:hover:not(.disabled), .chip-filled.chip-color-primary:focus-visible:not(.disabled) { + background-color: var(--palette-primary-darken); +} +.chip-filled.chip-color-secondary { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.chip-filled.chip-color-secondary:hover:not(.disabled), .chip-filled.chip-color-secondary:focus-visible:not(.disabled) { + background-color: var(--palette-secondary-darken); +} +.chip-filled.chip-color-tertiary { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.chip-filled.chip-color-tertiary:hover:not(.disabled), .chip-filled.chip-color-tertiary:focus-visible:not(.disabled) { + background-color: var(--palette-tertiary-darken); +} +.chip-filled.chip-color-info { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.chip-filled.chip-color-info:hover:not(.disabled), .chip-filled.chip-color-info:focus-visible:not(.disabled) { + background-color: var(--palette-info-darken); +} +.chip-filled.chip-color-success { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.chip-filled.chip-color-success:hover:not(.disabled), .chip-filled.chip-color-success:focus-visible:not(.disabled) { + background-color: var(--palette-success-darken); +} +.chip-filled.chip-color-warning { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.chip-filled.chip-color-warning:hover:not(.disabled), .chip-filled.chip-color-warning:focus-visible:not(.disabled) { + background-color: var(--palette-warning-darken); +} +.chip-filled.chip-color-error { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.chip-filled.chip-color-error:hover:not(.disabled), .chip-filled.chip-color-error:focus-visible:not(.disabled) { + background-color: var(--palette-error-darken); +} +.chip-filled.chip-color-dark { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} +.chip-filled.chip-color-dark:hover:not(.disabled), .chip-filled.chip-color-dark:focus-visible:not(.disabled) { + background-color: var(--palette-dark-darken); +} + +.chip-outlined { + color: var(--palette-text-primary); + border: 1px solid var(--palette-lines-inputs); +} +.chip-outlined:hover:not(.disabled), .chip-outlined:focus-visible:not(.disabled) { + background-color: var(--palette-action-default-hover); +} +.chip-outlined.chip-color-primary { + color: var(--palette-primary); + border: 1px solid var(--palette-primary); +} +.chip-outlined.chip-color-primary:hover:not(.disabled), .chip-outlined.chip-color-primary:focus-visible:not(.disabled) { + background-color: var(--palette-primary-hover); +} +.chip-outlined.chip-color-primary.chip-selected { + background-color: var(--palette-primary-hover); +} +.chip-outlined.chip-color-primary.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-primary.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-primary-rgb), 0.12); +} +.chip-outlined.chip-color-secondary { + color: var(--palette-secondary); + border: 1px solid var(--palette-secondary); +} +.chip-outlined.chip-color-secondary:hover:not(.disabled), .chip-outlined.chip-color-secondary:focus-visible:not(.disabled) { + background-color: var(--palette-secondary-hover); +} +.chip-outlined.chip-color-secondary.chip-selected { + background-color: var(--palette-secondary-hover); +} +.chip-outlined.chip-color-secondary.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-secondary.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-secondary-rgb), 0.12); +} +.chip-outlined.chip-color-tertiary { + color: var(--palette-tertiary); + border: 1px solid var(--palette-tertiary); +} +.chip-outlined.chip-color-tertiary:hover:not(.disabled), .chip-outlined.chip-color-tertiary:focus-visible:not(.disabled) { + background-color: var(--palette-tertiary-hover); +} +.chip-outlined.chip-color-tertiary.chip-selected { + background-color: var(--palette-tertiary-hover); +} +.chip-outlined.chip-color-tertiary.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-tertiary.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-tertiary-rgb), 0.12); +} +.chip-outlined.chip-color-info { + color: var(--palette-info); + border: 1px solid var(--palette-info); +} +.chip-outlined.chip-color-info:hover:not(.disabled), .chip-outlined.chip-color-info:focus-visible:not(.disabled) { + background-color: var(--palette-info-hover); +} +.chip-outlined.chip-color-info.chip-selected { + background-color: var(--palette-info-hover); +} +.chip-outlined.chip-color-info.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-info.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-info-rgb), 0.12); +} +.chip-outlined.chip-color-success { + color: var(--palette-success); + border: 1px solid var(--palette-success); +} +.chip-outlined.chip-color-success:hover:not(.disabled), .chip-outlined.chip-color-success:focus-visible:not(.disabled) { + background-color: var(--palette-success-hover); +} +.chip-outlined.chip-color-success.chip-selected { + background-color: var(--palette-success-hover); +} +.chip-outlined.chip-color-success.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-success.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-success-rgb), 0.12); +} +.chip-outlined.chip-color-warning { + color: var(--palette-warning); + border: 1px solid var(--palette-warning); +} +.chip-outlined.chip-color-warning:hover:not(.disabled), .chip-outlined.chip-color-warning:focus-visible:not(.disabled) { + background-color: var(--palette-warning-hover); +} +.chip-outlined.chip-color-warning.chip-selected { + background-color: var(--palette-warning-hover); +} +.chip-outlined.chip-color-warning.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-warning.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-warning-rgb), 0.12); +} +.chip-outlined.chip-color-error { + color: var(--palette-error); + border: 1px solid var(--palette-error); +} +.chip-outlined.chip-color-error:hover:not(.disabled), .chip-outlined.chip-color-error:focus-visible:not(.disabled) { + background-color: var(--palette-error-hover); +} +.chip-outlined.chip-color-error.chip-selected { + background-color: var(--palette-error-hover); +} +.chip-outlined.chip-color-error.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-error.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-error-rgb), 0.12); +} +.chip-outlined.chip-color-dark { + color: var(--palette-dark); + border: 1px solid var(--palette-dark); +} +.chip-outlined.chip-color-dark:hover:not(.disabled), .chip-outlined.chip-color-dark:focus-visible:not(.disabled) { + background-color: var(--palette-dark-hover); +} +.chip-outlined.chip-color-dark.chip-selected { + background-color: var(--palette-dark-hover); +} +.chip-outlined.chip-color-dark.chip-selected:hover:not(.disabled), .chip-outlined.chip-color-dark.chip-selected:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-dark-rgb), 0.12); +} + +.chip-text { + color: var(--palette-text-primary); + background-color: var(--palette-action-default-hover); +} +.chip-text:hover:not(.disabled), .chip-text:focus-visible:not(.disabled) { + background-color: var(--palette-action-disabled-background); +} +.chip-text.chip-color-primary { + color: var(--palette-primary); + background-color: var(--palette-primary-hover); +} +.chip-text.chip-color-primary:hover:not(.disabled), .chip-text.chip-color-primary:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-primary-rgb), 0.12); +} +.chip-text.chip-color-secondary { + color: var(--palette-secondary); + background-color: var(--palette-secondary-hover); +} +.chip-text.chip-color-secondary:hover:not(.disabled), .chip-text.chip-color-secondary:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-secondary-rgb), 0.12); +} +.chip-text.chip-color-tertiary { + color: var(--palette-tertiary); + background-color: var(--palette-tertiary-hover); +} +.chip-text.chip-color-tertiary:hover:not(.disabled), .chip-text.chip-color-tertiary:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-tertiary-rgb), 0.12); +} +.chip-text.chip-color-info { + color: var(--palette-info); + background-color: var(--palette-info-hover); +} +.chip-text.chip-color-info:hover:not(.disabled), .chip-text.chip-color-info:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-info-rgb), 0.12); +} +.chip-text.chip-color-success { + color: var(--palette-success); + background-color: var(--palette-success-hover); +} +.chip-text.chip-color-success:hover:not(.disabled), .chip-text.chip-color-success:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-success-rgb), 0.12); +} +.chip-text.chip-color-warning { + color: var(--palette-warning); + background-color: var(--palette-warning-hover); +} +.chip-text.chip-color-warning:hover:not(.disabled), .chip-text.chip-color-warning:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-warning-rgb), 0.12); +} +.chip-text.chip-color-error { + color: var(--palette-error); + background-color: var(--palette-error-hover); +} +.chip-text.chip-color-error:hover:not(.disabled), .chip-text.chip-color-error:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-error-rgb), 0.12); +} +.chip-text.chip-color-dark { + color: var(--palette-dark); + background-color: var(--palette-dark-hover); +} +.chip-text.chip-color-dark:hover:not(.disabled), .chip-text.chip-color-dark:focus-visible:not(.disabled) { + background-color: rgba(var(--palette-dark-rgb), 0.12); +} + +.collapse-container { + height: 0px; + overflow: hidden; +} + +@keyframes expand-anim { + from { + height: 0; + } +} +.collapse-entering { + animation: expand-anim 1s ease-in-out 0ms 1 forwards; +} +.collapse-entering.navgroup-collapse { + animation-duration: 300ms !important; +} + +.collapse-entered { + overflow: initial; +} + +@keyframes collapse-anim { + to { + height: 0; + } +} +.collapse-exiting { + animation: collapse-anim 0.5s cubic-bezier(0, 1, 0, 1) 0ms 1 forwards; +} +.collapse-exiting.navgroup-collapse { + animation-duration: 300ms; +} + +.collapse-hidden { + visibility: hidden; +} + +.collapse-wrapper { + display: flex; +} + +.collapse-wrapper-inner { + width: 100%; +} + +.dialog-container { + display: flex; + position: fixed; + top: 0; + width: 100%; + height: 100%; + z-index: var(--zindex-dialog); +} +.dialog-container.dialog-center { + align-items: center; + justify-content: center; +} +.dialog-container.dialog-topcenter { + align-items: flex-start; + justify-content: center; + padding-top: 32px; +} +.dialog-container.dialog-bottomcenter { + align-items: flex-end; + justify-content: center; + padding-bottom: 32px; +} +.dialog-container.dialog-centerright { + align-items: center; + justify-content: flex-end; + padding-right: 32px; +} +.dialog-container.dialog-centerleft { + align-items: center; + justify-content: flex-start; + padding-left: 32px; +} +.dialog-container.dialog-topleft .dialog { + position: absolute; + top: 32px; + left: 32px; +} +.dialog-container.dialog-topright .dialog { + position: absolute; + top: 32px; + right: 32px; +} +.dialog-container.dialog-bottomleft .dialog { + position: absolute; + bottom: 32px; + left: 32px; +} +.dialog-container.dialog-bottomright .dialog { + position: absolute; + bottom: 32px; + right: 32px; +} + +.dialog { + display: flex; + z-index: calc(var(--zindex-dialog) + 2); + flex-direction: column; + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + -webkit-animation: open-dialog-center 0.1s cubic-bezier(0.39, 0.575, 0.565, 1) both; + animation: open-dialog-center 0.1s cubic-bezier(0.39, 0.575, 0.565, 1) both; + box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12); +} +.dialog.dialog-rtl .dialog-title .button-root { + right: unset; + left: 8px; +} +.dialog .dialog-title { + z-index: 1; + flex: 0 0 auto; + margin: 0; + padding: 16px 24px; + border-top-left-radius: var(--default-borderradius); + border-top-right-radius: var(--default-borderradius); +} +.dialog .dialog-title + * > .dialog-content { + border-radius: 0; +} +.dialog .dialog-title .button-root { + top: 8px; + right: 8px; + position: absolute; +} +.dialog .dialog-content { + position: relative; + flex: 1 1 auto; + padding: 8px 24px; + -webkit-overflow-scrolling: touch; + border-top-left-radius: var(--default-borderradius); + border-top-right-radius: var(--default-borderradius); +} +.dialog .dialog-content.dialog-no-side-padding { + padding: 12px 0px; +} +.dialog .dialog-actions { + flex: 0 0 auto; + display: flex; + padding: 8px; + align-items: center; + justify-content: flex-end; + border-bottom-left-radius: var(--default-borderradius); + border-bottom-right-radius: var(--default-borderradius); +} +.dialog .dialog-actions > :not(:first-child) { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +.dialog-width-false { + max-width: calc(100% - 64px); +} + +.dialog-width-xs { + max-width: 444px; +} + +.dialog-width-sm { + max-width: 600px; +} + +.dialog-width-md { + max-width: 960px; +} + +.dialog-width-lg { + max-width: 1280px; +} + +.dialog-width-xl { + max-width: 1920px; +} + +.dialog-width-xxl { + max-width: 2560px; +} + +.dialog-width-full { + width: calc(100% - 64px); +} + +.dialog-fullscreen { + width: 100%; + height: 100%; + margin: 0; + max-width: 100%; + max-height: none; + border-radius: 0; +} + +@-webkit-keyframes open-dialog-center { + 0% { + opacity: 0; + } + 1% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 1; + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@keyframes open-dialog-center { + 0% { + opacity: 0; + } + 1% { + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 1; + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +.input-control.field .input-slot { + height: auto; + min-height: 19px; +} +.input-control.field .input-slot.input-root-outlined.input-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 14px; +} +.input-control.field .input-slot.input-root-filled.input-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 12px; +} +.input-control.field .input-slot.input-slot-nopadding { + padding-top: 0px; + padding-bottom: 0px; +} +.input-control.field .input-slot.input-slot-nopadding.input-root-filled { + padding-top: 21px; + padding-bottom: 2px; +} +.input-control.field .input-slot.input-slot-nopadding.input-root-outlined { + padding-top: 7px; + padding-bottom: 2px; +} + +.grid { + width: 100%; + display: flex; + flex-wrap: wrap; + box-sizing: border-box; +} + +.grid-item { + margin: 0; + box-sizing: border-box; +} + +.grid-spacing-xs-1 { + width: calc(100% + 8px); + margin: -4px; +} + +.grid-spacing-xs-1 > .grid-item { + padding: 4px; +} + +.grid-spacing-xs-2 { + width: calc(100% + 16px); + margin: -8px; +} + +.grid-spacing-xs-2 > .grid-item { + padding: 8px; +} + +.grid-spacing-xs-3 { + width: calc(100% + 24px); + margin: -12px; +} + +.grid-spacing-xs-3 > .grid-item { + padding: 12px; +} + +.grid-spacing-xs-4 { + width: calc(100% + 32px); + margin: -16px; +} + +.grid-spacing-xs-4 > .grid-item { + padding: 16px; +} + +.grid-spacing-xs-5 { + width: calc(100% + 40px); + margin: -20px; +} + +.grid-spacing-xs-5 > .grid-item { + padding: 20px; +} + +.grid-spacing-xs-6 { + width: calc(100% + 48px); + margin: -24px; +} + +.grid-spacing-xs-6 > .grid-item { + padding: 24px; +} + +.grid-spacing-xs-7 { + width: calc(100% + 56px); + margin: -28px; +} + +.grid-spacing-xs-7 > .grid-item { + padding: 28px; +} + +.grid-spacing-xs-8 { + width: calc(100% + 64px); + margin: -32px; +} + +.grid-spacing-xs-8 > .grid-item { + padding: 32px; +} + +.grid-spacing-xs-9 { + width: calc(100% + 72px); + margin: -36px; +} + +.grid-spacing-xs-9 > .grid-item { + padding: 36px; +} + +.grid-spacing-xs-10 { + width: calc(100% + 80px); + margin: -40px; +} + +.grid-spacing-xs-10 > .grid-item { + padding: 40px; +} + +.grid-item-xs-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; +} + +.grid-item-xs-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; +} + +.grid-item-xs-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; +} + +.grid-item-xs-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; +} + +.grid-item-xs-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; +} + +.grid-item-xs-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; +} + +.grid-item-xs-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; +} + +.grid-item-xs-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; +} + +.grid-item-xs-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; +} + +.grid-item-xs-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; +} + +.grid-item-xs-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; +} + +.grid-item-xs-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; +} + +.grid-item-xs-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; +} + +.grid-item-xs-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; +} + +@media (min-width: 600px) { + .grid-item-sm-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-sm-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-sm-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-sm-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-sm-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-sm-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-sm-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-sm-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-sm-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-sm-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-sm-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-sm-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-sm-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-sm-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} +@media (min-width: 960px) { + .grid-item-md-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-md-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-md-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-md-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-md-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-md-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-md-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-md-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-md-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-md-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-md-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-md-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-md-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-md-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} +@media (min-width: 1280px) { + .grid-item-lg-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-lg-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-lg-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-lg-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-lg-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-lg-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-lg-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-lg-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-lg-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-lg-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-lg-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-lg-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-lg-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-lg-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} +@media (min-width: 1920px) { + .grid-item-xl-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-xl-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-xl-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-xl-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-xl-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-xl-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-xl-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-xl-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-xl-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-xl-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-xl-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-xl-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-xl-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-xl-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} +@media (min-width: 2560px) { + .grid-item-xxl-auto { + flex-grow: 0; + max-width: none; + flex-basis: auto; + } + + .grid-item-xxl-true { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } + + .grid-item-xxl-1 { + flex-grow: 0; + max-width: 8.333333%; + flex-basis: 8.333333%; + } + + .grid-item-xxl-2 { + flex-grow: 0; + max-width: 16.666667%; + flex-basis: 16.666667%; + } + + .grid-item-xxl-3 { + flex-grow: 0; + max-width: 25%; + flex-basis: 25%; + } + + .grid-item-xxl-4 { + flex-grow: 0; + max-width: 33.333333%; + flex-basis: 33.333333%; + } + + .grid-item-xxl-5 { + flex-grow: 0; + max-width: 41.666667%; + flex-basis: 41.666667%; + } + + .grid-item-xxl-6 { + flex-grow: 0; + max-width: 50%; + flex-basis: 50%; + } + + .grid-item-xxl-7 { + flex-grow: 0; + max-width: 58.333333%; + flex-basis: 58.333333%; + } + + .grid-item-xxl-8 { + flex-grow: 0; + max-width: 66.666667%; + flex-basis: 66.666667%; + } + + .grid-item-xxl-9 { + flex-grow: 0; + max-width: 75%; + flex-basis: 75%; + } + + .grid-item-xxl-10 { + flex-grow: 0; + max-width: 83.333333%; + flex-basis: 83.333333%; + } + + .grid-item-xxl-11 { + flex-grow: 0; + max-width: 91.666667%; + flex-basis: 91.666667%; + } + + .grid-item-xxl-12 { + flex-grow: 0; + max-width: 100%; + flex-basis: 100%; + } +} +.paper { + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.paper-square { + border-radius: 0px; +} + +.paper-outlined { + border: 1px solid var(--palette-lines-default); +} + +.icon-default { + color: var(--palette-text-secondary); +} + +.disabled .icon-root, .disabled .svg-icon, .disabled .icon-default { + color: var(--palette-text-disabled); +} + +.icon-root { + width: 1em; + height: 1em; + display: inline-block; + transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + flex-shrink: 0; + user-select: none; +} +.icon-root:focus { + outline: none; +} +.icon-root.svg-icon { + fill: currentColor; +} + +.icon-size-small { + font-size: 1.25rem; +} + +.icon-size-medium { + font-size: 1.5rem; +} + +.icon-size-large { + font-size: 2.25rem; +} + +.divider { + margin: 0; + flex-shrink: 0; + border-color: var(--palette-divider); + border-width: 1px; + border-style: solid none none none; +} + +.divider-absolute { + left: 0; + width: 100%; + bottom: 0; + position: absolute; +} + +.divider-inset { + margin-left: 72px; + margin-inline-start: 72px; + margin-inline-end: unset; +} + +.divider-light { + border-color: var(--palette-divider-light); +} + +.divider-middle { + margin-left: 16px; + margin-right: 16px; +} + +.divider-vertical { + border-style: none solid none none; + height: 100%; +} + +.divider-flexitem { + height: auto; + align-self: stretch; +} + +.drop-zone { + position: relative; + transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.drop-zone-drag-block > * { + pointer-events: none; +} + +.drop-zone-can-drop { + background-color: var(--palette-success-hover); +} + +.drop-zone-no-drop { + background-color: var(--palette-error-hover); +} + +.drop-item:not(.drop-item-preview-start) { + cursor: grab; + user-select: none; +} +.drop-item:not(.drop-item-preview-start):active { + cursor: grabbing; +} + +.drop-item-preview-start { + height: 20px; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; +} + +.expansion-panels { + flex: 0 1 auto; + position: relative; + max-width: 100%; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); + border-radius: var(--default-borderradius); +} +.expansion-panels.expansion-panels-square { + border-radius: 0px; +} +.expansion-panels.expansion-panels-borders .expand-panel { + border-bottom: 1px solid var(--palette-lines-default); +} + +.expand-panel { + flex: 1 0 100%; + max-width: 100%; + position: relative; + transition: margin 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); + transition-delay: 100ms; + color: var(--palette-text-primary); + background-color: var(--palette-surface); +} +.expand-panel.expand-panel-border { + border-bottom: 1px solid var(--palette-lines-default); +} +.expand-panel:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.expand-panel:last-child { + border-bottom: none; + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; +} +.expand-panel.panel-expanded { + margin: 16px 0; + border-radius: inherit; + border-bottom: none; + transition-delay: 0ms; +} +.expand-panel.panel-expanded:first-child { + margin-top: 0; +} +.expand-panel.panel-expanded:last-child { + margin-bottom: 0; +} +.expand-panel.panel-expanded + .expand-panel { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.expand-panel.panel-next-expanded { + border-bottom: none; + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; +} +.expand-panel .expand-panel-header { + width: 100%; + align-items: center; + display: flex; + font-size: 0.9375rem; + line-height: 1; + min-height: 48px; + outline: none; + padding: 16px 24px; + position: relative; + transition: min-height 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); + user-select: none; +} +.expand-panel .expand-panel-header:hover { + cursor: pointer; +} +.expand-panel .expand-panel-header .expand-panel-text { + flex: 1 1 auto; +} +.expand-panel .expand-panel-header .expand-panel-icon { + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), visibility 0s; +} +.expand-panel .expand-panel-header .expand-panel-icon.transform { + transform: rotate(-180deg); +} +.expand-panel .expand-panel-content { + padding: 0 24px 16px; + flex: 1 1 auto; + max-width: 100%; +} +.expand-panel .expand-panel-content.expand-panel-gutters { + padding-left: 0px; + padding-right: 0px; +} +.expand-panel .expand-panel-content.expand-panel-dense { + padding-top: 0px; + padding-bottom: 0px; +} + +.disabled > .expand-panel-header { + color: var(--palette-text-disabled); +} +.disabled > .expand-panel-header:hover { + cursor: default; +} + +.fab { + padding: 0; + font-family: var(--typography-button-family); + font-size: var(--typography-button-size); + font-weight: var(--typography-button-weight); + line-height: var(--typography-button-lineheight); + letter-spacing: var(--typography-button-letterspacing); + text-transform: var(--typography-button-text-transform); + min-width: 0; + box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12); + box-sizing: border-box; + min-height: 36px; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 50%; + color: var(--palette-text-primary); + background-color: var(--palette-action-default-hover); +} +.fab:hover, .fab:focus-visible { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); + text-decoration: none; + background-color: var(--palette-action-disabled-background); +} +.fab:active { + box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 12px 17px 2px rgba(0, 0, 0, 0.14), 0px 5px 22px 4px rgba(0, 0, 0, 0.12); +} +.fab:disabled { + color: var(--palette-action-disabled); + box-shadow: none; + background-color: var(--palette-action-disabled-background); + cursor: default; + pointer-events: none; +} +.fab:disabled:hover { + background-color: var(--palette-action-disabled-background); +} + +.fab-disable-elevation { + box-shadow: none; +} +.fab-disable-elevation:hover { + box-shadow: none; +} +.fab-disable-elevation:active { + box-shadow: none; +} +.fab-disable-elevation.focus-visible { + box-shadow: none; +} +.fab-disable-elevation:disabled { + box-shadow: none; +} + +.fab-label { + width: 100%; + display: inherit; + align-items: inherit; + justify-content: inherit; +} + +.fab-primary { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.fab-primary:hover, .fab-primary:focus-visible { + background-color: var(--palette-primary-darken); +} + +.fab-secondary { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.fab-secondary:hover, .fab-secondary:focus-visible { + background-color: var(--palette-secondary-darken); +} + +.fab-tertiary { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.fab-tertiary:hover, .fab-tertiary:focus-visible { + background-color: var(--palette-tertiary-darken); +} + +.fab-info { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.fab-info:hover, .fab-info:focus-visible { + background-color: var(--palette-info-darken); +} + +.fab-success { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.fab-success:hover, .fab-success:focus-visible { + background-color: var(--palette-success-darken); +} + +.fab-warning { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.fab-warning:hover, .fab-warning:focus-visible { + background-color: var(--palette-warning-darken); +} + +.fab-error { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.fab-error:hover, .fab-error:focus-visible { + background-color: var(--palette-error-darken); +} + +.fab-dark { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} +.fab-dark:hover, .fab-dark:focus-visible { + background-color: var(--palette-dark-darken); +} + +.fab-extended.fab-size-large { + width: auto; + height: 48px; + padding: 0 16px; + min-width: 48px; + min-height: auto; + border-radius: 24px; +} +.fab-extended.fab-size-large .fab-label { + gap: 8px; +} +.fab-extended.fab-size-small { + width: auto; + height: 34px; + padding: 0 12px; + min-width: 34px; + border-radius: 17px; +} +.fab-extended.fab-size-small .fab-label { + gap: 4px; +} +.fab-extended.fab-size-medium { + width: auto; + height: 40px; + padding: 0 16px; + min-width: 40px; + border-radius: 20px; +} +.fab-extended.fab-size-medium .fab-label { + gap: 8px; +} + +.fab-color-inherit { + color: inherit; +} + +.fab-size-small { + width: 40px; + height: 40px; +} + +.fab-size-medium { + width: 48px; + height: 48px; +} + +.fab-size-large { + width: 56px; + height: 56px; +} + +.list { + margin: 0; + padding: 0; + position: relative; + list-style: none; +} +.list.list-padding { + padding-top: 8px; + padding-bottom: 8px; +} + +.list-item { + width: 100%; + display: flex; + position: relative; + box-sizing: border-box; + text-align: start; + align-items: center; + padding-top: 8px; + padding-bottom: 8px; + justify-content: flex-start; + text-decoration: none; +} +.list-item.list-item-dense { + padding-top: 4px; + padding-bottom: 4px; +} +.list-item.list-item-disabled { + color: var(--palette-action-disabled) !important; + cursor: default !important; + pointer-events: none !important; +} +.list-item.list-item-disabled .list-item-icon { + color: var(--palette-action-disabled) !important; +} + +.list-item-clickable { + color: inherit; + border: 0; + cursor: pointer; + margin: 0; + outline: 0; + user-select: none; + border-radius: 0; + vertical-align: middle; + background-color: transparent; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.list-item-clickable:hover { + background-color: var(--palette-action-default-hover); +} +.list-item-clickable:focus:not(.selected-item) { + background-color: var(--palette-action-default-hover); +} + +.list-item-gutters { + padding-left: 16px; + padding-right: 16px; +} + +.list-item-text { + flex: 1 1 auto; + min-width: 0; + margin-top: 4px; + margin-bottom: 4px; +} + +.list-item-text-inset { + padding-left: 56px; + padding-inline-start: 56px; + padding-inline-end: unset; +} + +.list-item-icon { + color: var(--palette-action-default); + display: inline-flex; + min-width: 56px; + flex-shrink: 0; +} + +.list-subheader { + color: var(--palette-action-default); + font-size: 0.875rem; + box-sizing: border-box; + list-style: none; + font-weight: 500; + padding-top: 8px; + padding-bottom: 20px; +} + +.list-subheader-gutters { + padding-left: 16px; + padding-right: 16px; +} + +.list-subheader-inset { + padding-left: 72px; + padding-inline-start: 72px; + padding-inline-end: unset; +} + +.list-subheader-sticky { + top: 0; + z-index: 1; + position: sticky; + background-color: inherit; +} + +.list-item-avatar { + min-width: 56px; + flex-shrink: 0; +} + +.nested-list > .list-item { + padding-left: 32px; + padding-inline-start: 32px; + padding-inline-end: unset; +} + +.application-layout-rtl { + direction: rtl; +} + +.menu { + display: inline-flex; + align-self: center; + position: relative; +} +.menu * { + cursor: pointer; +} +.menu > div.disabled { + cursor: default; +} +.menu > div.disabled * { + cursor: default; +} +.menu > div.menu-activator { + display: contents; +} + +.link.link-underline-none { + text-decoration: none; +} +.link.link-underline-hover { + text-decoration: none; +} +.link.link-underline-hover:hover, .link.link-underline-hover:focus-visible { + text-decoration: underline; +} +.link.link-underline-always { + text-decoration: underline; +} +.link.link-disabled { + cursor: default; + color: var(--palette-action-disabled) !important; +} +.link.link-disabled:not(.link-underline-always) { + text-decoration: none; +} + +.navmenu { + margin: 0; + position: relative; + list-style: none; + overscroll-behavior-y: contain; +} + +.nav-group { + width: 100%; + display: block; + justify-content: flex-start; +} +.nav-group > .nav-link > .nav-link-text { + font-weight: 500; +} +.nav-group * .nav-group > .nav-link > .nav-link-text { + font-weight: 400; +} +.nav-group * .nav-group > .nav-link.expanded > .nav-link-text { + font-weight: 500; +} +.nav-group * .navmenu .nav-item .nav-link { + padding-left: 36px; + padding-inline-start: 36px; + padding-inline-end: unset; +} + +.nav-group-disabled, .nav-group-disabled .nav-link-text, .nav-group-disabled .nav-link-expand-icon, .nav-group-disabled .nav-link-icon { + color: var(--palette-text-disabled) !important; + cursor: default; + pointer-events: none; +} + +.nav-item { + width: 100%; + display: flex; + justify-content: flex-start; + text-decoration: none; +} + +.nav-link { + width: 100%; + font-weight: 400; + padding: 8px 16px 8px 16px; + color: inherit; + line-height: 1.75; + display: inline-flex; + align-items: center; + justify-content: flex-start; + text-transform: inherit; + background-color: transparent; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, padding 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: flex-start; +} +.nav-link.nav-link-disabled { + color: var(--palette-text-disabled) !important; + cursor: default; + pointer-events: none; +} +.nav-link:hover:not(.nav-link-disabled) { + cursor: pointer; + text-decoration: none; + background-color: var(--palette-action-default-hover); +} +.nav-link:focus:not(.nav-link-disabled) { + background-color: var(--palette-action-default-hover); +} +.nav-link.active:not(.nav-link-disabled) { + font-weight: 500 !important; +} +.nav-link:not(.nav-link-disabled) .nav-link-icon.nav-link-icon-default { + color: var(--palette-drawer-icon); +} +.nav-link.nav-link-disabled .nav-link-icon { + color: var(--palette-text-disabled); +} +.nav-link .nav-link-expand-icon { + color: var(--palette-drawer-icon); + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), visibility 0s; +} +.nav-link .nav-link-expand-icon.transform { + transform: rotate(-180deg); +} +.nav-link .nav-link-expand-icon.transform-disabled { + transform: rotate(-180deg); +} +.nav-link .nav-link-text { + width: 100%; + text-align: start; + margin-left: 12px; + margin-inline-start: 12px; + margin-inline-end: unset; + letter-spacing: 0; +} + +.navmenu.navmenu-dense .nav-link { + padding: 4px 16px 4px 16px; +} +.navmenu.navmenu-margin-dense .nav-link { + margin: 2px 0; +} +.navmenu.navmenu-margin-normal .nav-link { + margin: 4px 0; +} +.navmenu.navmenu-rounded .nav-link { + border-radius: var(--default-borderradius); +} +.navmenu.navmenu-bordered .nav-link.active:not(.nav-link-disabled) { + border-inline-end-style: solid; + border-inline-end-width: 2px; +} +.navmenu.navmenu-default .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-primary); + background-color: var(--palette-action-default-hover); +} +.navmenu.navmenu-default .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-default .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: var(--palette-action-default-hover); +} +.navmenu.navmenu-default .nav-link-expand-icon.transform { + fill: var(--palette-primary); +} +.navmenu.navmenu-primary .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-primary); + background-color: var(--palette-primary-hover); +} +.navmenu.navmenu-primary .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-primary .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-primary-rgb), 0.12); +} +.navmenu.navmenu-primary .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-primary); +} +.navmenu.navmenu-primary .nav-link-expand-icon.transform { + fill: var(--palette-primary); +} +.navmenu.navmenu-secondary .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-secondary); + background-color: var(--palette-secondary-hover); +} +.navmenu.navmenu-secondary .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-secondary .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-secondary-rgb), 0.12); +} +.navmenu.navmenu-secondary .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-secondary); +} +.navmenu.navmenu-secondary .nav-link-expand-icon.transform { + fill: var(--palette-secondary); +} +.navmenu.navmenu-tertiary .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-tertiary); + background-color: var(--palette-tertiary-hover); +} +.navmenu.navmenu-tertiary .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-tertiary .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-tertiary-rgb), 0.12); +} +.navmenu.navmenu-tertiary .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-tertiary); +} +.navmenu.navmenu-tertiary .nav-link-expand-icon.transform { + fill: var(--palette-tertiary); +} +.navmenu.navmenu-info .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-info); + background-color: var(--palette-info-hover); +} +.navmenu.navmenu-info .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-info .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-info-rgb), 0.12); +} +.navmenu.navmenu-info .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-info); +} +.navmenu.navmenu-info .nav-link-expand-icon.transform { + fill: var(--palette-info); +} +.navmenu.navmenu-success .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-success); + background-color: var(--palette-success-hover); +} +.navmenu.navmenu-success .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-success .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-success-rgb), 0.12); +} +.navmenu.navmenu-success .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-success); +} +.navmenu.navmenu-success .nav-link-expand-icon.transform { + fill: var(--palette-success); +} +.navmenu.navmenu-warning .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-warning); + background-color: var(--palette-warning-hover); +} +.navmenu.navmenu-warning .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-warning .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-warning-rgb), 0.12); +} +.navmenu.navmenu-warning .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-warning); +} +.navmenu.navmenu-warning .nav-link-expand-icon.transform { + fill: var(--palette-warning); +} +.navmenu.navmenu-error .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-error); + background-color: var(--palette-error-hover); +} +.navmenu.navmenu-error .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-error .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-error-rgb), 0.12); +} +.navmenu.navmenu-error .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-error); +} +.navmenu.navmenu-error .nav-link-expand-icon.transform { + fill: var(--palette-error); +} +.navmenu.navmenu-dark .nav-link.active:not(.nav-link-disabled) { + color: var(--palette-dark); + background-color: var(--palette-dark-hover); +} +.navmenu.navmenu-dark .nav-link.active:not(.nav-link-disabled):hover:not(.nav-link-disabled), .navmenu.navmenu-dark .nav-link.active:not(.nav-link-disabled):focus-visible:not(.nav-link-disabled) { + background-color: rgba(var(--palette-dark-rgb), 0.12); +} +.navmenu.navmenu-dark .nav-link.active:not(.nav-link-disabled) .nav-link-icon { + color: var(--palette-dark); +} +.navmenu.navmenu-dark .nav-link-expand-icon.transform { + fill: var(--palette-dark); +} + +.nav-group * .navmenu > .nav-group .nav-link { + padding-left: 36px; + padding-inline-start: 36px; + padding-inline-end: 16px; +} +.nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding-left: 48px; + padding-inline-start: 48px; +} +.nav-group * .navmenu > .nav-group * .navmenu > .nav-group .nav-link { + padding-left: 48px; + padding-inline-start: 48px; + padding-inline-end: 16px; +} +.nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding-left: 60px; + padding-inline-start: 60px; + padding-inline-end: 0; +} +.nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu > .nav-group .nav-link { + padding-left: 60px; + padding-inline-start: 60px; + padding-inline-end: 16px; +} +.nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding-left: 72px; + padding-inline-start: 72px; + padding-inline-end: 0; +} + +.drawer--closed.drawer-mini > .drawer-content > .navmenu .nav-link .icon-root:first-child + .nav-link-text { + display: none; +} +.drawer--closed.drawer-mini .nav-group * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group * .navmenu > .nav-group .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu > .nav-group .nav-link { + padding: 8px 16px 8px 16px; +} +.drawer--closed.drawer-mini .nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu > .nav-group * .navmenu .nav-item .nav-link { + padding: 8px 16px 8px 16px; +} + +.page-content-navigation .page-content-navigation-navlink.active .nav-link { + color: var(--palette-primary); + border-color: var(--palette-primary); + background-color: transparent; +} +.page-content-navigation .page-content-navigation-navlink .nav-link { + padding: 4px 16px 4px 16px; + color: var(--palette-text-secondary); + border-left: 2px solid var(--palette-action-disabled-background); +} +.page-content-navigation .page-content-navigation-navlink .nav-link.active { + color: var(--palette-primary); + border-color: var(--palette-primary); + background-color: transparent; +} +.page-content-navigation .page-content-navigation-navlink .nav-link .nav-link-text { + margin-left: 0px; + margin-inline-start: 0px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.pagination { + display: inline-flex; + flex-wrap: wrap; + gap: 6px; + align-items: center; + margin: 0; +} +.pagination .pagination-item > * { + height: 32px; + min-width: 32px; + margin: 0 3px; + padding: 0 6px; + text-align: center; + border-radius: 16px; +} +.pagination .pagination-item :not(pagination-item-selected) > * { + box-shadow: none; +} +.pagination .pagination-item .button { + line-height: normal; +} +.pagination .pagination-item .icon-button { + padding: 0; +} +.pagination .pagination-item-rectangular .button { + border-radius: var(--default-borderradius); +} +.pagination .pagination-item .typography[disabled] { + color: var(--palette-action-disabled) !important; +} +.pagination-outlined .pagination-item-selected .button-outlined-default { + background-color: var(--palette-action-default-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-primary { + background-color: var(--palette-primary-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-secondary { + background-color: var(--palette-secondary-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-tertiary { + background-color: var(--palette-tertiary-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-info { + background-color: var(--palette-info-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-success { + background-color: var(--palette-success-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-warning { + background-color: var(--palette-warning-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-error { + background-color: var(--palette-error-hover); +} +.pagination-outlined .pagination-item-selected .button-outlined-dark { + background-color: var(--palette-dark-hover); +} +.pagination-filled .pagination-item:not(.pagination-item-selected) .button { + background-color: var(--palette-surface); +} +.pagination-filled .pagination-item .button { + box-shadow: var(--elevation-1); +} +.pagination-small .pagination-item > * { + height: 26px; + min-width: 26px; + margin: 0 1px; + padding: 0 4px; + border-radius: 13px; +} +.pagination-large .pagination-item > * { + height: 40px; + min-width: 40px; + padding: 0 10px; + border-radius: 20px; +} +.pagination-disable-elevation .pagination-item .button { + box-shadow: none; +} +.pagination-rtl .pagination-item .icon-root { + transform: scaleX(-1); +} + +.picker.rounded { + border-radius: var(--default-borderradius); +} +.picker .picker-actions { + flex: 0 0 auto; + display: flex; + padding: 8px; + align-items: center; + justify-content: flex-end; +} +.picker .picker-actions > :not(:first-child) { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +.picker-inline { + display: flex; + flex: 1 1 auto; + position: relative; + max-width: 100%; +} +.picker-inline.picker-input-button .input, .picker-inline.picker-input-button .input .input-root { + cursor: pointer; +} +.picker-inline.picker-input-button.disabled .input, .picker-inline.picker-input-button.disabled .input .input-root { + cursor: default; +} +.picker-inline.picker-input-text { + cursor: text; +} +.picker-inline.picker-input-text:hover { + cursor: text; +} +.picker-inline.picker-input-text.disabled { + cursor: default; +} +.picker-inline.picker-input-text.disabled:hover { + cursor: default; +} + +.picker-static { + display: flex; + overflow: hidden; + min-width: 310px; + flex-direction: column; +} + +.picker-container { + display: flex; + flex-direction: column; + border-radius: inherit; +} +.picker-container.picker-container-landscape { + flex-direction: row; +} +.picker-container .toolbar { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} + +.picker-popover-paper { + outline: 0; + z-index: calc(var(--zindex-popover) + 1); + position: absolute; + min-width: 16px; + min-height: 16px; + overflow-x: hidden; + overflow-y: auto; +} + +.picker-view { + display: none; + margin-top: 20px; +} +.picker-view.picker-open { + display: block; + animation: animation-fadein 251ms; +} + +.picker-content { + display: flex; + max-width: 100%; + min-width: 310px; + min-height: 305px; + overflow: hidden; + flex-direction: column; + justify-content: center; +} +.picker-content.picker-content-landscape { + padding: 0 8px; +} + +.picker-toolbar { + height: 100px; + display: flex; + align-items: center; + flex-direction: row; + justify-content: center; +} +.picker-toolbar.picker-toolbar-landscape { + height: auto; + padding: 8px; + max-width: 150px; + justify-content: flex-start; +} +.picker-toolbar.button-root { + padding: 0; + min-width: 16px; + text-transform: none; +} + +.picker-inline-paper .paper { + position: relative !important; +} + +.picker-hidden { + visibility: hidden; +} + +.picker-pos-top { + top: 0px; + position: fixed; + visibility: visible; +} +.picker-pos-top.picker-pos-left { + left: 10px; +} +.picker-pos-top.picker-pos-right { + right: 10px; +} + +.picker-pos-above { + bottom: 0px; + visibility: visible; +} +.picker-pos-above.picker-pos-left { + left: 50%; + transform: translateX(-50%); +} +.picker-pos-above.picker-pos-right { + right: 0px; +} + +.picker-pos-bottom { + bottom: 10px; + position: fixed; + visibility: visible; +} +.picker-pos-bottom.picker-pos-left { + left: 10px; +} +.picker-pos-bottom.picker-pos-right { + right: 10px; +} + +.picker-pos-below { + visibility: visible; +} +.picker-pos-below.picker-pos-left { + left: 50%; + transform: translateX(-50%); +} +.picker-pos-below.picker-pos-right { + right: 0px; +} + +.picker-datepicker-toolbar { + align-items: flex-start; + flex-direction: column; +} +.picker-datepicker-toolbar .button-year { + font-size: 1rem; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; +} +.picker-datepicker-toolbar .button-date { + font-size: 2.125rem; + font-weight: 400; + line-height: 1.17; + letter-spacing: 0.00735em; + text-transform: none; +} + +.picker-datepicker-toolbar-landscape { + padding: 16px; +} + +.picker-datepicker-date-landscape { + margin-right: 16px; + margin-inline-end: 16px; + margin-inline-start: unset; +} + +.picker-calendar-header-switch { + display: flex; + margin-top: 4px; + align-items: center; + margin-bottom: 8px; + justify-content: space-between; +} +.picker-calendar-header-switch > .icon-button { + z-index: 1; + padding: 8px; + margin: 6px; + background-color: var(--palette-surface); +} +.picker-calendar-header-switch > .icon-button:hover { + background-color: var(--palette-action-default-hover); +} +.picker-calendar-header-switch .picker-calendar-header-transition { + width: 100%; + height: 23px; + overflow: hidden; +} +.picker-calendar-header-switch .picker-calendar-header-transition:hover .typography { + cursor: pointer; + font-weight: 500; +} + +.picker-calendar-header-day { + display: flex; + max-height: 16px; + align-items: center; + justify-content: center; +} +.picker-calendar-header-day .day-label { + color: var(--palette-text-secondary); + width: 36px; + margin: 0 2px; + text-align: center; +} + +.picker-year-container { + height: 300px; + overflow-y: auto; +} +.picker-year-container .picker-year { + cursor: pointer; + height: 40px; + display: flex; + outline: none; + align-items: center; + justify-content: center; + user-select: none; + animation: animation-fadein 500ms; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.picker-year-container .picker-year:hover { + background-color: var(--palette-action-default-hover); +} +.picker-year-container .picker-year .picker-year-selected { + margin: 10px 0; + font-weight: 500; +} + +.picker-month-container { + width: 310px; + display: flex; + flex-wrap: wrap; + align-content: stretch; +} +.picker-month-container .picker-month { + flex: 1 0 33.33%; + cursor: pointer; + height: 60px; + display: flex; + outline: none; + transition: font-size 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + align-items: center; + justify-content: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.picker-month-container .picker-month:hover { + background-color: var(--palette-action-default-hover); +} +.picker-month-container .picker-month .picker-month-selected { + font-weight: 500; +} +.picker-month-container .picker-month.disabled { + color: var(--palette-text-disabled); + pointer-events: none; +} + +.picker-slide-transition { + display: block; + position: relative; +} + +.picker-slide-transition > * { + top: 0; + left: 0; + right: 0; + position: absolute; +} + +.picker-calendar-transition { + margin-top: 12px; + min-height: 216px; +} + +.picker-calendar-progress-container { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.picker-calendar-content { + display: grid; + --selected-day: 0; + grid-column-gap: 10px; + grid-template-columns: auto; +} + +@media (min-width: 600px) { + .picker-calendar-content:not(.picker-calendar-content-1) { + grid-template-columns: repeat(2, minmax(auto, 1fr)); + } + .picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-1 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-3 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-5 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-7 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-9 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-11 .picker-nav-button-next { + visibility: hidden; + } + .picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-1 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-3 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-5 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-7 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-9 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-11 .picker-nav-button-prev { + visibility: visible; + } + .picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-2 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-4 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-6 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-8 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-10 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-12 .picker-nav-button-next { + visibility: visible; + } + .picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-2 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-4 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-6 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-8 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-10 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1) .picker-calendar-header-12 .picker-nav-button-prev { + visibility: hidden; + } +} +@media (min-width: 960px) { + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) { + grid-template-columns: repeat(3, minmax(auto, 1fr)); + } + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-1 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-4 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-7 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-10 .picker-nav-button-next { + visibility: hidden; + } + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-1 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-4 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-7 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-10 .picker-nav-button-prev { + visibility: visible; + } + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-2 .picker-nav-button-next, .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-2 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-5 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-5 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-8 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-8 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-11 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-11 .picker-nav-button-prev { + visibility: hidden; + } + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-3 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-6 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-9 .picker-nav-button-next, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-12 .picker-nav-button-next { + visibility: visible; + } + .picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-3 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-6 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-9 .picker-nav-button-prev, +.picker-calendar-content:not(.picker-calendar-content-1):not(.picker-calendar-content-2) .picker-calendar-header-12 .picker-nav-button-prev { + visibility: hidden; + } +} +:not(.picker-hidden) .picker-calendar-header-last .picker-nav-button-next { + visibility: inherit !important; +} + +.picker-hidden .picker-nav-button-next, .picker-hidden .picker-nav-button-prev { + visibility: hidden !important; +} + +.picker-calendar-container { + display: flex; + width: 310px; + flex-direction: column; +} + +.picker-calendar { + display: flex; + flex-wrap: wrap; + justify-content: center; +} +.picker-calendar .day { + color: var(--palette-text-primary); + width: 36px; + height: 36px; + margin: 0 2px; + padding: 0; + font-size: 0.75rem; + font-weight: 500; +} +.picker-calendar .day:hover { + background-color: var(--palette-action-default-hover); +} +.picker-calendar .day.hidden { + opacity: 0; + pointer-events: none; +} +.picker-calendar .day.current { + font-weight: 600; +} +.picker-calendar .day.selected { + font-weight: 500; +} +.picker-calendar .day .typography { + margin-top: 2px; +} +.picker-calendar .day.disabled { + color: var(--palette-text-disabled); + pointer-events: none; +} +.picker-calendar .day.range { + margin: 0; + width: 40px; + transition: none; +} +.picker-calendar .day.range.range-start-selected { + border-radius: 50% 0% 0% 50%; +} +.picker-calendar .day.range.range-end-selected { + border-radius: 0% 50% 50% 0%; +} +.picker-calendar .day.range.range-between { + border-radius: 0; + background-color: var(--palette-action-default-hover); +} +.picker-calendar .day.range.range-selection:hover.range-start-selected { + border-radius: 50%; +} +.picker-calendar .day.range.range-selection:hover:not(.range-start-selected) { + border-radius: 0% 50% 50% 0%; +} +.picker-calendar .day.range.range-selection:not(:hover):not(.range-start-selected) { + border-radius: 0; + background: linear-gradient(var(--palette-action-default-hover) 100%, var(--palette-action-default-hover) 100%, transparent 0%); + background-size: 100% calc(100% * (var(--selected-day) - var(--day-id))); +} + +.range-selection-primary:hover { + color: var(--palette-primary-text) !important; + background-color: var(--palette-primary) !important; +} + +.range-selection-secondary:hover { + color: var(--palette-secondary-text) !important; + background-color: var(--palette-secondary) !important; +} + +.range-selection-tertiary:hover { + color: var(--palette-tertiary-text) !important; + background-color: var(--palette-tertiary) !important; +} + +.range-selection-info:hover { + color: var(--palette-info-text) !important; + background-color: var(--palette-info) !important; +} + +.range-selection-success:hover { + color: var(--palette-success-text) !important; + background-color: var(--palette-success) !important; +} + +.range-selection-warning:hover { + color: var(--palette-warning-text) !important; + background-color: var(--palette-warning) !important; +} + +.range-selection-error:hover { + color: var(--palette-error-text) !important; + background-color: var(--palette-error) !important; +} + +.range-selection-dark:hover { + color: var(--palette-dark-text) !important; + background-color: var(--palette-dark) !important; +} + +.picker-calendar-week { + display: flex; + margin: 0 5px; + justify-content: center; + align-items: center; +} +.picker-calendar-week .picker-calendar-week-text { + width: 15px; + margin-top: 2px !important; + color: var(--palette-text-disabled); +} + +.application-layout-rtl .picker-calendar .day.range.range-start-selected { + border-radius: 0% 50% 50% 0%; +} +.application-layout-rtl .picker-calendar .day.range.range-end-selected { + border-radius: 50% 0% 0% 50%; +} +.application-layout-rtl .picker-calendar .day.range.range-selection:hover:not(.range-start-selected) { + border-radius: 50% 0% 0% 50%; +} + +.picker-timepicker-toolbar .timepicker-button { + padding: 0; + min-width: 16px; + text-transform: none; +} +.picker-timepicker-toolbar .timepicker-button.timepicker-toolbar-text { + color: rgba(255, 255, 255, 0.54); +} +.picker-timepicker-toolbar .timepicker-button:hover { + background-color: var(--theme-default-hover); +} +.picker-timepicker-toolbar .timepicker-hourminute { + display: flex; + align-items: baseline; + justify-content: flex-end; +} +.picker-timepicker-toolbar .timepicker-hourminute .timepicker-button { + font-size: 3.75rem; + font-weight: 300; + line-height: 1; + letter-spacing: -0.00833em; +} +.picker-timepicker-toolbar .timepicker-ampm { + display: flex; + margin-left: 20px; + margin-right: -20px; + margin-inline-start: 20px; + margin-inline-end: -20px; + flex-direction: column; +} +.picker-timepicker-toolbar .timepicker-ampm .timepicker-button { + font-size: 18px; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; +} +.picker-timepicker-toolbar .timepicker-separator { + cursor: default; + margin: 0 4px 0 2px; + margin-inline-start: 2px; + margin-inline-end: 4px; +} +.picker-timepicker-toolbar.picker-timepicker-toolbar-landscape { + flex-wrap: wrap; + width: 150px; + justify-content: center; +} +.picker-timepicker-toolbar.picker-timepicker-toolbar-landscape .timepicker-hourminute .timepicker-button { + font-size: 3rem; + font-weight: 400; + line-height: 1.04; + letter-spacing: 0em; +} +.picker-timepicker-toolbar.picker-timepicker-toolbar-landscape .timepicker-ampm { + display: flex; + margin-left: 20px; + margin-right: -20px; + margin-inline-start: 20px; + margin-inline-end: -20px; + flex-direction: column; +} +.picker-timepicker-toolbar.picker-timepicker-toolbar-landscape .timepicker-ampm .timepicker-button { + font-size: 18px; + font-weight: 400; + line-height: 1.75; + letter-spacing: 0.00938em; +} +.picker-timepicker-toolbar.picker-timepicker-toolbar-landscape .timepicker-separator { + font-size: 3rem; + font-weight: 400; + line-height: 1.04; + letter-spacing: 0em; +} + +.picker-time-container { + margin: 16px 0 8px; + display: flex; + align-items: flex-end; + justify-content: center; +} +.picker-time-container .picker-time-clock { + width: 260px; + height: 260px; + position: relative; + border-radius: 50%; + pointer-events: none; + background-color: rgba(0, 0, 0, 0.07); +} +.picker-time-container .picker-time-clock .picker-time-clock-mask { + width: 100%; + height: 100%; + outline: none; + position: absolute; + user-select: none; + touch-actions: none; + pointer-events: auto; +} +.picker-time-container .picker-time-clock .picker-time-clock-pin { + top: 50%; + left: 50%; + width: 6px; + height: 6px; + position: absolute; + transform: translate(-50%, -50%); + border-radius: 50%; +} +.picker-time-container .picker-time-clock .picker-stick-inner { + left: calc(50% - 1px); + width: 3px; + height: 35%; + bottom: 0; + position: absolute; + transform-origin: center bottom 0px; +} +.picker-time-container .picker-time-clock .picker-stick-inner.hour:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + height: 48px; + width: 48px; + top: -60%; + border-radius: 50%; + background-color: inherit; +} +.picker-time-container .picker-time-clock .picker-stick-outer { + left: calc(50% - 1px); + width: 0; + height: 35%; + bottom: 35%; + position: absolute; + transform-origin: center bottom 0px; +} +.picker-time-container .picker-time-clock .picker-stick-outer.hour:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + height: 48px; + width: 62px; + top: -20px; + border-radius: 50%; + background-color: inherit; +} +.picker-time-container .picker-time-clock .picker-stick { + left: calc(50% - 1px); + width: 3px; + height: 50%; + bottom: 50%; + position: absolute; + transform-origin: center bottom 0px; +} +.picker-time-container .picker-time-clock .picker-stick.hour:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + height: 62px; + width: 62px; + top: 20px; + border-radius: 50%; + background-color: inherit; +} +.picker-time-container .picker-time-clock .picker-stick.minute:after { + content: ""; + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + height: 44px; + width: 15px; + top: 20px; + border-radius: 50%; + background-color: inherit; +} +.picker-time-container .picker-time-clock .picker-time-clock-pointer { + left: calc(50% - 1px); + width: 2px; + bottom: 50%; + position: absolute; + transform-origin: center bottom 0px; +} +.picker-time-container .picker-time-clock .picker-time-clock-pointer.picker-time-clock-pointer-animation { + transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, height 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.picker-time-container .picker-time-clock .picker-time-clock-pointer .picker-time-clock-pointer-thumb { + position: absolute; + border-radius: 100%; +} +.picker-time-container .picker-time-clock .picker-time-clock-pointer .picker-time-clock-pointer-thumb.onclock-text { + top: -19px; + left: -13px; + width: 28px; + height: 28px; + border: none; + background-color: inherit; +} +.picker-time-container .picker-time-clock .picker-time-clock-pointer .picker-time-clock-pointer-thumb.onclock-minute { + background: transparent; + border: 2px solid; + width: 10px; + height: 10px; + top: -9px; + left: -4px; +} +.picker-time-container .picker-time-clock .clock-number { + left: calc((100% - 32px) / 2); + color: var(--palette-text-primary); + background-color: transparent !important; + width: 32px; + height: 32px; + display: inline-flex; + position: absolute; + align-items: center; + user-select: none; + border-radius: 50%; + justify-content: center; + transition-duration: 120ms; + transition-property: color; +} + +.time-picker-dial { + width: 100%; + height: 100%; + position: absolute; + transition: transform 350ms, opacity 350ms; +} + +.time-picker-dial-out { + opacity: 0; +} + +.time-picker-hour.time-picker-dial-out { + transform: scale(1.2, 1.2); + transform-origin: center; +} + +.time-picker-minute.time-picker-dial-out { + transform: scale(0.8, 0.8); + transform-origin: center; +} + +.time-picker-dial-hidden { + visibility: hidden; +} + +.picker-container + .picker-color-toolbar { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.picker-container + .picker-color-content { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} + +.picker-color-toolbar { + height: 32px; + padding-right: 2px; + padding-left: 2px; +} + +.picker-color-content { + min-height: unset; + position: relative; +} + +.picker-color-picker { + width: 312px; + height: 250px; + position: relative; + overflow: hidden; +} +.picker-color-picker .picker-color-overlay { + width: 100%; + height: 100%; +} +.picker-color-picker .picker-color-overlay.picker-color-overlay-white { + background: linear-gradient(to right, white 0%, rgba(255, 255, 255, 0) 100%); +} +.picker-color-picker .picker-color-overlay.picker-color-overlay-black { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, black 100%); +} +.picker-color-picker .picker-color-selector { + position: absolute; + top: -13px; + left: -13px; +} + +.picker-color-controls { + width: 312px; + padding: 16px; + display: flex; + flex-direction: column; +} +.picker-color-controls .picker-color-controls-row { + display: flex; + align-items: center; +} +.picker-color-controls .picker-color-controls-row + .picker-color-controls-row { + margin-top: 24px; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders { + display: flex; + flex: 1 0 auto; + flex-direction: column; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider { + min-width: 224px; + border-radius: var(--default-borderradius); +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input { + height: 10px; + border-radius: var(--default-borderradius); +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input::-webkit-slider-runnable-track { + background: initial; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input::-moz-range-track { + background: initial; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input::-webkit-slider-thumb { + appearance: none; + margin-top: -6px; + height: 14px; + width: 14px; + transform: none; + transition: none; + background: #f0f0f0; + box-shadow: rgba(0, 0, 0, 0.37) 0px 1px 4px 0px; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input::-moz-range-thumb { + appearance: none; + margin-top: -6px; + height: 14px; + width: 14px; + transform: none; + transition: none; + background: #f0f0f0; + box-shadow: rgba(0, 0, 0, 0.37) 0px 1px 4px 0px; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input:active::-webkit-slider-thumb { + box-shadow: 0 0 0 2px var(--palette-action-default-hover) !important; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider .slider-input:active::-moz-range-thumb { + box-shadow: 0 0 0 2px var(--palette-action-default-hover) !important; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider.hue + .alpha { + margin-top: 18px; +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider.hue .slider-input { + background: linear-gradient(90deg, #FF0000, #ff0 16.66%, #0f0 33.33%, #0ff 50%, #00f 66.66%, #f0f 83.33%, #FF0000); +} +.picker-color-controls .picker-color-controls-row .picker-color-sliders .picker-color-slider.alpha .slider-input { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGCQwoKxgqGgcJA5h3yFAAs8BRWVSwooAAAAAElFTkSuQmCC) repeat; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs { + display: flex; + flex: 1 1 auto; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs .picker-color-inputfield { + width: 100%; + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs .picker-color-inputfield:last-of-type { + margin-right: 0; + margin-inline-end: 0; + margin-inline-start: unset; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs .picker-color-inputfield .input input { + padding: 6px; + height: 1em; + text-align: center; + font-size: 14px; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs .picker-color-inputfield .input-helper-text { + text-align: center; +} +.picker-color-controls .picker-color-controls-row .picker-color-inputs .picker-color-inputfield .input-helper-text div div { + margin: auto; +} +.picker-color-controls .picker-color-controls-row .picker-control-switch { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; + padding-bottom: 16px; +} +.picker-color-controls .picker-color-controls-row .picker-color-collection { + display: flex; + min-width: 230px; + justify-content: space-between; +} +.picker-color-controls .picker-color-controls-row .picker-color-collection .picker-color-dot { + max-width: 38px; +} + +.picker-color-dot { + height: 38px; + min-width: 38px; + width: 100%; + transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border-radius 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: var(--default-borderradius); + box-shadow: 0 0 6px rgba(127, 130, 134, 0.18); +} +.picker-color-dot:hover { + cursor: pointer; + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); +} +.picker-color-dot.picker-color-dot-current { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGCQwoKxgqGgcJA5h3yFAAs8BRWVSwooAAAAAElFTkSuQmCC) repeat; +} +.picker-color-dot .picker-color-fill { + width: 100%; + height: 100%; + border-radius: inherit; +} +.picker-color-dot + .picker-color-sliders { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; +} +.picker-color-dot + .picker-color-collection { + margin-left: 10px; + margin-inline-start: 10px; + margin-inline-end: unset; +} + +.picker-color-view { + position: absolute; + width: 100%; + height: 100%; + overflow: auto; + padding: 6px; + background-color: var(--palette-surface); +} +.picker-color-view .picker-color-view-collection { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; +} +.picker-color-view .picker-color-view-collection .picker-color-dot { + max-width: 38px; + margin: 8px; +} +.picker-color-view .picker-color-view-collection .picker-color-dot.selected { + border-radius: 50%; + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); +} + +.picker-color-picker .picker-color-grid { + display: flex; + flex-wrap: wrap; +} +.picker-color-picker .picker-color-grid .picker-color-dot { + height: 25px; + min-width: 26px; + max-width: 26px; + border-radius: 0px; + box-shadow: none; +} + +.popover { + outline: 0; + z-index: calc(var(--zindex-popover) + 1); + position: absolute; + opacity: 0; +} +.popover.popover-fixed { + position: fixed; +} +.popover.popover-relative-width { + width: 100%; +} +.popover.popover-open { + opacity: 1; + transition: opacity; +} +.popover:not(.popover-open) { + pointer-events: none; + transition-duration: 0ms !important; + transition-delay: 0ms !important; +} + +.appbar .popover-cascading-value { + z-index: calc(var(--zindex-appbar) + 2); +} + +.drawer:not(.drawer-temporary) .popover-cascading-value { + z-index: calc(var(--zindex-drawer) + 2); +} +.drawer.drawer-temporary .popover-cascading-value, .drawer.drawer-responsive .popover-cascading-value { + z-index: calc(var(--zindex-appbar) + 4); +} + +.dialog .popover-cascading-value { + z-index: calc(var(--zindex-dialog) + 3); +} + +.popover .list { + max-height: inherit; + overflow-y: auto; +} + +.simple-table table { + width: 100%; + display: table; + border-spacing: 0; + border-collapse: collapse; +} +.simple-table table thead { + display: table-header-group; +} +.simple-table table tbody { + display: table-row-group; +} +.simple-table table * tr { + color: inherit; + display: table-row; + outline: 0; + vertical-align: middle; +} +.simple-table table * tr > td, .simple-table table * tr th { + display: table-cell; + padding: 16px; + font-size: 0.875rem; + text-align: start; + font-weight: 400; + line-height: 1.43; + border-bottom: 1px solid var(--palette-table-lines); + letter-spacing: 0.01071em; + vertical-align: inherit; +} +.simple-table table * tr > th { + font-weight: 500; + line-height: 1.5rem; +} +.simple-table table tbody tr:last-child td { + border-bottom: none; +} + +.simple-table.table-dense * tr td, .simple-table.table-dense * tr th { + padding: 6px 16px; +} + +.simple-table.table-hover .table-container table tbody tr:hover { + background-color: var(--palette-table-hover); +} + +.simple-table.table-bordered .table-container table tbody tr td { + border-right: 1px solid var(--palette-table-lines); +} +.simple-table.table-bordered .table-container table tbody tr td:last-child { + border-right: none; +} + +.simple-table.table-striped .table-container table tbody tr:nth-of-type(odd) { + background-color: var(--palette-table-striped); +} + +.table-hover.table-striped .table-container table tbody tr:nth-of-type(odd):nth-of-type(odd):hover { + background-color: var(--palette-table-hover); +} + +.simple-table.table-sticky-header .table-container { + overflow-x: auto; + max-height: 100%; +} +.simple-table.table-sticky-header * table { + border-collapse: separate; +} +.simple-table.table-sticky-header * table thead * th:first-child { + border-radius: var(--default-borderradius) 0 0 0; +} +.simple-table.table-sticky-header * table thead * th:last-child { + border-radius: 0 var(--default-borderradius) 0 0; +} +.simple-table.table-sticky-header * table thead * th { + background-color: var(--palette-surface); + position: sticky; + z-index: 1; + top: 0; +} + +.simple-table.table-sticky-footer .table-container { + overflow-x: auto; + max-height: 100%; +} +.simple-table.table-sticky-footer * table { + border-collapse: separate; +} +.simple-table.table-sticky-footer * table tfoot * td { + background-color: var(--palette-surface); + position: sticky; + z-index: 1; + bottom: 0; +} + +.skeleton { + height: 1.2em; + display: block; + background-color: rgba(0, 0, 0, 0.11); +} + +.skeleton-text { + height: auto; + transform: scale(1, 0.6); + margin-top: 0; + border-radius: var(--default-borderradius); + margin-bottom: 0; + transform-origin: 0 60%; +} + +.skeleton-text:empty:before { + content: " "; +} + +.skeleton-circle { + border-radius: 50%; +} + +.skeleton-pulse { + animation: skeleton-keyframes-pulse 1.5s ease-in-out 0.5s infinite; +} + +.skeleton-wave { + overflow: hidden; + position: relative; +} + +.skeleton-wave::after { + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + animation: skeleton-keyframes-wave 1.6s linear 0.5s infinite; + transform: translateX(-100%); + background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.04), transparent); +} + +.slider { + color: var(--palette-text-primary); + display: inline-block; + width: 100%; + user-select: none; +} +.slider > .typography { + margin-top: 10px; +} +.slider.slider-vertical { + transform: rotate(270deg); + height: 100%; + width: unset; +} +.slider .slider-input { + -webkit-appearance: none; + -moz-appearance: none; + position: relative; + display: block; + width: 100%; + background-color: transparent; + cursor: pointer; +} +.slider .slider-input:focus { + outline: none; +} +.slider .slider-input:active + .slider-value-label { + opacity: 1; +} +.slider .slider-input::-webkit-slider-runnable-track { + border-radius: var(--default-borderradius); + width: 100%; +} +.slider .slider-input::-moz-range-track { + border-radius: var(--default-borderradius); + width: 100%; +} +.slider .slider-input::-webkit-slider-thumb { + appearance: none; + -webkit-appearance: none; + border: none; + border-radius: 50%; + cursor: pointer; + transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.slider .slider-input::-moz-range-thumb { + appearance: none; + -webkit-appearance: none; + border: none; + border-radius: 50%; + cursor: pointer; + transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.slider .slider-input:disabled { + cursor: default; + opacity: 0.38; +} +.slider .slider-input:disabled::-webkit-slider-runnable-track { + background-color: var(--palette-text-disabled); +} +.slider .slider-input:disabled::-moz-range-track { + background-color: var(--palette-text-disabled); +} +.slider .slider-input:disabled::-webkit-slider-thumb { + background-color: black; + color: white; + box-shadow: 0 0 0 1px white !important; + transform: scale(4, 4); +} +.slider .slider-input:disabled::-webkit-slider-thumb:hover { + box-shadow: 0 0 0 1px white !important; +} +.slider .slider-input:disabled::-moz-range-thumb { + background-color: black; + color: white; + box-shadow: 0 0 0 1px white !important; + transform: scale(4, 4); +} +.slider .slider-input:disabled::-moz-range-thumb:hover { + box-shadow: 0 0 0 1px white !important; +} +.slider.slider-primary .slider-filled { + background-color: var(--palette-primary); +} +.slider.slider-primary .slider-track-tick { + background-color: var(--palette-primary); +} +.slider.slider-primary .slider-value-label { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.slider.slider-primary .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-primary-rgb), 0.3); +} +.slider.slider-primary .slider-input::-moz-range-track { + background-color: rgba(var(--palette-primary-rgb), 0.3); +} +.slider.slider-primary .slider-input::-webkit-slider-thumb { + background-color: var(--palette-primary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3); +} +.slider.slider-primary .slider-input::-moz-range-thumb { + background-color: var(--palette-primary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3); +} +.slider.slider-primary .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-primary-rgb), 0.24); +} +.slider.slider-primary .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-primary-rgb), 0.24); +} +.slider.slider-primary .slider-input:active::-webkit-slider-thumb, .slider.slider-primary .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-primary-rgb), 0.24); +} +.slider.slider-primary .slider-input:active::-moz-range-thumb, .slider.slider-primary .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-primary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-primary-rgb), 0.24); +} +.slider.slider-secondary .slider-filled { + background-color: var(--palette-secondary); +} +.slider.slider-secondary .slider-track-tick { + background-color: var(--palette-secondary); +} +.slider.slider-secondary .slider-value-label { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.slider.slider-secondary .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-secondary-rgb), 0.3); +} +.slider.slider-secondary .slider-input::-moz-range-track { + background-color: rgba(var(--palette-secondary-rgb), 0.3); +} +.slider.slider-secondary .slider-input::-webkit-slider-thumb { + background-color: var(--palette-secondary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3); +} +.slider.slider-secondary .slider-input::-moz-range-thumb { + background-color: var(--palette-secondary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3); +} +.slider.slider-secondary .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-secondary-rgb), 0.24); +} +.slider.slider-secondary .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-secondary-rgb), 0.24); +} +.slider.slider-secondary .slider-input:active::-webkit-slider-thumb, .slider.slider-secondary .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-secondary-rgb), 0.24); +} +.slider.slider-secondary .slider-input:active::-moz-range-thumb, .slider.slider-secondary .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-secondary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-secondary-rgb), 0.24); +} +.slider.slider-tertiary .slider-filled { + background-color: var(--palette-tertiary); +} +.slider.slider-tertiary .slider-track-tick { + background-color: var(--palette-tertiary); +} +.slider.slider-tertiary .slider-value-label { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.slider.slider-tertiary .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-tertiary-rgb), 0.3); +} +.slider.slider-tertiary .slider-input::-moz-range-track { + background-color: rgba(var(--palette-tertiary-rgb), 0.3); +} +.slider.slider-tertiary .slider-input::-webkit-slider-thumb { + background-color: var(--palette-tertiary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3); +} +.slider.slider-tertiary .slider-input::-moz-range-thumb { + background-color: var(--palette-tertiary); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3); +} +.slider.slider-tertiary .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-tertiary-rgb), 0.24); +} +.slider.slider-tertiary .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3), 0 0 0 1px rgba(var(--palette-tertiary-rgb), 0.24); +} +.slider.slider-tertiary .slider-input:active::-webkit-slider-thumb, .slider.slider-tertiary .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-tertiary-rgb), 0.24); +} +.slider.slider-tertiary .slider-input:active::-moz-range-thumb, .slider.slider-tertiary .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-tertiary-rgb), 0.3), 0 0 0 2px rgba(var(--palette-tertiary-rgb), 0.24); +} +.slider.slider-info .slider-filled { + background-color: var(--palette-info); +} +.slider.slider-info .slider-track-tick { + background-color: var(--palette-info); +} +.slider.slider-info .slider-value-label { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.slider.slider-info .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-info-rgb), 0.3); +} +.slider.slider-info .slider-input::-moz-range-track { + background-color: rgba(var(--palette-info-rgb), 0.3); +} +.slider.slider-info .slider-input::-webkit-slider-thumb { + background-color: var(--palette-info); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3); +} +.slider.slider-info .slider-input::-moz-range-thumb { + background-color: var(--palette-info); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3); +} +.slider.slider-info .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3), 0 0 0 1px rgba(var(--palette-info-rgb), 0.24); +} +.slider.slider-info .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3), 0 0 0 1px rgba(var(--palette-info-rgb), 0.24); +} +.slider.slider-info .slider-input:active::-webkit-slider-thumb, .slider.slider-info .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3), 0 0 0 2px rgba(var(--palette-info-rgb), 0.24); +} +.slider.slider-info .slider-input:active::-moz-range-thumb, .slider.slider-info .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-info-rgb), 0.3), 0 0 0 2px rgba(var(--palette-info-rgb), 0.24); +} +.slider.slider-success .slider-filled { + background-color: var(--palette-success); +} +.slider.slider-success .slider-track-tick { + background-color: var(--palette-success); +} +.slider.slider-success .slider-value-label { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.slider.slider-success .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-success-rgb), 0.3); +} +.slider.slider-success .slider-input::-moz-range-track { + background-color: rgba(var(--palette-success-rgb), 0.3); +} +.slider.slider-success .slider-input::-webkit-slider-thumb { + background-color: var(--palette-success); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3); +} +.slider.slider-success .slider-input::-moz-range-thumb { + background-color: var(--palette-success); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3); +} +.slider.slider-success .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3), 0 0 0 1px rgba(var(--palette-success-rgb), 0.24); +} +.slider.slider-success .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3), 0 0 0 1px rgba(var(--palette-success-rgb), 0.24); +} +.slider.slider-success .slider-input:active::-webkit-slider-thumb, .slider.slider-success .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3), 0 0 0 2px rgba(var(--palette-success-rgb), 0.24); +} +.slider.slider-success .slider-input:active::-moz-range-thumb, .slider.slider-success .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-success-rgb), 0.3), 0 0 0 2px rgba(var(--palette-success-rgb), 0.24); +} +.slider.slider-warning .slider-filled { + background-color: var(--palette-warning); +} +.slider.slider-warning .slider-track-tick { + background-color: var(--palette-warning); +} +.slider.slider-warning .slider-value-label { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.slider.slider-warning .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-warning-rgb), 0.3); +} +.slider.slider-warning .slider-input::-moz-range-track { + background-color: rgba(var(--palette-warning-rgb), 0.3); +} +.slider.slider-warning .slider-input::-webkit-slider-thumb { + background-color: var(--palette-warning); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3); +} +.slider.slider-warning .slider-input::-moz-range-thumb { + background-color: var(--palette-warning); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3); +} +.slider.slider-warning .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3), 0 0 0 1px rgba(var(--palette-warning-rgb), 0.24); +} +.slider.slider-warning .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3), 0 0 0 1px rgba(var(--palette-warning-rgb), 0.24); +} +.slider.slider-warning .slider-input:active::-webkit-slider-thumb, .slider.slider-warning .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3), 0 0 0 2px rgba(var(--palette-warning-rgb), 0.24); +} +.slider.slider-warning .slider-input:active::-moz-range-thumb, .slider.slider-warning .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-warning-rgb), 0.3), 0 0 0 2px rgba(var(--palette-warning-rgb), 0.24); +} +.slider.slider-error .slider-filled { + background-color: var(--palette-error); +} +.slider.slider-error .slider-track-tick { + background-color: var(--palette-error); +} +.slider.slider-error .slider-value-label { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.slider.slider-error .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-error-rgb), 0.3); +} +.slider.slider-error .slider-input::-moz-range-track { + background-color: rgba(var(--palette-error-rgb), 0.3); +} +.slider.slider-error .slider-input::-webkit-slider-thumb { + background-color: var(--palette-error); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3); +} +.slider.slider-error .slider-input::-moz-range-thumb { + background-color: var(--palette-error); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3); +} +.slider.slider-error .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3), 0 0 0 1px rgba(var(--palette-error-rgb), 0.24); +} +.slider.slider-error .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3), 0 0 0 1px rgba(var(--palette-error-rgb), 0.24); +} +.slider.slider-error .slider-input:active::-webkit-slider-thumb, .slider.slider-error .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3), 0 0 0 2px rgba(var(--palette-error-rgb), 0.24); +} +.slider.slider-error .slider-input:active::-moz-range-thumb, .slider.slider-error .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-error-rgb), 0.3), 0 0 0 2px rgba(var(--palette-error-rgb), 0.24); +} +.slider.slider-dark .slider-filled { + background-color: var(--palette-dark); +} +.slider.slider-dark .slider-track-tick { + background-color: var(--palette-dark); +} +.slider.slider-dark .slider-value-label { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} +.slider.slider-dark .slider-input::-webkit-slider-runnable-track { + background-color: rgba(var(--palette-dark-rgb), 0.3); +} +.slider.slider-dark .slider-input::-moz-range-track { + background-color: rgba(var(--palette-dark-rgb), 0.3); +} +.slider.slider-dark .slider-input::-webkit-slider-thumb { + background-color: var(--palette-dark); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3); +} +.slider.slider-dark .slider-input::-moz-range-thumb { + background-color: var(--palette-dark); + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3); +} +.slider.slider-dark .slider-input::-webkit-slider-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3), 0 0 0 1px rgba(var(--palette-dark-rgb), 0.24); +} +.slider.slider-dark .slider-input::-moz-range-thumb:hover { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3), 0 0 0 1px rgba(var(--palette-dark-rgb), 0.24); +} +.slider.slider-dark .slider-input:active::-webkit-slider-thumb, .slider.slider-dark .slider-input:focus-visible::-webkit-slider-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3), 0 0 0 2px rgba(var(--palette-dark-rgb), 0.24); +} +.slider.slider-dark .slider-input:active::-moz-range-thumb, .slider.slider-dark .slider-input:focus-visible::-moz-range-thumb { + box-shadow: 0px 1px 2px -1px rgba(var(--palette-dark-rgb), 0.3), 0 0 0 2px rgba(var(--palette-dark-rgb), 0.24); +} +.slider.slider-small .slider-filled { + height: 2px; +} +.slider.slider-small .slider-track-tick { + width: 2px; + height: 2px; +} +.slider.slider-small .slider-track-tick-label { + transform: translateX(-50%) translateY(50%); +} +.slider.slider-small .slider-input::-webkit-slider-runnable-track { + height: 2px; + margin: 10px 0; +} +.slider.slider-small .slider-input::-moz-range-track { + height: 2px; + margin: 10px 0; +} +.slider.slider-small .slider-input::-webkit-slider-thumb { + height: 2px; + width: 2px; + transform: scale(6, 6); +} +.slider.slider-small .slider-input::-moz-range-thumb { + height: 2px; + width: 2px; + transform: scale(6, 6); +} +.slider.slider-medium .slider-filled { + height: 4px; +} +.slider.slider-medium .slider-track-tick { + width: 4px; + height: 4px; +} +.slider.slider-medium .slider-track-tick-label { + transform: translateX(-50%) translateY(80%); +} +.slider.slider-medium .slider-input::-webkit-slider-runnable-track { + height: 4px; + margin: 12px 0; +} +.slider.slider-medium .slider-input::-moz-range-track { + height: 4px; + margin: 12px 0; +} +.slider.slider-medium .slider-input::-webkit-slider-thumb { + height: 4px; + width: 4px; + transform: scale(5, 5); +} +.slider.slider-medium .slider-input::-moz-range-thumb { + height: 4px; + width: 4px; + transform: scale(5, 5); +} +.slider.slider-large .slider-filled { + height: 6px; +} +.slider.slider-large .slider-track-tick { + width: 6px; + height: 6px; +} +.slider.slider-large .slider-track-tick-label { + transform: translateX(-50%) translateY(110%); +} +.slider.slider-large .slider-input::-webkit-slider-runnable-track { + height: 6px; + margin: 14px 0; +} +.slider.slider-large .slider-input::-moz-range-track { + height: 6px; + margin: 14px 0; +} +.slider.slider-large .slider-input::-webkit-slider-thumb { + height: 6px; + width: 6px; + transform: scale(4, 4); +} +.slider.slider-large .slider-input::-moz-range-thumb { + height: 6px; + width: 6px; + transform: scale(4, 4); +} +.slider .slider-container { + position: relative; + width: 100%; + display: flex; + align-content: center; +} +.slider .slider-filled { + border-radius: var(--default-borderradius); +} +.slider .slider-inner-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; +} +.slider .slider-value-label { + position: absolute; + top: 0; + transform: translateX(-50%) translateY(-125%); + padding: 4px 8px; + text-align: center; + align-items: center; + justify-content: center; + font-size: 12px; + border-radius: 2px; + line-height: normal; + opacity: 0; + transition: opacity 0.2s ease-in-out; + pointer-events: none; + user-select: none; +} +.slider .slider-tickmarks { + display: flex; + justify-content: space-between; + flex-grow: 1; +} +.slider .slider-track-tick { + border-radius: 9999%; + background-color: var(--palette-primary); +} +.slider .slider-track-tick-label { + position: absolute; + top: 0; + left: 0; +} + +.progress-circular { + display: inline-block; + color: var(--palette-text-secondary); +} +.progress-circular.progress-indeterminate { + animation: progress-circular-keyframes-circular-rotate 1.4s linear infinite; +} +.progress-circular.progress-static { + transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.progress-circular.progress-small { + height: 24px; + width: 24px; +} +.progress-circular.progress-medium { + height: 40px; + width: 40px; +} +.progress-circular.progress-large { + height: 56px; + width: 56px; +} + +.progress-circular-svg { + display: block; + transform: rotate(-90deg); +} + +.progress-circular-circle { + stroke: currentColor; +} +.progress-circular-circle.progress-indeterminate { + animation: progress-circular-keyframes-circular-dash 1.4s ease-in-out infinite; + stroke-dasharray: 80px, 200px; + stroke-dashoffset: 0px; +} +.progress-circular-circle.progress-static { + transition: stroke-dashoffset 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.progress-circular-disable-shrink { + animation: none; +} + +.progress-linear { + position: relative; +} +.progress-linear::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.2; +} +.progress-linear.horizontal { + width: 100%; +} +.progress-linear.horizontal.progress-linear-small { + height: 4px; +} +.progress-linear.horizontal.progress-linear-medium { + height: 8px; +} +.progress-linear.horizontal.progress-linear-large { + height: 12px; +} +.progress-linear.horizontal .progress-linear-dashed { + animation: progress-linear-horizontal-keyframes-buffer 3s infinite linear; +} +.progress-linear.vertical { + height: 100%; +} +.progress-linear.vertical.progress-linear-small { + width: 4px; +} +.progress-linear.vertical.progress-linear-medium { + width: 8px; +} +.progress-linear.vertical.progress-linear-large { + width: 12px; +} +.progress-linear .progress-linear-content { + position: absolute; + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; +} +.progress-linear .progress-linear-bars { + position: absolute; + height: 100%; + width: 100%; + overflow: hidden; +} +.progress-linear .progress-linear-bar { + top: 0; + left: 0; + width: 100%; + bottom: 0; + position: absolute; + transition: transform 0.2s linear; + transform-origin: left; +} +.progress-linear .progress-linear-bar.progress-linear-1-indeterminate.horizontal { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} +.progress-linear .progress-linear-bar.progress-linear-1-indeterminate.vertical { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} +.progress-linear .progress-linear-bar.progress-linear-2-indeterminate.horizontal { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; +} +.progress-linear .progress-linear-bar.progress-linear-2-indeterminate.vertical { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; +} +.progress-linear.progress-linear-color-default:not(.progress-linear-buffer)::before { + background-color: var(--palette-action-disabled); +} +.progress-linear.progress-linear-color-default:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-action-default); +} +.progress-linear.progress-linear-color-default.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-action-disabled) 0%, var(--palette-action-disabled) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-default.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-action-default); +} +.progress-linear.progress-linear-color-default.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-default.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-action-disabled); +} +.progress-linear.progress-linear-color-primary:not(.progress-linear-buffer)::before { + background-color: var(--palette-primary); +} +.progress-linear.progress-linear-color-primary:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-primary); +} +.progress-linear.progress-linear-color-primary.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-primary) 0%, var(--palette-primary) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-primary.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-primary); +} +.progress-linear.progress-linear-color-primary.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-primary.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-primary); +} +.progress-linear.progress-linear-color-secondary:not(.progress-linear-buffer)::before { + background-color: var(--palette-secondary); +} +.progress-linear.progress-linear-color-secondary:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-secondary); +} +.progress-linear.progress-linear-color-secondary.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-secondary) 0%, var(--palette-secondary) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-secondary.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-secondary); +} +.progress-linear.progress-linear-color-secondary.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-secondary.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-secondary); +} +.progress-linear.progress-linear-color-tertiary:not(.progress-linear-buffer)::before { + background-color: var(--palette-tertiary); +} +.progress-linear.progress-linear-color-tertiary:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-tertiary); +} +.progress-linear.progress-linear-color-tertiary.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-tertiary) 0%, var(--palette-tertiary) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-tertiary.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-tertiary); +} +.progress-linear.progress-linear-color-tertiary.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-tertiary.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-tertiary); +} +.progress-linear.progress-linear-color-info:not(.progress-linear-buffer)::before { + background-color: var(--palette-info); +} +.progress-linear.progress-linear-color-info:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-info); +} +.progress-linear.progress-linear-color-info.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-info) 0%, var(--palette-info) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-info.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-info); +} +.progress-linear.progress-linear-color-info.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-info.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-info); +} +.progress-linear.progress-linear-color-success:not(.progress-linear-buffer)::before { + background-color: var(--palette-success); +} +.progress-linear.progress-linear-color-success:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-success); +} +.progress-linear.progress-linear-color-success.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-success) 0%, var(--palette-success) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-success.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-success); +} +.progress-linear.progress-linear-color-success.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-success.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-success); +} +.progress-linear.progress-linear-color-warning:not(.progress-linear-buffer)::before { + background-color: var(--palette-warning); +} +.progress-linear.progress-linear-color-warning:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-warning); +} +.progress-linear.progress-linear-color-warning.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-warning) 0%, var(--palette-warning) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-warning.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-warning); +} +.progress-linear.progress-linear-color-warning.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-warning.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-warning); +} +.progress-linear.progress-linear-color-error:not(.progress-linear-buffer)::before { + background-color: var(--palette-error); +} +.progress-linear.progress-linear-color-error:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-error); +} +.progress-linear.progress-linear-color-error.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-error) 0%, var(--palette-error) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-error.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-error); +} +.progress-linear.progress-linear-color-error.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-error.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-error); +} +.progress-linear.progress-linear-color-dark:not(.progress-linear-buffer)::before { + background-color: var(--palette-dark); +} +.progress-linear.progress-linear-color-dark:not(.progress-linear-buffer) .progress-linear-bar { + background-color: var(--palette-dark); +} +.progress-linear.progress-linear-color-dark.progress-linear-buffer .progress-linear-bar:first-child { + background-size: 10px 10px; + background-image: radial-gradient(var(--palette-dark) 0%, var(--palette-dark) 16%, transparent 42%); + background-position: 0 -23px; +} +.progress-linear.progress-linear-color-dark.progress-linear-buffer .progress-linear-bar:nth-child(2) { + background-color: var(--palette-dark); +} +.progress-linear.progress-linear-color-dark.progress-linear-buffer .progress-linear-bar:last-child { + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-color-dark.progress-linear-buffer .progress-linear-bar:last-child::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + display: block; + opacity: 0.4; + background-color: var(--palette-dark); +} +.progress-linear.progress-indeterminate.horizontal .progress-linear-bar:first-child { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} +.progress-linear.progress-indeterminate.horizontal .progress-linear-bar:last-child { + width: auto; + animation: progress-linear-horizontal-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; +} +.progress-linear.progress-indeterminate.vertical .progress-linear-bar:first-child { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate1 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} +.progress-linear.progress-indeterminate.vertical .progress-linear-bar:last-child { + height: auto; + animation: progress-linear-vertical-keyframes-indeterminate2 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite; +} +.progress-linear.progress-linear-buffer .progress-linear-bar:first-child { + width: 100%; + height: 100%; + position: absolute; + margin-top: 0; +} +.progress-linear.progress-linear-buffer .progress-linear-bar:nth-child(2) { + z-index: 1; + transition: transform 0.4s linear; +} +.progress-linear.progress-linear-buffer.horizontal .progress-linear-bar:first-child { + animation: progress-linear-horizontal-keyframes-buffer 3s infinite linear; +} +.progress-linear.progress-linear-buffer.vertical .progress-linear-bar:first-child { + animation: progress-linear-vertical-keyframes-buffer 3s infinite linear; +} +.progress-linear.progress-linear-striped .progress-linear-bar { + background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.25) 25%, transparent 0, transparent 50%, rgba(255, 255, 255, 0.25) 0, rgba(255, 255, 255, 0.25) 75%, transparent 0, transparent); + background-size: 40px 40px; + background-repeat: repeat; + animation: progress-linear-striped-loading 10s linear infinite; +} +.progress-linear.progress-linear-rounded { + border-radius: var(--default-borderradius); +} +.progress-linear.progress-linear-rounded .progress-linear-bars { + border-radius: var(--default-borderradius); +} +.progress-linear.progress-linear-rounded .progress-linear-bar { + border-radius: var(--default-borderradius); +} + +.radio { + cursor: pointer; + display: inline-flex; + align-items: center; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; + color: var(--palette-action-default); +} +.radio > .radio-content { + color: var(--palette-text-primary); +} +.radio.disabled, .radio .disabled:hover, .radio .disabled:focus-visible { + cursor: default; + background-color: transparent !important; +} +.radio.disabled > .radio-content, .radio .disabled:hover > .radio-content, .radio .disabled:focus-visible > .radio-content { + color: var(--palette-text-disabled); +} +.radio.disabled *, .radio .disabled:hover *, .radio .disabled:focus-visible * { + cursor: default; + color: var(--palette-text-disabled); +} +.radio .radio-dense { + padding: 4px; +} +.radio.checked { + color: var(--palette-action-default); +} +.radio.checked:hover { + background-color: var(--palette-action-default-hover); +} + +.radio-button { + width: 100%; + display: flex; + align-items: inherit; + justify-content: inherit; +} +.radio-button .radio-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; +} +.radio-button .radio-icons { + display: flex; + position: relative; +} + +.radio-icons.checked .radio-icon-checked { + transform: scale(1); + transition: transform 150ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} + +.radio-icon-checked { + left: 0; + position: absolute; + transform: scale(0); + transition: transform 150ms cubic-bezier(0.4, 0, 1, 1) 0ms; +} + +.radio-content-placement-start { + margin-left: 16px; + margin-right: -11px; + margin-inline-start: 16px; + margin-inline-end: -11px; + flex-direction: row-reverse; +} +.radio-content-placement-end { + margin-left: -11px; + margin-right: 16px; + margin-inline-start: -11px; + margin-inline-end: 16px; + flex-direction: row; +} +.radio-content-placement-top { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; + flex-direction: column-reverse; +} +.radio-content-placement-bottom { + margin-left: 16px; + margin-inline-start: 16px; + margin-inline-end: unset; + flex-direction: column; +} + +.rating-root { + display: inline-flex; + color: #ffb400; +} +.rating-root:focus-visible { + outline: none; +} +.rating-root:focus-visible:not(.disabled) { + background-color: var(--palette-action-default-hover); +} + +.rating-item { + cursor: pointer; + transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.rating-item.rating-item-active { + transform: scale(1.2); +} +.rating-item.disabled, .rating-item .disabled:hover { + cursor: default; + pointer-events: none; +} +.rating-item.disabled *, .rating-item .disabled:hover * { + cursor: default; + color: var(--palette-text-disabled); +} +.rating-item.readonly { + cursor: default; +} +.rating-item .rating-input { + clip: rect(0, 0, 0, 0); + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; + cursor: inherit; + overflow: hidden; +} +.rating-item svg { + pointer-events: none; +} +.rating-item svg path { + pointer-events: none; +} + +.snackbar { + display: flex; + flex-grow: initial; + padding: 6px 16px; + align-items: center; + position: relative; + pointer-events: auto; + font-weight: 400; + line-height: 1.43; + overflow: hidden; + margin-top: 16px; + min-width: 288px; + max-width: 500px; + border-radius: var(--default-borderradius); + box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12); +} +.snackbar.force-cursor { + cursor: pointer; +} +.snackbar.snackbar-blurred { + backdrop-filter: blur(18px); +} +.snackbar.snackbar-surface { + background: var(--palette-surface); +} +.snackbar .snackbar-content-message { + padding: 8px 0; +} +.snackbar .snackbar-content-action { + display: flex; + align-items: center; + margin-left: auto; + margin-right: -8px; + padding-left: 16px; + margin-inline-start: auto; + margin-inline-end: -8px; + padding-inline-start: 16px; + padding-inline-end: unset; +} +.snackbar .snackbar-content-action > button { + color: inherit; +} + +.snackbar-location-top-left { + top: 24px; + left: 24px; +} +.snackbar-location-top-center { + top: 24px; + left: 50%; + transform: translateX(-50%); +} +.snackbar-location-top-right { + top: 24px; + right: 24px; +} +.snackbar-location-bottom-right { + right: 24px; + bottom: 24px; +} +.snackbar-location-bottom-center { + bottom: 24px; + left: 50%; + transform: translateX(-50%); +} +.snackbar-location-bottom-left { + bottom: 24px; + left: 24px; +} + +#snackbar-container { + position: fixed; + z-index: var(--zindex-snackbar); + pointer-events: none; +} + +.snackbar-icon { + display: flex; + opacity: 0.9; + padding: 7px 0; + font-size: 22px; + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} + +.switch { + cursor: pointer; + display: inline-flex; + align-items: center; + margin-left: -11px; + margin-right: 16px; + margin-inline-start: -11px; + margin-inline-end: 16px; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; +} +.switch.disabled { + color: var(--palette-text-disabled) !important; + cursor: default; +} +.switch.readonly, .switch .readonly:hover { + cursor: default; + background-color: transparent !important; +} + +.switch-span { + width: 58px; + height: 38px; + display: inline-flex; + padding: 12px; + z-index: 0; + overflow: hidden; + position: relative; + box-sizing: border-box; + flex-shrink: 0; + vertical-align: middle; +} +.switch-span .switch-track { + width: 100%; + height: 100%; + opacity: 0.48; + z-index: -1; + transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 7px; + background-color: var(--palette-black); +} + +.switch-base { + padding: 9px; + top: 0; + left: 0; + color: #fafafa; + z-index: 1; + position: absolute; + transition: left 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.switch-base.checked { + transform: translateX(20px); +} +.switch-base.checked + .switch-track { + opacity: 0.5; +} +.switch-base:hover { + background-color: var(--palette-action-default-hover); +} +.switch-base.switch-disabled { + color: var(--palette-grey-default) !important; +} +.switch-base.switch-disabled + .switch-track { + opacity: 0.12 !important; +} +.switch-base.switch-disabled:hover, .switch-base.switch-disabled:focus-visible { + cursor: default; + background-color: transparent !important; +} + +.switch-button { + display: flex; + align-items: inherit; + justify-content: inherit; +} +.switch-button .switch-input { + top: 0; + left: 0; + width: 100%; + cursor: inherit; + height: 100%; + margin: 0; + opacity: 0; + padding: 0; + z-index: 1; + position: absolute; +} +.switch-button .switch-thumb { + width: 20px; + height: 20px; + box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12); + border-radius: 50%; + background-color: currentColor; +} + +.timeline { + position: relative; + display: flex; +} + +.timeline-vertical { + padding-top: 24px; + flex-direction: column; +} +.timeline-vertical::before { + top: 0; + bottom: 0; + content: ""; + height: 100%; + position: absolute; + width: 2px; + background: var(--palette-divider); +} +.timeline-vertical .timeline-item { + padding-bottom: 24px; +} +.timeline-vertical .timeline-item .timeline-item-content { + max-width: calc(50% - 48px); +} +.timeline-vertical .timeline-item .timeline-item-divider { + min-width: 96px; +} +.timeline-vertical .timeline-item .timeline-item-opposite { + flex: 1 1 auto; + max-width: calc(50% - 48px); +} + +.timeline-horizontal { + flex-direction: row; +} +.timeline-horizontal::before { + top: 0; + bottom: 0; + content: ""; + height: 2px; + position: absolute; + width: 100%; + background: var(--palette-divider); +} +.timeline-horizontal .timeline-item { + padding-left: 24px; + padding-right: 24px; + width: 100%; +} +.timeline-horizontal .timeline-item .timeline-item-content { + max-height: calc(50% - 48px); +} +.timeline-horizontal .timeline-item .timeline-item-divider { + min-height: 96px; +} + +.timeline-item { + display: flex; +} +.timeline-item .timeline-item-content { + position: relative; + height: 100%; + flex: 1 1 auto; +} +.timeline-item .timeline-item-divider { + position: relative; + display: flex; + align-items: center; + justify-content: center; +} +.timeline-item .timeline-item-opposite { + align-self: center; +} + +.timeline-vertical { + /* Both Start & End */ +} +.timeline-vertical.timeline-align-start .timeline-item-divider { + align-items: flex-start; +} +.timeline-vertical.timeline-align-start .timeline-item-opposite { + align-self: flex-start; +} +.timeline-vertical.timeline-align-end .timeline-item-divider { + align-items: flex-end; +} +.timeline-vertical.timeline-align-end .timeline-item-opposite { + align-self: flex-end; +} +.timeline-vertical.timeline-position-alternate::before { + left: auto; + right: calc(50% - 1px); +} +.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start), .timeline-vertical.timeline-position-alternate .timeline-item.timeline-item-end { + flex-direction: row-reverse; +} +.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-opposite, .timeline-vertical.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-opposite { + text-align: end; +} +.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) { + flex-direction: row; +} +.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-opposite { + text-align: start; +} +.timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd):not(.timeline-item-end), .timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-start { + flex-direction: row; +} +.timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-opposite, .timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-start .timeline-item-opposite { + text-align: start; +} +.timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n):not(.timeline-item-start) { + flex-direction: row-reverse; +} +.timeline-vertical.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-opposite { + text-align: end; +} +.timeline-vertical.timeline-position-start::before { + right: auto; + left: 47px; +} +.timeline-vertical.timeline-position-start.timeline-rtl::before { + right: 47px; + left: auto; +} +.timeline-vertical.timeline-position-start .timeline-item { + flex-direction: row-reverse; +} +.timeline-vertical.timeline-position-end::before { + right: 47px; + left: auto; +} +.timeline-vertical.timeline-position-end.timeline-rtl::before { + left: 47px; + right: auto; +} +.timeline-vertical.timeline-position-end .timeline-item { + flex-direction: row; +} +.timeline-vertical.timeline-position-start .timeline-item-content, .timeline-vertical.timeline-position-end .timeline-item-content { + max-width: calc(100% - 96px); +} +.timeline-vertical.timeline-position-start .timeline-item-opposite, .timeline-vertical.timeline-position-end .timeline-item-opposite { + display: none; +} + +.timeline-horizontal { + /* Both Top & Bottom */ +} +.timeline-horizontal.timeline-align-start .timeline-item-divider { + justify-content: flex-start; +} +.timeline-horizontal.timeline-align-start .timeline-item-opposite { + align-self: flex-start; +} +.timeline-horizontal.timeline-align-end .timeline-item-divider { + justify-content: flex-end; +} +.timeline-horizontal.timeline-align-end .timeline-item-opposite { + align-self: flex-end; +} +.timeline-horizontal.timeline-position-alternate::before { + top: auto; + bottom: calc(50% - 1px); +} +.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(odd), .timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-end { + flex-direction: column-reverse; +} +.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(odd) .timeline-item-opposite, .timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-opposite { + /* I dont know */ +} +.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(2n), .timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-start { + flex-direction: column; +} +.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(2n) .timeline-item-opposite, .timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-start .timeline-item-opposite { + /* I dont know */ +} +.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd), .timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-end { + flex-direction: column; +} +.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd) .timeline-item-opposite, .timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-end .timeline-item-opposite { + /* I dont know */ +} +.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n), .timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-start { + flex-direction: column-reverse; +} +.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n) .timeline-item-opposite, .timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-start .timeline-item-opposite { + /* I dont know */ +} +.timeline-horizontal.timeline-position-top::before { + top: 47px; + bottom: auto; +} +.timeline-horizontal.timeline-position-top .timeline-item { + flex-direction: column-reverse; +} +.timeline-horizontal.timeline-position-bottom::before { + top: auto; + bottom: 47px; +} +.timeline-horizontal.timeline-position-bottom .timeline-item { + flex-direction: column; +} +.timeline-horizontal.timeline-position-top .timeline-item-content, .timeline-horizontal.timeline-position-bottom .timeline-item-content { + max-height: calc(100% - 96px); +} +.timeline-horizontal.timeline-position-top .timeline-item-opposite, .timeline-horizontal.timeline-position-bottom .timeline-item-opposite { + display: none; +} + +/*Dot*/ +.timeline-item-dot { + display: flex; + justify-content: center; + align-items: center; + background: var(--palette-surface); + border-radius: 50%; + left: calc(50% - 19px); +} +.timeline-item-dot.timeline-dot-size-small { + width: 24px; + height: 24px; +} +.timeline-item-dot.timeline-dot-size-small .timeline-item-dot-inner { + height: 18px; + width: 18px; +} +.timeline-item-dot.timeline-dot-size-medium { + width: 38px; + height: 38px; +} +.timeline-item-dot.timeline-dot-size-medium .timeline-item-dot-inner { + height: 30px; + width: 30px; +} +.timeline-item-dot.timeline-dot-size-large { + width: 52px; + height: 52px; +} +.timeline-item-dot.timeline-dot-size-large .timeline-item-dot-inner { + height: 42px; + width: 42px; +} +.timeline-item-dot .timeline-item-dot-inner { + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-fill { + height: inherit; + width: inherit; +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-default { + background-color: var(--palette-grey-light); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-primary { + color: var(--palette-primary-text); + background-color: var(--palette-primary); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-secondary { + color: var(--palette-secondary-text); + background-color: var(--palette-secondary); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-tertiary { + color: var(--palette-tertiary-text); + background-color: var(--palette-tertiary); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-info { + color: var(--palette-info-text); + background-color: var(--palette-info); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-success { + color: var(--palette-success-text); + background-color: var(--palette-success); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-warning { + color: var(--palette-warning-text); + background-color: var(--palette-warning); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-error { + color: var(--palette-error-text); + background-color: var(--palette-error); +} +.timeline-item-dot .timeline-item-dot-inner.timeline-dot-dark { + color: var(--palette-dark-text); + background-color: var(--palette-dark); +} + +/*Modifiers*/ +.timeline-modifiers .timeline-item-content .card::before, .timeline-modifiers .timeline-item-content .card::after { + content: ""; + position: absolute; +} +.timeline-modifiers.timeline-vertical.timeline-position-start:not(.timeline-rtl) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-start:not(.timeline-rtl) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-end.timeline-rtl .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-end.timeline-rtl .timeline-item-content .card::after { + transform: rotate(0); + left: -16px; + right: auto; +} +.timeline-modifiers.timeline-vertical.timeline-position-start:not(.timeline-rtl) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-end.timeline-rtl .timeline-item-content .card.paper-outlined::after { + left: -15px; +} +.timeline-modifiers.timeline-vertical.timeline-position-end:not(.timeline-rtl) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-end:not(.timeline-rtl) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-start.timeline-rtl .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-start.timeline-rtl .timeline-item-content .card::after { + transform: rotate(180deg); + right: -16px; + left: auto; +} +.timeline-modifiers.timeline-vertical.timeline-position-end:not(.timeline-rtl) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-start.timeline-rtl .timeline-item-content .card.paper-outlined::after { + right: -15px; +} +.timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card::after { + transform: rotate(0); + left: -16px; + right: auto; +} +.timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card.paper-outlined::after { + left: -15px; +} +.timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::after { + transform: rotate(180deg); + right: -16px; + left: auto; +} +.timeline-modifiers.timeline-vertical.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card.paper-outlined::after { + right: -15px; +} +.timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item.timeline-item-start .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item.timeline-item-start .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item.timeline-item-start .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item.timeline-item-start .timeline-item-content .card::after { + transform: rotate(180deg); + right: -16px; + left: auto; +} +.timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item.timeline-item-start .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(odd):not(.timeline-item-end) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item.timeline-item-start .timeline-item-content .card.paper-outlined::after { + right: -15px; +} +.timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card::before, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card::after { + transform: rotate(0); + left: -16px; + right: auto; +} +.timeline-modifiers.timeline-vertical.timeline-reverse:not(.timeline-rtl) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-vertical.timeline-position-alternate.timeline-rtl:not(.timeline-reverse) .timeline-item:nth-child(2n):not(.timeline-item-start) .timeline-item-content .card.paper-outlined::after { + left: -15px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-top .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-top .timeline-item-content .card::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-top .timeline-item-content .card.paper-outlined::after { + top: -23px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-bottom .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-bottom .timeline-item-content .card::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-bottom .timeline-item-content .card.paper-outlined::after { + bottom: -23px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::after, .timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item.timeline-item-end .timeline-item-content .card.paper-outlined::after { + top: -23px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card.paper-outlined::after { + bottom: -23px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card::after, .timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-end .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-end .timeline-item-content .card::after { + transform: rotate(270deg); + bottom: -24px; + top: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(odd):not(.timeline-item-start) .timeline-item-content .card.paper-outlined::after, .timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item.timeline-item-end .timeline-item-content .card.paper-outlined::after { + bottom: -23px; +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::before, .timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card::after { + transform: rotate(90deg); + top: -24px; + bottom: auto; + left: calc(50% - 8px); +} +.timeline-modifiers.timeline-horizontal.timeline-position-alternate.timeline-reverse .timeline-item:nth-child(2n):not(.timeline-item-end) .timeline-item-content .card.paper-outlined::after { + top: -23px; +} +.timeline-modifiers .timeline-item-content .card::before { + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + border-right: 16px solid rgba(0, 0, 0, 0.1); + top: calc(50% - 14px); +} +.timeline-modifiers .timeline-item-content .card::after { + border-top: 16px solid transparent; + border-bottom: 16px solid transparent; + border-right: 16px solid var(--palette-surface); + top: calc(50% - 16px); +} +.timeline-modifiers .timeline-item-content .card.paper-outlined::before { + top: calc(50% - 16px); + border-right-color: var(--palette-lines-default); +} + +.typography { + margin: 0; +} + +.typography-body1 { + font-size: var(--typography-body1-size); + font-family: var(--typography-body1-family); + font-weight: var(--typography-body1-weight); + line-height: var(--typography-body1-lineheight); + letter-spacing: var(--typography-body1-letterspacing); + text-transform: var(--typography-body1-text-transform); +} + +.typography-body2 { + font-size: var(--typography-body2-size); + font-family: var(--typography-body2-family); + font-weight: var(--typography-body2-weight); + line-height: var(--typography-body2-lineheight); + letter-spacing: var(--typography-body2-letterspacing); + text-transform: var(--typography-body2-text-transform); +} + +.typography-caption { + font-size: var(--typography-caption-size); + font-family: var(--typography-caption-family); + font-weight: var(--typography-caption-weight); + line-height: var(--typography-caption-lineheight); + letter-spacing: var(--typography-caption-letterspacing); + text-transform: var(--typography-caption-text-transform); +} + +.typography-button { + font-size: var(--typography-button-size); + font-family: var(--typography-button-family); + font-weight: var(--typography-button-weight); + line-height: var(--typography-button-lineheight); + letter-spacing: var(--typography-button-letterspacing); + text-transform: var(--typography-button-text-transform); +} + +.typography-h1 { + font-size: var(--typography-h1-size); + font-family: var(--typography-h1-family); + font-weight: var(--typography-h1-weight); + line-height: var(--typography-h1-lineheight); + letter-spacing: var(--typography-h1-letterspacing); + text-transform: var(--typography-h1-text-transform); +} + +.typography-h2 { + font-size: var(--typography-h2-size); + font-family: var(--typography-h2-family); + font-weight: var(--typography-h2-weight); + line-height: var(--typography-h2-lineheight); + letter-spacing: var(--typography-h2-letterspacing); + text-transform: var(--typography-h2-text-transform); +} + +.typography-h3 { + font-size: var(--typography-h3-size); + font-family: var(--typography-h3-family); + font-weight: var(--typography-h3-weight); + line-height: var(--typography-h3-lineheight); + letter-spacing: var(--typography-h3-letterspacing); + text-transform: var(--typography-h3-text-transform); +} + +.typography-h4 { + font-size: var(--typography-h4-size); + font-family: var(--typography-h4-family); + font-weight: var(--typography-h4-weight); + line-height: var(--typography-h4-lineheight); + letter-spacing: var(--typography-h4-letterspacing); + text-transform: var(--typography-h4-text-transform); +} + +.typography-h5 { + font-size: var(--typography-h5-size); + font-family: var(--typography-h5-family); + font-weight: var(--typography-h5-weight); + line-height: var(--typography-h5-lineheight); + letter-spacing: var(--typography-h5-letterspacing); + text-transform: var(--typography-h5-text-transform); +} + +.typography-h6 { + font-size: var(--typography-h6-size); + font-family: var(--typography-h6-family); + font-weight: var(--typography-h6-weight); + line-height: var(--typography-h6-lineheight); + letter-spacing: var(--typography-h6-letterspacing); + text-transform: var(--typography-h6-text-transform); +} + +.typography-subtitle1 { + font-size: var(--typography-subtitle1-size); + font-family: var(--typography-subtitle1-family); + font-weight: var(--typography-subtitle1-weight); + line-height: var(--typography-subtitle1-lineheight); + letter-spacing: var(--typography-subtitle1-letterspacing); + text-transform: var(--typography-subtitle1-text-transform); +} + +.typography-subtitle2 { + font-size: var(--typography-subtitle2-size); + font-family: var(--typography-subtitle2-family); + font-weight: var(--typography-subtitle2-weight); + line-height: var(--typography-subtitle2-lineheight); + letter-spacing: var(--typography-subtitle2-letterspacing); + text-transform: var(--typography-subtitle2-text-transform); +} + +.typography-overline { + font-size: var(--typography-overline-size); + font-family: var(--typography-overline-family); + font-weight: var(--typography-overline-weight); + line-height: var(--typography-overline-lineheight); + letter-spacing: var(--typography-overline-letterspacing); + text-transform: var(--typography-overline-text-transform); +} + +.typography-srOnly { + width: 1px; + height: 1px; + overflow: hidden; + position: absolute; +} + +.typography-align-left { + text-align: left; +} + +.typography-align-center { + text-align: center; +} + +.typography-align-right { + text-align: right; +} + +.typography-align-justify { + text-align: justify; +} + +.typography-nowrap { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.typography-gutterbottom { + margin-bottom: 0.35em; +} + +.typography-paragraph { + margin-bottom: 16px; +} + +.typography-display-inline { + display: inline; +} + +.typography-display-block { + display: block; +} + +.table { + color: var(--palette-text-primary); + background-color: var(--palette-surface); + border-radius: var(--default-borderradius); + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.table.table-square { + border-radius: 0px; +} +.table.table-outlined { + border: 1px solid var(--palette-lines-default); +} + +.table-container { + width: 100%; + overflow-y: auto; +} + +.table-root { + width: 100%; + border-spacing: 0; +} +.table-root .table-head { + display: table-header-group; +} +.table-root .table-head .table-cell { + color: var(--palette-text-primary); + font-weight: 500; + line-height: 1.5rem; +} +.table-root .table-body { + display: table-row-group; +} +.table-root .table-body .table-cell { + color: var(--palette-text-primary); +} +.table-root .table-body:last-child .table-row:last-child .table-cell { + border-bottom: none; +} + +.table-sort-label { + cursor: pointer; + display: inline-flex; + align-items: center; + flex-direction: inherit; + justify-content: flex-start; +} +.table-sort-label:hover { + color: var(--palette-action-default); +} +.table-sort-label:hover .table-sort-label-icon { + opacity: 0.8; +} +.table-sort-label .table-sort-label-icon { + font-size: 18px; + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + margin-left: 4px; + user-select: none; + margin-right: 4px; + opacity: 0; +} +.table-sort-label .table-sort-label-icon.direction-desc { + opacity: 1; + transform: rotate(180deg); +} +.table-sort-label .table-sort-label-icon.direction-asc { + opacity: 1; + transform: rotate(0deg); +} + +.table-toolbar { + padding-left: 16px; + padding-right: 8px; + padding-inline-start: 16px; + padding-inline-end: 8px; +} + +.table-cell { + display: table-cell; + padding: 16px; + font-size: 0.875rem; + text-align: start; + font-weight: 400; + line-height: 1.43; + border-bottom: 1px solid var(--palette-table-lines); + letter-spacing: 0.01071em; + vertical-align: inherit; +} +.table-cell .checkbox { + margin: -12px; +} + +.table-cell-footer { + color: var(--palette-text-secondary); + font-size: 0.75rem; + line-height: 1.3125rem; +} + +.table-dense * .table-row .table-cell { + padding: 6px 24px 6px 16px; + padding-inline-start: 16px; + padding-inline-end: 24px; +} +.table-dense * .table-row .table-cell .table-cell-checkbox .button-root { + padding: 4px; +} +.table-dense * .table-row .table-cell .table-row-expander { + padding: 4px; +} +.table-dense * .table-row .table-cell:last-child { + padding-right: 16px; + padding-inline-end: 16px; +} + +.table-bordered .table-container .table-root .table-body .table-row .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); +} +.table-bordered .table-container .table-root .table-head.table-head-bordered .table-row .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); +} +.table-bordered .table-container .table-root .table-foot.table-foot-bordered .table-row .table-cell:not(:last-child) { + border-right: 1px solid var(--palette-table-lines); +} + +.table-sticky-header .table-container { + overflow-x: auto; +} +.table-sticky-header * .table-root .table-head * .table-cell:first-child { + border-radius: var(--default-borderradius) 0px 0px 0px; +} +.table-sticky-header * .table-root .table-head * .table-cell:last-child { + border-radius: 0px var(--default-borderradius) 0px 0px; +} +.table-sticky-header * .table-root .table-head * .table-cell { + background-color: var(--palette-surface); + position: sticky; + z-index: 2; + top: 0; +} + +.table-sticky-footer .table-container { + overflow-x: auto; +} +.table-sticky-footer * .table-root .table-foot * .table-cell { + background-color: var(--palette-surface); + position: sticky; + z-index: 2; + bottom: 0; +} + +.table-row { + color: inherit; + display: table-row; + outline: 0; + vertical-align: middle; +} + +.table-hover .table-container .table-root .table-body .table-row:hover { + background-color: var(--palette-table-hover); +} + +.table-striped .table-container .table-root .table-body .table-row:nth-of-type(odd) { + background-color: var(--palette-table-striped); +} + +.table-hover.table-striped .table-container .table-root .table-body .table-row:nth-of-type(odd):hover { + background-color: var(--palette-table-hover); +} + +.table-cell > .input-control > div.input.input-text { + color: var(--theme-on-surface); + font-size: 0.875rem; + margin-top: -14px; + margin-bottom: -8px; +} +.table-cell > .select > .input-control > div.input.input-text { + color: var(--theme-on-surface); + font-size: 0.875rem; + margin-top: -14px; + margin-bottom: -8px; +} + +.table-cell-align-left { + text-align: left; +} +.table-cell-align-center { + text-align: center; +} +.table-cell-align-right { + text-align: right; + flex-direction: row-reverse; +} +.table-cell-align-justify { + text-align: justify; +} + +.table-pagination-display { + display: flex; + flex-shrink: 0; +} +.table-pagination-display .tablepager-left { + flex-direction: row !important; +} +.table-pagination-display .tablepager-right { + flex-direction: row-reverse !important; +} + +.table-pagination-information { + white-space: nowrap; + direction: initial; +} + +.table-page-number-information { + white-space: nowrap; + direction: initial; +} + +.table-pagination { + color: var(--theme-on-surface); + overflow: auto; + font-size: 0.875rem; + display: initial; +} + +.table-pagination:last-child { + padding: 0; +} + +.table-pagination-toolbar { + border-top: 1px solid var(--palette-table-lines); + height: 52px; + padding-right: 2px; + padding-inline-end: 2px; + padding-inline-start: unset; +} +.table-pagination-toolbar .tablepager-left { + flex-direction: row !important; +} +.table-pagination-toolbar .tablepager-right { + flex-direction: row-reverse !important; +} + +.table-pagination-spacer { + flex: 1 1 100%; +} + +.table-pagination-caption { + display: flex; + flex-shrink: 0; + align-items: center; + padding-left: 10px; + padding-right: 10px; +} + +.table-pagination-select { + cursor: pointer; + margin-left: 10px !important; + margin-right: 10px !important; + margin-top: 0px !important; + min-width: 52px; +} +.table-pagination-select .select-input { + margin-top: 0px !important; +} +.table-pagination-select .input .input-root { + max-width: 80px; + cursor: pointer; + margin-top: 2px; + border: none; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.43; + letter-spacing: 0.01071em; + color: var(--theme-on-surface); +} + +.table-pagination-actions { + flex-shrink: 0; + align-items: center; + margin-left: 10px; + margin-inline-start: 10px; + margin-inline-end: unset; +} + +.table-smalldevices-sortselect { + display: none; +} + +.table-loading { + position: relative; +} +.table-loading .table-loading-progress { + position: absolute; + width: 100%; +} + +.table-empty-row { + background-color: var(--palette-surface); + vertical-align: middle; + text-align: center; +} + +tr.table-row-group-indented-1 td:first-child { + padding-left: 48px !important; +} + +tr.table-row-group-indented-2 td:first-child { + padding-left: 96px !important; +} + +tr.table-row-group-indented-3 td:first-child { + padding-left: 144px !important; +} + +tr.table-row-group-indented-4 td:first-child { + padding-left: 192px !important; +} + +tr.table-row-group-indented-5 td:first-child { + padding-left: 240px !important; +} + +.table-row-expander { + margin: -12px -2px -12px -12px; +} + +@media (max-width: 360px) { + .table .table-pagination .select { + margin-left: auto; + margin-right: -14px; + margin-inline-start: auto; + margin-inline-end: -14px; + } + .table .table-pagination .select ~ .table-pagination-caption { + margin-left: unset !important; + margin-inline-start: unset !important; + } +} +@media (max-width: 416px) { + .table .table-pagination .table-pagination-toolbar { + flex-wrap: wrap; + padding-top: 16px; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + min-height: 100px; + } + .table .table-pagination .table-pagination-toolbar .table-pagination-actions { + margin-left: auto; + margin-right: -14px; + margin-inline-start: auto; + margin-inline-end: -14px; + } +} +@media (max-width: 600px) { + .xs-table .table-root .table-head, +.xs-table .table-root .table-foot { + display: none; + } + .xs-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .xs-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .xs-table .table-row { + display: initial; + } + .xs-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .xs-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .xs-table.table-dense .table-cell { + padding: 6px 16px; + } + .xs-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .xs-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .xs-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .xs-table .table-pagination .table-pagination-spacer { + flex: none; + } + .xs-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .xs-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .xs-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +@media (max-width: 960px) { + .sm-table .table-root .table-head, +.sm-table .table-root .table-foot { + display: none; + } + .sm-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .sm-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .sm-table .table-row { + display: initial; + } + .sm-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .sm-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .sm-table.table-dense .table-cell { + padding: 6px 16px; + } + .sm-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .sm-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .sm-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .sm-table .table-pagination .table-pagination-spacer { + flex: none; + } + .sm-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .sm-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .sm-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +@media (max-width: 1280px) { + .md-table .table-root .table-head, +.md-table .table-root .table-foot { + display: none; + } + .md-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .md-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .md-table .table-row { + display: initial; + } + .md-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .md-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .md-table.table-dense .table-cell { + padding: 6px 16px; + } + .md-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .md-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .md-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .md-table .table-pagination .table-pagination-spacer { + flex: none; + } + .md-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .md-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .md-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +@media (max-width: 1920px) { + .lg-table .table-root .table-head, +.lg-table .table-root .table-foot { + display: none; + } + .lg-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .lg-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .lg-table .table-row { + display: initial; + } + .lg-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .lg-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .lg-table.table-dense .table-cell { + padding: 6px 16px; + } + .lg-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .lg-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .lg-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .lg-table .table-pagination .table-pagination-spacer { + flex: none; + } + .lg-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .lg-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .lg-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +@media (max-width: 2560px) { + .xl-table .table-root .table-head, +.xl-table .table-root .table-foot { + display: none; + } + .xl-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .xl-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .xl-table .table-row { + display: initial; + } + .xl-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .xl-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .xl-table.table-dense .table-cell { + padding: 6px 16px; + } + .xl-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .xl-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .xl-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .xl-table .table-pagination .table-pagination-spacer { + flex: none; + } + .xl-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .xl-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .xl-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +@media (min-width: 2560px) { + .xxl-table .table-root .table-head, +.xxl-table .table-root .table-foot { + display: none; + } + .xxl-table .table-smalldevices-sortselect { + display: block; + padding: 4px 16px 8px; + } + .xxl-table .table-body { + border-top: 1px solid var(--palette-table-lines); + } + .xxl-table .table-row { + display: initial; + } + .xxl-table .table-row .table-cell:last-child { + border-bottom: 1px solid var(--palette-table-lines); + } + .xxl-table .table-cell { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 14px 16px; + text-align: start !important; + } + .xxl-table.table-dense .table-cell { + padding: 6px 16px; + } + .xxl-table .table-cell:before { + content: attr(data-label); + font-weight: 500; + padding-right: 16px; + padding-inline-end: 16px; + padding-inline-start: unset; + } + .xxl-table.table-small-alignright .table-cell:before { + margin-right: auto; + } + .xxl-table .table-cell-hide { + visibility: collapse; + height: 0; + padding: 0; + margin: 0; + } + .xxl-table .table-pagination .table-pagination-spacer { + flex: none; + } + .xxl-table .table-pagination .table-pagination-actions .button-root:first-child { + display: none; + } + .xxl-table .table-pagination .table-pagination-actions .button-root:last-child { + display: none; + } + .xxl-table .table-pagination .select ~ .table-pagination-caption { + margin-left: auto; + margin-inline-start: auto; + } +} +.tabs { + display: flex; + flex-direction: column; +} +.tabs.tabs-reverse { + flex-direction: column-reverse; +} +.tabs.tabs-vertical { + flex-direction: row; +} +.tabs.tabs-vertical-reverse { + flex-direction: row-reverse; +} +.tabs.tabs-rounded { + border-radius: var(--default-borderradius); +} +.tabs.tabs-rounded .tabs-toolbar { + border-radius: var(--default-borderradius); +} +.tabs.tabs-rounded .tabs-panels { + border-radius: var(--default-borderradius); +} + +.tabs-toolbar { + position: relative; + background-color: var(--palette-surface); +} +.tabs-toolbar.tabs-border-left { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-right: 1px solid var(--palette-lines-default); +} +.tabs-toolbar.tabs-border-right { + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-left: 1px solid var(--palette-lines-default); +} +.tabs-toolbar.tabs-border-top { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-bottom: 1px solid var(--palette-lines-default); +} +.tabs-toolbar.tabs-border-bottom { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; + border-top: 1px solid var(--palette-lines-default); +} +.tabs-toolbar.tabs-rounded { + border-radius: var(--default-borderradius); +} +.tabs-toolbar.tabs-vertical .tabs-toolbar-inner { + flex-direction: column; +} +.tabs-toolbar.tabs-vertical .tabs-toolbar-inner .tabs-scroll-button .button-root { + width: 100%; + border-radius: 0px; + height: 32px; +} +.tabs-toolbar.tabs-vertical .tabs-toolbar-inner .tabs-scroll-button .button-root .icon-button-label .icon-root { + transform: rotate(90deg); +} +.tabs-toolbar .tabs-toolbar-inner { + display: flex; + min-height: 48px; +} + +.tabs-toolbar-content { + width: 100%; + flex: 1 1 auto; + display: inline-block; + position: relative; + white-space: nowrap; + overflow: hidden; +} +.tabs-toolbar-content .tabs-toolbar-wrapper { + width: max-content; + position: inherit; + display: flex; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); +} +.tabs-toolbar-content .tabs-toolbar-wrapper.tabs-centered { + margin: auto; +} +.tabs-toolbar-content .tabs-toolbar-wrapper.tabs-vertical { + flex-direction: column; +} + +.tabs-panels { + position: relative; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); +} +.tabs-panels.tabs-vertical { + display: flex; + flex-grow: 1; +} + +.tab { + width: 100%; + min-width: 160px; + display: inline-flex; + padding: 6px 12px; + min-height: 48px; + flex-shrink: 0; + font-weight: 500; + line-height: 1.75; + user-select: none; + white-space: normal; + letter-spacing: 0.02857em; + text-transform: uppercase; + text-align: center; + align-items: center; + justify-content: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.tab:hover { + cursor: pointer; + background-color: var(--palette-action-default-hover); +} +.tab.tab-active { + color: var(--palette-primary); +} +.tab.tab-active:hover { + background-color: var(--palette-primary-hover); +} +.tab.disabled { + cursor: default; + pointer-events: none; + color: var(--palette-text-disabled); +} +.tab .tab-icon-text { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} + +.tab-slider { + position: absolute; + background: var(--palette-primary); +} +.tab-slider.tab-slider-horizontal { + height: 2px; + left: 0; + bottom: 0; + transition: left 0.3s cubic-bezier(0.64, 0.09, 0.08, 1); + will-change: left; +} +.tab-slider.tab-slider-horizontal.tab-slider-horizontal-reverse { + top: 0px; +} +.tab-slider.tab-slider-vertical { + width: 2px; + right: 0; + transition: top 0.3s cubic-bezier(0.64, 0.09, 0.08, 1); + will-change: top; +} +.tab-slider.tab-slider-vertical.tab-slider-vertical-reverse { + left: 0; + right: unset; +} + +.tab-badge { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +.tabs-toolbar-primary { + background-color: var(--palette-primary); + color: var(--palette-primary-text); +} +.tabs-toolbar-primary .tab-slider { + background: var(--palette-primary-text); +} +.tabs-toolbar-primary .tab.tab-active { + color: var(--palette-primary-text); +} +.tabs-toolbar-primary .tab.tab-active:hover { + background-color: var(--palette-primary-lighten); +} + +.tabs-toolbar-secondary { + background-color: var(--palette-secondary); + color: var(--palette-secondary-text); +} +.tabs-toolbar-secondary .tab-slider { + background: var(--palette-secondary-text); +} +.tabs-toolbar-secondary .tab.tab-active { + color: var(--palette-secondary-text); +} +.tabs-toolbar-secondary .tab.tab-active:hover { + background-color: var(--palette-secondary-lighten); +} + +.tabs-toolbar-tertiary { + background-color: var(--palette-tertiary); + color: var(--palette-tertiary-text); +} +.tabs-toolbar-tertiary .tab-slider { + background: var(--palette-tertiary-text); +} +.tabs-toolbar-tertiary .tab.tab-active { + color: var(--palette-tertiary-text); +} +.tabs-toolbar-tertiary .tab.tab-active:hover { + background-color: var(--palette-tertiary-lighten); +} + +.tabs-toolbar-info { + background-color: var(--palette-info); + color: var(--palette-info-text); +} +.tabs-toolbar-info .tab-slider { + background: var(--palette-info-text); +} +.tabs-toolbar-info .tab.tab-active { + color: var(--palette-info-text); +} +.tabs-toolbar-info .tab.tab-active:hover { + background-color: var(--palette-info-lighten); +} + +.tabs-toolbar-success { + background-color: var(--palette-success); + color: var(--palette-success-text); +} +.tabs-toolbar-success .tab-slider { + background: var(--palette-success-text); +} +.tabs-toolbar-success .tab.tab-active { + color: var(--palette-success-text); +} +.tabs-toolbar-success .tab.tab-active:hover { + background-color: var(--palette-success-lighten); +} + +.tabs-toolbar-warning { + background-color: var(--palette-warning); + color: var(--palette-warning-text); +} +.tabs-toolbar-warning .tab-slider { + background: var(--palette-warning-text); +} +.tabs-toolbar-warning .tab.tab-active { + color: var(--palette-warning-text); +} +.tabs-toolbar-warning .tab.tab-active:hover { + background-color: var(--palette-warning-lighten); +} + +.tabs-toolbar-error { + background-color: var(--palette-error); + color: var(--palette-error-text); +} +.tabs-toolbar-error .tab-slider { + background: var(--palette-error-text); +} +.tabs-toolbar-error .tab.tab-active { + color: var(--palette-error-text); +} +.tabs-toolbar-error .tab.tab-active:hover { + background-color: var(--palette-error-lighten); +} + +.tabs-toolbar-dark { + background-color: var(--palette-dark); + color: var(--palette-dark-text); +} +.tabs-toolbar-dark .tab-slider { + background: var(--palette-dark-text); +} +.tabs-toolbar-dark .tab.tab-active { + color: var(--palette-dark-text); +} +.tabs-toolbar-dark .tab.tab-active:hover { + background-color: var(--palette-dark-lighten); +} + +.tab-transition-enter { + transform: translate(100%, 0); +} +.tab-transition-leave, .tab-transition-leave-active { + position: absolute; + top: 0; +} +.tab-transition-leave-to { + position: absolute; + transform: translate(-100%, 0); +} + +.tab-reverse-transition-enter { + transform: translate(-100%, 0); +} +.tab-reverse-transition-leave, .tab-reverse-transition-leave-to { + top: 0; + position: absolute; + transform: translate(100%, 0); +} + +.dynamic-tabs .tabs-toolbar .tab { + padding: 6px 14px; +} +.dynamic-tabs .tabs-toolbar .tab .icon-button { + padding: 4px; + margin-right: -4px; + margin-inline-end: -4px; + margin-inline-start: unset; +} +.dynamic-tabs .tabs-toolbar .tab .tabs-panel-header-before { + padding-right: 8px; + padding-inline-end: 8px; + padding-inline-start: unset; +} +.dynamic-tabs .tabs-toolbar .tab .tabs-panel-header-after { + padding-left: 8px; + padding-inline-start: 8px; + padding-inline-end: unset; +} + +.tabs-header.tabs-header-before { + display: inherit; +} +.tabs-header.tabs-header-after { + display: inherit; +} + +.tabs-panel-header { + display: flex; + flex: 1 1 auto; +} +.tabs-panel-header.tabs-panel-header-before { + justify-content: flex-start; +} +.tabs-panel-header.tabs-panel-header-after { + justify-content: flex-end; +} + +.select { + display: flex; + flex-grow: 1; + position: relative; +} +.select.autocomplete { + display: block; +} +.select.autocomplete .select-input { + cursor: text; +} +.select.autocomplete .input-adornment { + cursor: pointer; +} +.select.autocomplete--with-progress .select-input input { + padding-right: 3.5rem !important; +} +.select.autocomplete--with-progress .input-adorned-end input { + padding-right: 4.5rem !important; +} +.select.autocomplete--with-progress .select-input .icon-button { + display: none !important; +} +.select.autocomplete--with-progress .progress-indicator-circular { + position: absolute; + width: 100%; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: flex-end; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-right: 1rem; +} +.select.autocomplete--with-progress .progress-indicator-circular--with-adornment { + padding-right: 3rem; +} +.select.autocomplete--with-progress .progress-linear { + position: absolute; + bottom: -1px; + height: 2px; +} +.select .select-input { + cursor: pointer; +} +.select .select-input .input-slot { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.select .select-input .input-adornment-end { + margin-left: 0; +} +.select .select-input:disabled { + cursor: default; +} +.select .disabled .select-input { + cursor: default; +} + +.select > .form-helpertext { + margin-top: -21px; +} + +.select-all { + margin-top: 10px; + border-bottom: 1px solid lightgrey; + padding-bottom: 18px; +} + +.input { + position: relative; + color: var(--palette-text-primary); + cursor: text; + display: inline-flex; + font-size: 1rem; + box-sizing: border-box; + align-items: center; + font-weight: 400; + line-height: 1.1876em; + letter-spacing: 0.00938em; +} +.input.input-full-width { + width: 100%; +} +.input.disabled { + color: var(--palette-text-disabled); + cursor: default; +} +.input.disabled > .input-adornment { + color: var(--palette-text-disabled); + pointer-events: none; +} +.input.input-underline:before { + left: 0; + right: 0; + bottom: 0; + content: " "; + position: absolute; + transition: border-bottom 0.2s, background-color 0.2s; + border-bottom: 1px solid var(--palette-lines-inputs); + pointer-events: none; +} +.input.input-underline:hover:not(.disabled):before { + border-bottom: 1px solid var(--palette-action-default); +} +.input.input-underline:after { + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + transform: scaleX(0); + transition: transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + border-bottom: 2px solid var(--palette-primary); + pointer-events: none; +} +.input.input-underline.disabled:before { + border-bottom-style: dotted; +} +.input.input-underline.input-error:after { + transform: scaleX(1); + border-bottom-color: var(--palette-error); +} +.input.input-filled { + position: relative; + transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + background-color: rgba(0, 0, 0, 0.09); + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.input.input-filled:hover { + background-color: rgba(0, 0, 0, 0.13); +} +.input.input-filled.focused { + background-color: rgba(0, 0, 0, 0.09); +} +.input.input-filled.disabled { + background-color: rgba(0, 0, 0, 0.12); +} +.input.input-filled.input-adorned-start { + padding-left: 12px; + padding-inline-start: 12px; + padding-inline-end: unset; +} +.input.input-filled.input-adorned-end { + padding-right: 12px; + padding-inline-end: 12px; + padding-inline-start: unset; +} +.input.input-filled.input-underline:before { + left: 0; + right: 0; + bottom: 0; + content: " "; + position: absolute; + transition: border-bottom-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-bottom: 1px solid var(--palette-lines-inputs); + pointer-events: none; +} +.input.input-filled.input-underline:after { + left: 0; + right: 0; + bottom: 0; + content: ""; + position: absolute; + transform: scaleX(0); + transition: transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; + border-bottom: 2px solid var(--palette-primary); + pointer-events: none; +} +.input.input-filled.input-underline:hover:before { + border-bottom: 1px solid var(--palette-action-default); +} +.input.input-filled.input-underline.disabled:before { + border-bottom-style: dotted; +} +.input.input-filled.input-underline.input-error:after { + transform: scaleX(1); + border-bottom-color: var(--palette-error); +} +.input.input-outlined { + position: relative; + border-width: 0px; +} +.input.input-outlined .input-outlined-border { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + box-sizing: border-box; + width: 100%; + max-width: 100%; + height: 100%; + text-align: start; + pointer-events: none; + border-radius: var(--default-borderradius); + border-color: var(--palette-lines-inputs); + border-width: 1px; + border-style: solid; + transition: border-width, border-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input.input-outlined:not(.disabled):not(:focus-within):hover .input-outlined-border { + border-color: var(--palette-action-default); +} +.input.input-outlined:focus-within .input-outlined-border { + border-width: 2px; + border-color: var(--palette-primary); +} +.input.input-outlined.disabled .input-outlined-border { + border-color: var(--palette-action-disabled); +} +.input.input-outlined.input-adorned-start { + padding-left: 14px; + padding-inline-start: 14px; + padding-inline-end: unset; +} +.input.input-outlined.input-adorned-end { + padding-right: 14px; + padding-inline-end: 14px; + padding-inline-start: unset; +} + +.input-error .input-outlined-border { + border-color: var(--palette-error) !important; +} + +.input:focus-within.input-underline:after { + transform: scaleX(1); +} + +.input > input.input-root, div.input-slot.input-root { + font: inherit; + color: currentColor; + width: 100%; + border: 0; + height: 1.1876em; + margin: 0; + display: block; + padding: 6px 0 7px; + min-width: 0; + background: none; + position: relative; + box-sizing: content-box; + letter-spacing: inherit; + -webkit-tap-highlight-color: transparent; + /* - Chrome ≤56, + - Safari 5-10.0 + - iOS Safari 4.2-10.2 + - Opera 15-43 + - Opera Mobile 12-12.1 + - Android Browser 2.1-4.4.4 + - Samsung Internet ≤6.2 + - QQ Browser */ +} +.input > input.input-root::placeholder, div.input-slot.input-root::placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root::-webkit-input-placeholder, div.input-slot.input-root::-webkit-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root:-moz-placeholder, div.input-slot.input-root:-moz-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root::-moz-placeholder, div.input-slot.input-root::-moz-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root:-ms-input-placeholder, div.input-slot.input-root:-ms-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root::-ms-input-placeholder, div.input-slot.input-root::-ms-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > input.input-root.input-root-margin-dense, div.input-slot.input-root.input-root-margin-dense { + padding-top: 3px; +} +.input > input.input-root.input-root-multiline, div.input-slot.input-root.input-root-multiline { + height: auto; + resize: none; + padding: 0; +} +.input > input.input-root.input-root-type-search, div.input-slot.input-root.input-root-type-search { + -moz-appearance: textfield; + -webkit-appearance: textfield; +} +.input > input.input-root:focus, div.input-slot.input-root:focus { + outline: 0; +} +.input > input.input-root:invalid, div.input-slot.input-root:invalid { + box-shadow: none; +} +.input > input.input-root:disabled, div.input-slot.input-root:disabled { + opacity: 1; +} +.input > input.input-root.input-root-filled, div.input-slot.input-root.input-root-filled { + padding: 27px 12px 10px; +} +.input > input.input-root.input-root-filled.input-root-margin-dense, div.input-slot.input-root.input-root-filled.input-root-margin-dense { + padding-top: 23px; + padding-bottom: 6px; +} +.input > input.input-root.input-root-filled:-webkit-autofill, div.input-slot.input-root.input-root-filled:-webkit-autofill { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.input > input.input-root.input-root-filled.input-root-hidden-label, div.input-slot.input-root.input-root-filled.input-root-hidden-label { + padding-top: 18px; + padding-bottom: 19px; +} +.input > input.input-root.input-root-filled.input-root-hidden-label.input-root-margin-dense, div.input-slot.input-root.input-root-filled.input-root-hidden-label.input-root-margin-dense { + padding-top: 10px; + padding-bottom: 11px; +} +.input > input.input-root.input-root-filled.input-root-multiline, div.input-slot.input-root.input-root-filled.input-root-multiline { + padding: 0; +} +.input > input.input-root.input-root-filled.input-root-adorned-start, div.input-slot.input-root.input-root-filled.input-root-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 12px; +} +.input > input.input-root.input-root-filled.input-root-adorned-end, div.input-slot.input-root.input-root-filled.input-root-adorned-end { + padding-right: 0; + padding-inline-end: 0; + padding-inline-start: 12px; +} +.input > input.input-root-outlined, div.input-slot.input-root-outlined { + padding: 18.5px 14px; +} +.input > input.input-root-outlined.input-root:-webkit-autofill, div.input-slot.input-root-outlined.input-root:-webkit-autofill { + border-radius: inherit; +} +.input > input.input-root-outlined.input-root-margin-dense, div.input-slot.input-root-outlined.input-root-margin-dense { + padding-top: 10.5px; + padding-bottom: 10.5px; +} +.input > input.input-root-outlined.input-root-adorned-start, div.input-slot.input-root-outlined.input-root-adorned-start { + padding-left: 0; + padding-inline-start: 0; + padding-inline-end: 14px; +} +.input > input.input-root-outlined.input-root-adorned-end, div.input-slot.input-root-outlined.input-root-adorned-end { + padding-right: 0; + padding-inline-end: 0; + padding-inline-start: 14px; +} +.input > input::-ms-reveal, .input > input::-ms-clear, div.input-slot::-ms-reveal, div.input-slot::-ms-clear { + display: none !important; +} + +.input > textarea.input-root { + font: inherit; + color: currentColor; + width: 100%; + border: 0; + height: auto; + margin: 6px 0 7px; + padding: 0; + display: block; + min-width: 0; + background: none; + position: relative; + box-sizing: content-box; + letter-spacing: inherit; + -webkit-tap-highlight-color: transparent; + height: auto; + resize: none; + cursor: auto; + /* - Chrome ≤56, + - Safari 5-10.0 + - iOS Safari 4.2-10.2 + - Opera 15-43 + - Opera Mobile 12-12.1 + - Android Browser 2.1-4.4.4 + - Samsung Internet ≤6.2 + - QQ Browser */ +} +.input > textarea.input-root::placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root::-webkit-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root:-moz-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root::-moz-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root:-ms-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root::-ms-input-placeholder { + color: currentColor; + opacity: 0.42; + transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} +.input > textarea.input-root.input-root-margin-dense { + margin-top: 3px; +} +.input > textarea.input-root.input-root-type-search { + -moz-appearance: textfield; + -webkit-appearance: textfield; +} +.input > textarea.input-root:focus { + outline: 0; +} +.input > textarea.input-root:invalid { + box-shadow: none; +} +.input > textarea.input-root:disabled { + opacity: 1; +} +.input > textarea.input-root.input-root-filled { + margin: 27px 12px 10px; +} +.input > textarea.input-root.input-root-filled.input-root-margin-dense { + margin-top: 23px; + margin-bottom: 6px; +} +.input > textarea.input-root.input-root-filled:-webkit-autofill { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.input > textarea.input-root.input-root-filled.input-root-hidden-label { + margin-top: 18px; + margin-bottom: 19px; +} +.input > textarea.input-root.input-root-filled.input-root-hidden-label.input-root-margin-dense { + margin-top: 10px; + margin-bottom: 11px; +} +.input > textarea.input-root.input-root-filled.input-root-adorned-start { + margin-left: 0; + margin-inline-start: 0; + margin-inline-end: 12px; +} +.input > textarea.input-root.input-root-filled.input-root-adorned-end { + margin-right: 0; + margin-inline-end: unset; + margin-inline-start: 12px; +} +.input > textarea.input-root::-webkit-scrollbar { + width: 8px; + height: 8px; + z-index: 1; + cursor: crosshair; +} +.input > textarea.input-root::-webkit-scrollbar-thumb { + background: var(--palette-lines-inputs); + border-radius: 1px; +} +.input > textarea.input-root::-webkit-scrollbar-track { + background: transparent; +} +.input > textarea.input-root-outlined { + margin: 18.5px 14px; +} +.input > textarea.input-root-outlined.input-root:-webkit-autofill { + border-radius: inherit; +} +.input > textarea.input-root-outlined.input-root-margin-dense { + margin-top: 10.5px; + margin-bottom: 10.5px; +} +.input > textarea.input-root-outlined.input-root-adorned-start { + margin-left: 0; + margin-inline-start: 0; + margin-inline-end: 14px; +} +.input > textarea.input-root-outlined.input-root-adorned-end { + margin-right: 0; + margin-inline-end: 0; + margin-inline-start: 14px; +} + +.input-adornment { + height: 0.01em; + display: flex; + max-height: 2em; + align-items: center; + white-space: nowrap; +} + +.input-adornment-start.input-root-filled-shrink { + margin-top: 16px; +} + +.input-adornment-start { + margin-right: 8px; + margin-inline-end: 8px; + margin-inline-start: unset; +} + +.input-adornment-end { + margin-left: 8px; + margin-inline-start: 8px; + margin-inline-end: unset; +} + +.input-number-control.input-showspin .input-adornment-end { + margin-right: 12px; + margin-inline-end: 12px; + margin-inline-start: unset; +} + +.input-number-control.input-showspin .input-underline:not(.input-filled) .input-adornment-end { + margin-right: 24px; + margin-inline-end: 24px; + margin-inline-start: unset; +} + +.input-adornment-disable-pointerevents { + pointer-events: none; +} + +.range-input-separator { + visibility: hidden; + margin: 0 4px; +} + +.input:focus-within .range-input-separator { + visibility: visible; +} + +.picker .shrink .range-input-separator { + visibility: visible; +} + +.input-control { + border: 0; + margin: 0; + padding: 0; + display: flex; + flex: 1 1 auto; + max-width: 100%; + position: relative; + flex-direction: column; + vertical-align: top; + margin-top: 6px; +} +.input-control.input-control-margin-normal { + margin-top: 16px; + margin-bottom: 8px; +} +.input-control.input-control-margin-dense { + margin-top: 3px; + margin-bottom: 2px; +} +.input-control.input-control-full-width { + width: 100%; +} +.input-control.input-control-boolean-input { + flex: none; + margin: 0; +} +.input-control > .input-control-input-container { + position: relative; + display: flex; + flex-direction: column; +} +.input-control > .input-control-input-container > div.input.input-text { + margin-top: 16px; +} +.input-control > .input-control-input-container > .input-label-outlined.input-label-inputcontrol { + line-height: 18px; +} +.input-control > .input-control-input-container > .input-label-inputcontrol { + color: var(--palette-text-secondary); + padding: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1; + letter-spacing: 0.00938em; + z-index: 0; + pointer-events: none; +} +.input-control > .input-control-input-container > .input-label-inputcontrol.disabled { + color: var(--palette-text-disabled); +} +.input-control > .input-control-input-container > .input-label-inputcontrol.input-error { + color: var(--palette-error) !important; +} +.input-control.input-required > .input-control-input-container > .input-label::after { + content: "*"; +} +.input-control.input-number-control input::-webkit-outer-spin-button, .input-control.input-number-control input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} +.input-control.input-number-control input[type=number] { + -moz-appearance: textfield; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end) input { + padding-right: 24px; + padding-inline-end: 24px; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end) input.input-root-margin-dense { + padding-right: 20px; + padding-inline-end: 20px; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-text input { + padding-inline-start: 0; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-text input.input-root-margin-dense { + padding-inline-start: 0; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-filled input { + padding-inline-start: 12px; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-filled input.input-root-margin-dense { + padding-inline-start: 12px; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-outlined input { + padding-inline-start: 14px; +} +.input-control.input-number-control.input-showspin .input:not(.input-adorned-end).input-outlined input.input-root-margin-dense { + padding-inline-start: 14px; +} +.input-control.input-number-control .input-numeric-spin { + display: inline-flex; + flex-direction: column; + justify-content: space-between; + position: absolute; + right: 0; + top: 0; + bottom: 0; +} +.input-control.input-number-control .input-numeric-spin button { + padding: 2px; + min-width: unset; + min-height: unset; +} +.input-control.input-number-control .input-numeric-spin button { + padding: 2px 0; +} + +.input-control-helper-container { + overflow: hidden; + margin-top: 3px; +} + +.input-helper-text { + color: var(--palette-text-secondary); + margin: 0; + font-size: 0.75rem; + text-align: start; + font-weight: 400; + line-height: 1.66; + letter-spacing: 0.03333em; +} +.input-helper-text.input-helper-onfocus { + transform: translateY(-100%); + transition: color 200ms cubic-bezier(0, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} + +.input-control:focus-within .input-helper-text.input-helper-onfocus, .input-control.input-error .input-helper-text.input-helper-onfocus { + transform: translateY(0); +} + +.input-helper-text.disabled { + color: var(--palette-text-disabled); +} + +.input-helper-text.input-error { + color: var(--palette-error) !important; +} + +.input-helper-text-margin-dense { + margin-top: 4px; +} + +.input-helper-text-contained { + margin-left: 14px; + margin-right: 14px; +} + +.application-layout-rtl .input-control.input-number-control .input-numeric-spin { + left: 0; + right: unset; +} + +.input-label { + display: block; + transform-origin: top left; +} + +.input-label-inputcontrol { + top: 0; + left: 0; + position: absolute; + transform: translate(0, 24px) scale(1); +} + +.input-label-margindense { + transform: translate(0, 21px) scale(1); +} + +.input-label-shrink { + transform: translate(0, 1.5px) scale(0.75); + transform-origin: top left; +} + +.input-label-animated { + transition: color 200ms cubic-bezier(0, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} + +.input-label-filled { + z-index: 1; + transform: translate(12px, 20px) scale(1); + pointer-events: none; +} +.input-label-filled.input-label-margin-dense { + transform: translate(12px, 17px) scale(1); +} + +.input-label-outlined { + transform: translate(14px, 20px) scale(1); + pointer-events: none; + background-color: var(--palette-surface); + padding: 0px 5px !important; +} +.input-label-outlined.input-label-margin-dense { + transform: translate(14px, 12px) scale(1); +} + +.shrink ~ label.input-label.input-label-inputcontrol { + color: var(--palette-text-primary); +} +.input:focus-within ~ label.input-label.input-label-inputcontrol { + color: var(--palette-primary); +} +.shrink ~ label.input-label.input-label-inputcontrol, .input:focus-within ~ label.input-label.input-label-inputcontrol { + transform: translate(0, 1.5px) scale(0.75); + transform-origin: top left; +} +.shrink ~ label.input-label.input-label-inputcontrol.input-label-filled, .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-filled { + transform: translate(12px, 10px) scale(0.75); +} +.shrink ~ label.input-label.input-label-inputcontrol.input-label-filled.input-label-margin-dense, .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-filled.input-label-margin-dense { + transform: translate(12px, 7px) scale(0.75); +} +.shrink ~ label.input-label.input-label-inputcontrol.input-label-outlined, .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-outlined { + transform: translate(14px, -6px) scale(0.75); +} +.input:focus-within ~ label.input-label.input-label-inputcontrol.input-error { + color: var(--palette-error); +} + +.application-layout-rtl .input-label { + transform-origin: top right; +} +.application-layout-rtl .input-label-inputcontrol { + left: unset; + right: 0; +} +.application-layout-rtl .input-label-shrink { + transform-origin: top right; +} +.application-layout-rtl .input-label-filled { + transform: translate(-12px, 20px) scale(1); +} +.application-layout-rtl .input-label-filled.input-label-margin-dense { + transform: translate(-12px, 17px) scale(1); +} +.application-layout-rtl .input-label-outlined { + transform: translate(-14px, 20px) scale(1); +} +.application-layout-rtl .input-label-outlined.input-label-margin-dense { + transform: translate(-14px, 12px) scale(1); +} +.application-layout-rtl .shrink ~ label.input-label.input-label-inputcontrol, .application-layout-rtl .input:focus-within ~ label.input-label.input-label-inputcontrol { + transform-origin: top right; +} +.application-layout-rtl .shrink ~ label.input-label.input-label-inputcontrol.input-label-filled, .application-layout-rtl .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-filled { + transform: translate(-12px, 10px) scale(0.75); +} +.application-layout-rtl .shrink ~ label.input-label.input-label-inputcontrol.input-label-filled.input-label-margin-dense, .application-layout-rtl .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-filled.input-label-margin-dense { + transform: translate(-12px, 7px) scale(0.75); +} +.application-layout-rtl .shrink ~ label.input-label.input-label-inputcontrol.input-label-outlined, .application-layout-rtl .input:focus-within ~ label.input-label.input-label-inputcontrol.input-label-outlined { + transform: translate(-14px, -6px) scale(0.75); +} + +.file-upload { + flex-grow: 0; +} + +.file-upload > .input-control-input-container { + display: initial !important; +} + +.image.fluid { + max-width: 100%; + height: auto; +} + +.overlay { + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0 !important; + align-items: center; + justify-content: center; + border-radius: inherit; + display: flex; + position: fixed; + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), z-index 1ms; + z-index: 5; +} +.overlay.overlay-absolute { + position: absolute; +} +.overlay .overlay-scrim { + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; + position: absolute; + height: 100%; + width: 100%; + border-color: transparent; + background-color: transparent; + animation: animation-fadein ease 0.15s; + -webkit-animation: animation-fadein ease 0.15s; + -moz-animation: animation-fadein ease 0.15s; + -o-animation: animation-fadein ease 0.15s; +} +.overlay .overlay-scrim.overlay-dark { + border-color: var(--palette-overlay-dark); + background-color: var(--palette-overlay-dark); +} +.overlay .overlay-scrim.overlay-light { + border-color: var(--palette-overlay-light); + background-color: var(--palette-overlay-light); +} +.overlay .overlay-scrim:hover { + cursor: default; +} +.overlay .overlay-content { + position: relative; +} +.overlay.overlay-popover { + z-index: var(--zindex-popover); +} +.overlay.overlay-dialog { + z-index: calc(var(--zindex-dialog) + 1); +} +.overlay.overlay-drawer { + z-index: calc(var(--zindex-appbar) + 1); +} + +.treeview { + margin: 0px; + padding: 0px; + list-style: none; + overflow: auto; +} +.treeview.treeview-selected-primary .treeview-item-content.treeview-item-selected { + color: var(--palette-primary); + background-color: var(--palette-primary-hover); +} +.treeview.treeview-selected-secondary .treeview-item-content.treeview-item-selected { + color: var(--palette-secondary); + background-color: var(--palette-secondary-hover); +} +.treeview.treeview-selected-tertiary .treeview-item-content.treeview-item-selected { + color: var(--palette-tertiary); + background-color: var(--palette-tertiary-hover); +} +.treeview.treeview-selected-info .treeview-item-content.treeview-item-selected { + color: var(--palette-info); + background-color: var(--palette-info-hover); +} +.treeview.treeview-selected-success .treeview-item-content.treeview-item-selected { + color: var(--palette-success); + background-color: var(--palette-success-hover); +} +.treeview.treeview-selected-warning .treeview-item-content.treeview-item-selected { + color: var(--palette-warning); + background-color: var(--palette-warning-hover); +} +.treeview.treeview-selected-error .treeview-item-content.treeview-item-selected { + color: var(--palette-error); + background-color: var(--palette-error-hover); +} +.treeview.treeview-selected-dark .treeview-item-content.treeview-item-selected { + color: var(--palette-dark); + background-color: var(--palette-dark-hover); +} +.treeview.treeview-checked-primary .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-primary); +} +.treeview.treeview-checked-secondary .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-secondary); +} +.treeview.treeview-checked-tertiary .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-tertiary); +} +.treeview.treeview-checked-info .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-info); +} +.treeview.treeview-checked-success .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-success); +} +.treeview.treeview-checked-warning .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-warning); +} +.treeview.treeview-checked-error .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-error); +} +.treeview.treeview-checked-dark .treeview-item-checkbox .button-root.icon-button { + color: var(--palette-dark); +} + +.treeview-group { + margin: 0px; + padding: 0px; + margin-left: 17px; + margin-inline-start: 17px; + margin-inline-end: unset; + list-style: none; +} + +.treeview-item { + margin: 0; + outline: 0; + padding: 0; + cursor: default; + list-style: none; + min-height: 2rem; + align-items: center; + -webkit-tap-highlight-color: transparent; +} +.treeview-item .treeview-item-arrow .icon-button, .treeview-item .treeview-item-checkbox .icon-button { + padding: 4px; +} + +.treeview-item-content { + width: 100%; + display: flex; + padding: 4px 8px; + align-items: center; + transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; +} + +.treeview-hover .treeview-item-content:hover { + background-color: var(--palette-action-default-hover); +} + +.treeview-item-arrow { + width: 2rem; + display: flex; + flex-shrink: 0; + margin: 0 4px; + min-height: 32px; + justify-content: center; +} +.treeview-item-arrow .treeview-item-arrow-expand { + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), visibility 0s; +} +.treeview-item-arrow .treeview-item-arrow-expand.transform { + transform: rotate(90deg); +} +.treeview-item-arrow .treeview-item-arrow-load { + animation: rotation 1s infinite linear; +} + +.treeview-item-icon { + width: 32px; + display: flex; + flex-shrink: 0; + margin-right: 4px; + margin-inline-end: 4px; + margin-inline-start: unset; + justify-content: center; +} + +.treeview-item-label { + flex-grow: 1; + padding-left: 4px; + padding-right: 4px; +} + +.treeview-dense .treeview-item { + min-height: unset; +} +.treeview-dense .treeview-item-content { + padding: 1px 4px; +} +.treeview-dense .treeview-item-arrow { + min-height: unset; +} +.treeview-dense .icon-button { + padding: 0; +} + +@keyframes rotation { + from { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} +.application-layout-rtl .treeview-item-arrow { + transform: scaleX(-1); +} + +.data-grid th { + position: relative; +} +.data-grid .table-cell.edit-mode-cell .input-control { + margin: 0 !important; +} +.data-grid .table-cell.edit-mode-cell .input { + font-size: inherit; +} +.data-grid .table-cell.edit-mode-cell .input:before { + content: none; +} +.data-grid .table-cell.edit-mode-cell .inputafter { + content: none; +} +.data-grid .table-cell.edit-mode-cell .input .input-outlined-border { + border: none; +} +.data-grid .table-cell.filter-header-cell { + padding: 6px 24px 6px 16px; + padding-inline-start: 16px; + padding-inline-end: 24px; +} +.data-grid .table-cell.sticky-left { + left: 0px; + position: sticky; + background-color: var(--palette-background-grey); + z-index: 1; +} +.data-grid .table-cell.sticky-right { + right: 0px; + position: sticky; + background-color: var(--palette-background-grey); + z-index: 1; +} +.data-grid .table-cell .input-text { + margin-top: 0 !important; +} +.data-grid .table-cell .column-header { + display: flex; + justify-content: space-between; +} +.data-grid .table-cell .column-header .sortable-column-header { + width: 100%; +} +.data-grid .table-cell .column-header:hover .column-options .sort-direction-icon, .data-grid .table-cell .column-header:hover .column-options .column-options-icon { + opacity: 0.8; + color: var(--palette-action-default); +} +.data-grid .table-cell .column-header:hover .column-options .menu .icon-button-label { + opacity: 1; + color: var(--palette-action-default); +} +.data-grid .table-cell .column-header .column-options { + display: inline-flex; + align-items: center; + flex-direction: inherit; + justify-content: flex-start; +} +.data-grid .table-cell .column-header .sort-direction-icon { + font-size: 18px; + margin-left: 4px; + margin-left: 4px; + margin-inline-start: 4px; + margin-inline-end: unset; + user-select: none; + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + opacity: 0; +} +.data-grid .table-cell .column-header .sort-direction-icon.direction-desc { + opacity: 1; + transform: rotate(180deg); +} +.data-grid .table-cell .column-header .sort-direction-icon.direction-asc { + opacity: 1; + transform: rotate(0deg); +} +.data-grid .table-cell .column-header .sort-index { + transform: scale(0.9) translate(-2px, -2px); +} +.data-grid .table-cell .column-header .column-options .menu .icon-button-label { + /*font-size: 18px;*/ + user-select: none; + /*margin-right: 4px;*/ + transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + opacity: 0; +} +.data-grid .table-cell .resizer { + position: absolute; + top: 0; + right: 0; + width: 8px; + cursor: col-resize; + user-select: none; +} +.data-grid .table-cell .resizer:hover, +.data-grid .table-cell .resizing { + border-right: 2px solid var(--palette-primary); +} + +.rounded-0 { + border-radius: 0 !important; +} + +.rounded-t-0 { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; +} + +.rounded-r-0, .rounded-e-0 { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-b-0 { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} + +.rounded-l-0, .rounded-s-0 { + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} + +.rounded-tl-0, .rounded-ts-0 { + border-top-left-radius: 0 !important; +} + +.rounded-tr-0, .rounded-te-0 { + border-top-right-radius: 0 !important; +} + +.rounded-br-0, .rounded-be-0 { + border-bottom-right-radius: 0 !important; +} + +.rounded-bl-0, .rounded-bs-0 { + border-bottom-left-radius: 0 !important; +} + +.application-layout-rtl .rounded-s-0 { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-e-0 { + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} +.application-layout-rtl .rounded-ts-0 { + border-top-right-radius: 0 !important; + border-top-left-radius: 0 !important; +} +.application-layout-rtl .rounded-te-0 { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; +} +.application-layout-rtl .rounded-bs-0 { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-be-0 { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-sm { + border-radius: 2px !important; +} + +.rounded-t-sm { + border-top-left-radius: 2px !important; + border-top-right-radius: 2px !important; +} + +.rounded-r-sm, .rounded-e-sm { + border-top-right-radius: 2px !important; + border-bottom-right-radius: 2px !important; +} + +.rounded-b-sm { + border-bottom-right-radius: 2px !important; + border-bottom-left-radius: 2px !important; +} + +.rounded-l-sm, .rounded-s-sm { + border-top-left-radius: 2px !important; + border-bottom-left-radius: 2px !important; +} + +.rounded-tl-sm, .rounded-ts-sm { + border-top-left-radius: 2px !important; +} + +.rounded-tr-sm, .rounded-te-sm { + border-top-right-radius: 2px !important; +} + +.rounded-br-sm, .rounded-be-sm { + border-bottom-right-radius: 2px !important; +} + +.rounded-bl-sm, .rounded-bs-sm { + border-bottom-left-radius: 2px !important; +} + +.application-layout-rtl .rounded-s-sm { + border-top-right-radius: 2px !important; + border-bottom-right-radius: 2px !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-e-sm { + border-top-left-radius: 2px !important; + border-bottom-left-radius: 2px !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} +.application-layout-rtl .rounded-ts-sm { + border-top-right-radius: 2px !important; + border-top-left-radius: 0 !important; +} +.application-layout-rtl .rounded-te-sm { + border-top-left-radius: 2px !important; + border-top-right-radius: 0 !important; +} +.application-layout-rtl .rounded-bs-sm { + border-bottom-right-radius: 2px !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-be-sm { + border-bottom-left-radius: 2px !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-lg { + border-radius: 8px !important; +} + +.rounded-t-lg { + border-top-left-radius: 8px !important; + border-top-right-radius: 8px !important; +} + +.rounded-r-lg, .rounded-e-lg { + border-top-right-radius: 8px !important; + border-bottom-right-radius: 8px !important; +} + +.rounded-b-lg { + border-bottom-right-radius: 8px !important; + border-bottom-left-radius: 8px !important; +} + +.rounded-l-lg, .rounded-s-lg { + border-top-left-radius: 8px !important; + border-bottom-left-radius: 8px !important; +} + +.rounded-tl-lg, .rounded-ts-lg { + border-top-left-radius: 8px !important; +} + +.rounded-tr-lg, .rounded-te-lg { + border-top-right-radius: 8px !important; +} + +.rounded-br-lg, .rounded-be-lg { + border-bottom-right-radius: 8px !important; +} + +.rounded-bl-lg, .rounded-bs-lg { + border-bottom-left-radius: 8px !important; +} + +.application-layout-rtl .rounded-s-lg { + border-top-right-radius: 8px !important; + border-bottom-right-radius: 8px !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-e-lg { + border-top-left-radius: 8px !important; + border-bottom-left-radius: 8px !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} +.application-layout-rtl .rounded-ts-lg { + border-top-right-radius: 8px !important; + border-top-left-radius: 0 !important; +} +.application-layout-rtl .rounded-te-lg { + border-top-left-radius: 8px !important; + border-top-right-radius: 0 !important; +} +.application-layout-rtl .rounded-bs-lg { + border-bottom-right-radius: 8px !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-be-lg { + border-bottom-left-radius: 8px !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-xl { + border-radius: 24px !important; +} + +.rounded-t-xl { + border-top-left-radius: 24px !important; + border-top-right-radius: 24px !important; +} + +.rounded-r-xl, .rounded-e-xl { + border-top-right-radius: 24px !important; + border-bottom-right-radius: 24px !important; +} + +.rounded-b-xl { + border-bottom-right-radius: 24px !important; + border-bottom-left-radius: 24px !important; +} + +.rounded-l-xl, .rounded-s-xl { + border-top-left-radius: 24px !important; + border-bottom-left-radius: 24px !important; +} + +.rounded-tl-xl, .rounded-ts-xl { + border-top-left-radius: 24px !important; +} + +.rounded-tr-xl, .rounded-te-xl { + border-top-right-radius: 24px !important; +} + +.rounded-br-xl, .rounded-be-xl { + border-bottom-right-radius: 24px !important; +} + +.rounded-bl-xl, .rounded-bs-xl { + border-bottom-left-radius: 24px !important; +} + +.application-layout-rtl .rounded-s-xl { + border-top-right-radius: 24px !important; + border-bottom-right-radius: 24px !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-e-xl { + border-top-left-radius: 24px !important; + border-bottom-left-radius: 24px !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} +.application-layout-rtl .rounded-ts-xl { + border-top-right-radius: 24px !important; + border-top-left-radius: 0 !important; +} +.application-layout-rtl .rounded-te-xl { + border-top-left-radius: 24px !important; + border-top-right-radius: 0 !important; +} +.application-layout-rtl .rounded-bs-xl { + border-bottom-right-radius: 24px !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-be-xl { + border-bottom-left-radius: 24px !important; + border-bottom-right-radius: 0 !important; +} + +.rounded { + border-radius: var(--default-borderradius) !important; +} + +.rounded-t { + border-top-left-radius: var(--default-borderradius) !important; + border-top-right-radius: var(--default-borderradius) !important; +} + +.rounded-r, .rounded-e { + border-top-right-radius: var(--default-borderradius) !important; + border-bottom-right-radius: var(--default-borderradius) !important; +} + +.rounded-b { + border-bottom-right-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; +} + +.rounded-l, .rounded-s { + border-top-left-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; +} + +.rounded-tl, .rounded-ts { + border-top-left-radius: var(--default-borderradius) !important; +} + +.rounded-tr, .rounded-te { + border-top-right-radius: var(--default-borderradius) !important; +} + +.rounded-br, .rounded-be { + border-bottom-right-radius: var(--default-borderradius) !important; +} + +.rounded-bl, .rounded-bs { + border-bottom-left-radius: var(--default-borderradius) !important; +} + +.application-layout-rtl .rounded-s { + border-top-right-radius: var(--default-borderradius) !important; + border-bottom-right-radius: var(--default-borderradius) !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-e { + border-top-left-radius: var(--default-borderradius) !important; + border-bottom-left-radius: var(--default-borderradius) !important; + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} +.application-layout-rtl .rounded-ts { + border-top-right-radius: var(--default-borderradius) !important; + border-top-left-radius: 0 !important; +} +.application-layout-rtl .rounded-te { + border-top-left-radius: var(--default-borderradius) !important; + border-top-right-radius: 0 !important; +} +.application-layout-rtl .rounded-bs { + border-bottom-right-radius: var(--default-borderradius) !important; + border-bottom-left-radius: 0 !important; +} +.application-layout-rtl .rounded-be { + border-bottom-left-radius: var(--default-borderradius) !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 9999px !important; +} + +.border-solid { + border-style: solid !important; +} + +.border-dashed { + border-style: dashed !important; +} + +.border-dotted { + border-style: dotted !important; +} + +.border-double { + border-style: double !important; +} + +.border-hidden { + border-style: hidden !important; +} + +.border-none { + border-style: none !important; +} + +.border-0 { + border-width: 0px !important; +} + +.border-t-0 { + border-top-width: 0px !important; +} + +.border-r-0 { + border-right-width: 0px !important; +} + +.border-b-0 { + border-bottom-width: 0px !important; +} + +.border-l-0 { + border-left-width: 0px !important; +} + +.border-x-0 { + border-left-width: 0px !important; + border-right-width: 0px !important; +} + +.border-y-0 { + border-top-width: 0px !important; + border-bottom-width: 0px !important; +} + +.border { + border-width: 1px !important; +} + +.border-t { + border-top-width: 1px !important; +} + +.border-r { + border-right-width: 1px !important; +} + +.border-b { + border-bottom-width: 1px !important; +} + +.border-l { + border-left-width: 1px !important; +} + +.border-x { + border-left-width: 1px !important; + border-right-width: 1px !important; +} + +.border-y { + border-top-width: 1px !important; + border-bottom-width: 1px !important; +} + +.border-2 { + border-width: 2px !important; +} + +.border-t-2 { + border-top-width: 2px !important; +} + +.border-r-2 { + border-right-width: 2px !important; +} + +.border-b-2 { + border-bottom-width: 2px !important; +} + +.border-l-2 { + border-left-width: 2px !important; +} + +.border-x-2 { + border-left-width: 2px !important; + border-right-width: 2px !important; +} + +.border-y-2 { + border-top-width: 2px !important; + border-bottom-width: 2px !important; +} + +.border-4 { + border-width: 4px !important; +} + +.border-t-4 { + border-top-width: 4px !important; +} + +.border-r-4 { + border-right-width: 4px !important; +} + +.border-b-4 { + border-bottom-width: 4px !important; +} + +.border-l-4 { + border-left-width: 4px !important; +} + +.border-x-4 { + border-left-width: 4px !important; + border-right-width: 4px !important; +} + +.border-y-4 { + border-top-width: 4px !important; + border-bottom-width: 4px !important; +} + +.border-8 { + border-width: 8px !important; +} + +.border-t-8 { + border-top-width: 8px !important; +} + +.border-r-8 { + border-right-width: 8px !important; +} + +.border-b-8 { + border-bottom-width: 8px !important; +} + +.border-l-8 { + border-left-width: 8px !important; +} + +.border-x-8 { + border-left-width: 8px !important; + border-right-width: 8px !important; +} + +.border-y-8 { + border-top-width: 8px !important; + border-bottom-width: 8px !important; +} + +/* Outline Style */ +.outline-none { + outline-style: none; +} + +.outline-solid { + outline-style: solid; +} + +.outline-dashed { + outline-style: dashed; +} + +.outline-dotted { + outline-style: dotted; +} + +.outline-double { + outline-style: double; +} + +.outline-hidden { + outline-style: hidden; +} + +/* Outline Color */ +/* To Doo */ +/* Outline Offset */ +/* To Doo */ +/* Outline Width */ +/* To Doo */ +.flex-1 { + flex: 1 1 0% !important; +} + +.flex-auto { + flex: 1 1 auto !important; +} + +.flex-initial { + flex: 0 1 auto !important; +} + +.flex-none { + flex: none !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-start { + justify-content: flex-start !important; +} + +.justify-end { + justify-content: flex-end !important; +} + +.justify-center { + justify-content: center !important; +} + +.justify-space-between { + justify-content: space-between !important; +} + +.justify-space-around { + justify-content: space-around !important; +} + +.justify-space-evenly { + justify-content: space-evenly !important; +} + +.order-first { + order: -9999 !important; +} + +.order-last { + order: 9999 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-6 { + order: 6 !important; +} + +.order-7 { + order: 7 !important; +} + +.order-8 { + order: 8 !important; +} + +.order-9 { + order: 9 !important; +} + +.order-10 { + order: 10 !important; +} + +.order-11 { + order: 11 !important; +} + +.order-12 { + order: 12 !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-space-between { + align-content: space-between !important; +} + +.align-content-space-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-start { + align-items: flex-start !important; +} + +.align-end { + align-items: flex-end !important; +} + +.align-center { + align-items: center !important; +} + +.align-baseline { + align-items: baseline !important; +} + +.align-stretch { + align-items: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.gap-0 { + gap: 0px; +} + +.gap-x-0 { + column-gap: 0px; +} + +.gap-y-0 { + row-gap: 0px; +} + +.gap-1 { + gap: 4px; +} + +.gap-x-1 { + column-gap: 4px; +} + +.gap-y-1 { + row-gap: 4px; +} + +.gap-2 { + gap: 8px; +} + +.gap-x-2 { + column-gap: 8px; +} + +.gap-y-2 { + row-gap: 8px; +} + +.gap-3 { + gap: 12px; +} + +.gap-x-3 { + column-gap: 12px; +} + +.gap-y-3 { + row-gap: 12px; +} + +.gap-4 { + gap: 16px; +} + +.gap-x-4 { + column-gap: 16px; +} + +.gap-y-4 { + row-gap: 16px; +} + +.gap-5 { + gap: 20px; +} + +.gap-x-5 { + column-gap: 20px; +} + +.gap-y-5 { + row-gap: 20px; +} + +.gap-6 { + gap: 24px; +} + +.gap-x-6 { + column-gap: 24px; +} + +.gap-y-6 { + row-gap: 24px; +} + +.gap-7 { + gap: 28px; +} + +.gap-x-7 { + column-gap: 28px; +} + +.gap-y-7 { + row-gap: 28px; +} + +.gap-8 { + gap: 32px; +} + +.gap-x-8 { + column-gap: 32px; +} + +.gap-y-8 { + row-gap: 32px; +} + +.gap-9 { + gap: 36px; +} + +.gap-x-9 { + column-gap: 36px; +} + +.gap-y-9 { + row-gap: 36px; +} + +.gap-10 { + gap: 40px; +} + +.gap-x-10 { + column-gap: 40px; +} + +.gap-y-10 { + row-gap: 40px; +} + +.gap-11 { + gap: 44px; +} + +.gap-x-11 { + column-gap: 44px; +} + +.gap-y-11 { + row-gap: 44px; +} + +.gap-12 { + gap: 48px; +} + +.gap-x-12 { + column-gap: 48px; +} + +.gap-y-12 { + row-gap: 48px; +} + +.gap-13 { + gap: 52px; +} + +.gap-x-13 { + column-gap: 52px; +} + +.gap-y-13 { + row-gap: 52px; +} + +.gap-14 { + gap: 56px; +} + +.gap-x-14 { + column-gap: 56px; +} + +.gap-y-14 { + row-gap: 56px; +} + +.gap-15 { + gap: 60px; +} + +.gap-x-15 { + column-gap: 60px; +} + +.gap-y-15 { + row-gap: 60px; +} + +.gap-16 { + gap: 64px; +} + +.gap-x-16 { + column-gap: 64px; +} + +.gap-y-16 { + row-gap: 64px; +} + +@media (min-width: 600px) { + .flex-sm-1 { + flex: 1 1 0% !important; + } + + .flex-sm-auto { + flex: 1 1 auto !important; + } + + .flex-sm-initial { + flex: 0 1 auto !important; + } + + .flex-sm-none { + flex: none !important; + } + + .flex-sm-row { + flex-direction: row !important; + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-sm-column { + flex-direction: column !important; + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-sm-wrap { + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-sm-start { + justify-content: flex-start !important; + } + + .justify-sm-end { + justify-content: flex-end !important; + } + + .justify-sm-center { + justify-content: center !important; + } + + .justify-sm-space-between { + justify-content: space-between !important; + } + + .justify-sm-space-around { + justify-content: space-around !important; + } + + .justify-sm-space-evenly { + justify-content: space-evenly !important; + } + + .order-sm-first { + order: -9999 !important; + } + + .order-sm-last { + order: 9999 !important; + } + + .order-sm-0 { + order: 0 !important; + } + + .order-sm-1 { + order: 1 !important; + } + + .order-sm-2 { + order: 2 !important; + } + + .order-sm-3 { + order: 3 !important; + } + + .order-sm-4 { + order: 4 !important; + } + + .order-sm-5 { + order: 5 !important; + } + + .order-sm-6 { + order: 6 !important; + } + + .order-sm-7 { + order: 7 !important; + } + + .order-sm-8 { + order: 8 !important; + } + + .order-sm-9 { + order: 9 !important; + } + + .order-sm-10 { + order: 10 !important; + } + + .order-sm-11 { + order: 11 !important; + } + + .order-sm-12 { + order: 12 !important; + } + + .align-content-sm-start { + align-content: flex-start !important; + } + + .align-content-sm-end { + align-content: flex-end !important; + } + + .align-content-sm-center { + align-content: center !important; + } + + .align-content-sm-space-between { + align-content: space-between !important; + } + + .align-content-sm-space-around { + align-content: space-around !important; + } + + .align-content-sm-stretch { + align-content: stretch !important; + } + + .align-sm-start { + align-items: flex-start !important; + } + + .align-sm-end { + align-items: flex-end !important; + } + + .align-sm-center { + align-items: center !important; + } + + .align-sm-baseline { + align-items: baseline !important; + } + + .align-sm-stretch { + align-items: stretch !important; + } + + .align-self-sm-auto { + align-self: auto !important; + } + + .align-self-sm-start { + align-self: flex-start !important; + } + + .align-self-sm-end { + align-self: flex-end !important; + } + + .align-self-sm-center { + align-self: center !important; + } + + .align-self-sm-stretch { + align-self: stretch !important; + } + + .gap-sm-0 { + gap: 0px; + } + + .gap-x-sm-0 { + column-gap: 0px; + } + + .gap-y-sm-0 { + row-gap: 0px; + } + + .gap-sm-1 { + gap: 4px; + } + + .gap-x-sm-1 { + column-gap: 4px; + } + + .gap-y-sm-1 { + row-gap: 4px; + } + + .gap-sm-2 { + gap: 8px; + } + + .gap-x-sm-2 { + column-gap: 8px; + } + + .gap-y-sm-2 { + row-gap: 8px; + } + + .gap-sm-3 { + gap: 12px; + } + + .gap-x-sm-3 { + column-gap: 12px; + } + + .gap-y-sm-3 { + row-gap: 12px; + } + + .gap-sm-4 { + gap: 16px; + } + + .gap-x-sm-4 { + column-gap: 16px; + } + + .gap-y-sm-4 { + row-gap: 16px; + } + + .gap-sm-5 { + gap: 20px; + } + + .gap-x-sm-5 { + column-gap: 20px; + } + + .gap-y-sm-5 { + row-gap: 20px; + } + + .gap-sm-6 { + gap: 24px; + } + + .gap-x-sm-6 { + column-gap: 24px; + } + + .gap-y-sm-6 { + row-gap: 24px; + } + + .gap-sm-7 { + gap: 28px; + } + + .gap-x-sm-7 { + column-gap: 28px; + } + + .gap-y-sm-7 { + row-gap: 28px; + } + + .gap-sm-8 { + gap: 32px; + } + + .gap-x-sm-8 { + column-gap: 32px; + } + + .gap-y-sm-8 { + row-gap: 32px; + } + + .gap-sm-9 { + gap: 36px; + } + + .gap-x-sm-9 { + column-gap: 36px; + } + + .gap-y-sm-9 { + row-gap: 36px; + } + + .gap-sm-10 { + gap: 40px; + } + + .gap-x-sm-10 { + column-gap: 40px; + } + + .gap-y-sm-10 { + row-gap: 40px; + } + + .gap-sm-11 { + gap: 44px; + } + + .gap-x-sm-11 { + column-gap: 44px; + } + + .gap-y-sm-11 { + row-gap: 44px; + } + + .gap-sm-12 { + gap: 48px; + } + + .gap-x-sm-12 { + column-gap: 48px; + } + + .gap-y-sm-12 { + row-gap: 48px; + } + + .gap-sm-13 { + gap: 52px; + } + + .gap-x-sm-13 { + column-gap: 52px; + } + + .gap-y-sm-13 { + row-gap: 52px; + } + + .gap-sm-14 { + gap: 56px; + } + + .gap-x-sm-14 { + column-gap: 56px; + } + + .gap-y-sm-14 { + row-gap: 56px; + } + + .gap-sm-15 { + gap: 60px; + } + + .gap-x-sm-15 { + column-gap: 60px; + } + + .gap-y-sm-15 { + row-gap: 60px; + } + + .gap-sm-16 { + gap: 64px; + } + + .gap-x-sm-16 { + column-gap: 64px; + } + + .gap-y-sm-16 { + row-gap: 64px; + } +} +@media (min-width: 960px) { + .flex-md-1 { + flex: 1 1 0% !important; + } + + .flex-md-auto { + flex: 1 1 auto !important; + } + + .flex-md-initial { + flex: 0 1 auto !important; + } + + .flex-md-none { + flex: none !important; + } + + .flex-md-row { + flex-direction: row !important; + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-md-column { + flex-direction: column !important; + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-md-grow-0 { + flex-grow: 0 !important; + } + + .flex-md-grow-1 { + flex-grow: 1 !important; + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-md-wrap { + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-md-start { + justify-content: flex-start !important; + } + + .justify-md-end { + justify-content: flex-end !important; + } + + .justify-md-center { + justify-content: center !important; + } + + .justify-md-space-between { + justify-content: space-between !important; + } + + .justify-md-space-around { + justify-content: space-around !important; + } + + .justify-md-space-evenly { + justify-content: space-evenly !important; + } + + .order-md-first { + order: -9999 !important; + } + + .order-md-last { + order: 9999 !important; + } + + .order-md-0 { + order: 0 !important; + } + + .order-md-1 { + order: 1 !important; + } + + .order-md-2 { + order: 2 !important; + } + + .order-md-3 { + order: 3 !important; + } + + .order-md-4 { + order: 4 !important; + } + + .order-md-5 { + order: 5 !important; + } + + .order-md-6 { + order: 6 !important; + } + + .order-md-7 { + order: 7 !important; + } + + .order-md-8 { + order: 8 !important; + } + + .order-md-9 { + order: 9 !important; + } + + .order-md-10 { + order: 10 !important; + } + + .order-md-11 { + order: 11 !important; + } + + .order-md-12 { + order: 12 !important; + } + + .align-content-md-start { + align-content: flex-start !important; + } + + .align-content-md-end { + align-content: flex-end !important; + } + + .align-content-md-center { + align-content: center !important; + } + + .align-content-md-space-between { + align-content: space-between !important; + } + + .align-content-md-space-around { + align-content: space-around !important; + } + + .align-content-md-stretch { + align-content: stretch !important; + } + + .align-md-start { + align-items: flex-start !important; + } + + .align-md-end { + align-items: flex-end !important; + } + + .align-md-center { + align-items: center !important; + } + + .align-md-baseline { + align-items: baseline !important; + } + + .align-md-stretch { + align-items: stretch !important; + } + + .align-self-md-auto { + align-self: auto !important; + } + + .align-self-md-start { + align-self: flex-start !important; + } + + .align-self-md-end { + align-self: flex-end !important; + } + + .align-self-md-center { + align-self: center !important; + } + + .align-self-md-stretch { + align-self: stretch !important; + } + + .gap-md-0 { + gap: 0px; + } + + .gap-x-md-0 { + column-gap: 0px; + } + + .gap-y-md-0 { + row-gap: 0px; + } + + .gap-md-1 { + gap: 4px; + } + + .gap-x-md-1 { + column-gap: 4px; + } + + .gap-y-md-1 { + row-gap: 4px; + } + + .gap-md-2 { + gap: 8px; + } + + .gap-x-md-2 { + column-gap: 8px; + } + + .gap-y-md-2 { + row-gap: 8px; + } + + .gap-md-3 { + gap: 12px; + } + + .gap-x-md-3 { + column-gap: 12px; + } + + .gap-y-md-3 { + row-gap: 12px; + } + + .gap-md-4 { + gap: 16px; + } + + .gap-x-md-4 { + column-gap: 16px; + } + + .gap-y-md-4 { + row-gap: 16px; + } + + .gap-md-5 { + gap: 20px; + } + + .gap-x-md-5 { + column-gap: 20px; + } + + .gap-y-md-5 { + row-gap: 20px; + } + + .gap-md-6 { + gap: 24px; + } + + .gap-x-md-6 { + column-gap: 24px; + } + + .gap-y-md-6 { + row-gap: 24px; + } + + .gap-md-7 { + gap: 28px; + } + + .gap-x-md-7 { + column-gap: 28px; + } + + .gap-y-md-7 { + row-gap: 28px; + } + + .gap-md-8 { + gap: 32px; + } + + .gap-x-md-8 { + column-gap: 32px; + } + + .gap-y-md-8 { + row-gap: 32px; + } + + .gap-md-9 { + gap: 36px; + } + + .gap-x-md-9 { + column-gap: 36px; + } + + .gap-y-md-9 { + row-gap: 36px; + } + + .gap-md-10 { + gap: 40px; + } + + .gap-x-md-10 { + column-gap: 40px; + } + + .gap-y-md-10 { + row-gap: 40px; + } + + .gap-md-11 { + gap: 44px; + } + + .gap-x-md-11 { + column-gap: 44px; + } + + .gap-y-md-11 { + row-gap: 44px; + } + + .gap-md-12 { + gap: 48px; + } + + .gap-x-md-12 { + column-gap: 48px; + } + + .gap-y-md-12 { + row-gap: 48px; + } + + .gap-md-13 { + gap: 52px; + } + + .gap-x-md-13 { + column-gap: 52px; + } + + .gap-y-md-13 { + row-gap: 52px; + } + + .gap-md-14 { + gap: 56px; + } + + .gap-x-md-14 { + column-gap: 56px; + } + + .gap-y-md-14 { + row-gap: 56px; + } + + .gap-md-15 { + gap: 60px; + } + + .gap-x-md-15 { + column-gap: 60px; + } + + .gap-y-md-15 { + row-gap: 60px; + } + + .gap-md-16 { + gap: 64px; + } + + .gap-x-md-16 { + column-gap: 64px; + } + + .gap-y-md-16 { + row-gap: 64px; + } +} +@media (min-width: 1280px) { + .flex-lg-1 { + flex: 1 1 0% !important; + } + + .flex-lg-auto { + flex: 1 1 auto !important; + } + + .flex-lg-initial { + flex: 0 1 auto !important; + } + + .flex-lg-none { + flex: none !important; + } + + .flex-lg-row { + flex-direction: row !important; + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-lg-column { + flex-direction: column !important; + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-lg-wrap { + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-lg-start { + justify-content: flex-start !important; + } + + .justify-lg-end { + justify-content: flex-end !important; + } + + .justify-lg-center { + justify-content: center !important; + } + + .justify-lg-space-between { + justify-content: space-between !important; + } + + .justify-lg-space-around { + justify-content: space-around !important; + } + + .justify-lg-space-evenly { + justify-content: space-evenly !important; + } + + .order-lg-first { + order: -9999 !important; + } + + .order-lg-last { + order: 9999 !important; + } + + .order-lg-0 { + order: 0 !important; + } + + .order-lg-1 { + order: 1 !important; + } + + .order-lg-2 { + order: 2 !important; + } + + .order-lg-3 { + order: 3 !important; + } + + .order-lg-4 { + order: 4 !important; + } + + .order-lg-5 { + order: 5 !important; + } + + .order-lg-6 { + order: 6 !important; + } + + .order-lg-7 { + order: 7 !important; + } + + .order-lg-8 { + order: 8 !important; + } + + .order-lg-9 { + order: 9 !important; + } + + .order-lg-10 { + order: 10 !important; + } + + .order-lg-11 { + order: 11 !important; + } + + .order-lg-12 { + order: 12 !important; + } + + .align-content-lg-start { + align-content: flex-start !important; + } + + .align-content-lg-end { + align-content: flex-end !important; + } + + .align-content-lg-center { + align-content: center !important; + } + + .align-content-lg-space-between { + align-content: space-between !important; + } + + .align-content-lg-space-around { + align-content: space-around !important; + } + + .align-content-lg-stretch { + align-content: stretch !important; + } + + .align-lg-start { + align-items: flex-start !important; + } + + .align-lg-end { + align-items: flex-end !important; + } + + .align-lg-center { + align-items: center !important; + } + + .align-lg-baseline { + align-items: baseline !important; + } + + .align-lg-stretch { + align-items: stretch !important; + } + + .align-self-lg-auto { + align-self: auto !important; + } + + .align-self-lg-start { + align-self: flex-start !important; + } + + .align-self-lg-end { + align-self: flex-end !important; + } + + .align-self-lg-center { + align-self: center !important; + } + + .align-self-lg-stretch { + align-self: stretch !important; + } + + .gap-lg-0 { + gap: 0px; + } + + .gap-x-lg-0 { + column-gap: 0px; + } + + .gap-y-lg-0 { + row-gap: 0px; + } + + .gap-lg-1 { + gap: 4px; + } + + .gap-x-lg-1 { + column-gap: 4px; + } + + .gap-y-lg-1 { + row-gap: 4px; + } + + .gap-lg-2 { + gap: 8px; + } + + .gap-x-lg-2 { + column-gap: 8px; + } + + .gap-y-lg-2 { + row-gap: 8px; + } + + .gap-lg-3 { + gap: 12px; + } + + .gap-x-lg-3 { + column-gap: 12px; + } + + .gap-y-lg-3 { + row-gap: 12px; + } + + .gap-lg-4 { + gap: 16px; + } + + .gap-x-lg-4 { + column-gap: 16px; + } + + .gap-y-lg-4 { + row-gap: 16px; + } + + .gap-lg-5 { + gap: 20px; + } + + .gap-x-lg-5 { + column-gap: 20px; + } + + .gap-y-lg-5 { + row-gap: 20px; + } + + .gap-lg-6 { + gap: 24px; + } + + .gap-x-lg-6 { + column-gap: 24px; + } + + .gap-y-lg-6 { + row-gap: 24px; + } + + .gap-lg-7 { + gap: 28px; + } + + .gap-x-lg-7 { + column-gap: 28px; + } + + .gap-y-lg-7 { + row-gap: 28px; + } + + .gap-lg-8 { + gap: 32px; + } + + .gap-x-lg-8 { + column-gap: 32px; + } + + .gap-y-lg-8 { + row-gap: 32px; + } + + .gap-lg-9 { + gap: 36px; + } + + .gap-x-lg-9 { + column-gap: 36px; + } + + .gap-y-lg-9 { + row-gap: 36px; + } + + .gap-lg-10 { + gap: 40px; + } + + .gap-x-lg-10 { + column-gap: 40px; + } + + .gap-y-lg-10 { + row-gap: 40px; + } + + .gap-lg-11 { + gap: 44px; + } + + .gap-x-lg-11 { + column-gap: 44px; + } + + .gap-y-lg-11 { + row-gap: 44px; + } + + .gap-lg-12 { + gap: 48px; + } + + .gap-x-lg-12 { + column-gap: 48px; + } + + .gap-y-lg-12 { + row-gap: 48px; + } + + .gap-lg-13 { + gap: 52px; + } + + .gap-x-lg-13 { + column-gap: 52px; + } + + .gap-y-lg-13 { + row-gap: 52px; + } + + .gap-lg-14 { + gap: 56px; + } + + .gap-x-lg-14 { + column-gap: 56px; + } + + .gap-y-lg-14 { + row-gap: 56px; + } + + .gap-lg-15 { + gap: 60px; + } + + .gap-x-lg-15 { + column-gap: 60px; + } + + .gap-y-lg-15 { + row-gap: 60px; + } + + .gap-lg-16 { + gap: 64px; + } + + .gap-x-lg-16 { + column-gap: 64px; + } + + .gap-y-lg-16 { + row-gap: 64px; + } +} +@media (min-width: 1920px) { + .flex-xl-1 { + flex: 1 1 0% !important; + } + + .flex-xl-auto { + flex: 1 1 auto !important; + } + + .flex-xl-initial { + flex: 0 1 auto !important; + } + + .flex-xl-none { + flex: none !important; + } + + .flex-xl-row { + flex-direction: row !important; + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xl-column { + flex-direction: column !important; + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xl-wrap { + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-xl-start { + justify-content: flex-start !important; + } + + .justify-xl-end { + justify-content: flex-end !important; + } + + .justify-xl-center { + justify-content: center !important; + } + + .justify-xl-space-between { + justify-content: space-between !important; + } + + .justify-xl-space-around { + justify-content: space-around !important; + } + + .justify-xl-space-evenly { + justify-content: space-evenly !important; + } + + .order-xl-first { + order: -9999 !important; + } + + .order-xl-last { + order: 9999 !important; + } + + .order-xl-0 { + order: 0 !important; + } + + .order-xl-1 { + order: 1 !important; + } + + .order-xl-2 { + order: 2 !important; + } + + .order-xl-3 { + order: 3 !important; + } + + .order-xl-4 { + order: 4 !important; + } + + .order-xl-5 { + order: 5 !important; + } + + .order-xl-6 { + order: 6 !important; + } + + .order-xl-7 { + order: 7 !important; + } + + .order-xl-8 { + order: 8 !important; + } + + .order-xl-9 { + order: 9 !important; + } + + .order-xl-10 { + order: 10 !important; + } + + .order-xl-11 { + order: 11 !important; + } + + .order-xl-12 { + order: 12 !important; + } + + .align-content-xl-start { + align-content: flex-start !important; + } + + .align-content-xl-end { + align-content: flex-end !important; + } + + .align-content-xl-center { + align-content: center !important; + } + + .align-content-xl-space-between { + align-content: space-between !important; + } + + .align-content-xl-space-around { + align-content: space-around !important; + } + + .align-content-xl-stretch { + align-content: stretch !important; + } + + .align-xl-start { + align-items: flex-start !important; + } + + .align-xl-end { + align-items: flex-end !important; + } + + .align-xl-center { + align-items: center !important; + } + + .align-xl-baseline { + align-items: baseline !important; + } + + .align-xl-stretch { + align-items: stretch !important; + } + + .align-self-xl-auto { + align-self: auto !important; + } + + .align-self-xl-start { + align-self: flex-start !important; + } + + .align-self-xl-end { + align-self: flex-end !important; + } + + .align-self-xl-center { + align-self: center !important; + } + + .align-self-xl-stretch { + align-self: stretch !important; + } + + .gap-xl-0 { + gap: 0px; + } + + .gap-x-xl-0 { + column-gap: 0px; + } + + .gap-y-xl-0 { + row-gap: 0px; + } + + .gap-xl-1 { + gap: 4px; + } + + .gap-x-xl-1 { + column-gap: 4px; + } + + .gap-y-xl-1 { + row-gap: 4px; + } + + .gap-xl-2 { + gap: 8px; + } + + .gap-x-xl-2 { + column-gap: 8px; + } + + .gap-y-xl-2 { + row-gap: 8px; + } + + .gap-xl-3 { + gap: 12px; + } + + .gap-x-xl-3 { + column-gap: 12px; + } + + .gap-y-xl-3 { + row-gap: 12px; + } + + .gap-xl-4 { + gap: 16px; + } + + .gap-x-xl-4 { + column-gap: 16px; + } + + .gap-y-xl-4 { + row-gap: 16px; + } + + .gap-xl-5 { + gap: 20px; + } + + .gap-x-xl-5 { + column-gap: 20px; + } + + .gap-y-xl-5 { + row-gap: 20px; + } + + .gap-xl-6 { + gap: 24px; + } + + .gap-x-xl-6 { + column-gap: 24px; + } + + .gap-y-xl-6 { + row-gap: 24px; + } + + .gap-xl-7 { + gap: 28px; + } + + .gap-x-xl-7 { + column-gap: 28px; + } + + .gap-y-xl-7 { + row-gap: 28px; + } + + .gap-xl-8 { + gap: 32px; + } + + .gap-x-xl-8 { + column-gap: 32px; + } + + .gap-y-xl-8 { + row-gap: 32px; + } + + .gap-xl-9 { + gap: 36px; + } + + .gap-x-xl-9 { + column-gap: 36px; + } + + .gap-y-xl-9 { + row-gap: 36px; + } + + .gap-xl-10 { + gap: 40px; + } + + .gap-x-xl-10 { + column-gap: 40px; + } + + .gap-y-xl-10 { + row-gap: 40px; + } + + .gap-xl-11 { + gap: 44px; + } + + .gap-x-xl-11 { + column-gap: 44px; + } + + .gap-y-xl-11 { + row-gap: 44px; + } + + .gap-xl-12 { + gap: 48px; + } + + .gap-x-xl-12 { + column-gap: 48px; + } + + .gap-y-xl-12 { + row-gap: 48px; + } + + .gap-xl-13 { + gap: 52px; + } + + .gap-x-xl-13 { + column-gap: 52px; + } + + .gap-y-xl-13 { + row-gap: 52px; + } + + .gap-xl-14 { + gap: 56px; + } + + .gap-x-xl-14 { + column-gap: 56px; + } + + .gap-y-xl-14 { + row-gap: 56px; + } + + .gap-xl-15 { + gap: 60px; + } + + .gap-x-xl-15 { + column-gap: 60px; + } + + .gap-y-xl-15 { + row-gap: 60px; + } + + .gap-xl-16 { + gap: 64px; + } + + .gap-x-xl-16 { + column-gap: 64px; + } + + .gap-y-xl-16 { + row-gap: 64px; + } +} +@media (min-width: 2560px) { + .flex-xxl-1 { + flex: 1 1 0% !important; + } + + .flex-xxl-auto { + flex: 1 1 auto !important; + } + + .flex-xxl-initial { + flex: 0 1 auto !important; + } + + .flex-xxl-none { + flex: none !important; + } + + .flex-xxl-row { + flex-direction: row !important; + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xxl-column { + flex-direction: column !important; + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .justify-xxl-start { + justify-content: flex-start !important; + } + + .justify-xxl-end { + justify-content: flex-end !important; + } + + .justify-xxl-center { + justify-content: center !important; + } + + .justify-xxl-space-between { + justify-content: space-between !important; + } + + .justify-xxl-space-around { + justify-content: space-around !important; + } + + .justify-xxl-space-evenly { + justify-content: space-evenly !important; + } + + .order-xxl-first { + order: -9999 !important; + } + + .order-xxl-last { + order: 9999 !important; + } + + .order-xxl-0 { + order: 0 !important; + } + + .order-xxl-1 { + order: 1 !important; + } + + .order-xxl-2 { + order: 2 !important; + } + + .order-xxl-3 { + order: 3 !important; + } + + .order-xxl-4 { + order: 4 !important; + } + + .order-xxl-5 { + order: 5 !important; + } + + .order-xxl-6 { + order: 6 !important; + } + + .order-xxl-7 { + order: 7 !important; + } + + .order-xxl-8 { + order: 8 !important; + } + + .order-xxl-9 { + order: 9 !important; + } + + .order-xxl-10 { + order: 10 !important; + } + + .order-xxl-11 { + order: 11 !important; + } + + .order-xxl-12 { + order: 12 !important; + } + + .align-content-xxl-start { + align-content: flex-start !important; + } + + .align-content-xxl-end { + align-content: flex-end !important; + } + + .align-content-xxl-center { + align-content: center !important; + } + + .align-content-xxl-space-between { + align-content: space-between !important; + } + + .align-content-xxl-space-around { + align-content: space-around !important; + } + + .align-content-xxl-stretch { + align-content: stretch !important; + } + + .align-xxl-start { + align-items: flex-start !important; + } + + .align-xxl-end { + align-items: flex-end !important; + } + + .align-xxl-center { + align-items: center !important; + } + + .align-xxl-baseline { + align-items: baseline !important; + } + + .align-xxl-stretch { + align-items: stretch !important; + } + + .align-self-xxl-auto { + align-self: auto !important; + } + + .align-self-xxl-start { + align-self: flex-start !important; + } + + .align-self-xxl-end { + align-self: flex-end !important; + } + + .align-self-xxl-center { + align-self: center !important; + } + + .align-self-xxl-stretch { + align-self: stretch !important; + } + + .gap-xxl-0 { + gap: 0px; + } + + .gap-x-xxl-0 { + column-gap: 0px; + } + + .gap-y-xxl-0 { + row-gap: 0px; + } + + .gap-xxl-1 { + gap: 4px; + } + + .gap-x-xxl-1 { + column-gap: 4px; + } + + .gap-y-xxl-1 { + row-gap: 4px; + } + + .gap-xxl-2 { + gap: 8px; + } + + .gap-x-xxl-2 { + column-gap: 8px; + } + + .gap-y-xxl-2 { + row-gap: 8px; + } + + .gap-xxl-3 { + gap: 12px; + } + + .gap-x-xxl-3 { + column-gap: 12px; + } + + .gap-y-xxl-3 { + row-gap: 12px; + } + + .gap-xxl-4 { + gap: 16px; + } + + .gap-x-xxl-4 { + column-gap: 16px; + } + + .gap-y-xxl-4 { + row-gap: 16px; + } + + .gap-xxl-5 { + gap: 20px; + } + + .gap-x-xxl-5 { + column-gap: 20px; + } + + .gap-y-xxl-5 { + row-gap: 20px; + } + + .gap-xxl-6 { + gap: 24px; + } + + .gap-x-xxl-6 { + column-gap: 24px; + } + + .gap-y-xxl-6 { + row-gap: 24px; + } + + .gap-xxl-7 { + gap: 28px; + } + + .gap-x-xxl-7 { + column-gap: 28px; + } + + .gap-y-xxl-7 { + row-gap: 28px; + } + + .gap-xxl-8 { + gap: 32px; + } + + .gap-x-xxl-8 { + column-gap: 32px; + } + + .gap-y-xxl-8 { + row-gap: 32px; + } + + .gap-xxl-9 { + gap: 36px; + } + + .gap-x-xxl-9 { + column-gap: 36px; + } + + .gap-y-xxl-9 { + row-gap: 36px; + } + + .gap-xxl-10 { + gap: 40px; + } + + .gap-x-xxl-10 { + column-gap: 40px; + } + + .gap-y-xxl-10 { + row-gap: 40px; + } + + .gap-xxl-11 { + gap: 44px; + } + + .gap-x-xxl-11 { + column-gap: 44px; + } + + .gap-y-xxl-11 { + row-gap: 44px; + } + + .gap-xxl-12 { + gap: 48px; + } + + .gap-x-xxl-12 { + column-gap: 48px; + } + + .gap-y-xxl-12 { + row-gap: 48px; + } + + .gap-xxl-13 { + gap: 52px; + } + + .gap-x-xxl-13 { + column-gap: 52px; + } + + .gap-y-xxl-13 { + row-gap: 52px; + } + + .gap-xxl-14 { + gap: 56px; + } + + .gap-x-xxl-14 { + column-gap: 56px; + } + + .gap-y-xxl-14 { + row-gap: 56px; + } + + .gap-xxl-15 { + gap: 60px; + } + + .gap-x-xxl-15 { + column-gap: 60px; + } + + .gap-y-xxl-15 { + row-gap: 60px; + } + + .gap-xxl-16 { + gap: 64px; + } + + .gap-x-xxl-16 { + column-gap: 64px; + } + + .gap-y-xxl-16 { + row-gap: 64px; + } +} +.cursor-auto { + cursor: auto !important; +} + +.cursor-default { + cursor: default !important; +} + +.cursor-pointer { + cursor: pointer !important; +} + +.cursor-wait { + cursor: wait !important; +} + +.cursor-text { + cursor: text !important; +} + +.cursor-move { + cursor: move !important; +} + +.cursor-help { + cursor: help !important; +} + +.cursor-not-allowed { + cursor: not-allowed !important; +} + +.cursor-none { + cursor: none !important; +} + +.cursor-progress { + cursor: progress !important; +} + +.cursor-cell { + cursor: cell !important; +} + +.cursor-crosshair { + cursor: crosshair !important; +} + +.cursor-vertical-text { + cursor: vertical-text !important; +} + +.cursor-alias { + cursor: alias !important; +} + +.cursor-copy { + cursor: copy !important; +} + +.cursor-no-drop { + cursor: no-drop !important; +} + +.cursor-grab { + cursor: grab !important; +} + +.cursor-grabbing { + cursor: grabbing !important; +} + +.cursor-all-scroll { + cursor: all-scroll !important; +} + +.cursor-col-resize { + cursor: col-resize !important; +} + +.cursor-row-resize { + cursor: row-resize !important; +} + +.cursor-n-resize { + cursor: n-resize !important; +} + +.cursor-w-resize { + cursor: w-resize !important; +} + +.cursor-zoom-in { + cursor: zoom-in !important; +} + +.cursor-zoom-out { + cursor: zoom-out !important; +} + +.cursor-url { + cursor: url !important; +} + +.pointer-events-none { + pointer-events: none; +} + +.pointer-events-auto { + pointer-events: auto; +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +@media (min-width: 600px) { + .d-sm-none { + display: none !important; + } + + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: flex !important; + } + + .d-sm-inline-flex { + display: inline-flex !important; + } +} +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } + + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: flex !important; + } + + .d-md-inline-flex { + display: inline-flex !important; + } +} +@media (min-width: 1280px) { + .d-lg-none { + display: none !important; + } + + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: flex !important; + } + + .d-lg-inline-flex { + display: inline-flex !important; + } +} +@media (min-width: 1920px) { + .d-xl-none { + display: none !important; + } + + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: flex !important; + } + + .d-xl-inline-flex { + display: inline-flex !important; + } +} +@media (min-width: 2560px) { + .d-xxl-none { + display: none !important; + } + + .d-xxl-inline { + display: inline !important; + } + + .d-xxl-inline-block { + display: inline-block !important; + } + + .d-xxl-block { + display: block !important; + } + + .d-xxl-table { + display: table !important; + } + + .d-xxl-table-row { + display: table-row !important; + } + + .d-xxl-table-cell { + display: table-cell !important; + } + + .d-xxl-flex { + display: flex !important; + } + + .d-xxl-inline-flex { + display: inline-flex !important; + } +} +.object-none { + object-fit: none; +} + +.object-cover { + object-fit: cover; +} + +.object-contain { + object-fit: contain; +} + +.object-fill { + object-fit: fill; +} + +.object-scale-down { + object-fit: scale-down; +} + +.object-center { + object-position: center; +} + +.object-top { + object-position: top; +} + +.object-bottom { + object-position: bottom; +} + +.object-left { + object-position: left; +} + +.object-left-top { + object-position: left top; +} + +.object-left-bottom { + object-position: left bottom; +} + +.object-right { + object-position: right; +} + +.object-right-top { + object-position: right top; +} + +.object-right-bottom { + object-position: right bottom; +} + +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-visible { + overflow: visible; +} + +.overflow-scroll { + overflow: scroll; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-x-hidden { + overflow-x: hidden; +} + +.overflow-y-hidden { + overflow-y: hidden; +} + +.overflow-x-visible { + overflow-x: visible; +} + +.overflow-y-visible { + overflow-y: visible; +} + +.overflow-x-scroll { + overflow-x: scroll; +} + +.overflow-y-scroll { + overflow-y: scroll; +} + +.absolute { + position: absolute; +} + +.fixed { + position: fixed; +} + +.relative { + position: relative; +} + +.static { + position: static; +} + +.sticky { + position: sticky; +} + +.visible { + visibility: visible; +} + +.invisible { + visibility: hidden; +} + +.z-0 { + z-index: 0; +} + +.z-10 { + z-index: 10; +} + +.z-20 { + z-index: 20; +} + +.z-30 { + z-index: 30; +} + +.z-40 { + z-index: 40; +} + +.z-50 { + z-index: 50; +} + +.z-60 { + z-index: 60; +} + +.z-70 { + z-index: 70; +} + +.z-80 { + z-index: 80; +} + +.z-90 { + z-index: 90; +} + +.z-100 { + z-index: 100; +} + +.z-auto { + z-index: auto; +} + +.mt-0, +.my-0 { + margin-top: 0 !important; +} + +.mr-0, +.mx-0 { + margin-right: 0 !important; +} + +.ml-0, +.mx-0 { + margin-left: 0 !important; +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} + +.ms-0 { + margin-inline-start: 0 !important; +} + +.me-0 { + margin-inline-end: 0 !important; +} + +.ma-0 { + margin: 0 !important; +} + +.mt-1, +.my-1 { + margin-top: 4px !important; +} + +.mr-1, +.mx-1 { + margin-right: 4px !important; +} + +.ml-1, +.mx-1 { + margin-left: 4px !important; +} + +.mb-1, +.my-1 { + margin-bottom: 4px !important; +} + +.ms-1 { + margin-inline-start: 4px !important; +} + +.me-1 { + margin-inline-end: 4px !important; +} + +.ma-1 { + margin: 4px !important; +} + +.mt-2, +.my-2 { + margin-top: 8px !important; +} + +.mr-2, +.mx-2 { + margin-right: 8px !important; +} + +.ml-2, +.mx-2 { + margin-left: 8px !important; +} + +.mb-2, +.my-2 { + margin-bottom: 8px !important; +} + +.ms-2 { + margin-inline-start: 8px !important; +} + +.me-2 { + margin-inline-end: 8px !important; +} + +.ma-2 { + margin: 8px !important; +} + +.mt-3, +.my-3 { + margin-top: 12px !important; +} + +.mr-3, +.mx-3 { + margin-right: 12px !important; +} + +.ml-3, +.mx-3 { + margin-left: 12px !important; +} + +.mb-3, +.my-3 { + margin-bottom: 12px !important; +} + +.ms-3 { + margin-inline-start: 12px !important; +} + +.me-3 { + margin-inline-end: 12px !important; +} + +.ma-3 { + margin: 12px !important; +} + +.mt-4, +.my-4 { + margin-top: 16px !important; +} + +.mr-4, +.mx-4 { + margin-right: 16px !important; +} + +.ml-4, +.mx-4 { + margin-left: 16px !important; +} + +.mb-4, +.my-4 { + margin-bottom: 16px !important; +} + +.ms-4 { + margin-inline-start: 16px !important; +} + +.me-4 { + margin-inline-end: 16px !important; +} + +.ma-4 { + margin: 16px !important; +} + +.mt-5, +.my-5 { + margin-top: 20px !important; +} + +.mr-5, +.mx-5 { + margin-right: 20px !important; +} + +.ml-5, +.mx-5 { + margin-left: 20px !important; +} + +.mb-5, +.my-5 { + margin-bottom: 20px !important; +} + +.ms-5 { + margin-inline-start: 20px !important; +} + +.me-5 { + margin-inline-end: 20px !important; +} + +.ma-5 { + margin: 20px !important; +} + +.mt-6, +.my-6 { + margin-top: 24px !important; +} + +.mr-6, +.mx-6 { + margin-right: 24px !important; +} + +.ml-6, +.mx-6 { + margin-left: 24px !important; +} + +.mb-6, +.my-6 { + margin-bottom: 24px !important; +} + +.ms-6 { + margin-inline-start: 24px !important; +} + +.me-6 { + margin-inline-end: 24px !important; +} + +.ma-6 { + margin: 24px !important; +} + +.mt-7, +.my-7 { + margin-top: 28px !important; +} + +.mr-7, +.mx-7 { + margin-right: 28px !important; +} + +.ml-7, +.mx-7 { + margin-left: 28px !important; +} + +.mb-7, +.my-7 { + margin-bottom: 28px !important; +} + +.ms-7 { + margin-inline-start: 28px !important; +} + +.me-7 { + margin-inline-end: 28px !important; +} + +.ma-7 { + margin: 28px !important; +} + +.mt-8, +.my-8 { + margin-top: 32px !important; +} + +.mr-8, +.mx-8 { + margin-right: 32px !important; +} + +.ml-8, +.mx-8 { + margin-left: 32px !important; +} + +.mb-8, +.my-8 { + margin-bottom: 32px !important; +} + +.ms-8 { + margin-inline-start: 32px !important; +} + +.me-8 { + margin-inline-end: 32px !important; +} + +.ma-8 { + margin: 32px !important; +} + +.mt-9, +.my-9 { + margin-top: 36px !important; +} + +.mr-9, +.mx-9 { + margin-right: 36px !important; +} + +.ml-9, +.mx-9 { + margin-left: 36px !important; +} + +.mb-9, +.my-9 { + margin-bottom: 36px !important; +} + +.ms-9 { + margin-inline-start: 36px !important; +} + +.me-9 { + margin-inline-end: 36px !important; +} + +.ma-9 { + margin: 36px !important; +} + +.mt-10, +.my-10 { + margin-top: 40px !important; +} + +.mr-10, +.mx-10 { + margin-right: 40px !important; +} + +.ml-10, +.mx-10 { + margin-left: 40px !important; +} + +.mb-10, +.my-10 { + margin-bottom: 40px !important; +} + +.ms-10 { + margin-inline-start: 40px !important; +} + +.me-10 { + margin-inline-end: 40px !important; +} + +.ma-10 { + margin: 40px !important; +} + +.mt-11, +.my-11 { + margin-top: 44px !important; +} + +.mr-11, +.mx-11 { + margin-right: 44px !important; +} + +.ml-11, +.mx-11 { + margin-left: 44px !important; +} + +.mb-11, +.my-11 { + margin-bottom: 44px !important; +} + +.ms-11 { + margin-inline-start: 44px !important; +} + +.me-11 { + margin-inline-end: 44px !important; +} + +.ma-11 { + margin: 44px !important; +} + +.mt-12, +.my-12 { + margin-top: 48px !important; +} + +.mr-12, +.mx-12 { + margin-right: 48px !important; +} + +.ml-12, +.mx-12 { + margin-left: 48px !important; +} + +.mb-12, +.my-12 { + margin-bottom: 48px !important; +} + +.ms-12 { + margin-inline-start: 48px !important; +} + +.me-12 { + margin-inline-end: 48px !important; +} + +.ma-12 { + margin: 48px !important; +} + +.mt-13, +.my-13 { + margin-top: 52px !important; +} + +.mr-13, +.mx-13 { + margin-right: 52px !important; +} + +.ml-13, +.mx-13 { + margin-left: 52px !important; +} + +.mb-13, +.my-13 { + margin-bottom: 52px !important; +} + +.ms-13 { + margin-inline-start: 52px !important; +} + +.me-13 { + margin-inline-end: 52px !important; +} + +.ma-13 { + margin: 52px !important; +} + +.mt-14, +.my-14 { + margin-top: 56px !important; +} + +.mr-14, +.mx-14 { + margin-right: 56px !important; +} + +.ml-14, +.mx-14 { + margin-left: 56px !important; +} + +.mb-14, +.my-14 { + margin-bottom: 56px !important; +} + +.ms-14 { + margin-inline-start: 56px !important; +} + +.me-14 { + margin-inline-end: 56px !important; +} + +.ma-14 { + margin: 56px !important; +} + +.mt-15, +.my-15 { + margin-top: 60px !important; +} + +.mr-15, +.mx-15 { + margin-right: 60px !important; +} + +.ml-15, +.mx-15 { + margin-left: 60px !important; +} + +.mb-15, +.my-15 { + margin-bottom: 60px !important; +} + +.ms-15 { + margin-inline-start: 60px !important; +} + +.me-15 { + margin-inline-end: 60px !important; +} + +.ma-15 { + margin: 60px !important; +} + +.mt-16, +.my-16 { + margin-top: 64px !important; +} + +.mr-16, +.mx-16 { + margin-right: 64px !important; +} + +.ml-16, +.mx-16 { + margin-left: 64px !important; +} + +.mb-16, +.my-16 { + margin-bottom: 64px !important; +} + +.ms-16 { + margin-inline-start: 64px !important; +} + +.me-16 { + margin-inline-end: 64px !important; +} + +.ma-16 { + margin: 64px !important; +} + +.mt-auto, +.my-auto { + margin-top: auto !important; +} + +.mr-auto, +.mx-auto { + margin-right: auto !important; +} + +.ml-auto, +.mx-auto { + margin-left: auto !important; +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} + +.ms-auto { + margin-inline-start: auto !important; +} + +.me-auto { + margin-inline-end: auto !important; +} + +.ma-auto { + margin: auto !important; +} + +.pt-0, +.py-0 { + padding-top: 0 !important; +} + +.pr-0, +.px-0 { + padding-right: 0 !important; +} + +.pl-0, +.px-0 { + padding-left: 0 !important; +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} + +.ps-0 { + padding-inline-start: 0 !important; +} + +.pe-0 { + padding-inline-end: 0 !important; +} + +.pa-0 { + padding: 0 !important; +} + +.pt-1, +.py-1 { + padding-top: 4px !important; +} + +.pr-1, +.px-1 { + padding-right: 4px !important; +} + +.pl-1, +.px-1 { + padding-left: 4px !important; +} + +.pb-1, +.py-1 { + padding-bottom: 4px !important; +} + +.ps-1 { + padding-inline-start: 4px !important; +} + +.pe-1 { + padding-inline-end: 4px !important; +} + +.pa-1 { + padding: 4px !important; +} + +.pt-2, +.py-2 { + padding-top: 8px !important; +} + +.pr-2, +.px-2 { + padding-right: 8px !important; +} + +.pl-2, +.px-2 { + padding-left: 8px !important; +} + +.pb-2, +.py-2 { + padding-bottom: 8px !important; +} + +.ps-2 { + padding-inline-start: 8px !important; +} + +.pe-2 { + padding-inline-end: 8px !important; +} + +.pa-2 { + padding: 8px !important; +} + +.pt-3, +.py-3 { + padding-top: 12px !important; +} + +.pr-3, +.px-3 { + padding-right: 12px !important; +} + +.pl-3, +.px-3 { + padding-left: 12px !important; +} + +.pb-3, +.py-3 { + padding-bottom: 12px !important; +} + +.ps-3 { + padding-inline-start: 12px !important; +} + +.pe-3 { + padding-inline-end: 12px !important; +} + +.pa-3 { + padding: 12px !important; +} + +.pt-4, +.py-4 { + padding-top: 16px !important; +} + +.pr-4, +.px-4 { + padding-right: 16px !important; +} + +.pl-4, +.px-4 { + padding-left: 16px !important; +} + +.pb-4, +.py-4 { + padding-bottom: 16px !important; +} + +.ps-4 { + padding-inline-start: 16px !important; +} + +.pe-4 { + padding-inline-end: 16px !important; +} + +.pa-4 { + padding: 16px !important; +} + +.pt-5, +.py-5 { + padding-top: 20px !important; +} + +.pr-5, +.px-5 { + padding-right: 20px !important; +} + +.pl-5, +.px-5 { + padding-left: 20px !important; +} + +.pb-5, +.py-5 { + padding-bottom: 20px !important; +} + +.ps-5 { + padding-inline-start: 20px !important; +} + +.pe-5 { + padding-inline-end: 20px !important; +} + +.pa-5 { + padding: 20px !important; +} + +.pt-6, +.py-6 { + padding-top: 24px !important; +} + +.pr-6, +.px-6 { + padding-right: 24px !important; +} + +.pl-6, +.px-6 { + padding-left: 24px !important; +} + +.pb-6, +.py-6 { + padding-bottom: 24px !important; +} + +.ps-6 { + padding-inline-start: 24px !important; +} + +.pe-6 { + padding-inline-end: 24px !important; +} + +.pa-6 { + padding: 24px !important; +} + +.pt-7, +.py-7 { + padding-top: 28px !important; +} + +.pr-7, +.px-7 { + padding-right: 28px !important; +} + +.pl-7, +.px-7 { + padding-left: 28px !important; +} + +.pb-7, +.py-7 { + padding-bottom: 28px !important; +} + +.ps-7 { + padding-inline-start: 28px !important; +} + +.pe-7 { + padding-inline-end: 28px !important; +} + +.pa-7 { + padding: 28px !important; +} + +.pt-8, +.py-8 { + padding-top: 32px !important; +} + +.pr-8, +.px-8 { + padding-right: 32px !important; +} + +.pl-8, +.px-8 { + padding-left: 32px !important; +} + +.pb-8, +.py-8 { + padding-bottom: 32px !important; +} + +.ps-8 { + padding-inline-start: 32px !important; +} + +.pe-8 { + padding-inline-end: 32px !important; +} + +.pa-8 { + padding: 32px !important; +} + +.pt-9, +.py-9 { + padding-top: 36px !important; +} + +.pr-9, +.px-9 { + padding-right: 36px !important; +} + +.pl-9, +.px-9 { + padding-left: 36px !important; +} + +.pb-9, +.py-9 { + padding-bottom: 36px !important; +} + +.ps-9 { + padding-inline-start: 36px !important; +} + +.pe-9 { + padding-inline-end: 36px !important; +} + +.pa-9 { + padding: 36px !important; +} + +.pt-10, +.py-10 { + padding-top: 40px !important; +} + +.pr-10, +.px-10 { + padding-right: 40px !important; +} + +.pl-10, +.px-10 { + padding-left: 40px !important; +} + +.pb-10, +.py-10 { + padding-bottom: 40px !important; +} + +.ps-10 { + padding-inline-start: 40px !important; +} + +.pe-10 { + padding-inline-end: 40px !important; +} + +.pa-10 { + padding: 40px !important; +} + +.pt-11, +.py-11 { + padding-top: 44px !important; +} + +.pr-11, +.px-11 { + padding-right: 44px !important; +} + +.pl-11, +.px-11 { + padding-left: 44px !important; +} + +.pb-11, +.py-11 { + padding-bottom: 44px !important; +} + +.ps-11 { + padding-inline-start: 44px !important; +} + +.pe-11 { + padding-inline-end: 44px !important; +} + +.pa-11 { + padding: 44px !important; +} + +.pt-12, +.py-12 { + padding-top: 48px !important; +} + +.pr-12, +.px-12 { + padding-right: 48px !important; +} + +.pl-12, +.px-12 { + padding-left: 48px !important; +} + +.pb-12, +.py-12 { + padding-bottom: 48px !important; +} + +.ps-12 { + padding-inline-start: 48px !important; +} + +.pe-12 { + padding-inline-end: 48px !important; +} + +.pa-12 { + padding: 48px !important; +} + +.pt-13, +.py-13 { + padding-top: 52px !important; +} + +.pr-13, +.px-13 { + padding-right: 52px !important; +} + +.pl-13, +.px-13 { + padding-left: 52px !important; +} + +.pb-13, +.py-13 { + padding-bottom: 52px !important; +} + +.ps-13 { + padding-inline-start: 52px !important; +} + +.pe-13 { + padding-inline-end: 52px !important; +} + +.pa-13 { + padding: 52px !important; +} + +.pt-14, +.py-14 { + padding-top: 56px !important; +} + +.pr-14, +.px-14 { + padding-right: 56px !important; +} + +.pl-14, +.px-14 { + padding-left: 56px !important; +} + +.pb-14, +.py-14 { + padding-bottom: 56px !important; +} + +.ps-14 { + padding-inline-start: 56px !important; +} + +.pe-14 { + padding-inline-end: 56px !important; +} + +.pa-14 { + padding: 56px !important; +} + +.pt-15, +.py-15 { + padding-top: 60px !important; +} + +.pr-15, +.px-15 { + padding-right: 60px !important; +} + +.pl-15, +.px-15 { + padding-left: 60px !important; +} + +.pb-15, +.py-15 { + padding-bottom: 60px !important; +} + +.ps-15 { + padding-inline-start: 60px !important; +} + +.pe-15 { + padding-inline-end: 60px !important; +} + +.pa-15 { + padding: 60px !important; +} + +.pt-16, +.py-16 { + padding-top: 64px !important; +} + +.pr-16, +.px-16 { + padding-right: 64px !important; +} + +.pl-16, +.px-16 { + padding-left: 64px !important; +} + +.pb-16, +.py-16 { + padding-bottom: 64px !important; +} + +.ps-16 { + padding-inline-start: 64px !important; +} + +.pe-16 { + padding-inline-end: 64px !important; +} + +.pa-16 { + padding: 64px !important; +} + +.pt-auto, +.py-auto { + padding-top: auto !important; +} + +.pr-auto, +.px-auto { + padding-right: auto !important; +} + +.pl-auto, +.px-auto { + padding-left: auto !important; +} + +.pb-auto, +.py-auto { + padding-bottom: auto !important; +} + +.ps-auto { + padding-inline-start: auto !important; +} + +.pe-auto { + padding-inline-end: auto !important; +} + +.pa-auto { + padding: auto !important; +} + +.mt-n1, +.my-n1 { + margin-top: -4px !important; +} + +.mr-n1, +.mx-n1 { + margin-right: -4px !important; +} + +.ml-n1, +.mx-n1 { + margin-left: -4px !important; +} + +.mb-n1, +.my-n1 { + margin-bottom: -4px !important; +} + +.ms-n1 { + margin-inline-start: -4px !important; +} + +.me-n1 { + margin-inline-end: -4px !important; +} + +.ma-n1 { + margin: -4px !important; +} + +.mt-n2, +.my-n2 { + margin-top: -8px !important; +} + +.mr-n2, +.mx-n2 { + margin-right: -8px !important; +} + +.ml-n2, +.mx-n2 { + margin-left: -8px !important; +} + +.mb-n2, +.my-n2 { + margin-bottom: -8px !important; +} + +.ms-n2 { + margin-inline-start: -8px !important; +} + +.me-n2 { + margin-inline-end: -8px !important; +} + +.ma-n2 { + margin: -8px !important; +} + +.mt-n3, +.my-n3 { + margin-top: -12px !important; +} + +.mr-n3, +.mx-n3 { + margin-right: -12px !important; +} + +.ml-n3, +.mx-n3 { + margin-left: -12px !important; +} + +.mb-n3, +.my-n3 { + margin-bottom: -12px !important; +} + +.ms-n3 { + margin-inline-start: -12px !important; +} + +.me-n3 { + margin-inline-end: -12px !important; +} + +.ma-n3 { + margin: -12px !important; +} + +.mt-n4, +.my-n4 { + margin-top: -16px !important; +} + +.mr-n4, +.mx-n4 { + margin-right: -16px !important; +} + +.ml-n4, +.mx-n4 { + margin-left: -16px !important; +} + +.mb-n4, +.my-n4 { + margin-bottom: -16px !important; +} + +.ms-n4 { + margin-inline-start: -16px !important; +} + +.me-n4 { + margin-inline-end: -16px !important; +} + +.ma-n4 { + margin: -16px !important; +} + +.mt-n5, +.my-n5 { + margin-top: -20px !important; +} + +.mr-n5, +.mx-n5 { + margin-right: -20px !important; +} + +.ml-n5, +.mx-n5 { + margin-left: -20px !important; +} + +.mb-n5, +.my-n5 { + margin-bottom: -20px !important; +} + +.ms-n5 { + margin-inline-start: -20px !important; +} + +.me-n5 { + margin-inline-end: -20px !important; +} + +.ma-n5 { + margin: -20px !important; +} + +.mt-n6, +.my-n6 { + margin-top: -24px !important; +} + +.mr-n6, +.mx-n6 { + margin-right: -24px !important; +} + +.ml-n6, +.mx-n6 { + margin-left: -24px !important; +} + +.mb-n6, +.my-n6 { + margin-bottom: -24px !important; +} + +.ms-n6 { + margin-inline-start: -24px !important; +} + +.me-n6 { + margin-inline-end: -24px !important; +} + +.ma-n6 { + margin: -24px !important; +} + +.mt-n7, +.my-n7 { + margin-top: -28px !important; +} + +.mr-n7, +.mx-n7 { + margin-right: -28px !important; +} + +.ml-n7, +.mx-n7 { + margin-left: -28px !important; +} + +.mb-n7, +.my-n7 { + margin-bottom: -28px !important; +} + +.ms-n7 { + margin-inline-start: -28px !important; +} + +.me-n7 { + margin-inline-end: -28px !important; +} + +.ma-n7 { + margin: -28px !important; +} + +.mt-n8, +.my-n8 { + margin-top: -32px !important; +} + +.mr-n8, +.mx-n8 { + margin-right: -32px !important; +} + +.ml-n8, +.mx-n8 { + margin-left: -32px !important; +} + +.mb-n8, +.my-n8 { + margin-bottom: -32px !important; +} + +.ms-n8 { + margin-inline-start: -32px !important; +} + +.me-n8 { + margin-inline-end: -32px !important; +} + +.ma-n8 { + margin: -32px !important; +} + +.mt-n9, +.my-n9 { + margin-top: -36px !important; +} + +.mr-n9, +.mx-n9 { + margin-right: -36px !important; +} + +.ml-n9, +.mx-n9 { + margin-left: -36px !important; +} + +.mb-n9, +.my-n9 { + margin-bottom: -36px !important; +} + +.ms-n9 { + margin-inline-start: -36px !important; +} + +.me-n9 { + margin-inline-end: -36px !important; +} + +.ma-n9 { + margin: -36px !important; +} + +.mt-n10, +.my-n10 { + margin-top: -40px !important; +} + +.mr-n10, +.mx-n10 { + margin-right: -40px !important; +} + +.ml-n10, +.mx-n10 { + margin-left: -40px !important; +} + +.mb-n10, +.my-n10 { + margin-bottom: -40px !important; +} + +.ms-n10 { + margin-inline-start: -40px !important; +} + +.me-n10 { + margin-inline-end: -40px !important; +} + +.ma-n10 { + margin: -40px !important; +} + +.mt-n11, +.my-n11 { + margin-top: -44px !important; +} + +.mr-n11, +.mx-n11 { + margin-right: -44px !important; +} + +.ml-n11, +.mx-n11 { + margin-left: -44px !important; +} + +.mb-n11, +.my-n11 { + margin-bottom: -44px !important; +} + +.ms-n11 { + margin-inline-start: -44px !important; +} + +.me-n11 { + margin-inline-end: -44px !important; +} + +.ma-n11 { + margin: -44px !important; +} + +.mt-n12, +.my-n12 { + margin-top: -48px !important; +} + +.mr-n12, +.mx-n12 { + margin-right: -48px !important; +} + +.ml-n12, +.mx-n12 { + margin-left: -48px !important; +} + +.mb-n12, +.my-n12 { + margin-bottom: -48px !important; +} + +.ms-n12 { + margin-inline-start: -48px !important; +} + +.me-n12 { + margin-inline-end: -48px !important; +} + +.ma-n12 { + margin: -48px !important; +} + +.mt-n13, +.my-n13 { + margin-top: -52px !important; +} + +.mr-n13, +.mx-n13 { + margin-right: -52px !important; +} + +.ml-n13, +.mx-n13 { + margin-left: -52px !important; +} + +.mb-n13, +.my-n13 { + margin-bottom: -52px !important; +} + +.ms-n13 { + margin-inline-start: -52px !important; +} + +.me-n13 { + margin-inline-end: -52px !important; +} + +.ma-n13 { + margin: -52px !important; +} + +.mt-n14, +.my-n14 { + margin-top: -56px !important; +} + +.mr-n14, +.mx-n14 { + margin-right: -56px !important; +} + +.ml-n14, +.mx-n14 { + margin-left: -56px !important; +} + +.mb-n14, +.my-n14 { + margin-bottom: -56px !important; +} + +.ms-n14 { + margin-inline-start: -56px !important; +} + +.me-n14 { + margin-inline-end: -56px !important; +} + +.ma-n14 { + margin: -56px !important; +} + +.mt-n15, +.my-n15 { + margin-top: -60px !important; +} + +.mr-n15, +.mx-n15 { + margin-right: -60px !important; +} + +.ml-n15, +.mx-n15 { + margin-left: -60px !important; +} + +.mb-n15, +.my-n15 { + margin-bottom: -60px !important; +} + +.ms-n15 { + margin-inline-start: -60px !important; +} + +.me-n15 { + margin-inline-end: -60px !important; +} + +.ma-n15 { + margin: -60px !important; +} + +.mt-n16, +.my-n16 { + margin-top: -64px !important; +} + +.mr-n16, +.mx-n16 { + margin-right: -64px !important; +} + +.ml-n16, +.mx-n16 { + margin-left: -64px !important; +} + +.mb-n16, +.my-n16 { + margin-bottom: -64px !important; +} + +.ms-n16 { + margin-inline-start: -64px !important; +} + +.me-n16 { + margin-inline-end: -64px !important; +} + +.ma-n16 { + margin: -64px !important; +} + +@media screen and (min-width: 600px) { + .mt-sm-0, +.my-sm-0 { + margin-top: 0 !important; + } + + .mr-sm-0, +.mx-sm-0 { + margin-right: 0 !important; + } + + .ml-sm-0, +.mx-sm-0 { + margin-left: 0 !important; + } + + .mb-sm-0, +.my-sm-0 { + margin-bottom: 0 !important; + } + + .ms-sm-0 { + margin-inline-start: 0 !important; + } + + .me-sm-0 { + margin-inline-end: 0 !important; + } + + .ma-sm-0 { + margin: 0 !important; + } + + .mt-sm-1, +.my-sm-1 { + margin-top: 4px !important; + } + + .mr-sm-1, +.mx-sm-1 { + margin-right: 4px !important; + } + + .ml-sm-1, +.mx-sm-1 { + margin-left: 4px !important; + } + + .mb-sm-1, +.my-sm-1 { + margin-bottom: 4px !important; + } + + .ms-sm-1 { + margin-inline-start: 4px !important; + } + + .me-sm-1 { + margin-inline-end: 4px !important; + } + + .ma-sm-1 { + margin: 4px !important; + } + + .mt-sm-2, +.my-sm-2 { + margin-top: 8px !important; + } + + .mr-sm-2, +.mx-sm-2 { + margin-right: 8px !important; + } + + .ml-sm-2, +.mx-sm-2 { + margin-left: 8px !important; + } + + .mb-sm-2, +.my-sm-2 { + margin-bottom: 8px !important; + } + + .ms-sm-2 { + margin-inline-start: 8px !important; + } + + .me-sm-2 { + margin-inline-end: 8px !important; + } + + .ma-sm-2 { + margin: 8px !important; + } + + .mt-sm-3, +.my-sm-3 { + margin-top: 12px !important; + } + + .mr-sm-3, +.mx-sm-3 { + margin-right: 12px !important; + } + + .ml-sm-3, +.mx-sm-3 { + margin-left: 12px !important; + } + + .mb-sm-3, +.my-sm-3 { + margin-bottom: 12px !important; + } + + .ms-sm-3 { + margin-inline-start: 12px !important; + } + + .me-sm-3 { + margin-inline-end: 12px !important; + } + + .ma-sm-3 { + margin: 12px !important; + } + + .mt-sm-4, +.my-sm-4 { + margin-top: 16px !important; + } + + .mr-sm-4, +.mx-sm-4 { + margin-right: 16px !important; + } + + .ml-sm-4, +.mx-sm-4 { + margin-left: 16px !important; + } + + .mb-sm-4, +.my-sm-4 { + margin-bottom: 16px !important; + } + + .ms-sm-4 { + margin-inline-start: 16px !important; + } + + .me-sm-4 { + margin-inline-end: 16px !important; + } + + .ma-sm-4 { + margin: 16px !important; + } + + .mt-sm-5, +.my-sm-5 { + margin-top: 20px !important; + } + + .mr-sm-5, +.mx-sm-5 { + margin-right: 20px !important; + } + + .ml-sm-5, +.mx-sm-5 { + margin-left: 20px !important; + } + + .mb-sm-5, +.my-sm-5 { + margin-bottom: 20px !important; + } + + .ms-sm-5 { + margin-inline-start: 20px !important; + } + + .me-sm-5 { + margin-inline-end: 20px !important; + } + + .ma-sm-5 { + margin: 20px !important; + } + + .mt-sm-6, +.my-sm-6 { + margin-top: 24px !important; + } + + .mr-sm-6, +.mx-sm-6 { + margin-right: 24px !important; + } + + .ml-sm-6, +.mx-sm-6 { + margin-left: 24px !important; + } + + .mb-sm-6, +.my-sm-6 { + margin-bottom: 24px !important; + } + + .ms-sm-6 { + margin-inline-start: 24px !important; + } + + .me-sm-6 { + margin-inline-end: 24px !important; + } + + .ma-sm-6 { + margin: 24px !important; + } + + .mt-sm-7, +.my-sm-7 { + margin-top: 28px !important; + } + + .mr-sm-7, +.mx-sm-7 { + margin-right: 28px !important; + } + + .ml-sm-7, +.mx-sm-7 { + margin-left: 28px !important; + } + + .mb-sm-7, +.my-sm-7 { + margin-bottom: 28px !important; + } + + .ms-sm-7 { + margin-inline-start: 28px !important; + } + + .me-sm-7 { + margin-inline-end: 28px !important; + } + + .ma-sm-7 { + margin: 28px !important; + } + + .mt-sm-8, +.my-sm-8 { + margin-top: 32px !important; + } + + .mr-sm-8, +.mx-sm-8 { + margin-right: 32px !important; + } + + .ml-sm-8, +.mx-sm-8 { + margin-left: 32px !important; + } + + .mb-sm-8, +.my-sm-8 { + margin-bottom: 32px !important; + } + + .ms-sm-8 { + margin-inline-start: 32px !important; + } + + .me-sm-8 { + margin-inline-end: 32px !important; + } + + .ma-sm-8 { + margin: 32px !important; + } + + .mt-sm-9, +.my-sm-9 { + margin-top: 36px !important; + } + + .mr-sm-9, +.mx-sm-9 { + margin-right: 36px !important; + } + + .ml-sm-9, +.mx-sm-9 { + margin-left: 36px !important; + } + + .mb-sm-9, +.my-sm-9 { + margin-bottom: 36px !important; + } + + .ms-sm-9 { + margin-inline-start: 36px !important; + } + + .me-sm-9 { + margin-inline-end: 36px !important; + } + + .ma-sm-9 { + margin: 36px !important; + } + + .mt-sm-10, +.my-sm-10 { + margin-top: 40px !important; + } + + .mr-sm-10, +.mx-sm-10 { + margin-right: 40px !important; + } + + .ml-sm-10, +.mx-sm-10 { + margin-left: 40px !important; + } + + .mb-sm-10, +.my-sm-10 { + margin-bottom: 40px !important; + } + + .ms-sm-10 { + margin-inline-start: 40px !important; + } + + .me-sm-10 { + margin-inline-end: 40px !important; + } + + .ma-sm-10 { + margin: 40px !important; + } + + .mt-sm-11, +.my-sm-11 { + margin-top: 44px !important; + } + + .mr-sm-11, +.mx-sm-11 { + margin-right: 44px !important; + } + + .ml-sm-11, +.mx-sm-11 { + margin-left: 44px !important; + } + + .mb-sm-11, +.my-sm-11 { + margin-bottom: 44px !important; + } + + .ms-sm-11 { + margin-inline-start: 44px !important; + } + + .me-sm-11 { + margin-inline-end: 44px !important; + } + + .ma-sm-11 { + margin: 44px !important; + } + + .mt-sm-12, +.my-sm-12 { + margin-top: 48px !important; + } + + .mr-sm-12, +.mx-sm-12 { + margin-right: 48px !important; + } + + .ml-sm-12, +.mx-sm-12 { + margin-left: 48px !important; + } + + .mb-sm-12, +.my-sm-12 { + margin-bottom: 48px !important; + } + + .ms-sm-12 { + margin-inline-start: 48px !important; + } + + .me-sm-12 { + margin-inline-end: 48px !important; + } + + .ma-sm-12 { + margin: 48px !important; + } + + .mt-sm-13, +.my-sm-13 { + margin-top: 52px !important; + } + + .mr-sm-13, +.mx-sm-13 { + margin-right: 52px !important; + } + + .ml-sm-13, +.mx-sm-13 { + margin-left: 52px !important; + } + + .mb-sm-13, +.my-sm-13 { + margin-bottom: 52px !important; + } + + .ms-sm-13 { + margin-inline-start: 52px !important; + } + + .me-sm-13 { + margin-inline-end: 52px !important; + } + + .ma-sm-13 { + margin: 52px !important; + } + + .mt-sm-14, +.my-sm-14 { + margin-top: 56px !important; + } + + .mr-sm-14, +.mx-sm-14 { + margin-right: 56px !important; + } + + .ml-sm-14, +.mx-sm-14 { + margin-left: 56px !important; + } + + .mb-sm-14, +.my-sm-14 { + margin-bottom: 56px !important; + } + + .ms-sm-14 { + margin-inline-start: 56px !important; + } + + .me-sm-14 { + margin-inline-end: 56px !important; + } + + .ma-sm-14 { + margin: 56px !important; + } + + .mt-sm-15, +.my-sm-15 { + margin-top: 60px !important; + } + + .mr-sm-15, +.mx-sm-15 { + margin-right: 60px !important; + } + + .ml-sm-15, +.mx-sm-15 { + margin-left: 60px !important; + } + + .mb-sm-15, +.my-sm-15 { + margin-bottom: 60px !important; + } + + .ms-sm-15 { + margin-inline-start: 60px !important; + } + + .me-sm-15 { + margin-inline-end: 60px !important; + } + + .ma-sm-15 { + margin: 60px !important; + } + + .mt-sm-16, +.my-sm-16 { + margin-top: 64px !important; + } + + .mr-sm-16, +.mx-sm-16 { + margin-right: 64px !important; + } + + .ml-sm-16, +.mx-sm-16 { + margin-left: 64px !important; + } + + .mb-sm-16, +.my-sm-16 { + margin-bottom: 64px !important; + } + + .ms-sm-16 { + margin-inline-start: 64px !important; + } + + .me-sm-16 { + margin-inline-end: 64px !important; + } + + .ma-sm-16 { + margin: 64px !important; + } + + .mt-sm-auto, +.my-sm-auto { + margin-top: auto !important; + } + + .mr-sm-auto, +.mx-sm-auto { + margin-right: auto !important; + } + + .ml-sm-auto, +.mx-sm-auto { + margin-left: auto !important; + } + + .mb-sm-auto, +.my-sm-auto { + margin-bottom: auto !important; + } + + .ms-sm-auto { + margin-inline-start: auto !important; + } + + .me-sm-auto { + margin-inline-end: auto !important; + } + + .ma-sm-auto { + margin: auto !important; + } + + .pt-sm-0, +.py-sm-0 { + padding-top: 0 !important; + } + + .pr-sm-0, +.px-sm-0 { + padding-right: 0 !important; + } + + .pl-sm-0, +.px-sm-0 { + padding-left: 0 !important; + } + + .pb-sm-0, +.py-sm-0 { + padding-bottom: 0 !important; + } + + .ps-sm-0 { + padding-inline-start: 0 !important; + } + + .pe-sm-0 { + padding-inline-end: 0 !important; + } + + .pa-sm-0 { + padding: 0 !important; + } + + .pt-sm-1, +.py-sm-1 { + padding-top: 4px !important; + } + + .pr-sm-1, +.px-sm-1 { + padding-right: 4px !important; + } + + .pl-sm-1, +.px-sm-1 { + padding-left: 4px !important; + } + + .pb-sm-1, +.py-sm-1 { + padding-bottom: 4px !important; + } + + .ps-sm-1 { + padding-inline-start: 4px !important; + } + + .pe-sm-1 { + padding-inline-end: 4px !important; + } + + .pa-sm-1 { + padding: 4px !important; + } + + .pt-sm-2, +.py-sm-2 { + padding-top: 8px !important; + } + + .pr-sm-2, +.px-sm-2 { + padding-right: 8px !important; + } + + .pl-sm-2, +.px-sm-2 { + padding-left: 8px !important; + } + + .pb-sm-2, +.py-sm-2 { + padding-bottom: 8px !important; + } + + .ps-sm-2 { + padding-inline-start: 8px !important; + } + + .pe-sm-2 { + padding-inline-end: 8px !important; + } + + .pa-sm-2 { + padding: 8px !important; + } + + .pt-sm-3, +.py-sm-3 { + padding-top: 12px !important; + } + + .pr-sm-3, +.px-sm-3 { + padding-right: 12px !important; + } + + .pl-sm-3, +.px-sm-3 { + padding-left: 12px !important; + } + + .pb-sm-3, +.py-sm-3 { + padding-bottom: 12px !important; + } + + .ps-sm-3 { + padding-inline-start: 12px !important; + } + + .pe-sm-3 { + padding-inline-end: 12px !important; + } + + .pa-sm-3 { + padding: 12px !important; + } + + .pt-sm-4, +.py-sm-4 { + padding-top: 16px !important; + } + + .pr-sm-4, +.px-sm-4 { + padding-right: 16px !important; + } + + .pl-sm-4, +.px-sm-4 { + padding-left: 16px !important; + } + + .pb-sm-4, +.py-sm-4 { + padding-bottom: 16px !important; + } + + .ps-sm-4 { + padding-inline-start: 16px !important; + } + + .pe-sm-4 { + padding-inline-end: 16px !important; + } + + .pa-sm-4 { + padding: 16px !important; + } + + .pt-sm-5, +.py-sm-5 { + padding-top: 20px !important; + } + + .pr-sm-5, +.px-sm-5 { + padding-right: 20px !important; + } + + .pl-sm-5, +.px-sm-5 { + padding-left: 20px !important; + } + + .pb-sm-5, +.py-sm-5 { + padding-bottom: 20px !important; + } + + .ps-sm-5 { + padding-inline-start: 20px !important; + } + + .pe-sm-5 { + padding-inline-end: 20px !important; + } + + .pa-sm-5 { + padding: 20px !important; + } + + .pt-sm-6, +.py-sm-6 { + padding-top: 24px !important; + } + + .pr-sm-6, +.px-sm-6 { + padding-right: 24px !important; + } + + .pl-sm-6, +.px-sm-6 { + padding-left: 24px !important; + } + + .pb-sm-6, +.py-sm-6 { + padding-bottom: 24px !important; + } + + .ps-sm-6 { + padding-inline-start: 24px !important; + } + + .pe-sm-6 { + padding-inline-end: 24px !important; + } + + .pa-sm-6 { + padding: 24px !important; + } + + .pt-sm-7, +.py-sm-7 { + padding-top: 28px !important; + } + + .pr-sm-7, +.px-sm-7 { + padding-right: 28px !important; + } + + .pl-sm-7, +.px-sm-7 { + padding-left: 28px !important; + } + + .pb-sm-7, +.py-sm-7 { + padding-bottom: 28px !important; + } + + .ps-sm-7 { + padding-inline-start: 28px !important; + } + + .pe-sm-7 { + padding-inline-end: 28px !important; + } + + .pa-sm-7 { + padding: 28px !important; + } + + .pt-sm-8, +.py-sm-8 { + padding-top: 32px !important; + } + + .pr-sm-8, +.px-sm-8 { + padding-right: 32px !important; + } + + .pl-sm-8, +.px-sm-8 { + padding-left: 32px !important; + } + + .pb-sm-8, +.py-sm-8 { + padding-bottom: 32px !important; + } + + .ps-sm-8 { + padding-inline-start: 32px !important; + } + + .pe-sm-8 { + padding-inline-end: 32px !important; + } + + .pa-sm-8 { + padding: 32px !important; + } + + .pt-sm-9, +.py-sm-9 { + padding-top: 36px !important; + } + + .pr-sm-9, +.px-sm-9 { + padding-right: 36px !important; + } + + .pl-sm-9, +.px-sm-9 { + padding-left: 36px !important; + } + + .pb-sm-9, +.py-sm-9 { + padding-bottom: 36px !important; + } + + .ps-sm-9 { + padding-inline-start: 36px !important; + } + + .pe-sm-9 { + padding-inline-end: 36px !important; + } + + .pa-sm-9 { + padding: 36px !important; + } + + .pt-sm-10, +.py-sm-10 { + padding-top: 40px !important; + } + + .pr-sm-10, +.px-sm-10 { + padding-right: 40px !important; + } + + .pl-sm-10, +.px-sm-10 { + padding-left: 40px !important; + } + + .pb-sm-10, +.py-sm-10 { + padding-bottom: 40px !important; + } + + .ps-sm-10 { + padding-inline-start: 40px !important; + } + + .pe-sm-10 { + padding-inline-end: 40px !important; + } + + .pa-sm-10 { + padding: 40px !important; + } + + .pt-sm-11, +.py-sm-11 { + padding-top: 44px !important; + } + + .pr-sm-11, +.px-sm-11 { + padding-right: 44px !important; + } + + .pl-sm-11, +.px-sm-11 { + padding-left: 44px !important; + } + + .pb-sm-11, +.py-sm-11 { + padding-bottom: 44px !important; + } + + .ps-sm-11 { + padding-inline-start: 44px !important; + } + + .pe-sm-11 { + padding-inline-end: 44px !important; + } + + .pa-sm-11 { + padding: 44px !important; + } + + .pt-sm-12, +.py-sm-12 { + padding-top: 48px !important; + } + + .pr-sm-12, +.px-sm-12 { + padding-right: 48px !important; + } + + .pl-sm-12, +.px-sm-12 { + padding-left: 48px !important; + } + + .pb-sm-12, +.py-sm-12 { + padding-bottom: 48px !important; + } + + .ps-sm-12 { + padding-inline-start: 48px !important; + } + + .pe-sm-12 { + padding-inline-end: 48px !important; + } + + .pa-sm-12 { + padding: 48px !important; + } + + .pt-sm-13, +.py-sm-13 { + padding-top: 52px !important; + } + + .pr-sm-13, +.px-sm-13 { + padding-right: 52px !important; + } + + .pl-sm-13, +.px-sm-13 { + padding-left: 52px !important; + } + + .pb-sm-13, +.py-sm-13 { + padding-bottom: 52px !important; + } + + .ps-sm-13 { + padding-inline-start: 52px !important; + } + + .pe-sm-13 { + padding-inline-end: 52px !important; + } + + .pa-sm-13 { + padding: 52px !important; + } + + .pt-sm-14, +.py-sm-14 { + padding-top: 56px !important; + } + + .pr-sm-14, +.px-sm-14 { + padding-right: 56px !important; + } + + .pl-sm-14, +.px-sm-14 { + padding-left: 56px !important; + } + + .pb-sm-14, +.py-sm-14 { + padding-bottom: 56px !important; + } + + .ps-sm-14 { + padding-inline-start: 56px !important; + } + + .pe-sm-14 { + padding-inline-end: 56px !important; + } + + .pa-sm-14 { + padding: 56px !important; + } + + .pt-sm-15, +.py-sm-15 { + padding-top: 60px !important; + } + + .pr-sm-15, +.px-sm-15 { + padding-right: 60px !important; + } + + .pl-sm-15, +.px-sm-15 { + padding-left: 60px !important; + } + + .pb-sm-15, +.py-sm-15 { + padding-bottom: 60px !important; + } + + .ps-sm-15 { + padding-inline-start: 60px !important; + } + + .pe-sm-15 { + padding-inline-end: 60px !important; + } + + .pa-sm-15 { + padding: 60px !important; + } + + .pt-sm-16, +.py-sm-16 { + padding-top: 64px !important; + } + + .pr-sm-16, +.px-sm-16 { + padding-right: 64px !important; + } + + .pl-sm-16, +.px-sm-16 { + padding-left: 64px !important; + } + + .pb-sm-16, +.py-sm-16 { + padding-bottom: 64px !important; + } + + .ps-sm-16 { + padding-inline-start: 64px !important; + } + + .pe-sm-16 { + padding-inline-end: 64px !important; + } + + .pa-sm-16 { + padding: 64px !important; + } + + .pt-sm-auto, +.py-sm-auto { + padding-top: auto !important; + } + + .pr-sm-auto, +.px-sm-auto { + padding-right: auto !important; + } + + .pl-sm-auto, +.px-sm-auto { + padding-left: auto !important; + } + + .pb-sm-auto, +.py-sm-auto { + padding-bottom: auto !important; + } + + .ps-sm-auto { + padding-inline-start: auto !important; + } + + .pe-sm-auto { + padding-inline-end: auto !important; + } + + .pa-sm-auto { + padding: auto !important; + } + + .mt-sm-n1, +.my-sm-n1 { + margin-top: -4px !important; + } + + .mr-sm-n1, +.mx-sm-n1 { + margin-right: -4px !important; + } + + .ml-sm-n1, +.mx-sm-n1 { + margin-left: -4px !important; + } + + .mb-sm-n1, +.my-sm-n1 { + margin-bottom: -4px !important; + } + + .ms-sm-n1 { + margin-inline-start: -4px !important; + } + + .me-sm-n1 { + margin-inline-end: -4px !important; + } + + .ma-sm-n1 { + margin: -4px !important; + } + + .mt-sm-n2, +.my-sm-n2 { + margin-top: -8px !important; + } + + .mr-sm-n2, +.mx-sm-n2 { + margin-right: -8px !important; + } + + .ml-sm-n2, +.mx-sm-n2 { + margin-left: -8px !important; + } + + .mb-sm-n2, +.my-sm-n2 { + margin-bottom: -8px !important; + } + + .ms-sm-n2 { + margin-inline-start: -8px !important; + } + + .me-sm-n2 { + margin-inline-end: -8px !important; + } + + .ma-sm-n2 { + margin: -8px !important; + } + + .mt-sm-n3, +.my-sm-n3 { + margin-top: -12px !important; + } + + .mr-sm-n3, +.mx-sm-n3 { + margin-right: -12px !important; + } + + .ml-sm-n3, +.mx-sm-n3 { + margin-left: -12px !important; + } + + .mb-sm-n3, +.my-sm-n3 { + margin-bottom: -12px !important; + } + + .ms-sm-n3 { + margin-inline-start: -12px !important; + } + + .me-sm-n3 { + margin-inline-end: -12px !important; + } + + .ma-sm-n3 { + margin: -12px !important; + } + + .mt-sm-n4, +.my-sm-n4 { + margin-top: -16px !important; + } + + .mr-sm-n4, +.mx-sm-n4 { + margin-right: -16px !important; + } + + .ml-sm-n4, +.mx-sm-n4 { + margin-left: -16px !important; + } + + .mb-sm-n4, +.my-sm-n4 { + margin-bottom: -16px !important; + } + + .ms-sm-n4 { + margin-inline-start: -16px !important; + } + + .me-sm-n4 { + margin-inline-end: -16px !important; + } + + .ma-sm-n4 { + margin: -16px !important; + } + + .mt-sm-n5, +.my-sm-n5 { + margin-top: -20px !important; + } + + .mr-sm-n5, +.mx-sm-n5 { + margin-right: -20px !important; + } + + .ml-sm-n5, +.mx-sm-n5 { + margin-left: -20px !important; + } + + .mb-sm-n5, +.my-sm-n5 { + margin-bottom: -20px !important; + } + + .ms-sm-n5 { + margin-inline-start: -20px !important; + } + + .me-sm-n5 { + margin-inline-end: -20px !important; + } + + .ma-sm-n5 { + margin: -20px !important; + } + + .mt-sm-n6, +.my-sm-n6 { + margin-top: -24px !important; + } + + .mr-sm-n6, +.mx-sm-n6 { + margin-right: -24px !important; + } + + .ml-sm-n6, +.mx-sm-n6 { + margin-left: -24px !important; + } + + .mb-sm-n6, +.my-sm-n6 { + margin-bottom: -24px !important; + } + + .ms-sm-n6 { + margin-inline-start: -24px !important; + } + + .me-sm-n6 { + margin-inline-end: -24px !important; + } + + .ma-sm-n6 { + margin: -24px !important; + } + + .mt-sm-n7, +.my-sm-n7 { + margin-top: -28px !important; + } + + .mr-sm-n7, +.mx-sm-n7 { + margin-right: -28px !important; + } + + .ml-sm-n7, +.mx-sm-n7 { + margin-left: -28px !important; + } + + .mb-sm-n7, +.my-sm-n7 { + margin-bottom: -28px !important; + } + + .ms-sm-n7 { + margin-inline-start: -28px !important; + } + + .me-sm-n7 { + margin-inline-end: -28px !important; + } + + .ma-sm-n7 { + margin: -28px !important; + } + + .mt-sm-n8, +.my-sm-n8 { + margin-top: -32px !important; + } + + .mr-sm-n8, +.mx-sm-n8 { + margin-right: -32px !important; + } + + .ml-sm-n8, +.mx-sm-n8 { + margin-left: -32px !important; + } + + .mb-sm-n8, +.my-sm-n8 { + margin-bottom: -32px !important; + } + + .ms-sm-n8 { + margin-inline-start: -32px !important; + } + + .me-sm-n8 { + margin-inline-end: -32px !important; + } + + .ma-sm-n8 { + margin: -32px !important; + } + + .mt-sm-n9, +.my-sm-n9 { + margin-top: -36px !important; + } + + .mr-sm-n9, +.mx-sm-n9 { + margin-right: -36px !important; + } + + .ml-sm-n9, +.mx-sm-n9 { + margin-left: -36px !important; + } + + .mb-sm-n9, +.my-sm-n9 { + margin-bottom: -36px !important; + } + + .ms-sm-n9 { + margin-inline-start: -36px !important; + } + + .me-sm-n9 { + margin-inline-end: -36px !important; + } + + .ma-sm-n9 { + margin: -36px !important; + } + + .mt-sm-n10, +.my-sm-n10 { + margin-top: -40px !important; + } + + .mr-sm-n10, +.mx-sm-n10 { + margin-right: -40px !important; + } + + .ml-sm-n10, +.mx-sm-n10 { + margin-left: -40px !important; + } + + .mb-sm-n10, +.my-sm-n10 { + margin-bottom: -40px !important; + } + + .ms-sm-n10 { + margin-inline-start: -40px !important; + } + + .me-sm-n10 { + margin-inline-end: -40px !important; + } + + .ma-sm-n10 { + margin: -40px !important; + } + + .mt-sm-n11, +.my-sm-n11 { + margin-top: -44px !important; + } + + .mr-sm-n11, +.mx-sm-n11 { + margin-right: -44px !important; + } + + .ml-sm-n11, +.mx-sm-n11 { + margin-left: -44px !important; + } + + .mb-sm-n11, +.my-sm-n11 { + margin-bottom: -44px !important; + } + + .ms-sm-n11 { + margin-inline-start: -44px !important; + } + + .me-sm-n11 { + margin-inline-end: -44px !important; + } + + .ma-sm-n11 { + margin: -44px !important; + } + + .mt-sm-n12, +.my-sm-n12 { + margin-top: -48px !important; + } + + .mr-sm-n12, +.mx-sm-n12 { + margin-right: -48px !important; + } + + .ml-sm-n12, +.mx-sm-n12 { + margin-left: -48px !important; + } + + .mb-sm-n12, +.my-sm-n12 { + margin-bottom: -48px !important; + } + + .ms-sm-n12 { + margin-inline-start: -48px !important; + } + + .me-sm-n12 { + margin-inline-end: -48px !important; + } + + .ma-sm-n12 { + margin: -48px !important; + } + + .mt-sm-n13, +.my-sm-n13 { + margin-top: -52px !important; + } + + .mr-sm-n13, +.mx-sm-n13 { + margin-right: -52px !important; + } + + .ml-sm-n13, +.mx-sm-n13 { + margin-left: -52px !important; + } + + .mb-sm-n13, +.my-sm-n13 { + margin-bottom: -52px !important; + } + + .ms-sm-n13 { + margin-inline-start: -52px !important; + } + + .me-sm-n13 { + margin-inline-end: -52px !important; + } + + .ma-sm-n13 { + margin: -52px !important; + } + + .mt-sm-n14, +.my-sm-n14 { + margin-top: -56px !important; + } + + .mr-sm-n14, +.mx-sm-n14 { + margin-right: -56px !important; + } + + .ml-sm-n14, +.mx-sm-n14 { + margin-left: -56px !important; + } + + .mb-sm-n14, +.my-sm-n14 { + margin-bottom: -56px !important; + } + + .ms-sm-n14 { + margin-inline-start: -56px !important; + } + + .me-sm-n14 { + margin-inline-end: -56px !important; + } + + .ma-sm-n14 { + margin: -56px !important; + } + + .mt-sm-n15, +.my-sm-n15 { + margin-top: -60px !important; + } + + .mr-sm-n15, +.mx-sm-n15 { + margin-right: -60px !important; + } + + .ml-sm-n15, +.mx-sm-n15 { + margin-left: -60px !important; + } + + .mb-sm-n15, +.my-sm-n15 { + margin-bottom: -60px !important; + } + + .ms-sm-n15 { + margin-inline-start: -60px !important; + } + + .me-sm-n15 { + margin-inline-end: -60px !important; + } + + .ma-sm-n15 { + margin: -60px !important; + } + + .mt-sm-n16, +.my-sm-n16 { + margin-top: -64px !important; + } + + .mr-sm-n16, +.mx-sm-n16 { + margin-right: -64px !important; + } + + .ml-sm-n16, +.mx-sm-n16 { + margin-left: -64px !important; + } + + .mb-sm-n16, +.my-sm-n16 { + margin-bottom: -64px !important; + } + + .ms-sm-n16 { + margin-inline-start: -64px !important; + } + + .me-sm-n16 { + margin-inline-end: -64px !important; + } + + .ma-sm-n16 { + margin: -64px !important; + } +} +@media screen and (min-width: 960px) { + .mt-md-0, +.my-md-0 { + margin-top: 0 !important; + } + + .mr-md-0, +.mx-md-0 { + margin-right: 0 !important; + } + + .ml-md-0, +.mx-md-0 { + margin-left: 0 !important; + } + + .mb-md-0, +.my-md-0 { + margin-bottom: 0 !important; + } + + .ms-md-0 { + margin-inline-start: 0 !important; + } + + .me-md-0 { + margin-inline-end: 0 !important; + } + + .ma-md-0 { + margin: 0 !important; + } + + .mt-md-1, +.my-md-1 { + margin-top: 4px !important; + } + + .mr-md-1, +.mx-md-1 { + margin-right: 4px !important; + } + + .ml-md-1, +.mx-md-1 { + margin-left: 4px !important; + } + + .mb-md-1, +.my-md-1 { + margin-bottom: 4px !important; + } + + .ms-md-1 { + margin-inline-start: 4px !important; + } + + .me-md-1 { + margin-inline-end: 4px !important; + } + + .ma-md-1 { + margin: 4px !important; + } + + .mt-md-2, +.my-md-2 { + margin-top: 8px !important; + } + + .mr-md-2, +.mx-md-2 { + margin-right: 8px !important; + } + + .ml-md-2, +.mx-md-2 { + margin-left: 8px !important; + } + + .mb-md-2, +.my-md-2 { + margin-bottom: 8px !important; + } + + .ms-md-2 { + margin-inline-start: 8px !important; + } + + .me-md-2 { + margin-inline-end: 8px !important; + } + + .ma-md-2 { + margin: 8px !important; + } + + .mt-md-3, +.my-md-3 { + margin-top: 12px !important; + } + + .mr-md-3, +.mx-md-3 { + margin-right: 12px !important; + } + + .ml-md-3, +.mx-md-3 { + margin-left: 12px !important; + } + + .mb-md-3, +.my-md-3 { + margin-bottom: 12px !important; + } + + .ms-md-3 { + margin-inline-start: 12px !important; + } + + .me-md-3 { + margin-inline-end: 12px !important; + } + + .ma-md-3 { + margin: 12px !important; + } + + .mt-md-4, +.my-md-4 { + margin-top: 16px !important; + } + + .mr-md-4, +.mx-md-4 { + margin-right: 16px !important; + } + + .ml-md-4, +.mx-md-4 { + margin-left: 16px !important; + } + + .mb-md-4, +.my-md-4 { + margin-bottom: 16px !important; + } + + .ms-md-4 { + margin-inline-start: 16px !important; + } + + .me-md-4 { + margin-inline-end: 16px !important; + } + + .ma-md-4 { + margin: 16px !important; + } + + .mt-md-5, +.my-md-5 { + margin-top: 20px !important; + } + + .mr-md-5, +.mx-md-5 { + margin-right: 20px !important; + } + + .ml-md-5, +.mx-md-5 { + margin-left: 20px !important; + } + + .mb-md-5, +.my-md-5 { + margin-bottom: 20px !important; + } + + .ms-md-5 { + margin-inline-start: 20px !important; + } + + .me-md-5 { + margin-inline-end: 20px !important; + } + + .ma-md-5 { + margin: 20px !important; + } + + .mt-md-6, +.my-md-6 { + margin-top: 24px !important; + } + + .mr-md-6, +.mx-md-6 { + margin-right: 24px !important; + } + + .ml-md-6, +.mx-md-6 { + margin-left: 24px !important; + } + + .mb-md-6, +.my-md-6 { + margin-bottom: 24px !important; + } + + .ms-md-6 { + margin-inline-start: 24px !important; + } + + .me-md-6 { + margin-inline-end: 24px !important; + } + + .ma-md-6 { + margin: 24px !important; + } + + .mt-md-7, +.my-md-7 { + margin-top: 28px !important; + } + + .mr-md-7, +.mx-md-7 { + margin-right: 28px !important; + } + + .ml-md-7, +.mx-md-7 { + margin-left: 28px !important; + } + + .mb-md-7, +.my-md-7 { + margin-bottom: 28px !important; + } + + .ms-md-7 { + margin-inline-start: 28px !important; + } + + .me-md-7 { + margin-inline-end: 28px !important; + } + + .ma-md-7 { + margin: 28px !important; + } + + .mt-md-8, +.my-md-8 { + margin-top: 32px !important; + } + + .mr-md-8, +.mx-md-8 { + margin-right: 32px !important; + } + + .ml-md-8, +.mx-md-8 { + margin-left: 32px !important; + } + + .mb-md-8, +.my-md-8 { + margin-bottom: 32px !important; + } + + .ms-md-8 { + margin-inline-start: 32px !important; + } + + .me-md-8 { + margin-inline-end: 32px !important; + } + + .ma-md-8 { + margin: 32px !important; + } + + .mt-md-9, +.my-md-9 { + margin-top: 36px !important; + } + + .mr-md-9, +.mx-md-9 { + margin-right: 36px !important; + } + + .ml-md-9, +.mx-md-9 { + margin-left: 36px !important; + } + + .mb-md-9, +.my-md-9 { + margin-bottom: 36px !important; + } + + .ms-md-9 { + margin-inline-start: 36px !important; + } + + .me-md-9 { + margin-inline-end: 36px !important; + } + + .ma-md-9 { + margin: 36px !important; + } + + .mt-md-10, +.my-md-10 { + margin-top: 40px !important; + } + + .mr-md-10, +.mx-md-10 { + margin-right: 40px !important; + } + + .ml-md-10, +.mx-md-10 { + margin-left: 40px !important; + } + + .mb-md-10, +.my-md-10 { + margin-bottom: 40px !important; + } + + .ms-md-10 { + margin-inline-start: 40px !important; + } + + .me-md-10 { + margin-inline-end: 40px !important; + } + + .ma-md-10 { + margin: 40px !important; + } + + .mt-md-11, +.my-md-11 { + margin-top: 44px !important; + } + + .mr-md-11, +.mx-md-11 { + margin-right: 44px !important; + } + + .ml-md-11, +.mx-md-11 { + margin-left: 44px !important; + } + + .mb-md-11, +.my-md-11 { + margin-bottom: 44px !important; + } + + .ms-md-11 { + margin-inline-start: 44px !important; + } + + .me-md-11 { + margin-inline-end: 44px !important; + } + + .ma-md-11 { + margin: 44px !important; + } + + .mt-md-12, +.my-md-12 { + margin-top: 48px !important; + } + + .mr-md-12, +.mx-md-12 { + margin-right: 48px !important; + } + + .ml-md-12, +.mx-md-12 { + margin-left: 48px !important; + } + + .mb-md-12, +.my-md-12 { + margin-bottom: 48px !important; + } + + .ms-md-12 { + margin-inline-start: 48px !important; + } + + .me-md-12 { + margin-inline-end: 48px !important; + } + + .ma-md-12 { + margin: 48px !important; + } + + .mt-md-13, +.my-md-13 { + margin-top: 52px !important; + } + + .mr-md-13, +.mx-md-13 { + margin-right: 52px !important; + } + + .ml-md-13, +.mx-md-13 { + margin-left: 52px !important; + } + + .mb-md-13, +.my-md-13 { + margin-bottom: 52px !important; + } + + .ms-md-13 { + margin-inline-start: 52px !important; + } + + .me-md-13 { + margin-inline-end: 52px !important; + } + + .ma-md-13 { + margin: 52px !important; + } + + .mt-md-14, +.my-md-14 { + margin-top: 56px !important; + } + + .mr-md-14, +.mx-md-14 { + margin-right: 56px !important; + } + + .ml-md-14, +.mx-md-14 { + margin-left: 56px !important; + } + + .mb-md-14, +.my-md-14 { + margin-bottom: 56px !important; + } + + .ms-md-14 { + margin-inline-start: 56px !important; + } + + .me-md-14 { + margin-inline-end: 56px !important; + } + + .ma-md-14 { + margin: 56px !important; + } + + .mt-md-15, +.my-md-15 { + margin-top: 60px !important; + } + + .mr-md-15, +.mx-md-15 { + margin-right: 60px !important; + } + + .ml-md-15, +.mx-md-15 { + margin-left: 60px !important; + } + + .mb-md-15, +.my-md-15 { + margin-bottom: 60px !important; + } + + .ms-md-15 { + margin-inline-start: 60px !important; + } + + .me-md-15 { + margin-inline-end: 60px !important; + } + + .ma-md-15 { + margin: 60px !important; + } + + .mt-md-16, +.my-md-16 { + margin-top: 64px !important; + } + + .mr-md-16, +.mx-md-16 { + margin-right: 64px !important; + } + + .ml-md-16, +.mx-md-16 { + margin-left: 64px !important; + } + + .mb-md-16, +.my-md-16 { + margin-bottom: 64px !important; + } + + .ms-md-16 { + margin-inline-start: 64px !important; + } + + .me-md-16 { + margin-inline-end: 64px !important; + } + + .ma-md-16 { + margin: 64px !important; + } + + .mt-md-auto, +.my-md-auto { + margin-top: auto !important; + } + + .mr-md-auto, +.mx-md-auto { + margin-right: auto !important; + } + + .ml-md-auto, +.mx-md-auto { + margin-left: auto !important; + } + + .mb-md-auto, +.my-md-auto { + margin-bottom: auto !important; + } + + .ms-md-auto { + margin-inline-start: auto !important; + } + + .me-md-auto { + margin-inline-end: auto !important; + } + + .ma-md-auto { + margin: auto !important; + } + + .pt-md-0, +.py-md-0 { + padding-top: 0 !important; + } + + .pr-md-0, +.px-md-0 { + padding-right: 0 !important; + } + + .pl-md-0, +.px-md-0 { + padding-left: 0 !important; + } + + .pb-md-0, +.py-md-0 { + padding-bottom: 0 !important; + } + + .ps-md-0 { + padding-inline-start: 0 !important; + } + + .pe-md-0 { + padding-inline-end: 0 !important; + } + + .pa-md-0 { + padding: 0 !important; + } + + .pt-md-1, +.py-md-1 { + padding-top: 4px !important; + } + + .pr-md-1, +.px-md-1 { + padding-right: 4px !important; + } + + .pl-md-1, +.px-md-1 { + padding-left: 4px !important; + } + + .pb-md-1, +.py-md-1 { + padding-bottom: 4px !important; + } + + .ps-md-1 { + padding-inline-start: 4px !important; + } + + .pe-md-1 { + padding-inline-end: 4px !important; + } + + .pa-md-1 { + padding: 4px !important; + } + + .pt-md-2, +.py-md-2 { + padding-top: 8px !important; + } + + .pr-md-2, +.px-md-2 { + padding-right: 8px !important; + } + + .pl-md-2, +.px-md-2 { + padding-left: 8px !important; + } + + .pb-md-2, +.py-md-2 { + padding-bottom: 8px !important; + } + + .ps-md-2 { + padding-inline-start: 8px !important; + } + + .pe-md-2 { + padding-inline-end: 8px !important; + } + + .pa-md-2 { + padding: 8px !important; + } + + .pt-md-3, +.py-md-3 { + padding-top: 12px !important; + } + + .pr-md-3, +.px-md-3 { + padding-right: 12px !important; + } + + .pl-md-3, +.px-md-3 { + padding-left: 12px !important; + } + + .pb-md-3, +.py-md-3 { + padding-bottom: 12px !important; + } + + .ps-md-3 { + padding-inline-start: 12px !important; + } + + .pe-md-3 { + padding-inline-end: 12px !important; + } + + .pa-md-3 { + padding: 12px !important; + } + + .pt-md-4, +.py-md-4 { + padding-top: 16px !important; + } + + .pr-md-4, +.px-md-4 { + padding-right: 16px !important; + } + + .pl-md-4, +.px-md-4 { + padding-left: 16px !important; + } + + .pb-md-4, +.py-md-4 { + padding-bottom: 16px !important; + } + + .ps-md-4 { + padding-inline-start: 16px !important; + } + + .pe-md-4 { + padding-inline-end: 16px !important; + } + + .pa-md-4 { + padding: 16px !important; + } + + .pt-md-5, +.py-md-5 { + padding-top: 20px !important; + } + + .pr-md-5, +.px-md-5 { + padding-right: 20px !important; + } + + .pl-md-5, +.px-md-5 { + padding-left: 20px !important; + } + + .pb-md-5, +.py-md-5 { + padding-bottom: 20px !important; + } + + .ps-md-5 { + padding-inline-start: 20px !important; + } + + .pe-md-5 { + padding-inline-end: 20px !important; + } + + .pa-md-5 { + padding: 20px !important; + } + + .pt-md-6, +.py-md-6 { + padding-top: 24px !important; + } + + .pr-md-6, +.px-md-6 { + padding-right: 24px !important; + } + + .pl-md-6, +.px-md-6 { + padding-left: 24px !important; + } + + .pb-md-6, +.py-md-6 { + padding-bottom: 24px !important; + } + + .ps-md-6 { + padding-inline-start: 24px !important; + } + + .pe-md-6 { + padding-inline-end: 24px !important; + } + + .pa-md-6 { + padding: 24px !important; + } + + .pt-md-7, +.py-md-7 { + padding-top: 28px !important; + } + + .pr-md-7, +.px-md-7 { + padding-right: 28px !important; + } + + .pl-md-7, +.px-md-7 { + padding-left: 28px !important; + } + + .pb-md-7, +.py-md-7 { + padding-bottom: 28px !important; + } + + .ps-md-7 { + padding-inline-start: 28px !important; + } + + .pe-md-7 { + padding-inline-end: 28px !important; + } + + .pa-md-7 { + padding: 28px !important; + } + + .pt-md-8, +.py-md-8 { + padding-top: 32px !important; + } + + .pr-md-8, +.px-md-8 { + padding-right: 32px !important; + } + + .pl-md-8, +.px-md-8 { + padding-left: 32px !important; + } + + .pb-md-8, +.py-md-8 { + padding-bottom: 32px !important; + } + + .ps-md-8 { + padding-inline-start: 32px !important; + } + + .pe-md-8 { + padding-inline-end: 32px !important; + } + + .pa-md-8 { + padding: 32px !important; + } + + .pt-md-9, +.py-md-9 { + padding-top: 36px !important; + } + + .pr-md-9, +.px-md-9 { + padding-right: 36px !important; + } + + .pl-md-9, +.px-md-9 { + padding-left: 36px !important; + } + + .pb-md-9, +.py-md-9 { + padding-bottom: 36px !important; + } + + .ps-md-9 { + padding-inline-start: 36px !important; + } + + .pe-md-9 { + padding-inline-end: 36px !important; + } + + .pa-md-9 { + padding: 36px !important; + } + + .pt-md-10, +.py-md-10 { + padding-top: 40px !important; + } + + .pr-md-10, +.px-md-10 { + padding-right: 40px !important; + } + + .pl-md-10, +.px-md-10 { + padding-left: 40px !important; + } + + .pb-md-10, +.py-md-10 { + padding-bottom: 40px !important; + } + + .ps-md-10 { + padding-inline-start: 40px !important; + } + + .pe-md-10 { + padding-inline-end: 40px !important; + } + + .pa-md-10 { + padding: 40px !important; + } + + .pt-md-11, +.py-md-11 { + padding-top: 44px !important; + } + + .pr-md-11, +.px-md-11 { + padding-right: 44px !important; + } + + .pl-md-11, +.px-md-11 { + padding-left: 44px !important; + } + + .pb-md-11, +.py-md-11 { + padding-bottom: 44px !important; + } + + .ps-md-11 { + padding-inline-start: 44px !important; + } + + .pe-md-11 { + padding-inline-end: 44px !important; + } + + .pa-md-11 { + padding: 44px !important; + } + + .pt-md-12, +.py-md-12 { + padding-top: 48px !important; + } + + .pr-md-12, +.px-md-12 { + padding-right: 48px !important; + } + + .pl-md-12, +.px-md-12 { + padding-left: 48px !important; + } + + .pb-md-12, +.py-md-12 { + padding-bottom: 48px !important; + } + + .ps-md-12 { + padding-inline-start: 48px !important; + } + + .pe-md-12 { + padding-inline-end: 48px !important; + } + + .pa-md-12 { + padding: 48px !important; + } + + .pt-md-13, +.py-md-13 { + padding-top: 52px !important; + } + + .pr-md-13, +.px-md-13 { + padding-right: 52px !important; + } + + .pl-md-13, +.px-md-13 { + padding-left: 52px !important; + } + + .pb-md-13, +.py-md-13 { + padding-bottom: 52px !important; + } + + .ps-md-13 { + padding-inline-start: 52px !important; + } + + .pe-md-13 { + padding-inline-end: 52px !important; + } + + .pa-md-13 { + padding: 52px !important; + } + + .pt-md-14, +.py-md-14 { + padding-top: 56px !important; + } + + .pr-md-14, +.px-md-14 { + padding-right: 56px !important; + } + + .pl-md-14, +.px-md-14 { + padding-left: 56px !important; + } + + .pb-md-14, +.py-md-14 { + padding-bottom: 56px !important; + } + + .ps-md-14 { + padding-inline-start: 56px !important; + } + + .pe-md-14 { + padding-inline-end: 56px !important; + } + + .pa-md-14 { + padding: 56px !important; + } + + .pt-md-15, +.py-md-15 { + padding-top: 60px !important; + } + + .pr-md-15, +.px-md-15 { + padding-right: 60px !important; + } + + .pl-md-15, +.px-md-15 { + padding-left: 60px !important; + } + + .pb-md-15, +.py-md-15 { + padding-bottom: 60px !important; + } + + .ps-md-15 { + padding-inline-start: 60px !important; + } + + .pe-md-15 { + padding-inline-end: 60px !important; + } + + .pa-md-15 { + padding: 60px !important; + } + + .pt-md-16, +.py-md-16 { + padding-top: 64px !important; + } + + .pr-md-16, +.px-md-16 { + padding-right: 64px !important; + } + + .pl-md-16, +.px-md-16 { + padding-left: 64px !important; + } + + .pb-md-16, +.py-md-16 { + padding-bottom: 64px !important; + } + + .ps-md-16 { + padding-inline-start: 64px !important; + } + + .pe-md-16 { + padding-inline-end: 64px !important; + } + + .pa-md-16 { + padding: 64px !important; + } + + .pt-md-auto, +.py-md-auto { + padding-top: auto !important; + } + + .pr-md-auto, +.px-md-auto { + padding-right: auto !important; + } + + .pl-md-auto, +.px-md-auto { + padding-left: auto !important; + } + + .pb-md-auto, +.py-md-auto { + padding-bottom: auto !important; + } + + .ps-md-auto { + padding-inline-start: auto !important; + } + + .pe-md-auto { + padding-inline-end: auto !important; + } + + .pa-md-auto { + padding: auto !important; + } + + .mt-md-n1, +.my-md-n1 { + margin-top: -4px !important; + } + + .mr-md-n1, +.mx-md-n1 { + margin-right: -4px !important; + } + + .ml-md-n1, +.mx-md-n1 { + margin-left: -4px !important; + } + + .mb-md-n1, +.my-md-n1 { + margin-bottom: -4px !important; + } + + .ms-md-n1 { + margin-inline-start: -4px !important; + } + + .me-md-n1 { + margin-inline-end: -4px !important; + } + + .ma-md-n1 { + margin: -4px !important; + } + + .mt-md-n2, +.my-md-n2 { + margin-top: -8px !important; + } + + .mr-md-n2, +.mx-md-n2 { + margin-right: -8px !important; + } + + .ml-md-n2, +.mx-md-n2 { + margin-left: -8px !important; + } + + .mb-md-n2, +.my-md-n2 { + margin-bottom: -8px !important; + } + + .ms-md-n2 { + margin-inline-start: -8px !important; + } + + .me-md-n2 { + margin-inline-end: -8px !important; + } + + .ma-md-n2 { + margin: -8px !important; + } + + .mt-md-n3, +.my-md-n3 { + margin-top: -12px !important; + } + + .mr-md-n3, +.mx-md-n3 { + margin-right: -12px !important; + } + + .ml-md-n3, +.mx-md-n3 { + margin-left: -12px !important; + } + + .mb-md-n3, +.my-md-n3 { + margin-bottom: -12px !important; + } + + .ms-md-n3 { + margin-inline-start: -12px !important; + } + + .me-md-n3 { + margin-inline-end: -12px !important; + } + + .ma-md-n3 { + margin: -12px !important; + } + + .mt-md-n4, +.my-md-n4 { + margin-top: -16px !important; + } + + .mr-md-n4, +.mx-md-n4 { + margin-right: -16px !important; + } + + .ml-md-n4, +.mx-md-n4 { + margin-left: -16px !important; + } + + .mb-md-n4, +.my-md-n4 { + margin-bottom: -16px !important; + } + + .ms-md-n4 { + margin-inline-start: -16px !important; + } + + .me-md-n4 { + margin-inline-end: -16px !important; + } + + .ma-md-n4 { + margin: -16px !important; + } + + .mt-md-n5, +.my-md-n5 { + margin-top: -20px !important; + } + + .mr-md-n5, +.mx-md-n5 { + margin-right: -20px !important; + } + + .ml-md-n5, +.mx-md-n5 { + margin-left: -20px !important; + } + + .mb-md-n5, +.my-md-n5 { + margin-bottom: -20px !important; + } + + .ms-md-n5 { + margin-inline-start: -20px !important; + } + + .me-md-n5 { + margin-inline-end: -20px !important; + } + + .ma-md-n5 { + margin: -20px !important; + } + + .mt-md-n6, +.my-md-n6 { + margin-top: -24px !important; + } + + .mr-md-n6, +.mx-md-n6 { + margin-right: -24px !important; + } + + .ml-md-n6, +.mx-md-n6 { + margin-left: -24px !important; + } + + .mb-md-n6, +.my-md-n6 { + margin-bottom: -24px !important; + } + + .ms-md-n6 { + margin-inline-start: -24px !important; + } + + .me-md-n6 { + margin-inline-end: -24px !important; + } + + .ma-md-n6 { + margin: -24px !important; + } + + .mt-md-n7, +.my-md-n7 { + margin-top: -28px !important; + } + + .mr-md-n7, +.mx-md-n7 { + margin-right: -28px !important; + } + + .ml-md-n7, +.mx-md-n7 { + margin-left: -28px !important; + } + + .mb-md-n7, +.my-md-n7 { + margin-bottom: -28px !important; + } + + .ms-md-n7 { + margin-inline-start: -28px !important; + } + + .me-md-n7 { + margin-inline-end: -28px !important; + } + + .ma-md-n7 { + margin: -28px !important; + } + + .mt-md-n8, +.my-md-n8 { + margin-top: -32px !important; + } + + .mr-md-n8, +.mx-md-n8 { + margin-right: -32px !important; + } + + .ml-md-n8, +.mx-md-n8 { + margin-left: -32px !important; + } + + .mb-md-n8, +.my-md-n8 { + margin-bottom: -32px !important; + } + + .ms-md-n8 { + margin-inline-start: -32px !important; + } + + .me-md-n8 { + margin-inline-end: -32px !important; + } + + .ma-md-n8 { + margin: -32px !important; + } + + .mt-md-n9, +.my-md-n9 { + margin-top: -36px !important; + } + + .mr-md-n9, +.mx-md-n9 { + margin-right: -36px !important; + } + + .ml-md-n9, +.mx-md-n9 { + margin-left: -36px !important; + } + + .mb-md-n9, +.my-md-n9 { + margin-bottom: -36px !important; + } + + .ms-md-n9 { + margin-inline-start: -36px !important; + } + + .me-md-n9 { + margin-inline-end: -36px !important; + } + + .ma-md-n9 { + margin: -36px !important; + } + + .mt-md-n10, +.my-md-n10 { + margin-top: -40px !important; + } + + .mr-md-n10, +.mx-md-n10 { + margin-right: -40px !important; + } + + .ml-md-n10, +.mx-md-n10 { + margin-left: -40px !important; + } + + .mb-md-n10, +.my-md-n10 { + margin-bottom: -40px !important; + } + + .ms-md-n10 { + margin-inline-start: -40px !important; + } + + .me-md-n10 { + margin-inline-end: -40px !important; + } + + .ma-md-n10 { + margin: -40px !important; + } + + .mt-md-n11, +.my-md-n11 { + margin-top: -44px !important; + } + + .mr-md-n11, +.mx-md-n11 { + margin-right: -44px !important; + } + + .ml-md-n11, +.mx-md-n11 { + margin-left: -44px !important; + } + + .mb-md-n11, +.my-md-n11 { + margin-bottom: -44px !important; + } + + .ms-md-n11 { + margin-inline-start: -44px !important; + } + + .me-md-n11 { + margin-inline-end: -44px !important; + } + + .ma-md-n11 { + margin: -44px !important; + } + + .mt-md-n12, +.my-md-n12 { + margin-top: -48px !important; + } + + .mr-md-n12, +.mx-md-n12 { + margin-right: -48px !important; + } + + .ml-md-n12, +.mx-md-n12 { + margin-left: -48px !important; + } + + .mb-md-n12, +.my-md-n12 { + margin-bottom: -48px !important; + } + + .ms-md-n12 { + margin-inline-start: -48px !important; + } + + .me-md-n12 { + margin-inline-end: -48px !important; + } + + .ma-md-n12 { + margin: -48px !important; + } + + .mt-md-n13, +.my-md-n13 { + margin-top: -52px !important; + } + + .mr-md-n13, +.mx-md-n13 { + margin-right: -52px !important; + } + + .ml-md-n13, +.mx-md-n13 { + margin-left: -52px !important; + } + + .mb-md-n13, +.my-md-n13 { + margin-bottom: -52px !important; + } + + .ms-md-n13 { + margin-inline-start: -52px !important; + } + + .me-md-n13 { + margin-inline-end: -52px !important; + } + + .ma-md-n13 { + margin: -52px !important; + } + + .mt-md-n14, +.my-md-n14 { + margin-top: -56px !important; + } + + .mr-md-n14, +.mx-md-n14 { + margin-right: -56px !important; + } + + .ml-md-n14, +.mx-md-n14 { + margin-left: -56px !important; + } + + .mb-md-n14, +.my-md-n14 { + margin-bottom: -56px !important; + } + + .ms-md-n14 { + margin-inline-start: -56px !important; + } + + .me-md-n14 { + margin-inline-end: -56px !important; + } + + .ma-md-n14 { + margin: -56px !important; + } + + .mt-md-n15, +.my-md-n15 { + margin-top: -60px !important; + } + + .mr-md-n15, +.mx-md-n15 { + margin-right: -60px !important; + } + + .ml-md-n15, +.mx-md-n15 { + margin-left: -60px !important; + } + + .mb-md-n15, +.my-md-n15 { + margin-bottom: -60px !important; + } + + .ms-md-n15 { + margin-inline-start: -60px !important; + } + + .me-md-n15 { + margin-inline-end: -60px !important; + } + + .ma-md-n15 { + margin: -60px !important; + } + + .mt-md-n16, +.my-md-n16 { + margin-top: -64px !important; + } + + .mr-md-n16, +.mx-md-n16 { + margin-right: -64px !important; + } + + .ml-md-n16, +.mx-md-n16 { + margin-left: -64px !important; + } + + .mb-md-n16, +.my-md-n16 { + margin-bottom: -64px !important; + } + + .ms-md-n16 { + margin-inline-start: -64px !important; + } + + .me-md-n16 { + margin-inline-end: -64px !important; + } + + .ma-md-n16 { + margin: -64px !important; + } +} +@media screen and (min-width: 1280px) { + .mt-lg-0, +.my-lg-0 { + margin-top: 0 !important; + } + + .mr-lg-0, +.mx-lg-0 { + margin-right: 0 !important; + } + + .ml-lg-0, +.mx-lg-0 { + margin-left: 0 !important; + } + + .mb-lg-0, +.my-lg-0 { + margin-bottom: 0 !important; + } + + .ms-lg-0 { + margin-inline-start: 0 !important; + } + + .me-lg-0 { + margin-inline-end: 0 !important; + } + + .ma-lg-0 { + margin: 0 !important; + } + + .mt-lg-1, +.my-lg-1 { + margin-top: 4px !important; + } + + .mr-lg-1, +.mx-lg-1 { + margin-right: 4px !important; + } + + .ml-lg-1, +.mx-lg-1 { + margin-left: 4px !important; + } + + .mb-lg-1, +.my-lg-1 { + margin-bottom: 4px !important; + } + + .ms-lg-1 { + margin-inline-start: 4px !important; + } + + .me-lg-1 { + margin-inline-end: 4px !important; + } + + .ma-lg-1 { + margin: 4px !important; + } + + .mt-lg-2, +.my-lg-2 { + margin-top: 8px !important; + } + + .mr-lg-2, +.mx-lg-2 { + margin-right: 8px !important; + } + + .ml-lg-2, +.mx-lg-2 { + margin-left: 8px !important; + } + + .mb-lg-2, +.my-lg-2 { + margin-bottom: 8px !important; + } + + .ms-lg-2 { + margin-inline-start: 8px !important; + } + + .me-lg-2 { + margin-inline-end: 8px !important; + } + + .ma-lg-2 { + margin: 8px !important; + } + + .mt-lg-3, +.my-lg-3 { + margin-top: 12px !important; + } + + .mr-lg-3, +.mx-lg-3 { + margin-right: 12px !important; + } + + .ml-lg-3, +.mx-lg-3 { + margin-left: 12px !important; + } + + .mb-lg-3, +.my-lg-3 { + margin-bottom: 12px !important; + } + + .ms-lg-3 { + margin-inline-start: 12px !important; + } + + .me-lg-3 { + margin-inline-end: 12px !important; + } + + .ma-lg-3 { + margin: 12px !important; + } + + .mt-lg-4, +.my-lg-4 { + margin-top: 16px !important; + } + + .mr-lg-4, +.mx-lg-4 { + margin-right: 16px !important; + } + + .ml-lg-4, +.mx-lg-4 { + margin-left: 16px !important; + } + + .mb-lg-4, +.my-lg-4 { + margin-bottom: 16px !important; + } + + .ms-lg-4 { + margin-inline-start: 16px !important; + } + + .me-lg-4 { + margin-inline-end: 16px !important; + } + + .ma-lg-4 { + margin: 16px !important; + } + + .mt-lg-5, +.my-lg-5 { + margin-top: 20px !important; + } + + .mr-lg-5, +.mx-lg-5 { + margin-right: 20px !important; + } + + .ml-lg-5, +.mx-lg-5 { + margin-left: 20px !important; + } + + .mb-lg-5, +.my-lg-5 { + margin-bottom: 20px !important; + } + + .ms-lg-5 { + margin-inline-start: 20px !important; + } + + .me-lg-5 { + margin-inline-end: 20px !important; + } + + .ma-lg-5 { + margin: 20px !important; + } + + .mt-lg-6, +.my-lg-6 { + margin-top: 24px !important; + } + + .mr-lg-6, +.mx-lg-6 { + margin-right: 24px !important; + } + + .ml-lg-6, +.mx-lg-6 { + margin-left: 24px !important; + } + + .mb-lg-6, +.my-lg-6 { + margin-bottom: 24px !important; + } + + .ms-lg-6 { + margin-inline-start: 24px !important; + } + + .me-lg-6 { + margin-inline-end: 24px !important; + } + + .ma-lg-6 { + margin: 24px !important; + } + + .mt-lg-7, +.my-lg-7 { + margin-top: 28px !important; + } + + .mr-lg-7, +.mx-lg-7 { + margin-right: 28px !important; + } + + .ml-lg-7, +.mx-lg-7 { + margin-left: 28px !important; + } + + .mb-lg-7, +.my-lg-7 { + margin-bottom: 28px !important; + } + + .ms-lg-7 { + margin-inline-start: 28px !important; + } + + .me-lg-7 { + margin-inline-end: 28px !important; + } + + .ma-lg-7 { + margin: 28px !important; + } + + .mt-lg-8, +.my-lg-8 { + margin-top: 32px !important; + } + + .mr-lg-8, +.mx-lg-8 { + margin-right: 32px !important; + } + + .ml-lg-8, +.mx-lg-8 { + margin-left: 32px !important; + } + + .mb-lg-8, +.my-lg-8 { + margin-bottom: 32px !important; + } + + .ms-lg-8 { + margin-inline-start: 32px !important; + } + + .me-lg-8 { + margin-inline-end: 32px !important; + } + + .ma-lg-8 { + margin: 32px !important; + } + + .mt-lg-9, +.my-lg-9 { + margin-top: 36px !important; + } + + .mr-lg-9, +.mx-lg-9 { + margin-right: 36px !important; + } + + .ml-lg-9, +.mx-lg-9 { + margin-left: 36px !important; + } + + .mb-lg-9, +.my-lg-9 { + margin-bottom: 36px !important; + } + + .ms-lg-9 { + margin-inline-start: 36px !important; + } + + .me-lg-9 { + margin-inline-end: 36px !important; + } + + .ma-lg-9 { + margin: 36px !important; + } + + .mt-lg-10, +.my-lg-10 { + margin-top: 40px !important; + } + + .mr-lg-10, +.mx-lg-10 { + margin-right: 40px !important; + } + + .ml-lg-10, +.mx-lg-10 { + margin-left: 40px !important; + } + + .mb-lg-10, +.my-lg-10 { + margin-bottom: 40px !important; + } + + .ms-lg-10 { + margin-inline-start: 40px !important; + } + + .me-lg-10 { + margin-inline-end: 40px !important; + } + + .ma-lg-10 { + margin: 40px !important; + } + + .mt-lg-11, +.my-lg-11 { + margin-top: 44px !important; + } + + .mr-lg-11, +.mx-lg-11 { + margin-right: 44px !important; + } + + .ml-lg-11, +.mx-lg-11 { + margin-left: 44px !important; + } + + .mb-lg-11, +.my-lg-11 { + margin-bottom: 44px !important; + } + + .ms-lg-11 { + margin-inline-start: 44px !important; + } + + .me-lg-11 { + margin-inline-end: 44px !important; + } + + .ma-lg-11 { + margin: 44px !important; + } + + .mt-lg-12, +.my-lg-12 { + margin-top: 48px !important; + } + + .mr-lg-12, +.mx-lg-12 { + margin-right: 48px !important; + } + + .ml-lg-12, +.mx-lg-12 { + margin-left: 48px !important; + } + + .mb-lg-12, +.my-lg-12 { + margin-bottom: 48px !important; + } + + .ms-lg-12 { + margin-inline-start: 48px !important; + } + + .me-lg-12 { + margin-inline-end: 48px !important; + } + + .ma-lg-12 { + margin: 48px !important; + } + + .mt-lg-13, +.my-lg-13 { + margin-top: 52px !important; + } + + .mr-lg-13, +.mx-lg-13 { + margin-right: 52px !important; + } + + .ml-lg-13, +.mx-lg-13 { + margin-left: 52px !important; + } + + .mb-lg-13, +.my-lg-13 { + margin-bottom: 52px !important; + } + + .ms-lg-13 { + margin-inline-start: 52px !important; + } + + .me-lg-13 { + margin-inline-end: 52px !important; + } + + .ma-lg-13 { + margin: 52px !important; + } + + .mt-lg-14, +.my-lg-14 { + margin-top: 56px !important; + } + + .mr-lg-14, +.mx-lg-14 { + margin-right: 56px !important; + } + + .ml-lg-14, +.mx-lg-14 { + margin-left: 56px !important; + } + + .mb-lg-14, +.my-lg-14 { + margin-bottom: 56px !important; + } + + .ms-lg-14 { + margin-inline-start: 56px !important; + } + + .me-lg-14 { + margin-inline-end: 56px !important; + } + + .ma-lg-14 { + margin: 56px !important; + } + + .mt-lg-15, +.my-lg-15 { + margin-top: 60px !important; + } + + .mr-lg-15, +.mx-lg-15 { + margin-right: 60px !important; + } + + .ml-lg-15, +.mx-lg-15 { + margin-left: 60px !important; + } + + .mb-lg-15, +.my-lg-15 { + margin-bottom: 60px !important; + } + + .ms-lg-15 { + margin-inline-start: 60px !important; + } + + .me-lg-15 { + margin-inline-end: 60px !important; + } + + .ma-lg-15 { + margin: 60px !important; + } + + .mt-lg-16, +.my-lg-16 { + margin-top: 64px !important; + } + + .mr-lg-16, +.mx-lg-16 { + margin-right: 64px !important; + } + + .ml-lg-16, +.mx-lg-16 { + margin-left: 64px !important; + } + + .mb-lg-16, +.my-lg-16 { + margin-bottom: 64px !important; + } + + .ms-lg-16 { + margin-inline-start: 64px !important; + } + + .me-lg-16 { + margin-inline-end: 64px !important; + } + + .ma-lg-16 { + margin: 64px !important; + } + + .mt-lg-auto, +.my-lg-auto { + margin-top: auto !important; + } + + .mr-lg-auto, +.mx-lg-auto { + margin-right: auto !important; + } + + .ml-lg-auto, +.mx-lg-auto { + margin-left: auto !important; + } + + .mb-lg-auto, +.my-lg-auto { + margin-bottom: auto !important; + } + + .ms-lg-auto { + margin-inline-start: auto !important; + } + + .me-lg-auto { + margin-inline-end: auto !important; + } + + .ma-lg-auto { + margin: auto !important; + } + + .pt-lg-0, +.py-lg-0 { + padding-top: 0 !important; + } + + .pr-lg-0, +.px-lg-0 { + padding-right: 0 !important; + } + + .pl-lg-0, +.px-lg-0 { + padding-left: 0 !important; + } + + .pb-lg-0, +.py-lg-0 { + padding-bottom: 0 !important; + } + + .ps-lg-0 { + padding-inline-start: 0 !important; + } + + .pe-lg-0 { + padding-inline-end: 0 !important; + } + + .pa-lg-0 { + padding: 0 !important; + } + + .pt-lg-1, +.py-lg-1 { + padding-top: 4px !important; + } + + .pr-lg-1, +.px-lg-1 { + padding-right: 4px !important; + } + + .pl-lg-1, +.px-lg-1 { + padding-left: 4px !important; + } + + .pb-lg-1, +.py-lg-1 { + padding-bottom: 4px !important; + } + + .ps-lg-1 { + padding-inline-start: 4px !important; + } + + .pe-lg-1 { + padding-inline-end: 4px !important; + } + + .pa-lg-1 { + padding: 4px !important; + } + + .pt-lg-2, +.py-lg-2 { + padding-top: 8px !important; + } + + .pr-lg-2, +.px-lg-2 { + padding-right: 8px !important; + } + + .pl-lg-2, +.px-lg-2 { + padding-left: 8px !important; + } + + .pb-lg-2, +.py-lg-2 { + padding-bottom: 8px !important; + } + + .ps-lg-2 { + padding-inline-start: 8px !important; + } + + .pe-lg-2 { + padding-inline-end: 8px !important; + } + + .pa-lg-2 { + padding: 8px !important; + } + + .pt-lg-3, +.py-lg-3 { + padding-top: 12px !important; + } + + .pr-lg-3, +.px-lg-3 { + padding-right: 12px !important; + } + + .pl-lg-3, +.px-lg-3 { + padding-left: 12px !important; + } + + .pb-lg-3, +.py-lg-3 { + padding-bottom: 12px !important; + } + + .ps-lg-3 { + padding-inline-start: 12px !important; + } + + .pe-lg-3 { + padding-inline-end: 12px !important; + } + + .pa-lg-3 { + padding: 12px !important; + } + + .pt-lg-4, +.py-lg-4 { + padding-top: 16px !important; + } + + .pr-lg-4, +.px-lg-4 { + padding-right: 16px !important; + } + + .pl-lg-4, +.px-lg-4 { + padding-left: 16px !important; + } + + .pb-lg-4, +.py-lg-4 { + padding-bottom: 16px !important; + } + + .ps-lg-4 { + padding-inline-start: 16px !important; + } + + .pe-lg-4 { + padding-inline-end: 16px !important; + } + + .pa-lg-4 { + padding: 16px !important; + } + + .pt-lg-5, +.py-lg-5 { + padding-top: 20px !important; + } + + .pr-lg-5, +.px-lg-5 { + padding-right: 20px !important; + } + + .pl-lg-5, +.px-lg-5 { + padding-left: 20px !important; + } + + .pb-lg-5, +.py-lg-5 { + padding-bottom: 20px !important; + } + + .ps-lg-5 { + padding-inline-start: 20px !important; + } + + .pe-lg-5 { + padding-inline-end: 20px !important; + } + + .pa-lg-5 { + padding: 20px !important; + } + + .pt-lg-6, +.py-lg-6 { + padding-top: 24px !important; + } + + .pr-lg-6, +.px-lg-6 { + padding-right: 24px !important; + } + + .pl-lg-6, +.px-lg-6 { + padding-left: 24px !important; + } + + .pb-lg-6, +.py-lg-6 { + padding-bottom: 24px !important; + } + + .ps-lg-6 { + padding-inline-start: 24px !important; + } + + .pe-lg-6 { + padding-inline-end: 24px !important; + } + + .pa-lg-6 { + padding: 24px !important; + } + + .pt-lg-7, +.py-lg-7 { + padding-top: 28px !important; + } + + .pr-lg-7, +.px-lg-7 { + padding-right: 28px !important; + } + + .pl-lg-7, +.px-lg-7 { + padding-left: 28px !important; + } + + .pb-lg-7, +.py-lg-7 { + padding-bottom: 28px !important; + } + + .ps-lg-7 { + padding-inline-start: 28px !important; + } + + .pe-lg-7 { + padding-inline-end: 28px !important; + } + + .pa-lg-7 { + padding: 28px !important; + } + + .pt-lg-8, +.py-lg-8 { + padding-top: 32px !important; + } + + .pr-lg-8, +.px-lg-8 { + padding-right: 32px !important; + } + + .pl-lg-8, +.px-lg-8 { + padding-left: 32px !important; + } + + .pb-lg-8, +.py-lg-8 { + padding-bottom: 32px !important; + } + + .ps-lg-8 { + padding-inline-start: 32px !important; + } + + .pe-lg-8 { + padding-inline-end: 32px !important; + } + + .pa-lg-8 { + padding: 32px !important; + } + + .pt-lg-9, +.py-lg-9 { + padding-top: 36px !important; + } + + .pr-lg-9, +.px-lg-9 { + padding-right: 36px !important; + } + + .pl-lg-9, +.px-lg-9 { + padding-left: 36px !important; + } + + .pb-lg-9, +.py-lg-9 { + padding-bottom: 36px !important; + } + + .ps-lg-9 { + padding-inline-start: 36px !important; + } + + .pe-lg-9 { + padding-inline-end: 36px !important; + } + + .pa-lg-9 { + padding: 36px !important; + } + + .pt-lg-10, +.py-lg-10 { + padding-top: 40px !important; + } + + .pr-lg-10, +.px-lg-10 { + padding-right: 40px !important; + } + + .pl-lg-10, +.px-lg-10 { + padding-left: 40px !important; + } + + .pb-lg-10, +.py-lg-10 { + padding-bottom: 40px !important; + } + + .ps-lg-10 { + padding-inline-start: 40px !important; + } + + .pe-lg-10 { + padding-inline-end: 40px !important; + } + + .pa-lg-10 { + padding: 40px !important; + } + + .pt-lg-11, +.py-lg-11 { + padding-top: 44px !important; + } + + .pr-lg-11, +.px-lg-11 { + padding-right: 44px !important; + } + + .pl-lg-11, +.px-lg-11 { + padding-left: 44px !important; + } + + .pb-lg-11, +.py-lg-11 { + padding-bottom: 44px !important; + } + + .ps-lg-11 { + padding-inline-start: 44px !important; + } + + .pe-lg-11 { + padding-inline-end: 44px !important; + } + + .pa-lg-11 { + padding: 44px !important; + } + + .pt-lg-12, +.py-lg-12 { + padding-top: 48px !important; + } + + .pr-lg-12, +.px-lg-12 { + padding-right: 48px !important; + } + + .pl-lg-12, +.px-lg-12 { + padding-left: 48px !important; + } + + .pb-lg-12, +.py-lg-12 { + padding-bottom: 48px !important; + } + + .ps-lg-12 { + padding-inline-start: 48px !important; + } + + .pe-lg-12 { + padding-inline-end: 48px !important; + } + + .pa-lg-12 { + padding: 48px !important; + } + + .pt-lg-13, +.py-lg-13 { + padding-top: 52px !important; + } + + .pr-lg-13, +.px-lg-13 { + padding-right: 52px !important; + } + + .pl-lg-13, +.px-lg-13 { + padding-left: 52px !important; + } + + .pb-lg-13, +.py-lg-13 { + padding-bottom: 52px !important; + } + + .ps-lg-13 { + padding-inline-start: 52px !important; + } + + .pe-lg-13 { + padding-inline-end: 52px !important; + } + + .pa-lg-13 { + padding: 52px !important; + } + + .pt-lg-14, +.py-lg-14 { + padding-top: 56px !important; + } + + .pr-lg-14, +.px-lg-14 { + padding-right: 56px !important; + } + + .pl-lg-14, +.px-lg-14 { + padding-left: 56px !important; + } + + .pb-lg-14, +.py-lg-14 { + padding-bottom: 56px !important; + } + + .ps-lg-14 { + padding-inline-start: 56px !important; + } + + .pe-lg-14 { + padding-inline-end: 56px !important; + } + + .pa-lg-14 { + padding: 56px !important; + } + + .pt-lg-15, +.py-lg-15 { + padding-top: 60px !important; + } + + .pr-lg-15, +.px-lg-15 { + padding-right: 60px !important; + } + + .pl-lg-15, +.px-lg-15 { + padding-left: 60px !important; + } + + .pb-lg-15, +.py-lg-15 { + padding-bottom: 60px !important; + } + + .ps-lg-15 { + padding-inline-start: 60px !important; + } + + .pe-lg-15 { + padding-inline-end: 60px !important; + } + + .pa-lg-15 { + padding: 60px !important; + } + + .pt-lg-16, +.py-lg-16 { + padding-top: 64px !important; + } + + .pr-lg-16, +.px-lg-16 { + padding-right: 64px !important; + } + + .pl-lg-16, +.px-lg-16 { + padding-left: 64px !important; + } + + .pb-lg-16, +.py-lg-16 { + padding-bottom: 64px !important; + } + + .ps-lg-16 { + padding-inline-start: 64px !important; + } + + .pe-lg-16 { + padding-inline-end: 64px !important; + } + + .pa-lg-16 { + padding: 64px !important; + } + + .pt-lg-auto, +.py-lg-auto { + padding-top: auto !important; + } + + .pr-lg-auto, +.px-lg-auto { + padding-right: auto !important; + } + + .pl-lg-auto, +.px-lg-auto { + padding-left: auto !important; + } + + .pb-lg-auto, +.py-lg-auto { + padding-bottom: auto !important; + } + + .ps-lg-auto { + padding-inline-start: auto !important; + } + + .pe-lg-auto { + padding-inline-end: auto !important; + } + + .pa-lg-auto { + padding: auto !important; + } + + .mt-lg-n1, +.my-lg-n1 { + margin-top: -4px !important; + } + + .mr-lg-n1, +.mx-lg-n1 { + margin-right: -4px !important; + } + + .ml-lg-n1, +.mx-lg-n1 { + margin-left: -4px !important; + } + + .mb-lg-n1, +.my-lg-n1 { + margin-bottom: -4px !important; + } + + .ms-lg-n1 { + margin-inline-start: -4px !important; + } + + .me-lg-n1 { + margin-inline-end: -4px !important; + } + + .ma-lg-n1 { + margin: -4px !important; + } + + .mt-lg-n2, +.my-lg-n2 { + margin-top: -8px !important; + } + + .mr-lg-n2, +.mx-lg-n2 { + margin-right: -8px !important; + } + + .ml-lg-n2, +.mx-lg-n2 { + margin-left: -8px !important; + } + + .mb-lg-n2, +.my-lg-n2 { + margin-bottom: -8px !important; + } + + .ms-lg-n2 { + margin-inline-start: -8px !important; + } + + .me-lg-n2 { + margin-inline-end: -8px !important; + } + + .ma-lg-n2 { + margin: -8px !important; + } + + .mt-lg-n3, +.my-lg-n3 { + margin-top: -12px !important; + } + + .mr-lg-n3, +.mx-lg-n3 { + margin-right: -12px !important; + } + + .ml-lg-n3, +.mx-lg-n3 { + margin-left: -12px !important; + } + + .mb-lg-n3, +.my-lg-n3 { + margin-bottom: -12px !important; + } + + .ms-lg-n3 { + margin-inline-start: -12px !important; + } + + .me-lg-n3 { + margin-inline-end: -12px !important; + } + + .ma-lg-n3 { + margin: -12px !important; + } + + .mt-lg-n4, +.my-lg-n4 { + margin-top: -16px !important; + } + + .mr-lg-n4, +.mx-lg-n4 { + margin-right: -16px !important; + } + + .ml-lg-n4, +.mx-lg-n4 { + margin-left: -16px !important; + } + + .mb-lg-n4, +.my-lg-n4 { + margin-bottom: -16px !important; + } + + .ms-lg-n4 { + margin-inline-start: -16px !important; + } + + .me-lg-n4 { + margin-inline-end: -16px !important; + } + + .ma-lg-n4 { + margin: -16px !important; + } + + .mt-lg-n5, +.my-lg-n5 { + margin-top: -20px !important; + } + + .mr-lg-n5, +.mx-lg-n5 { + margin-right: -20px !important; + } + + .ml-lg-n5, +.mx-lg-n5 { + margin-left: -20px !important; + } + + .mb-lg-n5, +.my-lg-n5 { + margin-bottom: -20px !important; + } + + .ms-lg-n5 { + margin-inline-start: -20px !important; + } + + .me-lg-n5 { + margin-inline-end: -20px !important; + } + + .ma-lg-n5 { + margin: -20px !important; + } + + .mt-lg-n6, +.my-lg-n6 { + margin-top: -24px !important; + } + + .mr-lg-n6, +.mx-lg-n6 { + margin-right: -24px !important; + } + + .ml-lg-n6, +.mx-lg-n6 { + margin-left: -24px !important; + } + + .mb-lg-n6, +.my-lg-n6 { + margin-bottom: -24px !important; + } + + .ms-lg-n6 { + margin-inline-start: -24px !important; + } + + .me-lg-n6 { + margin-inline-end: -24px !important; + } + + .ma-lg-n6 { + margin: -24px !important; + } + + .mt-lg-n7, +.my-lg-n7 { + margin-top: -28px !important; + } + + .mr-lg-n7, +.mx-lg-n7 { + margin-right: -28px !important; + } + + .ml-lg-n7, +.mx-lg-n7 { + margin-left: -28px !important; + } + + .mb-lg-n7, +.my-lg-n7 { + margin-bottom: -28px !important; + } + + .ms-lg-n7 { + margin-inline-start: -28px !important; + } + + .me-lg-n7 { + margin-inline-end: -28px !important; + } + + .ma-lg-n7 { + margin: -28px !important; + } + + .mt-lg-n8, +.my-lg-n8 { + margin-top: -32px !important; + } + + .mr-lg-n8, +.mx-lg-n8 { + margin-right: -32px !important; + } + + .ml-lg-n8, +.mx-lg-n8 { + margin-left: -32px !important; + } + + .mb-lg-n8, +.my-lg-n8 { + margin-bottom: -32px !important; + } + + .ms-lg-n8 { + margin-inline-start: -32px !important; + } + + .me-lg-n8 { + margin-inline-end: -32px !important; + } + + .ma-lg-n8 { + margin: -32px !important; + } + + .mt-lg-n9, +.my-lg-n9 { + margin-top: -36px !important; + } + + .mr-lg-n9, +.mx-lg-n9 { + margin-right: -36px !important; + } + + .ml-lg-n9, +.mx-lg-n9 { + margin-left: -36px !important; + } + + .mb-lg-n9, +.my-lg-n9 { + margin-bottom: -36px !important; + } + + .ms-lg-n9 { + margin-inline-start: -36px !important; + } + + .me-lg-n9 { + margin-inline-end: -36px !important; + } + + .ma-lg-n9 { + margin: -36px !important; + } + + .mt-lg-n10, +.my-lg-n10 { + margin-top: -40px !important; + } + + .mr-lg-n10, +.mx-lg-n10 { + margin-right: -40px !important; + } + + .ml-lg-n10, +.mx-lg-n10 { + margin-left: -40px !important; + } + + .mb-lg-n10, +.my-lg-n10 { + margin-bottom: -40px !important; + } + + .ms-lg-n10 { + margin-inline-start: -40px !important; + } + + .me-lg-n10 { + margin-inline-end: -40px !important; + } + + .ma-lg-n10 { + margin: -40px !important; + } + + .mt-lg-n11, +.my-lg-n11 { + margin-top: -44px !important; + } + + .mr-lg-n11, +.mx-lg-n11 { + margin-right: -44px !important; + } + + .ml-lg-n11, +.mx-lg-n11 { + margin-left: -44px !important; + } + + .mb-lg-n11, +.my-lg-n11 { + margin-bottom: -44px !important; + } + + .ms-lg-n11 { + margin-inline-start: -44px !important; + } + + .me-lg-n11 { + margin-inline-end: -44px !important; + } + + .ma-lg-n11 { + margin: -44px !important; + } + + .mt-lg-n12, +.my-lg-n12 { + margin-top: -48px !important; + } + + .mr-lg-n12, +.mx-lg-n12 { + margin-right: -48px !important; + } + + .ml-lg-n12, +.mx-lg-n12 { + margin-left: -48px !important; + } + + .mb-lg-n12, +.my-lg-n12 { + margin-bottom: -48px !important; + } + + .ms-lg-n12 { + margin-inline-start: -48px !important; + } + + .me-lg-n12 { + margin-inline-end: -48px !important; + } + + .ma-lg-n12 { + margin: -48px !important; + } + + .mt-lg-n13, +.my-lg-n13 { + margin-top: -52px !important; + } + + .mr-lg-n13, +.mx-lg-n13 { + margin-right: -52px !important; + } + + .ml-lg-n13, +.mx-lg-n13 { + margin-left: -52px !important; + } + + .mb-lg-n13, +.my-lg-n13 { + margin-bottom: -52px !important; + } + + .ms-lg-n13 { + margin-inline-start: -52px !important; + } + + .me-lg-n13 { + margin-inline-end: -52px !important; + } + + .ma-lg-n13 { + margin: -52px !important; + } + + .mt-lg-n14, +.my-lg-n14 { + margin-top: -56px !important; + } + + .mr-lg-n14, +.mx-lg-n14 { + margin-right: -56px !important; + } + + .ml-lg-n14, +.mx-lg-n14 { + margin-left: -56px !important; + } + + .mb-lg-n14, +.my-lg-n14 { + margin-bottom: -56px !important; + } + + .ms-lg-n14 { + margin-inline-start: -56px !important; + } + + .me-lg-n14 { + margin-inline-end: -56px !important; + } + + .ma-lg-n14 { + margin: -56px !important; + } + + .mt-lg-n15, +.my-lg-n15 { + margin-top: -60px !important; + } + + .mr-lg-n15, +.mx-lg-n15 { + margin-right: -60px !important; + } + + .ml-lg-n15, +.mx-lg-n15 { + margin-left: -60px !important; + } + + .mb-lg-n15, +.my-lg-n15 { + margin-bottom: -60px !important; + } + + .ms-lg-n15 { + margin-inline-start: -60px !important; + } + + .me-lg-n15 { + margin-inline-end: -60px !important; + } + + .ma-lg-n15 { + margin: -60px !important; + } + + .mt-lg-n16, +.my-lg-n16 { + margin-top: -64px !important; + } + + .mr-lg-n16, +.mx-lg-n16 { + margin-right: -64px !important; + } + + .ml-lg-n16, +.mx-lg-n16 { + margin-left: -64px !important; + } + + .mb-lg-n16, +.my-lg-n16 { + margin-bottom: -64px !important; + } + + .ms-lg-n16 { + margin-inline-start: -64px !important; + } + + .me-lg-n16 { + margin-inline-end: -64px !important; + } + + .ma-lg-n16 { + margin: -64px !important; + } +} +@media screen and (min-width: 1920px) { + .mt-xl-0, +.my-xl-0 { + margin-top: 0 !important; + } + + .mr-xl-0, +.mx-xl-0 { + margin-right: 0 !important; + } + + .ml-xl-0, +.mx-xl-0 { + margin-left: 0 !important; + } + + .mb-xl-0, +.my-xl-0 { + margin-bottom: 0 !important; + } + + .ms-xl-0 { + margin-inline-start: 0 !important; + } + + .me-xl-0 { + margin-inline-end: 0 !important; + } + + .ma-xl-0 { + margin: 0 !important; + } + + .mt-xl-1, +.my-xl-1 { + margin-top: 4px !important; + } + + .mr-xl-1, +.mx-xl-1 { + margin-right: 4px !important; + } + + .ml-xl-1, +.mx-xl-1 { + margin-left: 4px !important; + } + + .mb-xl-1, +.my-xl-1 { + margin-bottom: 4px !important; + } + + .ms-xl-1 { + margin-inline-start: 4px !important; + } + + .me-xl-1 { + margin-inline-end: 4px !important; + } + + .ma-xl-1 { + margin: 4px !important; + } + + .mt-xl-2, +.my-xl-2 { + margin-top: 8px !important; + } + + .mr-xl-2, +.mx-xl-2 { + margin-right: 8px !important; + } + + .ml-xl-2, +.mx-xl-2 { + margin-left: 8px !important; + } + + .mb-xl-2, +.my-xl-2 { + margin-bottom: 8px !important; + } + + .ms-xl-2 { + margin-inline-start: 8px !important; + } + + .me-xl-2 { + margin-inline-end: 8px !important; + } + + .ma-xl-2 { + margin: 8px !important; + } + + .mt-xl-3, +.my-xl-3 { + margin-top: 12px !important; + } + + .mr-xl-3, +.mx-xl-3 { + margin-right: 12px !important; + } + + .ml-xl-3, +.mx-xl-3 { + margin-left: 12px !important; + } + + .mb-xl-3, +.my-xl-3 { + margin-bottom: 12px !important; + } + + .ms-xl-3 { + margin-inline-start: 12px !important; + } + + .me-xl-3 { + margin-inline-end: 12px !important; + } + + .ma-xl-3 { + margin: 12px !important; + } + + .mt-xl-4, +.my-xl-4 { + margin-top: 16px !important; + } + + .mr-xl-4, +.mx-xl-4 { + margin-right: 16px !important; + } + + .ml-xl-4, +.mx-xl-4 { + margin-left: 16px !important; + } + + .mb-xl-4, +.my-xl-4 { + margin-bottom: 16px !important; + } + + .ms-xl-4 { + margin-inline-start: 16px !important; + } + + .me-xl-4 { + margin-inline-end: 16px !important; + } + + .ma-xl-4 { + margin: 16px !important; + } + + .mt-xl-5, +.my-xl-5 { + margin-top: 20px !important; + } + + .mr-xl-5, +.mx-xl-5 { + margin-right: 20px !important; + } + + .ml-xl-5, +.mx-xl-5 { + margin-left: 20px !important; + } + + .mb-xl-5, +.my-xl-5 { + margin-bottom: 20px !important; + } + + .ms-xl-5 { + margin-inline-start: 20px !important; + } + + .me-xl-5 { + margin-inline-end: 20px !important; + } + + .ma-xl-5 { + margin: 20px !important; + } + + .mt-xl-6, +.my-xl-6 { + margin-top: 24px !important; + } + + .mr-xl-6, +.mx-xl-6 { + margin-right: 24px !important; + } + + .ml-xl-6, +.mx-xl-6 { + margin-left: 24px !important; + } + + .mb-xl-6, +.my-xl-6 { + margin-bottom: 24px !important; + } + + .ms-xl-6 { + margin-inline-start: 24px !important; + } + + .me-xl-6 { + margin-inline-end: 24px !important; + } + + .ma-xl-6 { + margin: 24px !important; + } + + .mt-xl-7, +.my-xl-7 { + margin-top: 28px !important; + } + + .mr-xl-7, +.mx-xl-7 { + margin-right: 28px !important; + } + + .ml-xl-7, +.mx-xl-7 { + margin-left: 28px !important; + } + + .mb-xl-7, +.my-xl-7 { + margin-bottom: 28px !important; + } + + .ms-xl-7 { + margin-inline-start: 28px !important; + } + + .me-xl-7 { + margin-inline-end: 28px !important; + } + + .ma-xl-7 { + margin: 28px !important; + } + + .mt-xl-8, +.my-xl-8 { + margin-top: 32px !important; + } + + .mr-xl-8, +.mx-xl-8 { + margin-right: 32px !important; + } + + .ml-xl-8, +.mx-xl-8 { + margin-left: 32px !important; + } + + .mb-xl-8, +.my-xl-8 { + margin-bottom: 32px !important; + } + + .ms-xl-8 { + margin-inline-start: 32px !important; + } + + .me-xl-8 { + margin-inline-end: 32px !important; + } + + .ma-xl-8 { + margin: 32px !important; + } + + .mt-xl-9, +.my-xl-9 { + margin-top: 36px !important; + } + + .mr-xl-9, +.mx-xl-9 { + margin-right: 36px !important; + } + + .ml-xl-9, +.mx-xl-9 { + margin-left: 36px !important; + } + + .mb-xl-9, +.my-xl-9 { + margin-bottom: 36px !important; + } + + .ms-xl-9 { + margin-inline-start: 36px !important; + } + + .me-xl-9 { + margin-inline-end: 36px !important; + } + + .ma-xl-9 { + margin: 36px !important; + } + + .mt-xl-10, +.my-xl-10 { + margin-top: 40px !important; + } + + .mr-xl-10, +.mx-xl-10 { + margin-right: 40px !important; + } + + .ml-xl-10, +.mx-xl-10 { + margin-left: 40px !important; + } + + .mb-xl-10, +.my-xl-10 { + margin-bottom: 40px !important; + } + + .ms-xl-10 { + margin-inline-start: 40px !important; + } + + .me-xl-10 { + margin-inline-end: 40px !important; + } + + .ma-xl-10 { + margin: 40px !important; + } + + .mt-xl-11, +.my-xl-11 { + margin-top: 44px !important; + } + + .mr-xl-11, +.mx-xl-11 { + margin-right: 44px !important; + } + + .ml-xl-11, +.mx-xl-11 { + margin-left: 44px !important; + } + + .mb-xl-11, +.my-xl-11 { + margin-bottom: 44px !important; + } + + .ms-xl-11 { + margin-inline-start: 44px !important; + } + + .me-xl-11 { + margin-inline-end: 44px !important; + } + + .ma-xl-11 { + margin: 44px !important; + } + + .mt-xl-12, +.my-xl-12 { + margin-top: 48px !important; + } + + .mr-xl-12, +.mx-xl-12 { + margin-right: 48px !important; + } + + .ml-xl-12, +.mx-xl-12 { + margin-left: 48px !important; + } + + .mb-xl-12, +.my-xl-12 { + margin-bottom: 48px !important; + } + + .ms-xl-12 { + margin-inline-start: 48px !important; + } + + .me-xl-12 { + margin-inline-end: 48px !important; + } + + .ma-xl-12 { + margin: 48px !important; + } + + .mt-xl-13, +.my-xl-13 { + margin-top: 52px !important; + } + + .mr-xl-13, +.mx-xl-13 { + margin-right: 52px !important; + } + + .ml-xl-13, +.mx-xl-13 { + margin-left: 52px !important; + } + + .mb-xl-13, +.my-xl-13 { + margin-bottom: 52px !important; + } + + .ms-xl-13 { + margin-inline-start: 52px !important; + } + + .me-xl-13 { + margin-inline-end: 52px !important; + } + + .ma-xl-13 { + margin: 52px !important; + } + + .mt-xl-14, +.my-xl-14 { + margin-top: 56px !important; + } + + .mr-xl-14, +.mx-xl-14 { + margin-right: 56px !important; + } + + .ml-xl-14, +.mx-xl-14 { + margin-left: 56px !important; + } + + .mb-xl-14, +.my-xl-14 { + margin-bottom: 56px !important; + } + + .ms-xl-14 { + margin-inline-start: 56px !important; + } + + .me-xl-14 { + margin-inline-end: 56px !important; + } + + .ma-xl-14 { + margin: 56px !important; + } + + .mt-xl-15, +.my-xl-15 { + margin-top: 60px !important; + } + + .mr-xl-15, +.mx-xl-15 { + margin-right: 60px !important; + } + + .ml-xl-15, +.mx-xl-15 { + margin-left: 60px !important; + } + + .mb-xl-15, +.my-xl-15 { + margin-bottom: 60px !important; + } + + .ms-xl-15 { + margin-inline-start: 60px !important; + } + + .me-xl-15 { + margin-inline-end: 60px !important; + } + + .ma-xl-15 { + margin: 60px !important; + } + + .mt-xl-16, +.my-xl-16 { + margin-top: 64px !important; + } + + .mr-xl-16, +.mx-xl-16 { + margin-right: 64px !important; + } + + .ml-xl-16, +.mx-xl-16 { + margin-left: 64px !important; + } + + .mb-xl-16, +.my-xl-16 { + margin-bottom: 64px !important; + } + + .ms-xl-16 { + margin-inline-start: 64px !important; + } + + .me-xl-16 { + margin-inline-end: 64px !important; + } + + .ma-xl-16 { + margin: 64px !important; + } + + .mt-xl-auto, +.my-xl-auto { + margin-top: auto !important; + } + + .mr-xl-auto, +.mx-xl-auto { + margin-right: auto !important; + } + + .ml-xl-auto, +.mx-xl-auto { + margin-left: auto !important; + } + + .mb-xl-auto, +.my-xl-auto { + margin-bottom: auto !important; + } + + .ms-xl-auto { + margin-inline-start: auto !important; + } + + .me-xl-auto { + margin-inline-end: auto !important; + } + + .ma-xl-auto { + margin: auto !important; + } + + .pt-xl-0, +.py-xl-0 { + padding-top: 0 !important; + } + + .pr-xl-0, +.px-xl-0 { + padding-right: 0 !important; + } + + .pl-xl-0, +.px-xl-0 { + padding-left: 0 !important; + } + + .pb-xl-0, +.py-xl-0 { + padding-bottom: 0 !important; + } + + .ps-xl-0 { + padding-inline-start: 0 !important; + } + + .pe-xl-0 { + padding-inline-end: 0 !important; + } + + .pa-xl-0 { + padding: 0 !important; + } + + .pt-xl-1, +.py-xl-1 { + padding-top: 4px !important; + } + + .pr-xl-1, +.px-xl-1 { + padding-right: 4px !important; + } + + .pl-xl-1, +.px-xl-1 { + padding-left: 4px !important; + } + + .pb-xl-1, +.py-xl-1 { + padding-bottom: 4px !important; + } + + .ps-xl-1 { + padding-inline-start: 4px !important; + } + + .pe-xl-1 { + padding-inline-end: 4px !important; + } + + .pa-xl-1 { + padding: 4px !important; + } + + .pt-xl-2, +.py-xl-2 { + padding-top: 8px !important; + } + + .pr-xl-2, +.px-xl-2 { + padding-right: 8px !important; + } + + .pl-xl-2, +.px-xl-2 { + padding-left: 8px !important; + } + + .pb-xl-2, +.py-xl-2 { + padding-bottom: 8px !important; + } + + .ps-xl-2 { + padding-inline-start: 8px !important; + } + + .pe-xl-2 { + padding-inline-end: 8px !important; + } + + .pa-xl-2 { + padding: 8px !important; + } + + .pt-xl-3, +.py-xl-3 { + padding-top: 12px !important; + } + + .pr-xl-3, +.px-xl-3 { + padding-right: 12px !important; + } + + .pl-xl-3, +.px-xl-3 { + padding-left: 12px !important; + } + + .pb-xl-3, +.py-xl-3 { + padding-bottom: 12px !important; + } + + .ps-xl-3 { + padding-inline-start: 12px !important; + } + + .pe-xl-3 { + padding-inline-end: 12px !important; + } + + .pa-xl-3 { + padding: 12px !important; + } + + .pt-xl-4, +.py-xl-4 { + padding-top: 16px !important; + } + + .pr-xl-4, +.px-xl-4 { + padding-right: 16px !important; + } + + .pl-xl-4, +.px-xl-4 { + padding-left: 16px !important; + } + + .pb-xl-4, +.py-xl-4 { + padding-bottom: 16px !important; + } + + .ps-xl-4 { + padding-inline-start: 16px !important; + } + + .pe-xl-4 { + padding-inline-end: 16px !important; + } + + .pa-xl-4 { + padding: 16px !important; + } + + .pt-xl-5, +.py-xl-5 { + padding-top: 20px !important; + } + + .pr-xl-5, +.px-xl-5 { + padding-right: 20px !important; + } + + .pl-xl-5, +.px-xl-5 { + padding-left: 20px !important; + } + + .pb-xl-5, +.py-xl-5 { + padding-bottom: 20px !important; + } + + .ps-xl-5 { + padding-inline-start: 20px !important; + } + + .pe-xl-5 { + padding-inline-end: 20px !important; + } + + .pa-xl-5 { + padding: 20px !important; + } + + .pt-xl-6, +.py-xl-6 { + padding-top: 24px !important; + } + + .pr-xl-6, +.px-xl-6 { + padding-right: 24px !important; + } + + .pl-xl-6, +.px-xl-6 { + padding-left: 24px !important; + } + + .pb-xl-6, +.py-xl-6 { + padding-bottom: 24px !important; + } + + .ps-xl-6 { + padding-inline-start: 24px !important; + } + + .pe-xl-6 { + padding-inline-end: 24px !important; + } + + .pa-xl-6 { + padding: 24px !important; + } + + .pt-xl-7, +.py-xl-7 { + padding-top: 28px !important; + } + + .pr-xl-7, +.px-xl-7 { + padding-right: 28px !important; + } + + .pl-xl-7, +.px-xl-7 { + padding-left: 28px !important; + } + + .pb-xl-7, +.py-xl-7 { + padding-bottom: 28px !important; + } + + .ps-xl-7 { + padding-inline-start: 28px !important; + } + + .pe-xl-7 { + padding-inline-end: 28px !important; + } + + .pa-xl-7 { + padding: 28px !important; + } + + .pt-xl-8, +.py-xl-8 { + padding-top: 32px !important; + } + + .pr-xl-8, +.px-xl-8 { + padding-right: 32px !important; + } + + .pl-xl-8, +.px-xl-8 { + padding-left: 32px !important; + } + + .pb-xl-8, +.py-xl-8 { + padding-bottom: 32px !important; + } + + .ps-xl-8 { + padding-inline-start: 32px !important; + } + + .pe-xl-8 { + padding-inline-end: 32px !important; + } + + .pa-xl-8 { + padding: 32px !important; + } + + .pt-xl-9, +.py-xl-9 { + padding-top: 36px !important; + } + + .pr-xl-9, +.px-xl-9 { + padding-right: 36px !important; + } + + .pl-xl-9, +.px-xl-9 { + padding-left: 36px !important; + } + + .pb-xl-9, +.py-xl-9 { + padding-bottom: 36px !important; + } + + .ps-xl-9 { + padding-inline-start: 36px !important; + } + + .pe-xl-9 { + padding-inline-end: 36px !important; + } + + .pa-xl-9 { + padding: 36px !important; + } + + .pt-xl-10, +.py-xl-10 { + padding-top: 40px !important; + } + + .pr-xl-10, +.px-xl-10 { + padding-right: 40px !important; + } + + .pl-xl-10, +.px-xl-10 { + padding-left: 40px !important; + } + + .pb-xl-10, +.py-xl-10 { + padding-bottom: 40px !important; + } + + .ps-xl-10 { + padding-inline-start: 40px !important; + } + + .pe-xl-10 { + padding-inline-end: 40px !important; + } + + .pa-xl-10 { + padding: 40px !important; + } + + .pt-xl-11, +.py-xl-11 { + padding-top: 44px !important; + } + + .pr-xl-11, +.px-xl-11 { + padding-right: 44px !important; + } + + .pl-xl-11, +.px-xl-11 { + padding-left: 44px !important; + } + + .pb-xl-11, +.py-xl-11 { + padding-bottom: 44px !important; + } + + .ps-xl-11 { + padding-inline-start: 44px !important; + } + + .pe-xl-11 { + padding-inline-end: 44px !important; + } + + .pa-xl-11 { + padding: 44px !important; + } + + .pt-xl-12, +.py-xl-12 { + padding-top: 48px !important; + } + + .pr-xl-12, +.px-xl-12 { + padding-right: 48px !important; + } + + .pl-xl-12, +.px-xl-12 { + padding-left: 48px !important; + } + + .pb-xl-12, +.py-xl-12 { + padding-bottom: 48px !important; + } + + .ps-xl-12 { + padding-inline-start: 48px !important; + } + + .pe-xl-12 { + padding-inline-end: 48px !important; + } + + .pa-xl-12 { + padding: 48px !important; + } + + .pt-xl-13, +.py-xl-13 { + padding-top: 52px !important; + } + + .pr-xl-13, +.px-xl-13 { + padding-right: 52px !important; + } + + .pl-xl-13, +.px-xl-13 { + padding-left: 52px !important; + } + + .pb-xl-13, +.py-xl-13 { + padding-bottom: 52px !important; + } + + .ps-xl-13 { + padding-inline-start: 52px !important; + } + + .pe-xl-13 { + padding-inline-end: 52px !important; + } + + .pa-xl-13 { + padding: 52px !important; + } + + .pt-xl-14, +.py-xl-14 { + padding-top: 56px !important; + } + + .pr-xl-14, +.px-xl-14 { + padding-right: 56px !important; + } + + .pl-xl-14, +.px-xl-14 { + padding-left: 56px !important; + } + + .pb-xl-14, +.py-xl-14 { + padding-bottom: 56px !important; + } + + .ps-xl-14 { + padding-inline-start: 56px !important; + } + + .pe-xl-14 { + padding-inline-end: 56px !important; + } + + .pa-xl-14 { + padding: 56px !important; + } + + .pt-xl-15, +.py-xl-15 { + padding-top: 60px !important; + } + + .pr-xl-15, +.px-xl-15 { + padding-right: 60px !important; + } + + .pl-xl-15, +.px-xl-15 { + padding-left: 60px !important; + } + + .pb-xl-15, +.py-xl-15 { + padding-bottom: 60px !important; + } + + .ps-xl-15 { + padding-inline-start: 60px !important; + } + + .pe-xl-15 { + padding-inline-end: 60px !important; + } + + .pa-xl-15 { + padding: 60px !important; + } + + .pt-xl-16, +.py-xl-16 { + padding-top: 64px !important; + } + + .pr-xl-16, +.px-xl-16 { + padding-right: 64px !important; + } + + .pl-xl-16, +.px-xl-16 { + padding-left: 64px !important; + } + + .pb-xl-16, +.py-xl-16 { + padding-bottom: 64px !important; + } + + .ps-xl-16 { + padding-inline-start: 64px !important; + } + + .pe-xl-16 { + padding-inline-end: 64px !important; + } + + .pa-xl-16 { + padding: 64px !important; + } + + .pt-xl-auto, +.py-xl-auto { + padding-top: auto !important; + } + + .pr-xl-auto, +.px-xl-auto { + padding-right: auto !important; + } + + .pl-xl-auto, +.px-xl-auto { + padding-left: auto !important; + } + + .pb-xl-auto, +.py-xl-auto { + padding-bottom: auto !important; + } + + .ps-xl-auto { + padding-inline-start: auto !important; + } + + .pe-xl-auto { + padding-inline-end: auto !important; + } + + .pa-xl-auto { + padding: auto !important; + } + + .mt-xl-n1, +.my-xl-n1 { + margin-top: -4px !important; + } + + .mr-xl-n1, +.mx-xl-n1 { + margin-right: -4px !important; + } + + .ml-xl-n1, +.mx-xl-n1 { + margin-left: -4px !important; + } + + .mb-xl-n1, +.my-xl-n1 { + margin-bottom: -4px !important; + } + + .ms-xl-n1 { + margin-inline-start: -4px !important; + } + + .me-xl-n1 { + margin-inline-end: -4px !important; + } + + .ma-xl-n1 { + margin: -4px !important; + } + + .mt-xl-n2, +.my-xl-n2 { + margin-top: -8px !important; + } + + .mr-xl-n2, +.mx-xl-n2 { + margin-right: -8px !important; + } + + .ml-xl-n2, +.mx-xl-n2 { + margin-left: -8px !important; + } + + .mb-xl-n2, +.my-xl-n2 { + margin-bottom: -8px !important; + } + + .ms-xl-n2 { + margin-inline-start: -8px !important; + } + + .me-xl-n2 { + margin-inline-end: -8px !important; + } + + .ma-xl-n2 { + margin: -8px !important; + } + + .mt-xl-n3, +.my-xl-n3 { + margin-top: -12px !important; + } + + .mr-xl-n3, +.mx-xl-n3 { + margin-right: -12px !important; + } + + .ml-xl-n3, +.mx-xl-n3 { + margin-left: -12px !important; + } + + .mb-xl-n3, +.my-xl-n3 { + margin-bottom: -12px !important; + } + + .ms-xl-n3 { + margin-inline-start: -12px !important; + } + + .me-xl-n3 { + margin-inline-end: -12px !important; + } + + .ma-xl-n3 { + margin: -12px !important; + } + + .mt-xl-n4, +.my-xl-n4 { + margin-top: -16px !important; + } + + .mr-xl-n4, +.mx-xl-n4 { + margin-right: -16px !important; + } + + .ml-xl-n4, +.mx-xl-n4 { + margin-left: -16px !important; + } + + .mb-xl-n4, +.my-xl-n4 { + margin-bottom: -16px !important; + } + + .ms-xl-n4 { + margin-inline-start: -16px !important; + } + + .me-xl-n4 { + margin-inline-end: -16px !important; + } + + .ma-xl-n4 { + margin: -16px !important; + } + + .mt-xl-n5, +.my-xl-n5 { + margin-top: -20px !important; + } + + .mr-xl-n5, +.mx-xl-n5 { + margin-right: -20px !important; + } + + .ml-xl-n5, +.mx-xl-n5 { + margin-left: -20px !important; + } + + .mb-xl-n5, +.my-xl-n5 { + margin-bottom: -20px !important; + } + + .ms-xl-n5 { + margin-inline-start: -20px !important; + } + + .me-xl-n5 { + margin-inline-end: -20px !important; + } + + .ma-xl-n5 { + margin: -20px !important; + } + + .mt-xl-n6, +.my-xl-n6 { + margin-top: -24px !important; + } + + .mr-xl-n6, +.mx-xl-n6 { + margin-right: -24px !important; + } + + .ml-xl-n6, +.mx-xl-n6 { + margin-left: -24px !important; + } + + .mb-xl-n6, +.my-xl-n6 { + margin-bottom: -24px !important; + } + + .ms-xl-n6 { + margin-inline-start: -24px !important; + } + + .me-xl-n6 { + margin-inline-end: -24px !important; + } + + .ma-xl-n6 { + margin: -24px !important; + } + + .mt-xl-n7, +.my-xl-n7 { + margin-top: -28px !important; + } + + .mr-xl-n7, +.mx-xl-n7 { + margin-right: -28px !important; + } + + .ml-xl-n7, +.mx-xl-n7 { + margin-left: -28px !important; + } + + .mb-xl-n7, +.my-xl-n7 { + margin-bottom: -28px !important; + } + + .ms-xl-n7 { + margin-inline-start: -28px !important; + } + + .me-xl-n7 { + margin-inline-end: -28px !important; + } + + .ma-xl-n7 { + margin: -28px !important; + } + + .mt-xl-n8, +.my-xl-n8 { + margin-top: -32px !important; + } + + .mr-xl-n8, +.mx-xl-n8 { + margin-right: -32px !important; + } + + .ml-xl-n8, +.mx-xl-n8 { + margin-left: -32px !important; + } + + .mb-xl-n8, +.my-xl-n8 { + margin-bottom: -32px !important; + } + + .ms-xl-n8 { + margin-inline-start: -32px !important; + } + + .me-xl-n8 { + margin-inline-end: -32px !important; + } + + .ma-xl-n8 { + margin: -32px !important; + } + + .mt-xl-n9, +.my-xl-n9 { + margin-top: -36px !important; + } + + .mr-xl-n9, +.mx-xl-n9 { + margin-right: -36px !important; + } + + .ml-xl-n9, +.mx-xl-n9 { + margin-left: -36px !important; + } + + .mb-xl-n9, +.my-xl-n9 { + margin-bottom: -36px !important; + } + + .ms-xl-n9 { + margin-inline-start: -36px !important; + } + + .me-xl-n9 { + margin-inline-end: -36px !important; + } + + .ma-xl-n9 { + margin: -36px !important; + } + + .mt-xl-n10, +.my-xl-n10 { + margin-top: -40px !important; + } + + .mr-xl-n10, +.mx-xl-n10 { + margin-right: -40px !important; + } + + .ml-xl-n10, +.mx-xl-n10 { + margin-left: -40px !important; + } + + .mb-xl-n10, +.my-xl-n10 { + margin-bottom: -40px !important; + } + + .ms-xl-n10 { + margin-inline-start: -40px !important; + } + + .me-xl-n10 { + margin-inline-end: -40px !important; + } + + .ma-xl-n10 { + margin: -40px !important; + } + + .mt-xl-n11, +.my-xl-n11 { + margin-top: -44px !important; + } + + .mr-xl-n11, +.mx-xl-n11 { + margin-right: -44px !important; + } + + .ml-xl-n11, +.mx-xl-n11 { + margin-left: -44px !important; + } + + .mb-xl-n11, +.my-xl-n11 { + margin-bottom: -44px !important; + } + + .ms-xl-n11 { + margin-inline-start: -44px !important; + } + + .me-xl-n11 { + margin-inline-end: -44px !important; + } + + .ma-xl-n11 { + margin: -44px !important; + } + + .mt-xl-n12, +.my-xl-n12 { + margin-top: -48px !important; + } + + .mr-xl-n12, +.mx-xl-n12 { + margin-right: -48px !important; + } + + .ml-xl-n12, +.mx-xl-n12 { + margin-left: -48px !important; + } + + .mb-xl-n12, +.my-xl-n12 { + margin-bottom: -48px !important; + } + + .ms-xl-n12 { + margin-inline-start: -48px !important; + } + + .me-xl-n12 { + margin-inline-end: -48px !important; + } + + .ma-xl-n12 { + margin: -48px !important; + } + + .mt-xl-n13, +.my-xl-n13 { + margin-top: -52px !important; + } + + .mr-xl-n13, +.mx-xl-n13 { + margin-right: -52px !important; + } + + .ml-xl-n13, +.mx-xl-n13 { + margin-left: -52px !important; + } + + .mb-xl-n13, +.my-xl-n13 { + margin-bottom: -52px !important; + } + + .ms-xl-n13 { + margin-inline-start: -52px !important; + } + + .me-xl-n13 { + margin-inline-end: -52px !important; + } + + .ma-xl-n13 { + margin: -52px !important; + } + + .mt-xl-n14, +.my-xl-n14 { + margin-top: -56px !important; + } + + .mr-xl-n14, +.mx-xl-n14 { + margin-right: -56px !important; + } + + .ml-xl-n14, +.mx-xl-n14 { + margin-left: -56px !important; + } + + .mb-xl-n14, +.my-xl-n14 { + margin-bottom: -56px !important; + } + + .ms-xl-n14 { + margin-inline-start: -56px !important; + } + + .me-xl-n14 { + margin-inline-end: -56px !important; + } + + .ma-xl-n14 { + margin: -56px !important; + } + + .mt-xl-n15, +.my-xl-n15 { + margin-top: -60px !important; + } + + .mr-xl-n15, +.mx-xl-n15 { + margin-right: -60px !important; + } + + .ml-xl-n15, +.mx-xl-n15 { + margin-left: -60px !important; + } + + .mb-xl-n15, +.my-xl-n15 { + margin-bottom: -60px !important; + } + + .ms-xl-n15 { + margin-inline-start: -60px !important; + } + + .me-xl-n15 { + margin-inline-end: -60px !important; + } + + .ma-xl-n15 { + margin: -60px !important; + } + + .mt-xl-n16, +.my-xl-n16 { + margin-top: -64px !important; + } + + .mr-xl-n16, +.mx-xl-n16 { + margin-right: -64px !important; + } + + .ml-xl-n16, +.mx-xl-n16 { + margin-left: -64px !important; + } + + .mb-xl-n16, +.my-xl-n16 { + margin-bottom: -64px !important; + } + + .ms-xl-n16 { + margin-inline-start: -64px !important; + } + + .me-xl-n16 { + margin-inline-end: -64px !important; + } + + .ma-xl-n16 { + margin: -64px !important; + } +} +@media screen and (min-width: 2560px) { + .mt-xxl-0, +.my-xxl-0 { + margin-top: 0 !important; + } + + .mr-xxl-0, +.mx-xxl-0 { + margin-right: 0 !important; + } + + .ml-xxl-0, +.mx-xxl-0 { + margin-left: 0 !important; + } + + .mb-xxl-0, +.my-xxl-0 { + margin-bottom: 0 !important; + } + + .ms-xxl-0 { + margin-inline-start: 0 !important; + } + + .me-xxl-0 { + margin-inline-end: 0 !important; + } + + .ma-xxl-0 { + margin: 0 !important; + } + + .mt-xxl-1, +.my-xxl-1 { + margin-top: 4px !important; + } + + .mr-xxl-1, +.mx-xxl-1 { + margin-right: 4px !important; + } + + .ml-xxl-1, +.mx-xxl-1 { + margin-left: 4px !important; + } + + .mb-xxl-1, +.my-xxl-1 { + margin-bottom: 4px !important; + } + + .ms-xxl-1 { + margin-inline-start: 4px !important; + } + + .me-xxl-1 { + margin-inline-end: 4px !important; + } + + .ma-xxl-1 { + margin: 4px !important; + } + + .mt-xxl-2, +.my-xxl-2 { + margin-top: 8px !important; + } + + .mr-xxl-2, +.mx-xxl-2 { + margin-right: 8px !important; + } + + .ml-xxl-2, +.mx-xxl-2 { + margin-left: 8px !important; + } + + .mb-xxl-2, +.my-xxl-2 { + margin-bottom: 8px !important; + } + + .ms-xxl-2 { + margin-inline-start: 8px !important; + } + + .me-xxl-2 { + margin-inline-end: 8px !important; + } + + .ma-xxl-2 { + margin: 8px !important; + } + + .mt-xxl-3, +.my-xxl-3 { + margin-top: 12px !important; + } + + .mr-xxl-3, +.mx-xxl-3 { + margin-right: 12px !important; + } + + .ml-xxl-3, +.mx-xxl-3 { + margin-left: 12px !important; + } + + .mb-xxl-3, +.my-xxl-3 { + margin-bottom: 12px !important; + } + + .ms-xxl-3 { + margin-inline-start: 12px !important; + } + + .me-xxl-3 { + margin-inline-end: 12px !important; + } + + .ma-xxl-3 { + margin: 12px !important; + } + + .mt-xxl-4, +.my-xxl-4 { + margin-top: 16px !important; + } + + .mr-xxl-4, +.mx-xxl-4 { + margin-right: 16px !important; + } + + .ml-xxl-4, +.mx-xxl-4 { + margin-left: 16px !important; + } + + .mb-xxl-4, +.my-xxl-4 { + margin-bottom: 16px !important; + } + + .ms-xxl-4 { + margin-inline-start: 16px !important; + } + + .me-xxl-4 { + margin-inline-end: 16px !important; + } + + .ma-xxl-4 { + margin: 16px !important; + } + + .mt-xxl-5, +.my-xxl-5 { + margin-top: 20px !important; + } + + .mr-xxl-5, +.mx-xxl-5 { + margin-right: 20px !important; + } + + .ml-xxl-5, +.mx-xxl-5 { + margin-left: 20px !important; + } + + .mb-xxl-5, +.my-xxl-5 { + margin-bottom: 20px !important; + } + + .ms-xxl-5 { + margin-inline-start: 20px !important; + } + + .me-xxl-5 { + margin-inline-end: 20px !important; + } + + .ma-xxl-5 { + margin: 20px !important; + } + + .mt-xxl-6, +.my-xxl-6 { + margin-top: 24px !important; + } + + .mr-xxl-6, +.mx-xxl-6 { + margin-right: 24px !important; + } + + .ml-xxl-6, +.mx-xxl-6 { + margin-left: 24px !important; + } + + .mb-xxl-6, +.my-xxl-6 { + margin-bottom: 24px !important; + } + + .ms-xxl-6 { + margin-inline-start: 24px !important; + } + + .me-xxl-6 { + margin-inline-end: 24px !important; + } + + .ma-xxl-6 { + margin: 24px !important; + } + + .mt-xxl-7, +.my-xxl-7 { + margin-top: 28px !important; + } + + .mr-xxl-7, +.mx-xxl-7 { + margin-right: 28px !important; + } + + .ml-xxl-7, +.mx-xxl-7 { + margin-left: 28px !important; + } + + .mb-xxl-7, +.my-xxl-7 { + margin-bottom: 28px !important; + } + + .ms-xxl-7 { + margin-inline-start: 28px !important; + } + + .me-xxl-7 { + margin-inline-end: 28px !important; + } + + .ma-xxl-7 { + margin: 28px !important; + } + + .mt-xxl-8, +.my-xxl-8 { + margin-top: 32px !important; + } + + .mr-xxl-8, +.mx-xxl-8 { + margin-right: 32px !important; + } + + .ml-xxl-8, +.mx-xxl-8 { + margin-left: 32px !important; + } + + .mb-xxl-8, +.my-xxl-8 { + margin-bottom: 32px !important; + } + + .ms-xxl-8 { + margin-inline-start: 32px !important; + } + + .me-xxl-8 { + margin-inline-end: 32px !important; + } + + .ma-xxl-8 { + margin: 32px !important; + } + + .mt-xxl-9, +.my-xxl-9 { + margin-top: 36px !important; + } + + .mr-xxl-9, +.mx-xxl-9 { + margin-right: 36px !important; + } + + .ml-xxl-9, +.mx-xxl-9 { + margin-left: 36px !important; + } + + .mb-xxl-9, +.my-xxl-9 { + margin-bottom: 36px !important; + } + + .ms-xxl-9 { + margin-inline-start: 36px !important; + } + + .me-xxl-9 { + margin-inline-end: 36px !important; + } + + .ma-xxl-9 { + margin: 36px !important; + } + + .mt-xxl-10, +.my-xxl-10 { + margin-top: 40px !important; + } + + .mr-xxl-10, +.mx-xxl-10 { + margin-right: 40px !important; + } + + .ml-xxl-10, +.mx-xxl-10 { + margin-left: 40px !important; + } + + .mb-xxl-10, +.my-xxl-10 { + margin-bottom: 40px !important; + } + + .ms-xxl-10 { + margin-inline-start: 40px !important; + } + + .me-xxl-10 { + margin-inline-end: 40px !important; + } + + .ma-xxl-10 { + margin: 40px !important; + } + + .mt-xxl-11, +.my-xxl-11 { + margin-top: 44px !important; + } + + .mr-xxl-11, +.mx-xxl-11 { + margin-right: 44px !important; + } + + .ml-xxl-11, +.mx-xxl-11 { + margin-left: 44px !important; + } + + .mb-xxl-11, +.my-xxl-11 { + margin-bottom: 44px !important; + } + + .ms-xxl-11 { + margin-inline-start: 44px !important; + } + + .me-xxl-11 { + margin-inline-end: 44px !important; + } + + .ma-xxl-11 { + margin: 44px !important; + } + + .mt-xxl-12, +.my-xxl-12 { + margin-top: 48px !important; + } + + .mr-xxl-12, +.mx-xxl-12 { + margin-right: 48px !important; + } + + .ml-xxl-12, +.mx-xxl-12 { + margin-left: 48px !important; + } + + .mb-xxl-12, +.my-xxl-12 { + margin-bottom: 48px !important; + } + + .ms-xxl-12 { + margin-inline-start: 48px !important; + } + + .me-xxl-12 { + margin-inline-end: 48px !important; + } + + .ma-xxl-12 { + margin: 48px !important; + } + + .mt-xxl-13, +.my-xxl-13 { + margin-top: 52px !important; + } + + .mr-xxl-13, +.mx-xxl-13 { + margin-right: 52px !important; + } + + .ml-xxl-13, +.mx-xxl-13 { + margin-left: 52px !important; + } + + .mb-xxl-13, +.my-xxl-13 { + margin-bottom: 52px !important; + } + + .ms-xxl-13 { + margin-inline-start: 52px !important; + } + + .me-xxl-13 { + margin-inline-end: 52px !important; + } + + .ma-xxl-13 { + margin: 52px !important; + } + + .mt-xxl-14, +.my-xxl-14 { + margin-top: 56px !important; + } + + .mr-xxl-14, +.mx-xxl-14 { + margin-right: 56px !important; + } + + .ml-xxl-14, +.mx-xxl-14 { + margin-left: 56px !important; + } + + .mb-xxl-14, +.my-xxl-14 { + margin-bottom: 56px !important; + } + + .ms-xxl-14 { + margin-inline-start: 56px !important; + } + + .me-xxl-14 { + margin-inline-end: 56px !important; + } + + .ma-xxl-14 { + margin: 56px !important; + } + + .mt-xxl-15, +.my-xxl-15 { + margin-top: 60px !important; + } + + .mr-xxl-15, +.mx-xxl-15 { + margin-right: 60px !important; + } + + .ml-xxl-15, +.mx-xxl-15 { + margin-left: 60px !important; + } + + .mb-xxl-15, +.my-xxl-15 { + margin-bottom: 60px !important; + } + + .ms-xxl-15 { + margin-inline-start: 60px !important; + } + + .me-xxl-15 { + margin-inline-end: 60px !important; + } + + .ma-xxl-15 { + margin: 60px !important; + } + + .mt-xxl-16, +.my-xxl-16 { + margin-top: 64px !important; + } + + .mr-xxl-16, +.mx-xxl-16 { + margin-right: 64px !important; + } + + .ml-xxl-16, +.mx-xxl-16 { + margin-left: 64px !important; + } + + .mb-xxl-16, +.my-xxl-16 { + margin-bottom: 64px !important; + } + + .ms-xxl-16 { + margin-inline-start: 64px !important; + } + + .me-xxl-16 { + margin-inline-end: 64px !important; + } + + .ma-xxl-16 { + margin: 64px !important; + } + + .mt-xxl-auto, +.my-xxl-auto { + margin-top: auto !important; + } + + .mr-xxl-auto, +.mx-xxl-auto { + margin-right: auto !important; + } + + .ml-xxl-auto, +.mx-xxl-auto { + margin-left: auto !important; + } + + .mb-xxl-auto, +.my-xxl-auto { + margin-bottom: auto !important; + } + + .ms-xxl-auto { + margin-inline-start: auto !important; + } + + .me-xxl-auto { + margin-inline-end: auto !important; + } + + .ma-xxl-auto { + margin: auto !important; + } + + .pt-xxl-0, +.py-xxl-0 { + padding-top: 0 !important; + } + + .pr-xxl-0, +.px-xxl-0 { + padding-right: 0 !important; + } + + .pl-xxl-0, +.px-xxl-0 { + padding-left: 0 !important; + } + + .pb-xxl-0, +.py-xxl-0 { + padding-bottom: 0 !important; + } + + .ps-xxl-0 { + padding-inline-start: 0 !important; + } + + .pe-xxl-0 { + padding-inline-end: 0 !important; + } + + .pa-xxl-0 { + padding: 0 !important; + } + + .pt-xxl-1, +.py-xxl-1 { + padding-top: 4px !important; + } + + .pr-xxl-1, +.px-xxl-1 { + padding-right: 4px !important; + } + + .pl-xxl-1, +.px-xxl-1 { + padding-left: 4px !important; + } + + .pb-xxl-1, +.py-xxl-1 { + padding-bottom: 4px !important; + } + + .ps-xxl-1 { + padding-inline-start: 4px !important; + } + + .pe-xxl-1 { + padding-inline-end: 4px !important; + } + + .pa-xxl-1 { + padding: 4px !important; + } + + .pt-xxl-2, +.py-xxl-2 { + padding-top: 8px !important; + } + + .pr-xxl-2, +.px-xxl-2 { + padding-right: 8px !important; + } + + .pl-xxl-2, +.px-xxl-2 { + padding-left: 8px !important; + } + + .pb-xxl-2, +.py-xxl-2 { + padding-bottom: 8px !important; + } + + .ps-xxl-2 { + padding-inline-start: 8px !important; + } + + .pe-xxl-2 { + padding-inline-end: 8px !important; + } + + .pa-xxl-2 { + padding: 8px !important; + } + + .pt-xxl-3, +.py-xxl-3 { + padding-top: 12px !important; + } + + .pr-xxl-3, +.px-xxl-3 { + padding-right: 12px !important; + } + + .pl-xxl-3, +.px-xxl-3 { + padding-left: 12px !important; + } + + .pb-xxl-3, +.py-xxl-3 { + padding-bottom: 12px !important; + } + + .ps-xxl-3 { + padding-inline-start: 12px !important; + } + + .pe-xxl-3 { + padding-inline-end: 12px !important; + } + + .pa-xxl-3 { + padding: 12px !important; + } + + .pt-xxl-4, +.py-xxl-4 { + padding-top: 16px !important; + } + + .pr-xxl-4, +.px-xxl-4 { + padding-right: 16px !important; + } + + .pl-xxl-4, +.px-xxl-4 { + padding-left: 16px !important; + } + + .pb-xxl-4, +.py-xxl-4 { + padding-bottom: 16px !important; + } + + .ps-xxl-4 { + padding-inline-start: 16px !important; + } + + .pe-xxl-4 { + padding-inline-end: 16px !important; + } + + .pa-xxl-4 { + padding: 16px !important; + } + + .pt-xxl-5, +.py-xxl-5 { + padding-top: 20px !important; + } + + .pr-xxl-5, +.px-xxl-5 { + padding-right: 20px !important; + } + + .pl-xxl-5, +.px-xxl-5 { + padding-left: 20px !important; + } + + .pb-xxl-5, +.py-xxl-5 { + padding-bottom: 20px !important; + } + + .ps-xxl-5 { + padding-inline-start: 20px !important; + } + + .pe-xxl-5 { + padding-inline-end: 20px !important; + } + + .pa-xxl-5 { + padding: 20px !important; + } + + .pt-xxl-6, +.py-xxl-6 { + padding-top: 24px !important; + } + + .pr-xxl-6, +.px-xxl-6 { + padding-right: 24px !important; + } + + .pl-xxl-6, +.px-xxl-6 { + padding-left: 24px !important; + } + + .pb-xxl-6, +.py-xxl-6 { + padding-bottom: 24px !important; + } + + .ps-xxl-6 { + padding-inline-start: 24px !important; + } + + .pe-xxl-6 { + padding-inline-end: 24px !important; + } + + .pa-xxl-6 { + padding: 24px !important; + } + + .pt-xxl-7, +.py-xxl-7 { + padding-top: 28px !important; + } + + .pr-xxl-7, +.px-xxl-7 { + padding-right: 28px !important; + } + + .pl-xxl-7, +.px-xxl-7 { + padding-left: 28px !important; + } + + .pb-xxl-7, +.py-xxl-7 { + padding-bottom: 28px !important; + } + + .ps-xxl-7 { + padding-inline-start: 28px !important; + } + + .pe-xxl-7 { + padding-inline-end: 28px !important; + } + + .pa-xxl-7 { + padding: 28px !important; + } + + .pt-xxl-8, +.py-xxl-8 { + padding-top: 32px !important; + } + + .pr-xxl-8, +.px-xxl-8 { + padding-right: 32px !important; + } + + .pl-xxl-8, +.px-xxl-8 { + padding-left: 32px !important; + } + + .pb-xxl-8, +.py-xxl-8 { + padding-bottom: 32px !important; + } + + .ps-xxl-8 { + padding-inline-start: 32px !important; + } + + .pe-xxl-8 { + padding-inline-end: 32px !important; + } + + .pa-xxl-8 { + padding: 32px !important; + } + + .pt-xxl-9, +.py-xxl-9 { + padding-top: 36px !important; + } + + .pr-xxl-9, +.px-xxl-9 { + padding-right: 36px !important; + } + + .pl-xxl-9, +.px-xxl-9 { + padding-left: 36px !important; + } + + .pb-xxl-9, +.py-xxl-9 { + padding-bottom: 36px !important; + } + + .ps-xxl-9 { + padding-inline-start: 36px !important; + } + + .pe-xxl-9 { + padding-inline-end: 36px !important; + } + + .pa-xxl-9 { + padding: 36px !important; + } + + .pt-xxl-10, +.py-xxl-10 { + padding-top: 40px !important; + } + + .pr-xxl-10, +.px-xxl-10 { + padding-right: 40px !important; + } + + .pl-xxl-10, +.px-xxl-10 { + padding-left: 40px !important; + } + + .pb-xxl-10, +.py-xxl-10 { + padding-bottom: 40px !important; + } + + .ps-xxl-10 { + padding-inline-start: 40px !important; + } + + .pe-xxl-10 { + padding-inline-end: 40px !important; + } + + .pa-xxl-10 { + padding: 40px !important; + } + + .pt-xxl-11, +.py-xxl-11 { + padding-top: 44px !important; + } + + .pr-xxl-11, +.px-xxl-11 { + padding-right: 44px !important; + } + + .pl-xxl-11, +.px-xxl-11 { + padding-left: 44px !important; + } + + .pb-xxl-11, +.py-xxl-11 { + padding-bottom: 44px !important; + } + + .ps-xxl-11 { + padding-inline-start: 44px !important; + } + + .pe-xxl-11 { + padding-inline-end: 44px !important; + } + + .pa-xxl-11 { + padding: 44px !important; + } + + .pt-xxl-12, +.py-xxl-12 { + padding-top: 48px !important; + } + + .pr-xxl-12, +.px-xxl-12 { + padding-right: 48px !important; + } + + .pl-xxl-12, +.px-xxl-12 { + padding-left: 48px !important; + } + + .pb-xxl-12, +.py-xxl-12 { + padding-bottom: 48px !important; + } + + .ps-xxl-12 { + padding-inline-start: 48px !important; + } + + .pe-xxl-12 { + padding-inline-end: 48px !important; + } + + .pa-xxl-12 { + padding: 48px !important; + } + + .pt-xxl-13, +.py-xxl-13 { + padding-top: 52px !important; + } + + .pr-xxl-13, +.px-xxl-13 { + padding-right: 52px !important; + } + + .pl-xxl-13, +.px-xxl-13 { + padding-left: 52px !important; + } + + .pb-xxl-13, +.py-xxl-13 { + padding-bottom: 52px !important; + } + + .ps-xxl-13 { + padding-inline-start: 52px !important; + } + + .pe-xxl-13 { + padding-inline-end: 52px !important; + } + + .pa-xxl-13 { + padding: 52px !important; + } + + .pt-xxl-14, +.py-xxl-14 { + padding-top: 56px !important; + } + + .pr-xxl-14, +.px-xxl-14 { + padding-right: 56px !important; + } + + .pl-xxl-14, +.px-xxl-14 { + padding-left: 56px !important; + } + + .pb-xxl-14, +.py-xxl-14 { + padding-bottom: 56px !important; + } + + .ps-xxl-14 { + padding-inline-start: 56px !important; + } + + .pe-xxl-14 { + padding-inline-end: 56px !important; + } + + .pa-xxl-14 { + padding: 56px !important; + } + + .pt-xxl-15, +.py-xxl-15 { + padding-top: 60px !important; + } + + .pr-xxl-15, +.px-xxl-15 { + padding-right: 60px !important; + } + + .pl-xxl-15, +.px-xxl-15 { + padding-left: 60px !important; + } + + .pb-xxl-15, +.py-xxl-15 { + padding-bottom: 60px !important; + } + + .ps-xxl-15 { + padding-inline-start: 60px !important; + } + + .pe-xxl-15 { + padding-inline-end: 60px !important; + } + + .pa-xxl-15 { + padding: 60px !important; + } + + .pt-xxl-16, +.py-xxl-16 { + padding-top: 64px !important; + } + + .pr-xxl-16, +.px-xxl-16 { + padding-right: 64px !important; + } + + .pl-xxl-16, +.px-xxl-16 { + padding-left: 64px !important; + } + + .pb-xxl-16, +.py-xxl-16 { + padding-bottom: 64px !important; + } + + .ps-xxl-16 { + padding-inline-start: 64px !important; + } + + .pe-xxl-16 { + padding-inline-end: 64px !important; + } + + .pa-xxl-16 { + padding: 64px !important; + } + + .pt-xxl-auto, +.py-xxl-auto { + padding-top: auto !important; + } + + .pr-xxl-auto, +.px-xxl-auto { + padding-right: auto !important; + } + + .pl-xxl-auto, +.px-xxl-auto { + padding-left: auto !important; + } + + .pb-xxl-auto, +.py-xxl-auto { + padding-bottom: auto !important; + } + + .ps-xxl-auto { + padding-inline-start: auto !important; + } + + .pe-xxl-auto { + padding-inline-end: auto !important; + } + + .pa-xxl-auto { + padding: auto !important; + } + + .mt-xxl-n1, +.my-xxl-n1 { + margin-top: -4px !important; + } + + .mr-xxl-n1, +.mx-xxl-n1 { + margin-right: -4px !important; + } + + .ml-xxl-n1, +.mx-xxl-n1 { + margin-left: -4px !important; + } + + .mb-xxl-n1, +.my-xxl-n1 { + margin-bottom: -4px !important; + } + + .ms-xxl-n1 { + margin-inline-start: -4px !important; + } + + .me-xxl-n1 { + margin-inline-end: -4px !important; + } + + .ma-xxl-n1 { + margin: -4px !important; + } + + .mt-xxl-n2, +.my-xxl-n2 { + margin-top: -8px !important; + } + + .mr-xxl-n2, +.mx-xxl-n2 { + margin-right: -8px !important; + } + + .ml-xxl-n2, +.mx-xxl-n2 { + margin-left: -8px !important; + } + + .mb-xxl-n2, +.my-xxl-n2 { + margin-bottom: -8px !important; + } + + .ms-xxl-n2 { + margin-inline-start: -8px !important; + } + + .me-xxl-n2 { + margin-inline-end: -8px !important; + } + + .ma-xxl-n2 { + margin: -8px !important; + } + + .mt-xxl-n3, +.my-xxl-n3 { + margin-top: -12px !important; + } + + .mr-xxl-n3, +.mx-xxl-n3 { + margin-right: -12px !important; + } + + .ml-xxl-n3, +.mx-xxl-n3 { + margin-left: -12px !important; + } + + .mb-xxl-n3, +.my-xxl-n3 { + margin-bottom: -12px !important; + } + + .ms-xxl-n3 { + margin-inline-start: -12px !important; + } + + .me-xxl-n3 { + margin-inline-end: -12px !important; + } + + .ma-xxl-n3 { + margin: -12px !important; + } + + .mt-xxl-n4, +.my-xxl-n4 { + margin-top: -16px !important; + } + + .mr-xxl-n4, +.mx-xxl-n4 { + margin-right: -16px !important; + } + + .ml-xxl-n4, +.mx-xxl-n4 { + margin-left: -16px !important; + } + + .mb-xxl-n4, +.my-xxl-n4 { + margin-bottom: -16px !important; + } + + .ms-xxl-n4 { + margin-inline-start: -16px !important; + } + + .me-xxl-n4 { + margin-inline-end: -16px !important; + } + + .ma-xxl-n4 { + margin: -16px !important; + } + + .mt-xxl-n5, +.my-xxl-n5 { + margin-top: -20px !important; + } + + .mr-xxl-n5, +.mx-xxl-n5 { + margin-right: -20px !important; + } + + .ml-xxl-n5, +.mx-xxl-n5 { + margin-left: -20px !important; + } + + .mb-xxl-n5, +.my-xxl-n5 { + margin-bottom: -20px !important; + } + + .ms-xxl-n5 { + margin-inline-start: -20px !important; + } + + .me-xxl-n5 { + margin-inline-end: -20px !important; + } + + .ma-xxl-n5 { + margin: -20px !important; + } + + .mt-xxl-n6, +.my-xxl-n6 { + margin-top: -24px !important; + } + + .mr-xxl-n6, +.mx-xxl-n6 { + margin-right: -24px !important; + } + + .ml-xxl-n6, +.mx-xxl-n6 { + margin-left: -24px !important; + } + + .mb-xxl-n6, +.my-xxl-n6 { + margin-bottom: -24px !important; + } + + .ms-xxl-n6 { + margin-inline-start: -24px !important; + } + + .me-xxl-n6 { + margin-inline-end: -24px !important; + } + + .ma-xxl-n6 { + margin: -24px !important; + } + + .mt-xxl-n7, +.my-xxl-n7 { + margin-top: -28px !important; + } + + .mr-xxl-n7, +.mx-xxl-n7 { + margin-right: -28px !important; + } + + .ml-xxl-n7, +.mx-xxl-n7 { + margin-left: -28px !important; + } + + .mb-xxl-n7, +.my-xxl-n7 { + margin-bottom: -28px !important; + } + + .ms-xxl-n7 { + margin-inline-start: -28px !important; + } + + .me-xxl-n7 { + margin-inline-end: -28px !important; + } + + .ma-xxl-n7 { + margin: -28px !important; + } + + .mt-xxl-n8, +.my-xxl-n8 { + margin-top: -32px !important; + } + + .mr-xxl-n8, +.mx-xxl-n8 { + margin-right: -32px !important; + } + + .ml-xxl-n8, +.mx-xxl-n8 { + margin-left: -32px !important; + } + + .mb-xxl-n8, +.my-xxl-n8 { + margin-bottom: -32px !important; + } + + .ms-xxl-n8 { + margin-inline-start: -32px !important; + } + + .me-xxl-n8 { + margin-inline-end: -32px !important; + } + + .ma-xxl-n8 { + margin: -32px !important; + } + + .mt-xxl-n9, +.my-xxl-n9 { + margin-top: -36px !important; + } + + .mr-xxl-n9, +.mx-xxl-n9 { + margin-right: -36px !important; + } + + .ml-xxl-n9, +.mx-xxl-n9 { + margin-left: -36px !important; + } + + .mb-xxl-n9, +.my-xxl-n9 { + margin-bottom: -36px !important; + } + + .ms-xxl-n9 { + margin-inline-start: -36px !important; + } + + .me-xxl-n9 { + margin-inline-end: -36px !important; + } + + .ma-xxl-n9 { + margin: -36px !important; + } + + .mt-xxl-n10, +.my-xxl-n10 { + margin-top: -40px !important; + } + + .mr-xxl-n10, +.mx-xxl-n10 { + margin-right: -40px !important; + } + + .ml-xxl-n10, +.mx-xxl-n10 { + margin-left: -40px !important; + } + + .mb-xxl-n10, +.my-xxl-n10 { + margin-bottom: -40px !important; + } + + .ms-xxl-n10 { + margin-inline-start: -40px !important; + } + + .me-xxl-n10 { + margin-inline-end: -40px !important; + } + + .ma-xxl-n10 { + margin: -40px !important; + } + + .mt-xxl-n11, +.my-xxl-n11 { + margin-top: -44px !important; + } + + .mr-xxl-n11, +.mx-xxl-n11 { + margin-right: -44px !important; + } + + .ml-xxl-n11, +.mx-xxl-n11 { + margin-left: -44px !important; + } + + .mb-xxl-n11, +.my-xxl-n11 { + margin-bottom: -44px !important; + } + + .ms-xxl-n11 { + margin-inline-start: -44px !important; + } + + .me-xxl-n11 { + margin-inline-end: -44px !important; + } + + .ma-xxl-n11 { + margin: -44px !important; + } + + .mt-xxl-n12, +.my-xxl-n12 { + margin-top: -48px !important; + } + + .mr-xxl-n12, +.mx-xxl-n12 { + margin-right: -48px !important; + } + + .ml-xxl-n12, +.mx-xxl-n12 { + margin-left: -48px !important; + } + + .mb-xxl-n12, +.my-xxl-n12 { + margin-bottom: -48px !important; + } + + .ms-xxl-n12 { + margin-inline-start: -48px !important; + } + + .me-xxl-n12 { + margin-inline-end: -48px !important; + } + + .ma-xxl-n12 { + margin: -48px !important; + } + + .mt-xxl-n13, +.my-xxl-n13 { + margin-top: -52px !important; + } + + .mr-xxl-n13, +.mx-xxl-n13 { + margin-right: -52px !important; + } + + .ml-xxl-n13, +.mx-xxl-n13 { + margin-left: -52px !important; + } + + .mb-xxl-n13, +.my-xxl-n13 { + margin-bottom: -52px !important; + } + + .ms-xxl-n13 { + margin-inline-start: -52px !important; + } + + .me-xxl-n13 { + margin-inline-end: -52px !important; + } + + .ma-xxl-n13 { + margin: -52px !important; + } + + .mt-xxl-n14, +.my-xxl-n14 { + margin-top: -56px !important; + } + + .mr-xxl-n14, +.mx-xxl-n14 { + margin-right: -56px !important; + } + + .ml-xxl-n14, +.mx-xxl-n14 { + margin-left: -56px !important; + } + + .mb-xxl-n14, +.my-xxl-n14 { + margin-bottom: -56px !important; + } + + .ms-xxl-n14 { + margin-inline-start: -56px !important; + } + + .me-xxl-n14 { + margin-inline-end: -56px !important; + } + + .ma-xxl-n14 { + margin: -56px !important; + } + + .mt-xxl-n15, +.my-xxl-n15 { + margin-top: -60px !important; + } + + .mr-xxl-n15, +.mx-xxl-n15 { + margin-right: -60px !important; + } + + .ml-xxl-n15, +.mx-xxl-n15 { + margin-left: -60px !important; + } + + .mb-xxl-n15, +.my-xxl-n15 { + margin-bottom: -60px !important; + } + + .ms-xxl-n15 { + margin-inline-start: -60px !important; + } + + .me-xxl-n15 { + margin-inline-end: -60px !important; + } + + .ma-xxl-n15 { + margin: -60px !important; + } + + .mt-xxl-n16, +.my-xxl-n16 { + margin-top: -64px !important; + } + + .mr-xxl-n16, +.mx-xxl-n16 { + margin-right: -64px !important; + } + + .ml-xxl-n16, +.mx-xxl-n16 { + margin-left: -64px !important; + } + + .mb-xxl-n16, +.my-xxl-n16 { + margin-bottom: -64px !important; + } + + .ms-xxl-n16 { + margin-inline-start: -64px !important; + } + + .me-xxl-n16 { + margin-inline-end: -64px !important; + } + + .ma-xxl-n16 { + margin: -64px !important; + } +} +.width-full { + width: 100%; +} + +.height-full { + height: 100%; +} + +.w-max { + width: max-content; +} + +.appbar { + width: 100%; + display: flex; + z-index: var(--zindex-appbar); + position: relative; + box-sizing: border-box; + flex-shrink: 0; + flex-direction: column; + color: var(--palette-appbar-text); + background-color: var(--palette-appbar-background); + transition: margin 225ms cubic-bezier(0, 0, 0.2, 1) 0ms, width 225ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} +.appbar.appbar-fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; +} +.appbar.appbar-fixed-top .popover-cascading-value { + position: fixed; +} +.appbar.appbar-fixed-bottom { + position: fixed; + bottom: 0; + right: 0; + left: 0; +} +.appbar.appbar-fixed-bottom .popover-cascading-value { + position: fixed; +} +.appbar .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 8); +} +@media (min-width: 0px) and (orientation: landscape) { + .appbar .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 600px) { + .appbar .toolbar-appbar { + height: var(--appbar-height); + } +} +.appbar.appbar-dense .toolbar-appbar { + height: calc(var(--appbar-height) - var(--appbar-height) / 4); +} + +@media (min-width: 0px) { + .drawer-open-responsive-xs-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-xs-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-xs-left.drawer-left-clipped-never.drawer-open-responsive-xs-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 600px) { + .drawer-open-responsive-sm-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-sm-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-sm-left.drawer-left-clipped-never.drawer-open-responsive-sm-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 960px) { + .drawer-open-responsive-md-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-md-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-md-left.drawer-left-clipped-never.drawer-open-responsive-md-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 1280px) { + .drawer-open-responsive-lg-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-lg-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-lg-left.drawer-left-clipped-never.drawer-open-responsive-lg-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 1920px) { + .drawer-open-responsive-xl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-xl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-xl-left.drawer-left-clipped-never.drawer-open-responsive-xl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 2560px) { + .drawer-open-responsive-xxl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-responsive-xxl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-responsive-xxl-left.drawer-left-clipped-never.drawer-open-responsive-xxl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +.drawer-open-persistent-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); +} +.drawer-open-persistent-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); +} +.drawer-open-persistent-left.drawer-left-clipped-never.drawer-open-persistent-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); +} +@media (min-width: 0px) { + .drawer-open-mini-xs-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-xs-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-xs-left.drawer-left-clipped-never.drawer-open-mini-xs-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 600px) { + .drawer-open-mini-sm-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-sm-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-sm-left.drawer-left-clipped-never.drawer-open-mini-sm-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 960px) { + .drawer-open-mini-md-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-md-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-md-left.drawer-left-clipped-never.drawer-open-mini-md-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 1280px) { + .drawer-open-mini-lg-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-lg-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-lg-left.drawer-left-clipped-never.drawer-open-mini-lg-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 1920px) { + .drawer-open-mini-xl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-xl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-xl-left.drawer-left-clipped-never.drawer-open-mini-xl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} +@media (min-width: 2560px) { + .drawer-open-mini-xxl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-left); + width: calc(100% - var(--drawer-width-left)); + } + .drawer-open-mini-xxl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-right)); + } + .drawer-open-mini-xxl-left.drawer-left-clipped-never.drawer-open-mini-xxl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-left); + margin-right: var(--drawer-width-right); + width: calc(100% - var(--drawer-width-left) - var(--drawer-width-right)); + } +} + +.drawer-close-mini-xs-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-xs-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-xs-left.drawer-left-clipped-never.drawer-close-mini-xs-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 0px) { + .drawer-close-mini-xs-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-xs-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-xs-left.drawer-left-clipped-docked.drawer-close-mini-xs-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} +.drawer-close-mini-sm-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-sm-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-sm-left.drawer-left-clipped-never.drawer-close-mini-sm-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 600px) { + .drawer-close-mini-sm-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-sm-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-sm-left.drawer-left-clipped-docked.drawer-close-mini-sm-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} +.drawer-close-mini-md-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-md-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-md-left.drawer-left-clipped-never.drawer-close-mini-md-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 960px) { + .drawer-close-mini-md-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-md-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-md-left.drawer-left-clipped-docked.drawer-close-mini-md-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} +.drawer-close-mini-lg-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-lg-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-lg-left.drawer-left-clipped-never.drawer-close-mini-lg-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 1280px) { + .drawer-close-mini-lg-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-lg-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-lg-left.drawer-left-clipped-docked.drawer-close-mini-lg-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} +.drawer-close-mini-xl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-xl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-xl-left.drawer-left-clipped-never.drawer-close-mini-xl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 1920px) { + .drawer-close-mini-xl-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-xl-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-xl-left.drawer-left-clipped-docked.drawer-close-mini-xl-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} +.drawer-close-mini-xxl-left.drawer-left-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); +} +.drawer-close-mini-xxl-right.drawer-right-clipped-never .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); +} +.drawer-close-mini-xxl-left.drawer-left-clipped-never.drawer-close-mini-xxl-right.drawer-right-clipped-never .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); +} +@media (max-width: 2560px) { + .drawer-close-mini-xxl-left.drawer-left-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + width: calc(100% - var(--drawer-width-mini-left)); + } + .drawer-close-mini-xxl-right.drawer-right-clipped-docked .appbar { + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-right)); + } + .drawer-close-mini-xxl-left.drawer-left-clipped-docked.drawer-close-mini-xxl-right.drawer-right-clipped-docked .appbar { + margin-left: var(--drawer-width-mini-left); + margin-right: var(--drawer-width-mini-right); + width: calc(100% - var(--drawer-width-mini-left) - var(--drawer-width-mini-right)); + } +} + +.drawer { + display: flex; + flex-shrink: 0; + flex-grow: 1; + flex: 0 0 auto; + outline: 0; + position: fixed; + z-index: var(--zindex-drawer); + overflow-y: auto; + flex-direction: column; + color: var(--palette-drawer-text); + background-color: var(--palette-drawer-background); + --drawer-content-height: 0; +} +.drawer .drawer-content { + height: 100%; + max-height: 100%; + display: flex; + flex-shrink: 0; + flex-grow: 1; + flex: 0 0 auto; + flex-direction: column; +} +.drawer:not(.drawer-fixed) { + position: absolute; +} +@media (max-width: -1px) { + .drawer.drawer-mini.drawer-xs:not(.drawer--closed), .drawer.drawer-responsive.drawer-xs { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-xs:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-xs.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +@media (max-width: 599px) { + .drawer.drawer-mini.drawer-sm:not(.drawer--closed), .drawer.drawer-responsive.drawer-sm { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-sm:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-sm.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +@media (max-width: 959px) { + .drawer.drawer-mini.drawer-md:not(.drawer--closed), .drawer.drawer-responsive.drawer-md { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-md:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-md.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +@media (max-width: 1279px) { + .drawer.drawer-mini.drawer-lg:not(.drawer--closed), .drawer.drawer-responsive.drawer-lg { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-lg:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-lg.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +@media (max-width: 1919px) { + .drawer.drawer-mini.drawer-xl:not(.drawer--closed), .drawer.drawer-responsive.drawer-xl { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-xl:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-xl.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +@media (max-width: 2559px) { + .drawer.drawer-mini.drawer-xxl:not(.drawer--closed), .drawer.drawer-responsive.drawer-xxl { + z-index: calc(var(--zindex-appbar) + 2); + } + .drawer.drawer-mini.drawer-xxl:not(.drawer--closed).drawer--initial:not(.drawer-mini), .drawer.drawer-responsive.drawer-xxl.drawer--initial:not(.drawer-mini) { + display: none !important; + } +} +.drawer.drawer-responsive, .drawer.drawer-persistent { + height: 100%; +} +.drawer.drawer-responsive.drawer-pos-left, .drawer.drawer-persistent.drawer-pos-left { + right: auto; + width: var(--drawer-width, var(--drawer-width-left)); +} +.drawer.drawer-responsive.drawer-pos-left.drawer--open, .drawer.drawer-persistent.drawer-pos-left.drawer--open { + left: 0; +} +.drawer.drawer-responsive.drawer-pos-left.drawer--open:not(.drawer--initial), .drawer.drawer-persistent.drawer-pos-left.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-left 225ms cubic-bezier(0, 0, 0.2, 1); +} +.drawer.drawer-responsive.drawer-pos-left.drawer--closed, .drawer.drawer-persistent.drawer-pos-left.drawer--closed { + box-shadow: none; + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); +} +.drawer.drawer-responsive.drawer-pos-left.drawer--closed:not(.drawer--initial), .drawer.drawer-persistent.drawer-pos-left.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-left 225ms cubic-bezier(0, 0, 0.2, 1); +} +.drawer.drawer-responsive.drawer-pos-right, .drawer.drawer-persistent.drawer-pos-right { + left: auto; + width: var(--drawer-width, var(--drawer-width-right)); +} +.drawer.drawer-responsive.drawer-pos-right.drawer--open, .drawer.drawer-persistent.drawer-pos-right.drawer--open { + right: 0; +} +.drawer.drawer-responsive.drawer-pos-right.drawer--open:not(.drawer--initial), .drawer.drawer-persistent.drawer-pos-right.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-right 225ms cubic-bezier(0, 0, 0.2, 1); +} +.drawer.drawer-responsive.drawer-pos-right.drawer--closed, .drawer.drawer-persistent.drawer-pos-right.drawer--closed { + box-shadow: none; + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); +} +.drawer.drawer-responsive.drawer-pos-right.drawer--closed:not(.drawer--initial), .drawer.drawer-persistent.drawer-pos-right.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-right 225ms cubic-bezier(0, 0, 0.2, 1); +} +.drawer.drawer-mini { + height: 100%; + transition: width 225ms cubic-bezier(0, 0, 0.2, 1); +} +.drawer.drawer-mini.drawer-pos-left { + left: 0; + right: auto; +} +.drawer.drawer-mini.drawer-pos-left.drawer--closed { + width: var(--drawer-width-mini-left); +} +.drawer.drawer-mini.drawer-pos-left.drawer--open { + width: var(--drawer-width-left); +} +.drawer.drawer-mini.drawer-pos-right { + left: auto; + right: 0; +} +.drawer.drawer-mini.drawer-pos-right.drawer--closed { + width: var(--drawer-width-mini-right); +} +.drawer.drawer-mini.drawer-pos-right.drawer--open { + width: var(--drawer-width-right); +} +.drawer.drawer-temporary { + margin: 0 !important; + z-index: calc(var(--zindex-appbar) + 2); + transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} +.drawer.drawer-temporary.drawer-pos-left { + right: auto; + top: 0; + height: 100%; + width: var(--drawer-width, var(--drawer-width-left)); +} +.drawer.drawer-temporary.drawer-pos-left.drawer--open { + left: 0; +} +.drawer.drawer-temporary.drawer-pos-left.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-left 225ms cubic-bezier(0, 0, 0.2, 1) forwards; +} +.drawer.drawer-temporary.drawer-pos-left.drawer--closed { + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); +} +.drawer.drawer-temporary.drawer-pos-left.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-left 225ms cubic-bezier(0, 0, 0.2, 1) forwards; +} +.drawer.drawer-temporary.drawer-pos-right { + left: auto; + top: 0; + height: 100%; + width: var(--drawer-width, var(--drawer-width-right)); +} +.drawer.drawer-temporary.drawer-pos-right.drawer--open { + right: 0; +} +.drawer.drawer-temporary.drawer-pos-right.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-right 225ms cubic-bezier(0, 0, 0.2, 1) forwards; +} +.drawer.drawer-temporary.drawer-pos-right.drawer--closed { + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); +} +.drawer.drawer-temporary.drawer-pos-right.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-right 225ms cubic-bezier(0, 0, 0.2, 1) forwards; +} +.drawer.drawer-temporary.drawer-pos-bottom { + left: 0; + top: auto; + width: 100%; +} +.drawer.drawer-temporary.drawer-pos-bottom.drawer--open { + bottom: 0; +} +.drawer.drawer-temporary.drawer-pos-bottom.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-bottom 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; +} +.drawer.drawer-temporary.drawer-pos-bottom.drawer--closed { + bottom: calc(-1 * var(--drawer-content-height)); +} +.drawer.drawer-temporary.drawer-pos-bottom.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-bottom 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; +} +.drawer.drawer-temporary.drawer-pos-top { + left: 0; + bottom: auto; + width: 100%; +} +.drawer.drawer-temporary.drawer-pos-top.drawer--open { + top: 0; +} +.drawer.drawer-temporary.drawer-pos-top.drawer--open:not(.drawer--initial) { + animation: drawer-slide-in-top 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; +} +.drawer.drawer-temporary.drawer-pos-top.drawer--closed { + top: calc(-1 * var(--drawer-content-height)); +} +.drawer.drawer-temporary.drawer-pos-top.drawer--closed:not(.drawer--initial) { + animation: drawer-slide-out-top 225ms cubic-bezier(0, 0, 0.2, 1) 0ms 1; +} +.drawer.drawer-mini.drawer-pos-left ~ div:not(.main-content), .drawer.drawer-mini.drawer-pos-right ~ div:not(.main-content), .drawer.drawer-persistent.drawer-pos-left ~ div:not(.main-content), .drawer.drawer-persistent.drawer-pos-right ~ div:not(.main-content) { + transition: margin 225ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} +.drawer.drawer-mini.drawer-pos-left.drawer--open ~ div:not(.main-content), .drawer.drawer-persistent.drawer-pos-left.drawer--open ~ div:not(.main-content) { + margin-left: var(--drawer-width, var(--drawer-width-left)); +} +.drawer.drawer-mini.drawer-pos-right.drawer--open ~ div:not(.main-content), .drawer.drawer-persistent.drawer-pos-right.drawer--open ~ div:not(.main-content) { + margin-right: var(--drawer-width, var(--drawer-width-right)); +} +.drawer.drawer-mini.drawer-pos-left.drawer--closed ~ div:not(.main-content) { + margin-left: var(--drawer-width, var(--drawer-width-mini-left)); +} +.drawer.drawer-mini.drawer-pos-right.drawer--closed ~ div:not(.main-content) { + margin-right: var(--drawer-width, var(--drawer-width-mini-right)); +} + +.drawer-header { + display: flex; + min-height: var(--appbar-height); + padding: 12px 24px 12px 24px; +} +.drawer-header.drawer-header-dense { + min-height: calc(var(--appbar-height) - var(--appbar-height) / 4); + padding: 8px 24px 8px 24px; +} + +.drawer-fixed.drawer-mini.drawer-clipped-always, .drawer-fixed.drawer-persistent:not(.drawer-clipped-never), .drawer-fixed.drawer-responsive.drawer-clipped-always, .drawer-fixed.drawer-temporary.drawer-clipped-always { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); +} +@media (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-always, .drawer-fixed.drawer-persistent:not(.drawer-clipped-never), .drawer-fixed.drawer-responsive.drawer-clipped-always, .drawer-fixed.drawer-temporary.drawer-clipped-always { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - (var(--appbar-height) - var(--appbar-height) / 4)); + } +} +@media (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-always, .drawer-fixed.drawer-persistent:not(.drawer-clipped-never), .drawer-fixed.drawer-responsive.drawer-clipped-always, .drawer-fixed.drawer-temporary.drawer-clipped-always { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - (var(--appbar-height) - var(--appbar-height) / 8)); + } +} +@media (min-width: 0px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xs, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xs { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 0px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xs, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xs { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 0px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xs, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xs { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} +@media (min-width: 600px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-sm, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-sm { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 600px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-sm, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-sm { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 600px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-sm, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-sm { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} +@media (min-width: 960px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-md, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-md { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 960px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-md, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-md { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 960px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-md, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-md { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} +@media (min-width: 1280px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-lg, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-lg { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 1280px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-lg, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-lg { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 1280px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-lg, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-lg { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} +@media (min-width: 1920px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xl { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 1920px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xl { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 1920px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xl { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} +@media (min-width: 2560px) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xxl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xxl { + top: var(--appbar-height); + height: calc(100% - var(--appbar-height)); + } +} +@media (min-width: 2560px) and (max-width: 599px) and (orientation: landscape) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xxl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xxl { + top: calc(var(--appbar-height) - var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 2560px) and (max-width: 599px) and (orientation: portrait) { + .drawer-fixed.drawer-mini.drawer-clipped-docked.drawer-xxl, .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xxl { + top: calc(var(--appbar-height) - var(--appbar-height) / 8); + height: calc(100% - var(--appbar-height) / 8); + } +} + +.appbar-dense ~ .drawer-fixed.drawer-mini:not(.drawer-clipped-never), .appbar-dense ~ .drawer-fixed.drawer-persistent:not(.drawer-clipped-never), .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-always, .appbar-dense ~ .drawer-fixed.drawer-temporary.drawer-clipped-always { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); +} +@media (min-width: 0px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xs { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} +@media (min-width: 600px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-sm { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} +@media (min-width: 960px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-md { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} +@media (min-width: 1280px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-lg { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} +@media (min-width: 1920px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xl { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} +@media (min-width: 2560px) { + .appbar-dense ~ .drawer-fixed.drawer-responsive.drawer-clipped-docked.drawer-xxl { + top: calc(var(--appbar-height) - var(--appbar-height) / 4); + height: calc(100% - var(--appbar-height) + var(--appbar-height) / 4); + } +} + +.drawer-overlay { + display: none; +} +@media (max-width: -1px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xs { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xs.drawer--initial { + display: none; + } +} +@media (max-width: -1px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-xs { + display: block; + } +} +@media (max-width: 599px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-sm { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-sm.drawer--initial { + display: none; + } +} +@media (max-width: 599px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-sm { + display: block; + } +} +@media (max-width: 959px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-md { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-md.drawer--initial { + display: none; + } +} +@media (max-width: 959px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-md { + display: block; + } +} +@media (max-width: 1279px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-lg { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-lg.drawer--initial { + display: none; + } +} +@media (max-width: 1279px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-lg { + display: block; + } +} +@media (max-width: 1919px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xl { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xl.drawer--initial { + display: none; + } +} +@media (max-width: 1919px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-xl { + display: block; + } +} +@media (max-width: 2559px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xxl { + display: block; + } + .drawer-overlay.drawer-overlay--open.drawer-overlay-responsive.drawer-overlay-xxl.drawer--initial { + display: none; + } +} +@media (max-width: 2559px) { + .drawer-overlay.drawer-overlay--open.drawer-overlay-mini.drawer-overlay-xxl { + display: block; + } +} +.drawer-overlay.drawer-overlay--open.drawer-overlay-temporary { + display: block; +} + +/*#region keyframes*/ +@keyframes drawer-slide-in-left { + from { + left: calc(-1 * var(--drawer-width, var(--drawer-width-left))); + } +} +@keyframes drawer-slide-out-left { + from { + left: 0; + } +} +@keyframes drawer-slide-in-right { + from { + right: calc(-1 * var(--drawer-width, var(--drawer-width-right))); + } +} +@keyframes drawer-slide-out-right { + from { + right: 0; + } +} +@keyframes drawer-slide-in-bottom { + from { + bottom: calc(-1 * var(--drawer-content-height)); + } +} +@keyframes drawer-slide-out-bottom { + from { + bottom: 0; + } +} +@keyframes drawer-slide-in-top { + from { + top: calc(-1 * var(--drawer-content-height)); + } +} +@keyframes drawer-slide-out-top { + from { + top: 0; + } +} +/*#endregion*/ +.main-content { + margin: 0; + flex: 1 1 auto; + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 8); + transition: margin 225ms cubic-bezier(0, 0, 0.2, 1) 0ms; +} + +@media (min-width: 0px) and (orientation: landscape) { + .main-content { + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 4); + } +} +@media (min-width: 600px) { + .main-content { + padding-top: var(--appbar-height); + } +} +.appbar-dense ~ .main-content { + padding-top: calc(var(--appbar-height) - var(--appbar-height) / 4); +} + +@media (min-width: 0px) { + .drawer-open-responsive-xs-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-xs-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-xs-left.drawer-open-responsive-xs-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 600px) { + .drawer-open-responsive-sm-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-sm-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-sm-left.drawer-open-responsive-sm-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 960px) { + .drawer-open-responsive-md-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-md-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-md-left.drawer-open-responsive-md-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 1280px) { + .drawer-open-responsive-lg-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-lg-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-lg-left.drawer-open-responsive-lg-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 1920px) { + .drawer-open-responsive-xl-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-xl-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-xl-left.drawer-open-responsive-xl-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 2560px) { + .drawer-open-responsive-xxl-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-responsive-xxl-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-responsive-xxl-left.drawer-open-responsive-xxl-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +.drawer-open-persistent-left:not(.drawer-open-persistent-right) .main-content { + margin-left: var(--drawer-width-left); +} +.drawer-open-persistent-right:not(.drawer-open-persistent-left) .main-content { + margin-right: var(--drawer-width-right); +} +.drawer-open-persistent-left.drawer-open-persistent-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); +} +@media (min-width: 0px) { + .drawer-open-mini-xs-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-xs-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-xs-left.drawer-open-mini-xs-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 600px) { + .drawer-open-mini-sm-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-sm-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-sm-left.drawer-open-mini-sm-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 960px) { + .drawer-open-mini-md-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-md-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-md-left.drawer-open-mini-md-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 1280px) { + .drawer-open-mini-lg-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-lg-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-lg-left.drawer-open-mini-lg-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 1920px) { + .drawer-open-mini-xl-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-xl-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-xl-left.drawer-open-mini-xl-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +@media (min-width: 2560px) { + .drawer-open-mini-xxl-left .main-content { + margin-left: var(--drawer-width-left); + } + .drawer-open-mini-xxl-right .main-content { + margin-right: var(--drawer-width-right); + } + .drawer-open-mini-xxl-left.drawer-open-mini-xxl-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); + } +} +.drawer-open-mini-none-left .main-content, .drawer-open-mini-always-left .main-content { + margin-left: var(--drawer-width-left); +} +.drawer-open-mini-none-right .main-content, .drawer-open-mini-always-right .main-content { + margin-right: var(--drawer-width-right); +} +.drawer-open-mini-none-left.drawer-open-mini-none, .drawer-open-mini-none .drawer-open-mini-always-right .main-content, .drawer-open-mini-always-left.drawer-open-mini-none, .drawer-open-mini-always .drawer-open-mini-always-right .main-content { + margin-right: var(--drawer-width-right); + margin-left: var(--drawer-width-left); +} + +.drawer-close-mini-xs-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-xs-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-xs-left.drawer-close-mini-xs-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-sm-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-sm-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-sm-left.drawer-close-mini-sm-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-md-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-md-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-md-left.drawer-close-mini-md-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-lg-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-lg-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-lg-left.drawer-close-mini-lg-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-xl-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-xl-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-xl-left.drawer-close-mini-xl-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-xxl-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-xxl-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-xxl-left.drawer-close-mini-xxl-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-none-left .main-content, .drawer-close-mini-always-left .main-content { + margin-left: var(--drawer-width-mini-left); +} +.drawer-close-mini-none-right .main-content, .drawer-close-mini-always-right .main-content { + margin-right: var(--drawer-width-mini-right); +} +.drawer-close-mini-none-left.drawer-close-mini-none, .drawer-close-mini-none .drawer-close-mini-always-right .main-content, .drawer-close-mini-always-left.drawer-close-mini-none, .drawer-close-mini-always .drawer-close-mini-always-right .main-content { + margin-right: var(--drawer-width-mini-right); + margin-left: var(--drawer-width-mini-left); +} + +.container { + width: 100%; + display: block; + box-sizing: border-box; + margin-left: auto; + margin-right: auto; + padding-left: 16px; + padding-right: 16px; +} + +@media (min-width: 600px) { + .container { + padding-left: 24px; + padding-right: 24px; + } +} +.container-disable-gutters { + padding-left: 0; + padding-right: 0; +} + +@media (min-width: 600px) { + .container-fixed { + max-width: 600px; + } +} +@media (min-width: 960px) { + .container-fixed { + max-width: 960px; + } +} +@media (min-width: 1280px) { + .container-fixed { + max-width: 1280px; + } +} +@media (min-width: 1920px) { + .container-fixed { + max-width: 1920px; + } +} +@media (min-width: 2560px) { + .container-fixed { + max-width: 2560px; + } +} +@media (min-width: 0px) { + .container-maxwidth-xs { + max-width: 444px; + } +} +@media (min-width: 600px) { + .container-maxwidth-sm { + max-width: 600px; + } +} +@media (min-width: 960px) { + .container-maxwidth-md { + max-width: 960px; + } +} +@media (min-width: 1280px) { + .container-maxwidth-lg { + max-width: 1280px; + } +} +@media (min-width: 1920px) { + .container-maxwidth-xl { + max-width: 1920px; + } +} +@media (min-width: 2560px) { + .container-maxwidth-xxl { + max-width: 2560px; + } +} +.scroll-locked { + padding-right: 8px; + overflow: hidden; +} +.scroll-locked .layout .appbar { + padding-right: 8px; +} +.scroll-locked .layout .main-content .scroll-to-top { + padding-right: 8px; +} + +@-moz-document url-prefix() { + .scroll-locked { + padding-right: 17px; + } + .scroll-locked .layout .appbar { + padding-right: 17px; + } + .scroll-locked .layout .main-content .scroll-to-top { + padding-right: 17px; + } +} +.scroll-to-top { + position: fixed; + cursor: pointer; + z-index: 100; +} +.scroll-to-top.visible { + bottom: 16px; + right: 16px; + opacity: 1; + transition: transform 0.5s; + flex: 1; +} +.scroll-to-top.hidden { + bottom: 16px; + right: 16px; + opacity: 0; + transition: all 0.5s; + visibility: hidden; + transform: scale(0) rotate(180deg); + flex: 0; +} +.scroll-to-top:after { + content: ""; + background: transparent; + top: 0; + bottom: 0; + left: 0; + right: 0; + position: absolute; + z-index: var(--zindex-tooltip); +} + +.red { + background-color: #F44336; +} + +.red-text { + color: #F44336; +} + +.red.lighten-5 { + background-color: #FFEBEE; +} + +.red-text.text-lighten-5 { + color: #FFEBEE; +} + +.red.lighten-4 { + background-color: #FFCDD2; +} + +.red-text.text-lighten-4 { + color: #FFCDD2; +} + +.red.lighten-3 { + background-color: #EF9A9A; +} + +.red-text.text-lighten-3 { + color: #EF9A9A; +} + +.red.lighten-2 { + background-color: #E57373; +} + +.red-text.text-lighten-2 { + color: #E57373; +} + +.red.lighten-1 { + background-color: #EF5350; +} + +.red-text.text-lighten-1 { + color: #EF5350; +} + +.red.darken-1 { + background-color: #E53935; +} + +.red-text.text-darken-1 { + color: #E53935; +} + +.red.darken-2 { + background-color: #D32F2F; +} + +.red-text.text-darken-2 { + color: #D32F2F; +} + +.red.darken-3 { + background-color: #C62828; +} + +.red-text.text-darken-3 { + color: #C62828; +} + +.red.darken-4 { + background-color: #B71C1C; +} + +.red-text.text-darken-4 { + color: #B71C1C; +} + +.red.accent-1 { + background-color: #FF8A80; +} + +.red-text.text-accent-1 { + color: #FF8A80; +} + +.red.accent-2 { + background-color: #FF5252; +} + +.red-text.text-accent-2 { + color: #FF5252; +} + +.red.accent-3 { + background-color: #FF1744; +} + +.red-text.text-accent-3 { + color: #FF1744; +} + +.red.accent-4 { + background-color: #D50000; +} + +.red-text.text-accent-4 { + color: #D50000; +} + +.pink { + background-color: #e91e63; +} + +.pink-text { + color: #e91e63; +} + +.pink.lighten-5 { + background-color: #fce4ec; +} + +.pink-text.text-lighten-5 { + color: #fce4ec; +} + +.pink.lighten-4 { + background-color: #f8bbd0; +} + +.pink-text.text-lighten-4 { + color: #f8bbd0; +} + +.pink.lighten-3 { + background-color: #f48fb1; +} + +.pink-text.text-lighten-3 { + color: #f48fb1; +} + +.pink.lighten-2 { + background-color: #f06292; +} + +.pink-text.text-lighten-2 { + color: #f06292; +} + +.pink.lighten-1 { + background-color: #ec407a; +} + +.pink-text.text-lighten-1 { + color: #ec407a; +} + +.pink.darken-1 { + background-color: #d81b60; +} + +.pink-text.text-darken-1 { + color: #d81b60; +} + +.pink.darken-2 { + background-color: #c2185b; +} + +.pink-text.text-darken-2 { + color: #c2185b; +} + +.pink.darken-3 { + background-color: #ad1457; +} + +.pink-text.text-darken-3 { + color: #ad1457; +} + +.pink.darken-4 { + background-color: #880e4f; +} + +.pink-text.text-darken-4 { + color: #880e4f; +} + +.pink.accent-1 { + background-color: #ff80ab; +} + +.pink-text.text-accent-1 { + color: #ff80ab; +} + +.pink.accent-2 { + background-color: #ff4081; +} + +.pink-text.text-accent-2 { + color: #ff4081; +} + +.pink.accent-3 { + background-color: #f50057; +} + +.pink-text.text-accent-3 { + color: #f50057; +} + +.pink.accent-4 { + background-color: #c51162; +} + +.pink-text.text-accent-4 { + color: #c51162; +} + +.purple { + background-color: #9c27b0; +} + +.purple-text { + color: #9c27b0; +} + +.purple.lighten-5 { + background-color: #f3e5f5; +} + +.purple-text.text-lighten-5 { + color: #f3e5f5; +} + +.purple.lighten-4 { + background-color: #e1bee7; +} + +.purple-text.text-lighten-4 { + color: #e1bee7; +} + +.purple.lighten-3 { + background-color: #ce93d8; +} + +.purple-text.text-lighten-3 { + color: #ce93d8; +} + +.purple.lighten-2 { + background-color: #ba68c8; +} + +.purple-text.text-lighten-2 { + color: #ba68c8; +} + +.purple.lighten-1 { + background-color: #ab47bc; +} + +.purple-text.text-lighten-1 { + color: #ab47bc; +} + +.purple.darken-1 { + background-color: #8e24aa; +} + +.purple-text.text-darken-1 { + color: #8e24aa; +} + +.purple.darken-2 { + background-color: #7b1fa2; +} + +.purple-text.text-darken-2 { + color: #7b1fa2; +} + +.purple.darken-3 { + background-color: #6a1b9a; +} + +.purple-text.text-darken-3 { + color: #6a1b9a; +} + +.purple.darken-4 { + background-color: #4a148c; +} + +.purple-text.text-darken-4 { + color: #4a148c; +} + +.purple.accent-1 { + background-color: #ea80fc; +} + +.purple-text.text-accent-1 { + color: #ea80fc; +} + +.purple.accent-2 { + background-color: #e040fb; +} + +.purple-text.text-accent-2 { + color: #e040fb; +} + +.purple.accent-3 { + background-color: #d500f9; +} + +.purple-text.text-accent-3 { + color: #d500f9; +} + +.purple.accent-4 { + background-color: #aa00ff; +} + +.purple-text.text-accent-4 { + color: #aa00ff; +} + +.deep-purple { + background-color: #673ab7; +} + +.deep-purple-text { + color: #673ab7; +} + +.deep-purple.lighten-5 { + background-color: #ede7f6; +} + +.deep-purple-text.text-lighten-5 { + color: #ede7f6; +} + +.deep-purple.lighten-4 { + background-color: #d1c4e9; +} + +.deep-purple-text.text-lighten-4 { + color: #d1c4e9; +} + +.deep-purple.lighten-3 { + background-color: #b39ddb; +} + +.deep-purple-text.text-lighten-3 { + color: #b39ddb; +} + +.deep-purple.lighten-2 { + background-color: #9575cd; +} + +.deep-purple-text.text-lighten-2 { + color: #9575cd; +} + +.deep-purple.lighten-1 { + background-color: #7e57c2; +} + +.deep-purple-text.text-lighten-1 { + color: #7e57c2; +} + +.deep-purple.darken-1 { + background-color: #5e35b1; +} + +.deep-purple-text.text-darken-1 { + color: #5e35b1; +} + +.deep-purple.darken-2 { + background-color: #512da8; +} + +.deep-purple-text.text-darken-2 { + color: #512da8; +} + +.deep-purple.darken-3 { + background-color: #4527a0; +} + +.deep-purple-text.text-darken-3 { + color: #4527a0; +} + +.deep-purple.darken-4 { + background-color: #311b92; +} + +.deep-purple-text.text-darken-4 { + color: #311b92; +} + +.deep-purple.accent-1 { + background-color: #b388ff; +} + +.deep-purple-text.text-accent-1 { + color: #b388ff; +} + +.deep-purple.accent-2 { + background-color: #7c4dff; +} + +.deep-purple-text.text-accent-2 { + color: #7c4dff; +} + +.deep-purple.accent-3 { + background-color: #651fff; +} + +.deep-purple-text.text-accent-3 { + color: #651fff; +} + +.deep-purple.accent-4 { + background-color: #6200ea; +} + +.deep-purple-text.text-accent-4 { + color: #6200ea; +} + +.indigo { + background-color: #3f51b5; +} + +.indigo-text { + color: #3f51b5; +} + +.indigo.lighten-5 { + background-color: #e8eaf6; +} + +.indigo-text.text-lighten-5 { + color: #e8eaf6; +} + +.indigo.lighten-4 { + background-color: #c5cae9; +} + +.indigo-text.text-lighten-4 { + color: #c5cae9; +} + +.indigo.lighten-3 { + background-color: #9fa8da; +} + +.indigo-text.text-lighten-3 { + color: #9fa8da; +} + +.indigo.lighten-2 { + background-color: #7986cb; +} + +.indigo-text.text-lighten-2 { + color: #7986cb; +} + +.indigo.lighten-1 { + background-color: #5c6bc0; +} + +.indigo-text.text-lighten-1 { + color: #5c6bc0; +} + +.indigo.darken-1 { + background-color: #3949ab; +} + +.indigo-text.text-darken-1 { + color: #3949ab; +} + +.indigo.darken-2 { + background-color: #303f9f; +} + +.indigo-text.text-darken-2 { + color: #303f9f; +} + +.indigo.darken-3 { + background-color: #283593; +} + +.indigo-text.text-darken-3 { + color: #283593; +} + +.indigo.darken-4 { + background-color: #1a237e; +} + +.indigo-text.text-darken-4 { + color: #1a237e; +} + +.indigo.accent-1 { + background-color: #8c9eff; +} + +.indigo-text.text-accent-1 { + color: #8c9eff; +} + +.indigo.accent-2 { + background-color: #536dfe; +} + +.indigo-text.text-accent-2 { + color: #536dfe; +} + +.indigo.accent-3 { + background-color: #3d5afe; +} + +.indigo-text.text-accent-3 { + color: #3d5afe; +} + +.indigo.accent-4 { + background-color: #304ffe; +} + +.indigo-text.text-accent-4 { + color: #304ffe; +} + +.blue { + background-color: #2196F3; +} + +.blue-text { + color: #2196F3; +} + +.blue.lighten-5 { + background-color: #E3F2FD; +} + +.blue-text.text-lighten-5 { + color: #E3F2FD; +} + +.blue.lighten-4 { + background-color: #BBDEFB; +} + +.blue-text.text-lighten-4 { + color: #BBDEFB; +} + +.blue.lighten-3 { + background-color: #90CAF9; +} + +.blue-text.text-lighten-3 { + color: #90CAF9; +} + +.blue.lighten-2 { + background-color: #64B5F6; +} + +.blue-text.text-lighten-2 { + color: #64B5F6; +} + +.blue.lighten-1 { + background-color: #42A5F5; +} + +.blue-text.text-lighten-1 { + color: #42A5F5; +} + +.blue.darken-1 { + background-color: #1E88E5; +} + +.blue-text.text-darken-1 { + color: #1E88E5; +} + +.blue.darken-2 { + background-color: #1976D2; +} + +.blue-text.text-darken-2 { + color: #1976D2; +} + +.blue.darken-3 { + background-color: #1565C0; +} + +.blue-text.text-darken-3 { + color: #1565C0; +} + +.blue.darken-4 { + background-color: #0D47A1; +} + +.blue-text.text-darken-4 { + color: #0D47A1; +} + +.blue.accent-1 { + background-color: #82B1FF; +} + +.blue-text.text-accent-1 { + color: #82B1FF; +} + +.blue.accent-2 { + background-color: #448AFF; +} + +.blue-text.text-accent-2 { + color: #448AFF; +} + +.blue.accent-3 { + background-color: #2979FF; +} + +.blue-text.text-accent-3 { + color: #2979FF; +} + +.blue.accent-4 { + background-color: #2962FF; +} + +.blue-text.text-accent-4 { + color: #2962FF; +} + +.light-blue { + background-color: #03a9f4; +} + +.light-blue-text { + color: #03a9f4; +} + +.light-blue.lighten-5 { + background-color: #e1f5fe; +} + +.light-blue-text.text-lighten-5 { + color: #e1f5fe; +} + +.light-blue.lighten-4 { + background-color: #b3e5fc; +} + +.light-blue-text.text-lighten-4 { + color: #b3e5fc; +} + +.light-blue.lighten-3 { + background-color: #81d4fa; +} + +.light-blue-text.text-lighten-3 { + color: #81d4fa; +} + +.light-blue.lighten-2 { + background-color: #4fc3f7; +} + +.light-blue-text.text-lighten-2 { + color: #4fc3f7; +} + +.light-blue.lighten-1 { + background-color: #29b6f6; +} + +.light-blue-text.text-lighten-1 { + color: #29b6f6; +} + +.light-blue.darken-1 { + background-color: #039be5; +} + +.light-blue-text.text-darken-1 { + color: #039be5; +} + +.light-blue.darken-2 { + background-color: #0288d1; +} + +.light-blue-text.text-darken-2 { + color: #0288d1; +} + +.light-blue.darken-3 { + background-color: #0277bd; +} + +.light-blue-text.text-darken-3 { + color: #0277bd; +} + +.light-blue.darken-4 { + background-color: #01579b; +} + +.light-blue-text.text-darken-4 { + color: #01579b; +} + +.light-blue.accent-1 { + background-color: #80d8ff; +} + +.light-blue-text.text-accent-1 { + color: #80d8ff; +} + +.light-blue.accent-2 { + background-color: #40c4ff; +} + +.light-blue-text.text-accent-2 { + color: #40c4ff; +} + +.light-blue.accent-3 { + background-color: #00b0ff; +} + +.light-blue-text.text-accent-3 { + color: #00b0ff; +} + +.light-blue.accent-4 { + background-color: #0091ea; +} + +.light-blue-text.text-accent-4 { + color: #0091ea; +} + +.cyan { + background-color: #00bcd4; +} + +.cyan-text { + color: #00bcd4; +} + +.cyan.lighten-5 { + background-color: #e0f7fa; +} + +.cyan-text.text-lighten-5 { + color: #e0f7fa; +} + +.cyan.lighten-4 { + background-color: #b2ebf2; +} + +.cyan-text.text-lighten-4 { + color: #b2ebf2; +} + +.cyan.lighten-3 { + background-color: #80deea; +} + +.cyan-text.text-lighten-3 { + color: #80deea; +} + +.cyan.lighten-2 { + background-color: #4dd0e1; +} + +.cyan-text.text-lighten-2 { + color: #4dd0e1; +} + +.cyan.lighten-1 { + background-color: #26c6da; +} + +.cyan-text.text-lighten-1 { + color: #26c6da; +} + +.cyan.darken-1 { + background-color: #00acc1; +} + +.cyan-text.text-darken-1 { + color: #00acc1; +} + +.cyan.darken-2 { + background-color: #0097a7; +} + +.cyan-text.text-darken-2 { + color: #0097a7; +} + +.cyan.darken-3 { + background-color: #00838f; +} + +.cyan-text.text-darken-3 { + color: #00838f; +} + +.cyan.darken-4 { + background-color: #006064; +} + +.cyan-text.text-darken-4 { + color: #006064; +} + +.cyan.accent-1 { + background-color: #84ffff; +} + +.cyan-text.text-accent-1 { + color: #84ffff; +} + +.cyan.accent-2 { + background-color: #18ffff; +} + +.cyan-text.text-accent-2 { + color: #18ffff; +} + +.cyan.accent-3 { + background-color: #00e5ff; +} + +.cyan-text.text-accent-3 { + color: #00e5ff; +} + +.cyan.accent-4 { + background-color: #00b8d4; +} + +.cyan-text.text-accent-4 { + color: #00b8d4; +} + +.teal { + background-color: #009688; +} + +.teal-text { + color: #009688; +} + +.teal.lighten-5 { + background-color: #e0f2f1; +} + +.teal-text.text-lighten-5 { + color: #e0f2f1; +} + +.teal.lighten-4 { + background-color: #b2dfdb; +} + +.teal-text.text-lighten-4 { + color: #b2dfdb; +} + +.teal.lighten-3 { + background-color: #80cbc4; +} + +.teal-text.text-lighten-3 { + color: #80cbc4; +} + +.teal.lighten-2 { + background-color: #4db6ac; +} + +.teal-text.text-lighten-2 { + color: #4db6ac; +} + +.teal.lighten-1 { + background-color: #26a69a; +} + +.teal-text.text-lighten-1 { + color: #26a69a; +} + +.teal.darken-1 { + background-color: #00897b; +} + +.teal-text.text-darken-1 { + color: #00897b; +} + +.teal.darken-2 { + background-color: #00796b; +} + +.teal-text.text-darken-2 { + color: #00796b; +} + +.teal.darken-3 { + background-color: #00695c; +} + +.teal-text.text-darken-3 { + color: #00695c; +} + +.teal.darken-4 { + background-color: #004d40; +} + +.teal-text.text-darken-4 { + color: #004d40; +} + +.teal.accent-1 { + background-color: #a7ffeb; +} + +.teal-text.text-accent-1 { + color: #a7ffeb; +} + +.teal.accent-2 { + background-color: #64ffda; +} + +.teal-text.text-accent-2 { + color: #64ffda; +} + +.teal.accent-3 { + background-color: #1de9b6; +} + +.teal-text.text-accent-3 { + color: #1de9b6; +} + +.teal.accent-4 { + background-color: #00bfa5; +} + +.teal-text.text-accent-4 { + color: #00bfa5; +} + +.green { + background-color: #4CAF50; +} + +.green-text { + color: #4CAF50; +} + +.green.lighten-5 { + background-color: #E8F5E9; +} + +.green-text.text-lighten-5 { + color: #E8F5E9; +} + +.green.lighten-4 { + background-color: #C8E6C9; +} + +.green-text.text-lighten-4 { + color: #C8E6C9; +} + +.green.lighten-3 { + background-color: #A5D6A7; +} + +.green-text.text-lighten-3 { + color: #A5D6A7; +} + +.green.lighten-2 { + background-color: #81C784; +} + +.green-text.text-lighten-2 { + color: #81C784; +} + +.green.lighten-1 { + background-color: #66BB6A; +} + +.green-text.text-lighten-1 { + color: #66BB6A; +} + +.green.darken-1 { + background-color: #43A047; +} + +.green-text.text-darken-1 { + color: #43A047; +} + +.green.darken-2 { + background-color: #388E3C; +} + +.green-text.text-darken-2 { + color: #388E3C; +} + +.green.darken-3 { + background-color: #2E7D32; +} + +.green-text.text-darken-3 { + color: #2E7D32; +} + +.green.darken-4 { + background-color: #1B5E20; +} + +.green-text.text-darken-4 { + color: #1B5E20; +} + +.green.accent-1 { + background-color: #B9F6CA; +} + +.green-text.text-accent-1 { + color: #B9F6CA; +} + +.green.accent-2 { + background-color: #69F0AE; +} + +.green-text.text-accent-2 { + color: #69F0AE; +} + +.green.accent-3 { + background-color: #00E676; +} + +.green-text.text-accent-3 { + color: #00E676; +} + +.green.accent-4 { + background-color: #00C853; +} + +.green-text.text-accent-4 { + color: #00C853; +} + +.light-green { + background-color: #8bc34a; +} + +.light-green-text { + color: #8bc34a; +} + +.light-green.lighten-5 { + background-color: #f1f8e9; +} + +.light-green-text.text-lighten-5 { + color: #f1f8e9; +} + +.light-green.lighten-4 { + background-color: #dcedc8; +} + +.light-green-text.text-lighten-4 { + color: #dcedc8; +} + +.light-green.lighten-3 { + background-color: #c5e1a5; +} + +.light-green-text.text-lighten-3 { + color: #c5e1a5; +} + +.light-green.lighten-2 { + background-color: #aed581; +} + +.light-green-text.text-lighten-2 { + color: #aed581; +} + +.light-green.lighten-1 { + background-color: #9ccc65; +} + +.light-green-text.text-lighten-1 { + color: #9ccc65; +} + +.light-green.darken-1 { + background-color: #7cb342; +} + +.light-green-text.text-darken-1 { + color: #7cb342; +} + +.light-green.darken-2 { + background-color: #689f38; +} + +.light-green-text.text-darken-2 { + color: #689f38; +} + +.light-green.darken-3 { + background-color: #558b2f; +} + +.light-green-text.text-darken-3 { + color: #558b2f; +} + +.light-green.darken-4 { + background-color: #33691e; +} + +.light-green-text.text-darken-4 { + color: #33691e; +} + +.light-green.accent-1 { + background-color: #ccff90; +} + +.light-green-text.text-accent-1 { + color: #ccff90; +} + +.light-green.accent-2 { + background-color: #b2ff59; +} + +.light-green-text.text-accent-2 { + color: #b2ff59; +} + +.light-green.accent-3 { + background-color: #76ff03; +} + +.light-green-text.text-accent-3 { + color: #76ff03; +} + +.light-green.accent-4 { + background-color: #64dd17; +} + +.light-green-text.text-accent-4 { + color: #64dd17; +} + +.lime { + background-color: #cddc39; +} + +.lime-text { + color: #cddc39; +} + +.lime.lighten-5 { + background-color: #f9fbe7; +} + +.lime-text.text-lighten-5 { + color: #f9fbe7; +} + +.lime.lighten-4 { + background-color: #f0f4c3; +} + +.lime-text.text-lighten-4 { + color: #f0f4c3; +} + +.lime.lighten-3 { + background-color: #e6ee9c; +} + +.lime-text.text-lighten-3 { + color: #e6ee9c; +} + +.lime.lighten-2 { + background-color: #dce775; +} + +.lime-text.text-lighten-2 { + color: #dce775; +} + +.lime.lighten-1 { + background-color: #d4e157; +} + +.lime-text.text-lighten-1 { + color: #d4e157; +} + +.lime.darken-1 { + background-color: #c0ca33; +} + +.lime-text.text-darken-1 { + color: #c0ca33; +} + +.lime.darken-2 { + background-color: #afb42b; +} + +.lime-text.text-darken-2 { + color: #afb42b; +} + +.lime.darken-3 { + background-color: #9e9d24; +} + +.lime-text.text-darken-3 { + color: #9e9d24; +} + +.lime.darken-4 { + background-color: #827717; +} + +.lime-text.text-darken-4 { + color: #827717; +} + +.lime.accent-1 { + background-color: #f4ff81; +} + +.lime-text.text-accent-1 { + color: #f4ff81; +} + +.lime.accent-2 { + background-color: #eeff41; +} + +.lime-text.text-accent-2 { + color: #eeff41; +} + +.lime.accent-3 { + background-color: #c6ff00; +} + +.lime-text.text-accent-3 { + color: #c6ff00; +} + +.lime.accent-4 { + background-color: #aeea00; +} + +.lime-text.text-accent-4 { + color: #aeea00; +} + +.yellow { + background-color: #ffeb3b; +} + +.yellow-text { + color: #ffeb3b; +} + +.yellow.lighten-5 { + background-color: #fffde7; +} + +.yellow-text.text-lighten-5 { + color: #fffde7; +} + +.yellow.lighten-4 { + background-color: #fff9c4; +} + +.yellow-text.text-lighten-4 { + color: #fff9c4; +} + +.yellow.lighten-3 { + background-color: #fff59d; +} + +.yellow-text.text-lighten-3 { + color: #fff59d; +} + +.yellow.lighten-2 { + background-color: #fff176; +} + +.yellow-text.text-lighten-2 { + color: #fff176; +} + +.yellow.lighten-1 { + background-color: #ffee58; +} + +.yellow-text.text-lighten-1 { + color: #ffee58; +} + +.yellow.darken-1 { + background-color: #fdd835; +} + +.yellow-text.text-darken-1 { + color: #fdd835; +} + +.yellow.darken-2 { + background-color: #fbc02d; +} + +.yellow-text.text-darken-2 { + color: #fbc02d; +} + +.yellow.darken-3 { + background-color: #f9a825; +} + +.yellow-text.text-darken-3 { + color: #f9a825; +} + +.yellow.darken-4 { + background-color: #f57f17; +} + +.yellow-text.text-darken-4 { + color: #f57f17; +} + +.yellow.accent-1 { + background-color: #ffff8d; +} + +.yellow-text.text-accent-1 { + color: #ffff8d; +} + +.yellow.accent-2 { + background-color: #ffff00; +} + +.yellow-text.text-accent-2 { + color: #ffff00; +} + +.yellow.accent-3 { + background-color: #ffea00; +} + +.yellow-text.text-accent-3 { + color: #ffea00; +} + +.yellow.accent-4 { + background-color: #ffd600; +} + +.yellow-text.text-accent-4 { + color: #ffd600; +} + +.amber { + background-color: #ffc107; +} + +.amber-text { + color: #ffc107; +} + +.amber.lighten-5 { + background-color: #fff8e1; +} + +.amber-text.text-lighten-5 { + color: #fff8e1; +} + +.amber.lighten-4 { + background-color: #ffecb3; +} + +.amber-text.text-lighten-4 { + color: #ffecb3; +} + +.amber.lighten-3 { + background-color: #ffe082; +} + +.amber-text.text-lighten-3 { + color: #ffe082; +} + +.amber.lighten-2 { + background-color: #ffd54f; +} + +.amber-text.text-lighten-2 { + color: #ffd54f; +} + +.amber.lighten-1 { + background-color: #ffca28; +} + +.amber-text.text-lighten-1 { + color: #ffca28; +} + +.amber.darken-1 { + background-color: #ffb300; +} + +.amber-text.text-darken-1 { + color: #ffb300; +} + +.amber.darken-2 { + background-color: #ffa000; +} + +.amber-text.text-darken-2 { + color: #ffa000; +} + +.amber.darken-3 { + background-color: #ff8f00; +} + +.amber-text.text-darken-3 { + color: #ff8f00; +} + +.amber.darken-4 { + background-color: #ff6f00; +} + +.amber-text.text-darken-4 { + color: #ff6f00; +} + +.amber.accent-1 { + background-color: #ffe57f; +} + +.amber-text.text-accent-1 { + color: #ffe57f; +} + +.amber.accent-2 { + background-color: #ffd740; +} + +.amber-text.text-accent-2 { + color: #ffd740; +} + +.amber.accent-3 { + background-color: #ffc400; +} + +.amber-text.text-accent-3 { + color: #ffc400; +} + +.amber.accent-4 { + background-color: #ffab00; +} + +.amber-text.text-accent-4 { + color: #ffab00; +} + +.orange { + background-color: #ff9800; +} + +.orange-text { + color: #ff9800; +} + +.orange.lighten-5 { + background-color: #fff3e0; +} + +.orange-text.text-lighten-5 { + color: #fff3e0; +} + +.orange.lighten-4 { + background-color: #ffe0b2; +} + +.orange-text.text-lighten-4 { + color: #ffe0b2; +} + +.orange.lighten-3 { + background-color: #ffcc80; +} + +.orange-text.text-lighten-3 { + color: #ffcc80; +} + +.orange.lighten-2 { + background-color: #ffb74d; +} + +.orange-text.text-lighten-2 { + color: #ffb74d; +} + +.orange.lighten-1 { + background-color: #ffa726; +} + +.orange-text.text-lighten-1 { + color: #ffa726; +} + +.orange.darken-1 { + background-color: #fb8c00; +} + +.orange-text.text-darken-1 { + color: #fb8c00; +} + +.orange.darken-2 { + background-color: #f57c00; +} + +.orange-text.text-darken-2 { + color: #f57c00; +} + +.orange.darken-3 { + background-color: #ef6c00; +} + +.orange-text.text-darken-3 { + color: #ef6c00; +} + +.orange.darken-4 { + background-color: #e65100; +} + +.orange-text.text-darken-4 { + color: #e65100; +} + +.orange.accent-1 { + background-color: #ffd180; +} + +.orange-text.text-accent-1 { + color: #ffd180; +} + +.orange.accent-2 { + background-color: #ffab40; +} + +.orange-text.text-accent-2 { + color: #ffab40; +} + +.orange.accent-3 { + background-color: #ff9100; +} + +.orange-text.text-accent-3 { + color: #ff9100; +} + +.orange.accent-4 { + background-color: #ff6d00; +} + +.orange-text.text-accent-4 { + color: #ff6d00; +} + +.deep-orange { + background-color: #ff5722; +} + +.deep-orange-text { + color: #ff5722; +} + +.deep-orange.lighten-5 { + background-color: #fbe9e7; +} + +.deep-orange-text.text-lighten-5 { + color: #fbe9e7; +} + +.deep-orange.lighten-4 { + background-color: #ffccbc; +} + +.deep-orange-text.text-lighten-4 { + color: #ffccbc; +} + +.deep-orange.lighten-3 { + background-color: #ffab91; +} + +.deep-orange-text.text-lighten-3 { + color: #ffab91; +} + +.deep-orange.lighten-2 { + background-color: #ff8a65; +} + +.deep-orange-text.text-lighten-2 { + color: #ff8a65; +} + +.deep-orange.lighten-1 { + background-color: #ff7043; +} + +.deep-orange-text.text-lighten-1 { + color: #ff7043; +} + +.deep-orange.darken-1 { + background-color: #f4511e; +} + +.deep-orange-text.text-darken-1 { + color: #f4511e; +} + +.deep-orange.darken-2 { + background-color: #e64a19; +} + +.deep-orange-text.text-darken-2 { + color: #e64a19; +} + +.deep-orange.darken-3 { + background-color: #d84315; +} + +.deep-orange-text.text-darken-3 { + color: #d84315; +} + +.deep-orange.darken-4 { + background-color: #bf360c; +} + +.deep-orange-text.text-darken-4 { + color: #bf360c; +} + +.deep-orange.accent-1 { + background-color: #ff9e80; +} + +.deep-orange-text.text-accent-1 { + color: #ff9e80; +} + +.deep-orange.accent-2 { + background-color: #ff6e40; +} + +.deep-orange-text.text-accent-2 { + color: #ff6e40; +} + +.deep-orange.accent-3 { + background-color: #ff3d00; +} + +.deep-orange-text.text-accent-3 { + color: #ff3d00; +} + +.deep-orange.accent-4 { + background-color: #dd2c00; +} + +.deep-orange-text.text-accent-4 { + color: #dd2c00; +} + +.brown { + background-color: #795548; +} + +.brown-text { + color: #795548; +} + +.brown.lighten-5 { + background-color: #efebe9; +} + +.brown-text.text-lighten-5 { + color: #efebe9; +} + +.brown.lighten-4 { + background-color: #d7ccc8; +} + +.brown-text.text-lighten-4 { + color: #d7ccc8; +} + +.brown.lighten-3 { + background-color: #bcaaa4; +} + +.brown-text.text-lighten-3 { + color: #bcaaa4; +} + +.brown.lighten-2 { + background-color: #a1887f; +} + +.brown-text.text-lighten-2 { + color: #a1887f; +} + +.brown.lighten-1 { + background-color: #8d6e63; +} + +.brown-text.text-lighten-1 { + color: #8d6e63; +} + +.brown.darken-1 { + background-color: #6d4c41; +} + +.brown-text.text-darken-1 { + color: #6d4c41; +} + +.brown.darken-2 { + background-color: #5d4037; +} + +.brown-text.text-darken-2 { + color: #5d4037; +} + +.brown.darken-3 { + background-color: #4e342e; +} + +.brown-text.text-darken-3 { + color: #4e342e; +} + +.brown.darken-4 { + background-color: #3e2723; +} + +.brown-text.text-darken-4 { + color: #3e2723; +} + +.blue-grey { + background-color: #607d8b; +} + +.blue-grey-text { + color: #607d8b; +} + +.blue-grey.lighten-5 { + background-color: #eceff1; +} + +.blue-grey-text.text-lighten-5 { + color: #eceff1; +} + +.blue-grey.lighten-4 { + background-color: #cfd8dc; +} + +.blue-grey-text.text-lighten-4 { + color: #cfd8dc; +} + +.blue-grey.lighten-3 { + background-color: #b0bec5; +} + +.blue-grey-text.text-lighten-3 { + color: #b0bec5; +} + +.blue-grey.lighten-2 { + background-color: #90a4ae; +} + +.blue-grey-text.text-lighten-2 { + color: #90a4ae; +} + +.blue-grey.lighten-1 { + background-color: #78909c; +} + +.blue-grey-text.text-lighten-1 { + color: #78909c; +} + +.blue-grey.darken-1 { + background-color: #546e7a; +} + +.blue-grey-text.text-darken-1 { + color: #546e7a; +} + +.blue-grey.darken-2 { + background-color: #455a64; +} + +.blue-grey-text.text-darken-2 { + color: #455a64; +} + +.blue-grey.darken-3 { + background-color: #37474f; +} + +.blue-grey-text.text-darken-3 { + color: #37474f; +} + +.blue-grey.darken-4 { + background-color: #263238; +} + +.blue-grey-text.text-darken-4 { + color: #263238; +} + +.grey { + background-color: #9e9e9e; +} + +.grey-text { + color: #9e9e9e; +} + +.grey.lighten-5 { + background-color: #fafafa; +} + +.grey-text.text-lighten-5 { + color: #fafafa; +} + +.grey.lighten-4 { + background-color: #f5f5f5; +} + +.grey-text.text-lighten-4 { + color: #f5f5f5; +} + +.grey.lighten-3 { + background-color: #eeeeee; +} + +.grey-text.text-lighten-3 { + color: #eeeeee; +} + +.grey.lighten-2 { + background-color: #e0e0e0; +} + +.grey-text.text-lighten-2 { + color: #e0e0e0; +} + +.grey.lighten-1 { + background-color: #bdbdbd; +} + +.grey-text.text-lighten-1 { + color: #bdbdbd; +} + +.grey.darken-1 { + background-color: #757575; +} + +.grey-text.text-darken-1 { + color: #757575; +} + +.grey.darken-2 { + background-color: #616161; +} + +.grey-text.text-darken-2 { + color: #616161; +} + +.grey.darken-3 { + background-color: #424242; +} + +.grey-text.text-darken-3 { + color: #424242; +} + +.grey.darken-4 { + background-color: #212121; +} + +.grey-text.text-darken-4 { + color: #212121; +} + +.shades.black { + background-color: #000000; +} + +.shades-text.text-black { + color: #000000; +} + +.shades.white { + background-color: #FFFFFF; +} + +.shades-text.text-white { + color: #FFFFFF; +} + +.shades.transparent { + background-color: transparent; +} + +.shades-text.text-transparent { + color: transparent; +} + +.ripple { + position: relative; + overflow: hidden; +} +.ripple:after { + content: ""; + display: block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + pointer-events: none; + background-image: radial-gradient(circle, #000 10%, transparent 10.01%); + background-repeat: no-repeat; + background-position: 50%; + transform: scale(10, 10); + opacity: 0; + transition: transform 0.3s, opacity 1s; +} +.ripple:active:after { + transform: scale(0, 0); + opacity: 0.1; + transition: 0s; +} + +.ripple-icon:after, .ripple-checkbox:after, .ripple-switch:after, .ripple-radio:after { + transform: scale(7, 7); +} + +.ripple-switch { + position: absolute; +} + +.rtl { + direction: rtl !important; +} + +.ltr { + direction: ltr !important; +} + +.application-layout-rtl .flip-x-rtl { + transform: scaleX(-1); +} diff --git a/wwwroot/Styles.css b/wwwroot/Styles.css new file mode 100644 index 0000000..08431b3 --- /dev/null +++ b/wwwroot/Styles.css @@ -0,0 +1,4 @@ +.important { + font-size: 3em; + color: green; +} diff --git a/wwwroot/Styles.scss b/wwwroot/Styles.scss new file mode 100644 index 0000000..50c963d --- /dev/null +++ b/wwwroot/Styles.scss @@ -0,0 +1,7 @@ +body { +} + +.important { + font-size: 3em; + color: green; +}