You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Annotations/CategoryAttribute.cs

539 lines
18 KiB

2 years ago
namespace Connected.Annotations;
/// <summary>
/// Specifies the name of the category in which to group the property of a MudBlazor component when displayed in the API documentation.
/// </summary>
/// <remarks>
/// Use this attribute together with the <see cref="Microsoft.AspNetCore.Components.ParameterAttribute"/>. <br/>
/// This attribute is similar to <see cref="System.ComponentModel.CategoryAttribute"/>. <br/>
/// The name of the category can be specified by using a constant defined in the <see cref="CategoryTypes"/> class.
/// </remarks>
[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;
}
/// <summary> The name of the category. </summary>
public string Name { get; }
/// <summary> The order of the category - the greater the number the lower the category will be displayed in the API documentation. </summary>
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<string, int> 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
};
}
/// <summary>
/// Possible categories of MudBlazor components properties.
/// </summary>
/// <remarks>
/// <b>General categories</b>
/// <para>
/// - <i>Data</i> - Used e.g. in form fields, pickers, <see cref="MudRating"/>, <see cref="MudTable{T}"/>, <see cref="MudTreeView{T}"/>,
/// <see cref="MudTreeViewItem{T}"/>, and <see cref="MudCarousel{TData}"/>. 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.<br/>
/// - <i>Validation</i> - Used in form fields and pickers.<br/>
/// - <i>Behavior</i> - 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 <c>Disabled</c> property, b) icons (or avatars) without default value
/// (because setting their value can pass additional information).<br/>
/// - <i>Appearance</i> - 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) <c>Elevation</c>, <c>Outlined</c>,
/// <c>Square</c>, <c>Rounded</c>, <c>DisableGutters</c>, <c>Dense</c>, <c>DisableRipple</c>; 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).<br/>
/// - <i>Common</i> - Properties defined in <see cref="UIComponent"/>.
/// </para>
/// <para>
/// Note: The following properties belong to the "Behavior" group, not to the "Appearance" group:<br/>
/// - <see cref="IconButton.Icon"/> - because it describes meaning of the button, since MudIconButton doesn't have text,<br/>
/// - <see cref="InputBase{T}.Label"/> - because it describes meaning of the field,<br/>
/// - <see cref="InputBase{T}.AdornmentText"/> - because it can describe information important to a user, e.g. a numeric field unit such as kilograms.<br/>
/// Sometimes choosing a category can be difficult - in such case choose a category that makes the most sense.
/// </para>
///
/// <b>Categories for specific behaviors or specific parts of components</b>
/// <para>If some elements or behaviors can be distinguished in a component, then their properties are included in separate groups.</para>
///
/// <para>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, <see cref="MudTableBase.CommitEditIcon"/> could belong to the "Appearance" group, but belongs to the "Editing" group.</para>
///
/// <b>Additional information</b>
/// <para>The list of categories is inspired by the categories displayed for Windows Forms and Web Forms components in the Visual Studio "Properties" window.</para>
/// </remarks>
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.
*/
/// <summary>Used in <see cref="UIComponent"/>.</summary>
public static class ComponentBase
{
public const string Common = "Common";
}
/// <summary>Used in: <see cref="ButtonBase"/>, all components inheriting from it, and <see cref="MudToggleIconButton"/>.</summary>
public static class Button
{
public const string Behavior = "Behavior";
public const string ClickAction = "Click action";
public const string Appearance = "Appearance";
}
/// <summary>Used in <see cref="FormComponent{T, U}"/> and all components inheriting from it.</summary>
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";
}
/// <summary>Used in all charts, that is in <see cref="MudChartBase"/> and all components inheriting from it.</summary>
public static class Chart
{
public const string Behavior = "Behavior";
public const string Appearance = "Appearance";
}
/// <summary>Used in other base classes.</summary>
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";
}
}