diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..eb5cfec430 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,552 @@ +# Blazor Code Style Guide + +This guide outlines best practices for Razor component development and documentation in Blazor. + +## Razor File Structure + +Use the following top-down order in `.razor` files: + +1. `@page` +2. `@using` +3. `@namespace` +4. `@inherits` +5. `@implements` +6. `@inject` + +Insert ` #end + +#license-key-version + +>tip This documentation section applies to Telerik UI for Blazor version **8.0.0** and above. Older versions do not require a license key. + +#end + +#license-key-update-whenever + +>tip Update your license key [whenever you renew or purchase a new Telerik license](slug:installation-license-key#license-key-updates). + +#end + +#license-key-manual-steps + +To download and install your Telerik license key: + +1. Go to the License Keys page in your Telerik account. +1. Click the **Download License Key** button. +1. Save the `telerik-license.txt` file to: + * (on Windows) `%AppData%\Telerik\telerik-license.txt`, for example, `C:\Users\...\AppData\Roaming\Telerik\telerik-license.txt` + * (on Mac or Linux) `~/.telerik/telerik-license.txt`, for example, `/Users/.../.telerik/telerik-license.txt` + +This will make the license key available to all Telerik .NET apps that you develop on your local machine. + +#end + +#license-key-know-more-link + +The [Telerik License Key](slug:installation-license-key) article provides additional details on installing and updating your Telerik license key in different scenarios. [Automatic license key maintenance](slug:installation-license-key#automatic-installation) is more effective and recommended in the long run. + +#end + +#ai-coding-assistant-ad + +Use the [Telerik AI Coding Assistant](slug:ai-overview) through the [Telerik Blazor MCP server](slug:ai-mcp-server) or the [Telerik Blazor GitHub Copilot extension](slug:ai-copilot-extension). These tools help you receive tips and generate code snippets that include Telerik UI for Blazor components and API. + +#end \ No newline at end of file diff --git a/_contentTemplates/common/grid-treelist-autogenerated-columns.md b/_contentTemplates/common/grid-treelist-autogenerated-columns.md index 7e6ea30f96..f7dbfca1d4 100644 --- a/_contentTemplates/common/grid-treelist-autogenerated-columns.md +++ b/_contentTemplates/common/grid-treelist-autogenerated-columns.md @@ -1,4 +1,4 @@ #grid-treelist-autogenerated-columns-limitation When the component initializes, it expects to know what columns to render before the data comes. -If the component is bound to a collection of dynamic objects (such as `Dictionary` or `ExpandoObject`), the component cannot know what columns to render, due to the nature of these objects. Therefore, the `AutoGenerateColumns` feature is not applicable in such scenarios. Columns must be declared explicitly or with a loop. Examples of such setups are available at [Binding Grid to ExpandoObject]({%slug grid-kb-binding-to-expando-object%}). +If the component is bound to a collection of dynamic objects (such as `Dictionary` or `ExpandoObject`), the component cannot know what columns to render, due to the nature of these objects. Therefore, the `AutoGenerateColumns` feature is not applicable in such scenarios. Columns must be declared explicitly or with a loop. Examples of such setups are available at [Binding Grid to ExpandoObject](slug:grid-kb-binding-to-expando-object). #end \ No newline at end of file diff --git a/_contentTemplates/common/grid-treelist-editing-notes.md b/_contentTemplates/common/grid-treelist-editing-notes.md deleted file mode 100644 index ebc72c5096..0000000000 --- a/_contentTemplates/common/grid-treelist-editing-notes.md +++ /dev/null @@ -1,10 +0,0 @@ -#grid-treelist-data-operations-while-editing - - * For operations like Filter, Group, Sort, Page, Search, Select, Row drag and Delete: - * InCell edit - if the validation is satisfied, a save operation will be executed. If the validation is **not** satisfied, editing will be cancelled, the `OnCancel` event will fire and the new user operation will be executed. In this case, you can handle the OnCancel event and set the `IsCancelled` property of the `CommandEventArgs` to true. Thus, the other data operation will be aborted and the Grid will remain in edit mode. - * Inline edit - regardless of the validation, editing will be cancelled, the `OnCancel` event will fire and the new user operation will be executed. In this case, you can handle the OnCancel event and set the `IsCancelled` property of the `CommandEventArgs` to true. Thus, the other data operation will be aborted and the Grid will remain in edit mode. - - * For operations like Edit, Add, Save: - * InCell edit - if the validation is satisfied, the currently edited item will be saved and the command will be executed. If the validation is **not** satisfied, the command will be blocked until the item is valid or editing is cancelled. - * Inline edit - if the validation is satisfied, `OnCancel` will be fired for the currently edited item and the command will be executed. If the validation is **not** satisfied, the command will be blocked until the item is valid or editing is cancelled. -#end \ No newline at end of file diff --git a/_contentTemplates/common/icons.md b/_contentTemplates/common/icons.md index 74137ba8d8..dfc0c08ed0 100644 --- a/_contentTemplates/common/icons.md +++ b/_contentTemplates/common/icons.md @@ -1,6 +1,6 @@ #font-icons-css-note -> Make sure to [register `font-icons.css` if using Telerik font icons]({%slug common-features-icons%}#font-icon-stylesheet). +> Make sure to [register `font-icons.css` if using Telerik font icons](slug:common-features-icons#font-icon-stylesheet). #end diff --git a/_contentTemplates/common/inputs.md b/_contentTemplates/common/inputs.md index 3626a1dae4..23374062b6 100644 --- a/_contentTemplates/common/inputs.md +++ b/_contentTemplates/common/inputs.md @@ -1,21 +1,19 @@ #focus-kb -Also check the dedicated KB article about [programmatic input component focusing]({%slug inputs-kb-focus%}), which provides more examples and tips. +Also check the dedicated KB article about [programmatic input component focusing](slug:inputs-kb-focus), which provides more examples and tips. #end #edit-debouncedelay - Consider setting `DebounceDelay="0"` to the component inside the editor template. This is how the default editors in all Telerik Blazor components work. Otherwise, fast users may try to save changes before the data item in edit mode receives the new value. - #end #adornments ## Adornments -The component allows you to add custom elements as prefixes and suffixes. [Read more about how to render custom adornments before and after the input element...]({%slug common-features/input-adornments%}) +The component allows you to add custom elements as prefixes and suffixes. [Read more about how to render custom adornments before and after the input element...](slug:common-features/input-adornments) #end #floating-label-and-preffix -When using the [`PrefixTemplate`]({%slug common-features/input-adornments%}#adding-a-prefix-adornment) for a component wrapped in a [FloatingLabel]({%slug floatinglabel-overview%}), the label will overlap the prefix. +When using the [`PrefixTemplate`](slug:common-features/input-adornments#adding-a-prefix-adornment) for a component wrapped in a [FloatingLabel](slug:floatinglabel-overview), the label will overlap the prefix. To ensure both the FloatingLabel and the prefix content are properly displayed, move the label with CSS: diff --git a/_contentTemplates/common/issues-and-warnings.md b/_contentTemplates/common/issues-and-warnings.md index cf9df67c97..d0b3c1be74 100644 --- a/_contentTemplates/common/issues-and-warnings.md +++ b/_contentTemplates/common/issues-and-warnings.md @@ -27,9 +27,7 @@ Open the Client `.csproj` file and ensure that the following switch is present. You may find useful the following Microsoft articles on securing your NuGet feed setup and supply chain as general best practices: * Lock down your dependencies using configurable trust policies - Blog Post - * How to Scan NuGet Packages for Security Vulnerabilities - Blog Post - * Best practices for a secure software supply chain - MSDN docs Telerik provides signed NuGet packages that you can verify. diff --git a/_contentTemplates/common/js-interop-file.md b/_contentTemplates/common/js-interop-file.md index aacaecf4c9..3a23fd9e20 100644 --- a/_contentTemplates/common/js-interop-file.md +++ b/_contentTemplates/common/js-interop-file.md @@ -7,27 +7,11 @@ #end -#add-js-interop-file-to-getting-started-server - Add the `telerik-blazor.js` file to your main index file: - - * `~/Pages/_Host.cshtml` for .NET 3.x and .NET 7 - * `~/Pages/_Layout.cshtml` for .NET 6 - - **HTML** - -@[template](/_contentTemplates/common/js-interop-file.md#js-interop-file-snippet) - -#end - #js-interop-file-snippet ````HTML . . . - - ```` #end @@ -37,10 +21,6 @@ . . . - - ```` #end diff --git a/_contentTemplates/common/navigation-components.md b/_contentTemplates/common/navigation-components.md index eff90e53cd..dc994c46c9 100644 --- a/_contentTemplates/common/navigation-components.md +++ b/_contentTemplates/common/navigation-components.md @@ -13,6 +13,6 @@ #default-fields-match-issues -If your model field names match any of the default names, the component will try to use them. For example, a field called `Icon` will try to produce a Telerik icon out of those values and that may not be what you want. If you want to override such behaviors, you can set `IconField="someNonExistingField"`. You can read more about this [here]({%slug common-kb-custom-font-icons-fail%}). This also applies to other fields too. Another example would be a field called `Url` - in case you want to perform navigation yourself through templates, you may want to set `UrlField="someFakeField"` so that the component does not navigate on its own. +If your model field names match any of the default names, the component will try to use them. For example, a field called `Icon` will try to produce a Telerik icon out of those values and that may not be what you want. If you want to override such behaviors, you can set `IconField="someNonExistingField"`. You can read more about this [here](slug:common-kb-custom-font-icons-fail). This also applies to other fields too. Another example would be a field called `Url` - in case you want to perform navigation yourself through templates, you may want to set `UrlField="someFakeField"` so that the component does not navigate on its own. #end \ No newline at end of file diff --git a/_contentTemplates/common/parameters-table-styles.md b/_contentTemplates/common/parameters-table-styles.md index f314fc28ec..807bf65038 100644 --- a/_contentTemplates/common/parameters-table-styles.md +++ b/_contentTemplates/common/parameters-table-styles.md @@ -1,8 +1,41 @@ #table-layout -#end \ No newline at end of file +#end + +#multidimensional-table + +#end diff --git a/_contentTemplates/common/popup-edit-customization.md b/_contentTemplates/common/popup-edit-customization.md index 2def29e38a..08c6a8b4dd 100644 --- a/_contentTemplates/common/popup-edit-customization.md +++ b/_contentTemplates/common/popup-edit-customization.md @@ -6,7 +6,7 @@ | --- | --- | --- | | `Class` | `string` | The CSS class of the edit popup | | `Title` | `string` | The title of the edit popup | -| `ThemeColor` | `string` | The color scheme of the window. Use the available members of the static class [`ThemeConstants.Window.ThemeColor`](/blazor-ui/api/Telerik.Blazor.ThemeConstants.Window.ThemeColor). | +| `ThemeColor` | `string` | The color scheme of the window. Use the available members of the static class [`ThemeConstants.Window.ThemeColor`](slug:Telerik.Blazor.ThemeConstants.Window.ThemeColor). | | `Width` | `string` | The Width of the edit popup | | `MaxWidth` | `string` | The maximum width of the window | | `MinWidth` | `string` | The minimum width of the window | diff --git a/_contentTemplates/common/rebind-method.md b/_contentTemplates/common/rebind-method.md index e92896381e..50f5922aa7 100644 --- a/_contentTemplates/common/rebind-method.md +++ b/_contentTemplates/common/rebind-method.md @@ -1,5 +1,5 @@ #intro -You can refresh the data by invoking the [`Rebind` method]({%slug common-features-data-binding-overview%}#refresh-data). Use the component reference to call the `Rebind` method after you have made the data changes (for example adding, removing items). This is needed in case you are not using [Observable data](#observable-data) or [resetting the collection reference](#new-collection-reference). Calling `Rebind` will force the component process the available data anew to reflect the updates. +You can refresh the data by invoking the [`Rebind` method](slug:common-features-data-binding-overview#refresh-data). Use the component reference to call the `Rebind` method after you have made the data changes (for example adding, removing items). This is needed in case you are not using [Observable data](#observable-data) or [resetting the collection reference](#new-collection-reference). Calling `Rebind` will force the component process the available data anew to reflect the updates. >caption Use the `Rebind` method to refresh the data. #end \ No newline at end of file diff --git a/_contentTemplates/common/refresh-data-not-applicable.md b/_contentTemplates/common/refresh-data-not-applicable.md index 16e99bc0ea..6ff1f6996a 100644 --- a/_contentTemplates/common/refresh-data-not-applicable.md +++ b/_contentTemplates/common/refresh-data-not-applicable.md @@ -1,3 +1,3 @@ #refresh-data-note ->note As part of our `3.0.1` release we introduced the `Rebind` method to the component reference. This would make the rest of the approaches in this article obsolete. -#end \ No newline at end of file +>note As part of our `3.0.1` release we introduced the `Rebind` method to the component reference. This can make some of the approaches in this article obsolete, especially resetting the collection reference. +#end diff --git a/_contentTemplates/date-inputs/general.md b/_contentTemplates/date-inputs/general.md index d11374c765..96de7ceb92 100644 --- a/_contentTemplates/date-inputs/general.md +++ b/_contentTemplates/date-inputs/general.md @@ -26,19 +26,19 @@ By default, the value for all parameters is `null`, which applies the full forma #end #dateinput-typing-settings -textbox is a [DateInput component]({%slug components/dateinput/overview%}), which provides various parameters to configure the keyboard typing experience. The settings are related to: +textbox is a [DateInput component](slug:components/dateinput/overview), which provides various parameters to configure the keyboard typing experience. The settings are related to: * Caret placement; * Two-digit year values; * Automatic correction of invalid date segments. -See the [DateInput keyboard documentation]({%slug dateinput-keyboard-typing%}) for details and examples. The same DateInput parameters with the same behavior exist for the +See the [DateInput keyboard documentation](slug:dateinput-keyboard-typing) for details and examples. The same DateInput parameters with the same behavior exist for the #end #typing-parameters ### Typing User Experience -The component provides multiple parameters, which control the [caret placement, two-digit year values and the auto-correct behavior of the textbox. See the **DateInput** documentation for details]({%slug dateinput-keyboard-typing%}). +The component provides multiple parameters, which control the [caret placement, two-digit year values and the auto-correct behavior of the textbox. See the **DateInput** documentation for details](slug:dateinput-keyboard-typing). #end diff --git a/_contentTemplates/dropdownbutton/notes.md b/_contentTemplates/dropdownbutton/notes.md index 5f8c5becb4..18f06ac0ba 100644 --- a/_contentTemplates/dropdownbutton/notes.md +++ b/_contentTemplates/dropdownbutton/notes.md @@ -1,7 +1,7 @@ #dropdownbutton-splitbutton-comparison The DropDownButton and SplitButton components are similar. They both consist of a primary button and a dropdown element that holds additional action items. The major difference is the purpose of the primary button. -* [DropDownButton]({%slug dropdownbutton-overview%})—The main purpose of the primary button is to open the popup with additional actions. The primary button exposes a separate [`OnClick` event]({%slug dropdownbutton-events%}), which can invoke a dedicated action. Clicking on the DropDownButton always opens the dropdown. +* [DropDownButton](slug:dropdownbutton-overview)—The main purpose of the primary button is to open the popup with additional actions. The primary button exposes a separate [`OnClick` event](slug:dropdownbutton-events), which can invoke a dedicated action. Clicking on the DropDownButton always opens the dropdown. -* [SplitButton]({%slug splitbutton-overview%})—The main element contains a primary button and a separate button for opening the dropdown. The purpose of the primary button is to [invoke a standalone action]({%slug splitbutton-events%}#onclick). Clicking on it does not open the dropdown. To open the popup with the additional actions, the user has to click the dedicated button with `caret-alt-down` icon. It is possible to [switch the primary and dropdown actions programmatically]({%slug splitbutton-kb-change-primary-action-onclick%}). +* [SplitButton](slug:splitbutton-overview)—The main element contains a primary button and a separate button for opening the dropdown. The purpose of the primary button is to [invoke a standalone action](slug:splitbutton-events#onclick). Clicking on it does not open the dropdown. To open the popup with the additional actions, the user has to click the dedicated button with `caret-alt-down` icon. It is possible to [switch the primary and dropdown actions programmatically](slug:splitbutton-kb-change-primary-action-onclick). #end \ No newline at end of file diff --git a/_contentTemplates/dropdowns/adaptive-rendering.md b/_contentTemplates/dropdowns/adaptive-rendering.md index 7d81bba92f..7930387cdb 100644 --- a/_contentTemplates/dropdowns/adaptive-rendering.md +++ b/_contentTemplates/dropdowns/adaptive-rendering.md @@ -1,7 +1,7 @@ #intro -The component supports different popup rendering depending on the screen size. [Read more about the Adaptive Rendering functionality and how to enable it...]({%slug adaptive-rendering%}) +The component supports different popup rendering depending on the screen size. [Read more about the Adaptive Rendering functionality and how to enable it...](slug:adaptive-rendering) #end #value-changed -> If [`AdaptiveRendering`]({%slug adaptive-rendering%}) is enabled, on small and medium devices `ValueChanged` will fire only when the user clicks the confirmation button in the action sheet. +> If [`AdaptiveRendering`](slug:adaptive-rendering) is enabled, on small and medium devices `ValueChanged` will fire only when the user clicks the confirmation button in the action sheet. #end \ No newline at end of file diff --git a/_contentTemplates/dropdowns/features.md b/_contentTemplates/dropdowns/features.md index bdb0e6634a..f8a23bb91a 100644 --- a/_contentTemplates/dropdowns/features.md +++ b/_contentTemplates/dropdowns/features.md @@ -15,7 +15,7 @@ You can use the functionality of the built-in templates and customize the defaul #end #validation -You can ensure that the component value is acceptable by using the built-in validation. [Read more about input validation...]({%slug common-features/input-validation%}). +You can ensure that the component value is acceptable by using the built-in validation. [Read more about input validation...](slug:common-features/input-validation). #end #virtualization @@ -25,7 +25,7 @@ By virtualizing the elements in the dropdown, you can use huge data sources with #styling | Parameter | Type | Description | | --- | --- | --- | -| `Class` | `string` | The CSS class that will be rendered on the main wrapping element of the component. Use it to [override the theme or apply custom styles]({%slug themes-override%}). | +| `Class` | `string` | The CSS class that will be rendered on the main wrapping element of the component. Use it to [override the theme or apply custom styles](slug:themes-override). | | `Width` | `string` | The width of the component. It will target both the dropdown and the main element if the dropdown has no specific width set. @[template](/_contentTemplates/inputs/inputs-width-template.md#inputs-width-information) | #end @@ -43,7 +43,7 @@ By virtualizing the elements in the dropdown, you can use huge data sources with | `MaxWidth` | `string` | The maximum width of the popup. | | `Width` | `string` | The width of the popup. If you don't specify a value, the dropdown width will match the anchor element width which can help with responsive layouts and 100% widths. | -The parameters that modify the popup dimensions (`Height`, `Width`, `MaxWidth`, etc.) expect [valid CSS values]({%slug common-features/dimensions%}). +The parameters that modify the popup dimensions (`Height`, `Width`, `MaxWidth`, etc.) expect [valid CSS values](slug:common-features/dimensions). The `MinHeight` and `MaxHeight` have no effect if the `Height` is always within their range. The min and max values are useful only when the dropdown height is set to a relative unit or changes at runtime. diff --git a/_contentTemplates/editor/general.md b/_contentTemplates/editor/general.md index c464d4da0e..53201c6172 100644 --- a/_contentTemplates/editor/general.md +++ b/_contentTemplates/editor/general.md @@ -8,7 +8,7 @@ The application must sanitize the content before passing it to the Editor and, o This section applies only to Blazor **Server** apps. Blazor **WebAssembly** apps do not require additional configuration for the Editor to work with large content. -Blazor **Server** apps use the **SignalR WebSocket** to send the Editor `Value` from the browser to the server .NET runtime and vice-versa. The default SignalR maximum message size is **32 KB**. To work with larger content (especially paste images as Base64 strings), [increase the max WebSocket message size for the Blazor application]({%slug common-kb-increase-signalr-max-message-size%}). +Blazor **Server** apps use the **SignalR WebSocket** to send the Editor `Value` from the browser to the server .NET runtime and vice-versa. The default SignalR maximum message size is **32 KB**. To work with larger content (especially paste images as Base64 strings), [increase the max WebSocket message size for the Blazor application](slug:common-kb-increase-signalr-max-message-size). #end #prosemirror-schema-prerequisites diff --git a/_contentTemplates/grid/built-in-dialogs.md b/_contentTemplates/grid/built-in-dialogs.md index 0597d3b8bc..90db720dd0 100644 --- a/_contentTemplates/grid/built-in-dialogs.md +++ b/_contentTemplates/grid/built-in-dialogs.md @@ -1,11 +1,11 @@ #delete-confirmation To customize the appearance and behavior of the delete confirmation dialog, use one of the following options: -* [Localization]({%slug globalization-localization%}) - this approach is useful if you want to change just the text of the built-in delete confirmation dialog elements. It does not allow adding item details to the dialog text. +* [Localization](slug:globalization-localization) - this approach is useful if you want to change just the text of the built-in delete confirmation dialog elements. It does not allow adding item details to the dialog text. -* [Predefined dialogs (`DialogFactory`)]({%slug dialog-predefined%}#confirm) - this option is useful if you want to change the dialog text and include some details for the item the user tries to delete (for example, record name). +* [Predefined dialogs (`DialogFactory`)](slug:dialog-predefined#confirm) - this option is useful if you want to change the dialog text and include some details for the item the user tries to delete (for example, record name). -* [Dialog Component]({%slug dialog-overview%}) - this solution allows you to fully customize the rendering and appearance of the dialog. You may set the desired `ThemeColor` and add any content there, be that custom text, HTML elements or other components. +* [Dialog Component](slug:dialog-overview) - this solution allows you to fully customize the rendering and appearance of the dialog. You may set the desired `ThemeColor` and add any content there, be that custom text, HTML elements or other components. -[Read more about customizing the delete confirmation dialog...]({%slug grid-kb-customize-delete-confirmation-dialog%}) +[Read more about customizing the delete confirmation dialog...](slug:grid-kb-customize-delete-confirmation-dialog) #end \ No newline at end of file diff --git a/_contentTemplates/grid/common-link.md b/_contentTemplates/grid/common-link.md index 4b4b40dd26..b98b81d664 100644 --- a/_contentTemplates/grid/common-link.md +++ b/_contentTemplates/grid/common-link.md @@ -110,7 +110,7 @@ You can use the standard C# formatting options, because the grid uses a `string. * The `CultureInfo.CurrentCulture` is used when rendering the formats, so if you need specific formats for specific users, you must set the culture of the app accordingly. -* The `DisplayFormat` parameter defines the format that is used to render Numeric or DateTime values when the component initializes. As it is not applied in edit mode, the editor will display the default format of the field depending on the culture. In order to customize the format when editing, together with setting the `DisplayFormat` parameter, you can use Editor Template for [Grid]({%slug grid-templates-editor%}) or [TreeList]({%slug treelist-templates-editor%}). +* The `DisplayFormat` parameter defines the format that is used to render Numeric or DateTime values when the component initializes. As it is not applied in edit mode, the editor will display the default format of the field depending on the culture. In order to customize the format when editing, together with setting the `DisplayFormat` parameter, you can use Editor Template for [Grid](slug:grid-templates-editor) or [TreeList](slug:treelist-templates-editor). #end @@ -211,3 +211,7 @@ Therefore, we advise that you do not set `Locked=false` for child columns of loc The keyboard navigation in the multi-column headers follows the functionality of Excel. #end + +#using-components-in-templates +See specifics and example in this knowledge base article: [Using Components in Grid Templates](slug:grid-kb-using-components-in-templates). +#end \ No newline at end of file diff --git a/_contentTemplates/grid/editing.md b/_contentTemplates/grid/editing.md new file mode 100644 index 0000000000..e027c9dc06 --- /dev/null +++ b/_contentTemplates/grid/editing.md @@ -0,0 +1,333 @@ +#overview-required + +> Make sure to read the [Grid CRUD Operations](slug:grid-editing-overview) article first. + +#end + +#without-commands + +Without using the above command buttons, the application can: + +* [Manage add or edit mode programmatically](slug:grid-kb-add-edit-state) through the [Grid state](slug:grid-state). +* Modify data items directly in the Grid data source. [Rebind the Grid](slug:common-features-data-binding-overview#refresh-data) afterwards. + +#end + +#basic-example-description +* Use the `OnCreate`, `OnDelete` and `OnUpdate` events to make changes to the Grid data source. +* Rebind the Grid automatically through the `OnRead` event after the create, delete, or update operation is complete. When [using the `Data` parameter, you must either query the data source again, or modify the local `Data` collection manually](#advanced). +* Use `DataAnnotations` validation for some model class properties. +#end + +#basic-example-parameters-columns + OnCreate="@OnGridCreate" + OnDelete="@OnGridDelete" + OnUpdate="@OnGridUpdate"> + + Add Item + + + + + + + +#end + +#basic-example-code + private ProductService GridProductService { get; set; } = new(); + + private async Task OnGridCreate(GridCommandEventArgs args) + { + var createdItem = (Product)args.Item; + + await GridProductService.Create(createdItem); + } + + private async Task OnGridDelete(GridCommandEventArgs args) + { + var deletedItem = (Product)args.Item; + + await GridProductService.Delete(deletedItem); + } + + private async Task OnGridRead(GridReadEventArgs args) + { + DataSourceResult result = await GridProductService.Read(args.Request); + + args.Data = result.Data; + args.Total = result.Total; + args.AggregateResults = result.AggregateResults; + } + + private async Task OnGridUpdate(GridCommandEventArgs args) + { + var updatedItem = (Product)args.Item; + + await GridProductService.Update(updatedItem); + } +#end + +#crud-service-and-model + public class Product + { + public int Id { get; set; } + [Required] + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public decimal? Price { get; set; } + public int Quantity { get; set; } + [Required] + public DateTime? ReleaseDate { get; set; } + public bool Discontinued { get; set; } + } + + #region Data Service + + public class ProductService + { + private List Items { get; set; } = new(); + + private int LastId { get; set; } + + public async Task Create(Product product) + { + await SimulateAsyncOperation(); + + product.Id = ++LastId; + + Items.Insert(0, product); + + return LastId; + } + + public async Task Delete(Product product) + { + await SimulateAsyncOperation(); + + if (Items.Contains(product)) + { + Items.Remove(product); + + return true; + } + + return false; + } + + public async Task> Read() + { + await SimulateAsyncOperation(); + + return Items; + } + + public async Task Read(DataSourceRequest request) + { + return await Items.ToDataSourceResultAsync(request); + } + + public async Task Update(Product product) + { + await SimulateAsyncOperation(); + + int originalItemIndex = Items.FindIndex(x => x.Id == product.Id); + + if (originalItemIndex != -1) + { + Items[originalItemIndex] = product; + return true; + } + + return false; + } + + private async Task SimulateAsyncOperation() + { + await Task.Delay(100); + } + + public ProductService(int itemCount = 5) + { + Random rnd = Random.Shared; + + for (int i = 1; i <= itemCount; i++) + { + Items.Add(new Product() + { + Id = ++LastId, + Name = $"Product {LastId}", + Description = $"Multi-line\ndescription {LastId}", + Price = LastId % 2 == 0 ? null : rnd.Next(0, 100) * 1.23m, + Quantity = LastId % 2 == 0 ? 0 : rnd.Next(0, 3000), + ReleaseDate = DateTime.Today.AddDays(-rnd.Next(365, 3650)), + Discontinued = LastId % 2 == 0 + }); + } + } + } + + #endregion Data Service +#end + +#advanced-example-description +* Use the `OnCreate`, `OnDelete` and `OnUpdate` events to make changes to the Grid data source. +* Use the `OnModelInit` event to provide [model instances](slug:grid-editing-overview#item-instances) with some default values before add and edit operations start. +* Use the `OnAdd` event to provide some default values before add operations start. +* Reload the Grid `Data` after making changes to the data source. When [using the Grid `OnRead` event, the component will fire `OnRead` and rebind automatically](#basic). +* Apply the user changes to the Grid `Data` parameter to spare one read request to the database. +* Use `DataAnnotations` validation for the `Name` and `ReleaseDate` properties. +* Define the `Id` column as non-editable. +* Customize the `Description` and `Discontinued` column editors without using an `EditorTemplate`. +* Render the **Delete** command button conditionally if `Discontinued` is `true`. +* Confirm **Delete** commands with the built-in Grid Dialog. You can also [intercept item deletion with a separate Dialog or a custom popup](slug:grid-kb-customize-delete-confirmation-dialog). +* Cancel the `OnAdd` and `OnEdit` events conditionally, so that the Grid does not go into edit mode. +* Cancel the `OnCancel` event conditionally, so that the Grid remains in edit mode and the user doesn't lose their unsaved changes. +#end + +#advanced-example-parameters + ConfirmDelete="@GridConfirmDelete" + OnAdd="@OnGridAdd" + OnCancel="@OnGridCancel" + OnCreate="@OnGridCreate" + OnDelete="@OnGridDelete" + OnEdit="@OnGridEdit" + OnModelInit="@OnGridModelInit" + OnUpdate="@OnGridUpdate" + Pageable="true" + PageSize="5" + Sortable="true"> +#end + +#advanced-example-toolbar + + Add Item + + + + + + + +#end + +#advanced-example-columns + + + + +#end + +#advanced-example-code + private List GridData { get; set; } = new(); + + private ProductService GridProductService { get; set; } = new(); + + [CascadingParameter] + public DialogFactory? TelerikDialogs { get; set; } + + #region Example Settings + + private bool GridConfirmDelete { get; set; } = true; + private bool ShouldCancelOnAddEdit { get; set; } + private bool ShouldConfirmOnCancel { get; set; } = true; + + private string AddEditButtonThemeColor => ShouldCancelOnAddEdit ? ThemeConstants.Button.ThemeColor.Error : ThemeConstants.Button.ThemeColor.Base; + private string DeleteButtonThemeColor => GridConfirmDelete ? ThemeConstants.Button.ThemeColor.Base : ThemeConstants.Button.ThemeColor.Warning; + private string CancelButtonThemeColor => ShouldConfirmOnCancel ? ThemeConstants.Button.ThemeColor.Base : ThemeConstants.Button.ThemeColor.Warning; + + #endregion Example Settings + + #region Grid Events + + private void OnGridAdd(GridCommandEventArgs args) + { + if (ShouldCancelOnAddEdit) + { + args.IsCancelled = true; + } + + var newItem = (Product)args.Item; + newItem.Name = "Value from OnAdd"; + } + + private async Task OnGridCancel(GridCommandEventArgs args) + { + if (ShouldConfirmOnCancel && TelerikDialogs != null) + { + bool shouldContinue = await TelerikDialogs.ConfirmAsync("Do you want to discard your changes?"); + + if (!shouldContinue) + { + args.IsCancelled = true; + } + } + } + + private async Task OnGridCreate(GridCommandEventArgs args) + { + var createdItem = (Product)args.Item; + + // Create the item in the database. + int newId = await GridProductService.Create(createdItem); + + // Reload the data from the database. + GridData = await GridProductService.Read(); + // OR + // Create the item in the local data instead of reloading. + //createdItem.Id = newId; + //GridData.Insert(0, createdItem); + } + + private async Task OnGridDelete(GridCommandEventArgs args) + { + var deletedItem = (Product)args.Item; + + // Delete the item in the database. + await GridProductService.Delete(deletedItem); + + // Reload the data from the database. + GridData = await GridProductService.Read(); + // OR + // Delete the item in the local data instead of reloading. + //GridData.Remove(deletedItem); + } + + private void OnGridEdit(GridCommandEventArgs args) + { + if (ShouldCancelOnAddEdit) + { + args.IsCancelled = true; + } + } + + private Product OnGridModelInit() + { + return new Product() { Description = "Value from OnModelInit" }; + } + + private async Task OnGridUpdate(GridCommandEventArgs args) + { + var updatedItem = (Product)args.Item; + + // Update the item in the database. + bool success = await GridProductService.Update(updatedItem); + + // Reload the data from the database. + GridData = await GridProductService.Read(); + // OR + // Update the item in the local data instead of reloading. + //int originalItemIndex = GridData.FindIndex(i => i.Id == updatedItem.Id); + //if (originalItemIndex != -1) + //{ + // GridData[originalItemIndex] = updatedItem; + //} + } + + #endregion Grid Events + + protected override async Task OnInitializedAsync() + { + GridData = await GridProductService.Read(); + } +#end diff --git a/_contentTemplates/grid/export.md b/_contentTemplates/grid/export.md deleted file mode 100644 index 3a484e2583..0000000000 --- a/_contentTemplates/grid/export.md +++ /dev/null @@ -1,78 +0,0 @@ -#export-common-notes -* `bool` fields are exported as `TRUE` or `FALSE` strings, because there is no boolean data type in Excel and these string values are the most common ones used in data and macros. - -* Date and number formats are exported with the following format: `mm/dd/yyyy hh:mm:ss` plus the current app culture AM/PM specifier for dates, and `Convert.ToDouble(value)` for numbers (which uses the current thread culture). The Excel date formats are different than .NET date formats and Excel may not always recognize the column as dates, for example, if the entire date format from the .NET culture is used. - -* The Grid exports only `` instances. Other types of columns are not exported, for example command, checkbox, hierarchy, group and row-drag columns. - -* If the Grid is using `OnRead` and is exporting all pages, it will fire an additional `OnRead` event at the time of exporting, with a request `PageSize` of `0`. This will enable the component to obtain all data. - -* With Server-side Blazor, the file may become larger than the default SignalR connection limit, and this can disconnect the client and result in an error. Generally, this requires quite a lot of data to happen, but you may need to increase the size limit of the connection in the `ConfigureServices` method of your `Startup.cs` file, for example: - -````C#.skip-repl -services.AddServerSideBlazor().AddHubOptions(o => -{ - o.MaximumReceiveMessageSize = 1024 * 1024; // 1MB -}); -```` - -* With Client-side Blazor (WebAssembly), all the code runs in the browser and, at the time of writing, is considerably slower than server-side Blazor, and it only has one actual thread. This means that while the file is being generated, the UI will be unresponsive, so you may want to show a loading sign to the user through the `OnClick` handler of the command button, something like: - -````RAZOR.skip-repl Component -@* Exporting a lot of rows can be slow in a WebAssembly app more so than in a server-side app, and it blocks the UI *@ - - - - Export to Excel - Export to CSV - - - - - - - - - Please wait... - We are exporting your data, your file will download shortly. - - -@code { - bool isExporting { get; set; } - - async Task ShowLoadingSign() - { - isExporting = true; - StateHasChanged(); - // This won't work for server-side Blazor, the UI will render immediately after the delay and the loading sign will only flicker - await Task.Delay(50); - isExporting = false; - } - - List GridData { get; set; } - - protected override void OnInitialized() - { - GridData = Enumerable.Range(1, 1000).Select(x => new SampleData - { - ProductId = x, - ProductName = $"Product {x}", - UnitsInStock = x * 2, - Price = 3.14159m * x, - Discontinued = x % 4 == 0, - FirstReleaseDate = DateTime.Now.AddDays(-x) - }).ToList(); - } - - public class SampleData - { - public int ProductId { get; set; } - public string ProductName { get; set; } - public int UnitsInStock { get; set; } - public decimal Price { get; set; } - public bool Discontinued { get; set; } - public DateTime FirstReleaseDate { get; set; } - } -} -```` -#end diff --git a/_contentTemplates/grid/state.md b/_contentTemplates/grid/state.md index 45a6dcc18a..9eaaadb693 100644 --- a/_contentTemplates/grid/state.md +++ b/_contentTemplates/grid/state.md @@ -1,5 +1,5 @@ #initial-state ->tip If you want to set an initial state to the Grid, use a similar snippet, but in the [`OnStateInit event`]({%slug grid-state%}#onstateinit) +>tip If you want to set an initial state to the Grid, use a similar snippet, but in the [`OnStateInit event`](slug:grid-state#onstateinit) #end @@ -716,14 +716,17 @@ + Reorderable="true" + Resizable="true"> Reorder Price and Quantity - Make Id Column Last + Resize Columns - Reset Column Order + Reset Column Configuration @@ -784,13 +787,32 @@ } } - private async Task ResetColumnOrder() + private async Task ResizeColumns() + { + if (GridRef != null) + { + var gridState = GridRef.GetState(); + int newColumnWidth = 160; + + foreach (GridColumnState columnState in gridState.ColumnStates) + { + columnState.Width = $"{newColumnWidth}px"; + } + + gridState.TableWidth = $"{newColumnWidth * gridState.ColumnStates.Count}px"; + + await GridRef.SetStateAsync(gridState); + } + } + + private async Task ResetColumns() { if (GridRef != null) { var gridState = GridRef.GetState(); gridState.ColumnStates = new List(); + gridState.TableWidth = null; await GridRef.SetStateAsync(gridState); } diff --git a/_contentTemplates/inputs/inputs-width-template.md b/_contentTemplates/inputs/inputs-width-template.md index 127b816add..77dc7ed40e 100644 --- a/_contentTemplates/inputs/inputs-width-template.md +++ b/_contentTemplates/inputs/inputs-width-template.md @@ -1,3 +1,3 @@ #inputs-width-information -The default `Width` value is null, but the theme applies `100%`. Use the `Width` property or custom CSS to set another value [in any supported unit]({%slug common-features/dimensions%}). +The default `Width` value is null, but the theme applies `100%`. Use the `Width` property or custom CSS to set another value [in any supported unit](slug:common-features/dimensions). #end diff --git a/_contentTemplates/map/general.md b/_contentTemplates/map/general.md index 6fdc791ffe..94a164ccbf 100644 --- a/_contentTemplates/map/general.md +++ b/_contentTemplates/map/general.md @@ -1,3 +1,3 @@ #urltemplate-csp -> The Map component provides two ways to define the `UrlTemplate` of tile layers and the `MapLayerMarkerSettings` `Template` of marker layers. See [Map Content Security Policy]({%slug components/map/overview%}#content-security-policy) for more information and comparison. +> The Map component provides two ways to define the `UrlTemplate` of tile layers and the `MapLayerMarkerSettings` `Template` of marker layers. See [Map Content Security Policy](slug:components/map/overview#content-security-policy) for more information and comparison. #end diff --git a/_contentTemplates/menu/basic-example.md b/_contentTemplates/menu/basic-example.md index 964919ad37..63face4c26 100644 --- a/_contentTemplates/menu/basic-example.md +++ b/_contentTemplates/menu/basic-example.md @@ -1,5 +1,5 @@ #data-binding-basics-link -Before continuing, make sure you are familiar with the [menu data binding basics]({%slug components/menu/data-binding/overview%}). +Before continuing, make sure you are familiar with the [menu data binding basics](slug:components/menu/data-binding/overview). #end #has-children-behavior @@ -7,5 +7,5 @@ If you set `HasChildren` to `false`, child items will not be rendered even if th #end #context-menudata-binding-basics-link -Before continuing, make sure you are familiar with the [context menu data binding basics]({%slug contextmenu-data-binding-overview%}). +Before continuing, make sure you are familiar with the [context menu data binding basics](slug:contextmenu-data-binding-overview). #end diff --git a/_contentTemplates/slider/common.md b/_contentTemplates/slider/common.md index 2679bd6e47..1780b8c373 100644 --- a/_contentTemplates/slider/common.md +++ b/_contentTemplates/slider/common.md @@ -2,7 +2,7 @@ | Parameter | Type | Description | | ----------- | ----------- | -------| | `Class` | `string` | the CSS class that will be rendered on the main wrapping element of the slider. -|`Width` | `stirng` | the width of the main element. In case you would like it to fit to a container you could set it to `100%` or other percent value depending on the application needs. You can read more in the [Dimensions]({%slug common-features/dimensions%}) article. +|`Width` | `stirng` | the width of the main element. In case you would like it to fit to a container you could set it to `100%` or other percent value depending on the application needs. You can read more in the [Dimensions](slug:common-features/dimensions) article. #end #large-step diff --git a/_contentTemplates/stockchart/chart-tooltip-context-templates.md b/_contentTemplates/stockchart/chart-tooltip-context-templates.md index 8d10343b3e..1796078c39 100644 --- a/_contentTemplates/stockchart/chart-tooltip-context-templates.md +++ b/_contentTemplates/stockchart/chart-tooltip-context-templates.md @@ -1,7 +1,7 @@ #context-parameter-information * `DataItem` - provides the data model of the current series item. You need to cast it to the type from your data source, which needs to be serializable. - * For [`OHLC`]({%slug stockchart-ohlc%}) and [`Candlestick`]({%slug stockchart-candlestick%}) chart types the `DataItem` will contain the information mapped to the `OpenField`, `CloseField`, `HighField` and `LowField` properties. - * For [`Line`]({%slug stockchart-line%}), [`Area`]({%slug stockchart-area%}) and [`Column`]({%slug stockchart-column%}) the `DataItem` will contain the information mapped to the `Field` properties. + * For [`OHLC`](slug:stockchart-ohlc) and [`Candlestick`](slug:stockchart-candlestick) chart types the `DataItem` will contain the information mapped to the `OpenField`, `CloseField`, `HighField` and `LowField` properties. + * For [`Line`](slug:stockchart-line), [`Area`](slug:stockchart-area) and [`Column`](slug:stockchart-column) the `DataItem` will contain the information mapped to the `Field` properties. * The `DataItem` will contain an aggregated value for the date, so in order to get it you can use the `Category` and parse it to `DateTime`. * `Category` - provides information on the category the data point is located in. Since the Stock Chart has a date X axis the `Category` should be cast to `DateTime`. diff --git a/_contentTemplates/stockchart/link-to-basics.md b/_contentTemplates/stockchart/link-to-basics.md index de669e1418..169a176912 100644 --- a/_contentTemplates/stockchart/link-to-basics.md +++ b/_contentTemplates/stockchart/link-to-basics.md @@ -1,5 +1,5 @@ #understand-basics-and-databinding-first -This article assumes you are familiar with the [stock chart basics]({%slug stockchart-overview%}) and [data binding]({%slug stockchart-data-binding%}). +This article assumes you are familiar with the [stock chart basics](slug:stockchart-overview) and [data binding](slug:stockchart-data-binding). #end diff --git a/_contentTemplates/treelist/databinding.md b/_contentTemplates/treelist/databinding.md index 0c75ff6fa4..05408085e7 100644 --- a/_contentTemplates/treelist/databinding.md +++ b/_contentTemplates/treelist/databinding.md @@ -1,15 +1,15 @@ #data-binding-modes -* [Hierarchical data]({%slug treelist-data-binding-hierarchical-data%}) - separate collections of items and their child items. This is the default mode of the component. See the `Items` setting. +* [Hierarchical data](slug:treelist-data-binding-hierarchical-data) - separate collections of items and their child items. This is the default mode of the component. See the `Items` setting. -* [Flat data]({%slug treelist-data-binding-flat-data%}) - a single collection of items with defined parent-child relationships. See the `Id` and `ParentId` settings. +* [Flat data](slug:treelist-data-binding-flat-data) - a single collection of items with defined parent-child relationships. See the `Id` and `ParentId` settings. -In either mode, you can implement [Load on Demand]({%slug treelist-data-binding-load-on-demand%}) or lazy loading - that is, provide children to a node when it expands through an event. See the `HasChildren` setting and the `OnExpand` event. +In either mode, you can implement [Load on Demand](slug:treelist-data-binding-load-on-demand) or lazy loading - that is, provide children to a node when it expands through an event. See the `HasChildren` setting and the `OnExpand` event. -Finally, you can also [bind the TreeList to an interface]({%slug treelist-data-binding-interface%}), no matter if you are using flat data or hierarchical data. +Finally, you can also [bind the TreeList to an interface](slug:treelist-data-binding-interface), no matter if you are using flat data or hierarchical data. #end #link-to-basics -Before continuing, make sure you are familiar with the [treelist data binding basics]({%slug treelist-data-binding-overview%}). +Before continuing, make sure you are familiar with the [treelist data binding basics](slug:treelist-data-binding-overview). #end \ No newline at end of file diff --git a/_contentTemplates/treelist/editing.md b/_contentTemplates/treelist/editing.md new file mode 100644 index 0000000000..9c8e486d24 --- /dev/null +++ b/_contentTemplates/treelist/editing.md @@ -0,0 +1,475 @@ +#overview-required + +> Make sure to read the [TreeList CRUD Operations](slug:treelist-editing-overview) article first. + +#end + +#without-commands + +Without using the above command buttons, the application can: + +* [Manage add or edit mode programmatically](slug:grid-kb-add-edit-state) through the [TreeList state](slug:treelist-state). +* Modify data items directly in the TreeList data source. [Rebind the TreeList](slug:common-features-data-binding-overview#refresh-data) afterwards. + +#end + +#basic-example-description +* Use the `OnCreate`, `OnDelete` and `OnUpdate` events to make changes to the TreeList data source. +* Query the data service and reload the TreeList `Data` when the create, delete, or update operation is complete. +* Use `DataAnnotations` validation for some model class properties. +* Define the `Id` column as non-editable. +* Customize the `Notes` column editor without using an `EditorTemplate`. +* Confirm **Delete** commands with the built-in TreeList Dialog. You can also [intercept item deletion with a separate Dialog or a custom popup](slug:grid-kb-customize-delete-confirmation-dialog). +* Override the `Equals()` method of the TreeList model class to prevent collapsing of updated items. +* Toggle the `HasChildren` property value of parent items when they lose all their children or gain their first child item. +* Delete all children of a deleted parent item. +#end + +#basic-example-parameters-columns + OnCreate="@OnTreeListCreate" + OnDelete="@OnTreeListDelete" + OnUpdate="@OnTreeListUpdate" + Height="400px"> + + Add Item + + + + + + + + + + +#end + +#basic-example-code + private IEnumerable? TreeListData { get; set; } + + private EmployeeService TreeListEmployeeService { get; set; } = new(); + + private async Task OnTreeListCreate(TreeListCommandEventArgs args) + { + var createdItem = (Employee)args.Item; + var parentItem = (Employee?)args.ParentItem; + + await TreeListEmployeeService.Create(createdItem, parentItem); + + TreeListData = await TreeListEmployeeService.Read(); + } + + private async Task OnTreeListDelete(TreeListCommandEventArgs args) + { + var deletedItem = (Employee)args.Item; + + await TreeListEmployeeService.Delete(deletedItem); + + TreeListData = await TreeListEmployeeService.Read(); + } + + private async Task OnTreeListUpdate(TreeListCommandEventArgs args) + { + var updatedItem = (Employee)args.Item; + + await TreeListEmployeeService.Update(updatedItem); + + TreeListData = await TreeListEmployeeService.Read(); + } + + protected override async Task OnInitializedAsync() + { + TreeListData = await TreeListEmployeeService.Read(); + } +#end + +#flat-crud-service-and-model + public class Employee + { + public int Id { get; set; } + public int? ParentId { get; set; } + public bool HasChildren { get; set; } + [Required] + public string Name { get; set; } = string.Empty; + public string Notes { get; set; } = string.Empty; + [Required] + public decimal? Salary { get; set; } + [Required] + public DateTime? HireDate { get; set; } + public bool IsDriver { get; set; } + + public override bool Equals(object? obj) + { + return obj is Employee && ((Employee)obj).Id == Id; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + #region Data Service + + public class EmployeeService + { + private List Items { get; set; } = new(); + + private readonly int TreeLevelCount; + private readonly int RootItemCount; + private readonly int ChildItemCount; + + private int LastId { get; set; } + private Random Rnd { get; set; } = Random.Shared; + + public async Task Create(Employee createdEmployee, Employee? parentEmployee) + { + await SimulateAsyncOperation(); + + createdEmployee.Id = ++LastId; + createdEmployee.ParentId = parentEmployee?.Id; + + Items.Insert(0, createdEmployee); + + if (parentEmployee != null) + { + parentEmployee.HasChildren = true; + } + + return LastId; + } + + public async Task Delete(Employee deletedEmployee) + { + await SimulateAsyncOperation(); + + if (Items.Contains(deletedEmployee)) + { + DeleteChildren(deletedEmployee.Id); + Items.Remove(deletedEmployee); + + if (deletedEmployee.ParentId.HasValue && !Items.Any(x => x.ParentId == deletedEmployee.ParentId.Value)) + { + Items.First(x => x.Id == deletedEmployee.ParentId.Value).HasChildren = false; + } + + return true; + } + + return false; + } + + public async Task> Read() + { + await SimulateAsyncOperation(); + + return Items; + } + + public async Task Read(DataSourceRequest request) + { + return await Items.ToDataSourceResultAsync(request); + } + + public async Task Update(Employee updatedEmployee) + { + await SimulateAsyncOperation(); + + int originalItemIndex = Items.FindIndex(x => x.Id == updatedEmployee.Id); + + if (originalItemIndex != -1) + { + Items[originalItemIndex] = updatedEmployee; + return true; + } + + return false; + } + + private async Task SimulateAsyncOperation() + { + await Task.Delay(100); + } + + private void DeleteChildren(int parentId) + { + List children = Items.Where(x => x.ParentId == parentId).ToList(); + + foreach (Employee child in children) + { + DeleteChildren(child.Id); + } + + Items.RemoveAll(x => x.ParentId == parentId); + } + + private void PopulateChildren(List items, int? parentId, int level) + { + int itemCount = level == 1 ? RootItemCount : ChildItemCount; + + for (int i = 1; i <= itemCount; i++) + { + int itemId = ++LastId; + + items.Add(new Employee() + { + Id = itemId, + ParentId = parentId, + HasChildren = level < TreeLevelCount, + Name = $"Employee Name {itemId}", // {level}-{i} + Notes = $"Multi-line\nnotes {itemId}", + Salary = Rnd.Next(1_000, 10_000) * 1.23m, + HireDate = DateTime.Today.AddDays(-Rnd.Next(365, 3650)), + IsDriver = itemId % 2 == 0 + }); + + if (level < TreeLevelCount) + { + PopulateChildren(items, itemId, level + 1); + } + } + } + + public EmployeeService(int treeLevelCount = 3, int rootItemCount = 3, int childItemCount = 2) + { + TreeLevelCount = treeLevelCount; + RootItemCount = rootItemCount; + ChildItemCount = childItemCount; + + List items = new(); + PopulateChildren(items, null, 1); + + Items = items; + } + } + + #endregion Data Service +#end + +#hierarchical-crud-service-and-model + public class Employee + { + public int Id { get; set; } + public bool HasChildren { get; set; } + public List? Items { get; set; } + [Required] + public string Name { get; set; } = string.Empty; + public string Notes { get; set; } = string.Empty; + [Required] + public decimal? Salary { get; set; } + [Required] + public DateTime? HireDate { get; set; } + public bool IsDriver { get; set; } + + public override bool Equals(object? obj) + { + return obj is Employee && ((Employee)obj).Id == Id; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + #region Data Service + + public class EmployeeService + { + private List Items { get; set; } = new(); + + private readonly int TreeLevelCount; + private readonly int RootItemCount; + private readonly int ChildItemCount; + + private int LastId { get; set; } + private readonly Random Rnd = Random.Shared; + + public async Task Create(Employee employee, Employee? parentEmployee) + { + await SimulateAsyncOperation(); + + employee.Id = ++LastId; + + if (parentEmployee != null) + { + parentEmployee.HasChildren = true; + parentEmployee.Items = parentEmployee.Items ?? new List(); + parentEmployee.Items.Insert(0, employee); + } + else + { + Items.Insert(0, employee); + } + + return LastId; + } + + public async Task Delete(Employee employee) + { + await SimulateAsyncOperation(); + + FindItem(Items, employee); + + if (FoundChildItem != null) + { + if (FoundParentItem != null) + { + FoundParentItem?.Items?.Remove(FoundChildItem); + if (FoundParentItem?.Items?.Count == 0) + { + FoundParentItem.Items = null; + FoundParentItem.HasChildren = false; + } + } + else + { + Items.Remove(FoundChildItem); + } + + ResetFoundItems(); + + return true; + } + + return false; + } + + public async Task> Read() + { + await SimulateAsyncOperation(); + + return Items; + } + + public async Task Read(DataSourceRequest request) + { + return await Items.ToDataSourceResultAsync(request); + } + + public async Task Update(Employee employee) + { + await SimulateAsyncOperation(); + + FindItem(Items, employee); + + if (FoundChildItem != null) + { + if (FoundParentItem != null) + { + FoundParentItem.Items![FoundChildItemIndex] = employee; + } + else + { + Items[FoundChildItemIndex] = employee; + } + + ResetFoundItems(); + + return true; + } + + return false; + } + + private async Task SimulateAsyncOperation() + { + await Task.Delay(100); + } + + private Employee? FoundParentItem { get; set; } + private int FoundChildItemIndex { get; set; } + private Employee? FoundChildItem { get; set; } + + private void ResetFoundItems() + { + FoundParentItem = null; + FoundChildItemIndex = default; + FoundChildItem = null; + } + + private void FindItem(List items, Employee item) + { + Employee? parentCandidate; + + for (int i = 0; i < items.Count; i++) + { + if (items[i].Id == item.Id) + { + FoundChildItemIndex = i; + FoundChildItem = item; + return; + } + + if (items[i].Items?.Count > 0) + { + parentCandidate = items[i]; + FindItem(items[i].Items!, item); + + if (FoundChildItem != null) + { + if (parentCandidate.Items!.Contains(FoundChildItem)) + { + FoundParentItem = parentCandidate; + } + + return; + } + } + } + } + + private void PopulateItems(List items, int level) + { + for (int i = 1; i <= (level == 1 ? RootItemCount : ChildItemCount); i++) + { + var itemId = ++LastId; + + var newItem = new Employee() + { + Id = itemId, + HasChildren = level < TreeLevelCount, + Name = $"Employee Name {itemId}", // {level}-{i} + Notes = $"Multi-line\nnotes {itemId}", + Salary = Rnd.Next(1_000, 10_000) * 1.23m, + HireDate = DateTime.Today.AddDays(-Rnd.Next(365, 3650)), + IsDriver = itemId % 2 == 0 + }; + + items.Add(newItem); + } + + if (level < TreeLevelCount) + { + PopulateChildren(items, level + 1); + } + } + + private void PopulateChildren(List items, int level) + { + foreach (var item in items) + { + item.Items = new List(); + + PopulateItems(item.Items, level); + } + } + + public EmployeeService(int treeLevelCount = 3, int rootItemCount = 3, int childItemCount = 2) + { + TreeLevelCount = treeLevelCount; + RootItemCount = rootItemCount; + ChildItemCount = childItemCount; + + List items = new(); + PopulateItems(items, 1); + + Items = items; + } + } + + #endregion Data Service +#end \ No newline at end of file diff --git a/_contentTemplates/treelist/state.md b/_contentTemplates/treelist/state.md index b1f599f180..07ee74efe1 100644 --- a/_contentTemplates/treelist/state.md +++ b/_contentTemplates/treelist/state.md @@ -1,5 +1,5 @@ #initial-state ->tip If you want to set an initial state to the TreeList, use a similar snippet, but in the [`OnStateInit event`]({%slug treelist-state%}#set-default-initial-state) +>tip If you want to set an initial state to the TreeList, use a similar snippet, but in the [`OnStateInit event`](slug:treelist-state#onstateinit) #end @@ -407,6 +407,106 @@ } #end +#search-from-code +@using Telerik.DataSource + + + + + Search Programmatically + Clear Search + + + + + + + +@code { + private TelerikTreeList? TreeListRef { get; set; } + + private List TreeListData { get; set; } = new(); + + private async Task OnSearchButtonClick() + { + if (TreeListRef != null) + { + var treelistState = TreeListRef.GetState(); + + var searchString = $"{(char)Random.Shared.Next(97, 123)}{(char)Random.Shared.Next(97, 123)}"; + + var cfd = new CompositeFilterDescriptor(); + + cfd.LogicalOperator = FilterCompositionLogicalOperator.Or; + cfd.FilterDescriptors = new FilterDescriptorCollection(); + + // Add one FilterDesccriptor for each string column + cfd.FilterDescriptors.Add(new FilterDescriptor() + { + Member = nameof(SampleModel.Name), + MemberType = typeof(string), + Operator = FilterOperator.Contains, + Value = searchString + }); + cfd.FilterDescriptors.Add(new FilterDescriptor() + { + Member = nameof(SampleModel.Description), + MemberType = typeof(string), + Operator = FilterOperator.Contains, + Value = searchString + }); + + treelistState.SearchFilter = cfd; + + await TreeListRef.SetStateAsync(treelistState); + } + } + + private async Task OnClearButtonClick() + { + if (TreeListRef != null) + { + var treelistState = TreeListRef.GetState(); + + (treelistState.SearchFilter as CompositeFilterDescriptor)?.FilterDescriptors.Clear(); + + await TreeListRef.SetStateAsync(treelistState); + } + } + + protected override void OnInitialized() + { + for (int i = 1; i <= 500; i++) + { + TreeListData.Add(new SampleModel() + { + Id = i, + ParentId = i <= 5 ? null : Random.Shared.Next(1, 6), + Name = $"{(char)Random.Shared.Next(65, 91)}{(char)Random.Shared.Next(65, 91)} " + + $"{(char)Random.Shared.Next(65, 91)}{(char)Random.Shared.Next(65, 91)} {i}", + Description = $"{(char)Random.Shared.Next(97, 123)}{(char)Random.Shared.Next(97, 123)} " + + $"{(char)Random.Shared.Next(97, 123)}{(char)Random.Shared.Next(97, 123)} {i}" + }); + } + } + + public class SampleModel + { + public int Id { get; set; } + public int? ParentId { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + } +} +#end #expand-items-from-code @*Expand a root level item on a button click*@ @@ -781,4 +881,8 @@ return await Task.FromResult(data); } } -#end \ No newline at end of file +#end + +#statechanged-possible-prop-values +The possible values for the `PropertyName` are `SortDescriptors`, `FilterDescriptors`, `SearchFilter`, `Page`, `Skip`, `ColumnStates`, `ExpandedItems`, `InsertedItem`, `OriginalEditItem`, `EditItem`. +#end diff --git a/_contentTemplates/treeview/basic-example.md b/_contentTemplates/treeview/basic-example.md index ccb5bdad90..108a1dbc36 100644 --- a/_contentTemplates/treeview/basic-example.md +++ b/_contentTemplates/treeview/basic-example.md @@ -100,6 +100,6 @@ Sample treeview bound to self-referencing flat data. Also uses the built-in icon #end #data-binding-basics-link -Before continuing, make sure you are familiar with the [treeview data binding basics]({%slug components/treeview/data-binding/overview%}). +Before continuing, make sure you are familiar with the [treeview data binding basics](slug:components/treeview/data-binding/overview). #end diff --git a/_contentTemplates/upload/notes.md b/_contentTemplates/upload/notes.md index 248071b86d..0d5e9f049f 100644 --- a/_contentTemplates/upload/notes.md +++ b/_contentTemplates/upload/notes.md @@ -15,7 +15,7 @@ The controller methods in this documentation do not implement security measures The FileSelect and Upload components are similar and even inter-changeable. The major difference is how they communicate with the server and this can determine which component to use. -* The [**FileSelect**]({%slug fileselect-overview%}) is more suitable for **WebAssembly** apps if you want to receive and manipulate the file in the browser's .NET runtime. Uploading the file to a remote server is optional and depends on manual coding in the [`OnSelect` handler]({%slug fileselect-events%}#onselect). The benefit is that FileSelect allows full control over the upload process. In Blazor **Server** apps, the FileSelect uses the **SignalR WebSocket** and large file support (> 32KB) requires [`MaximumReceiveMessageSize` configuration]({%slug fileselect-overview%}#large-file-support). -* The [**Upload**]({%slug upload-overview%}) uses the **HTTP protocol**. Prefer this component in Blazor **Server** and **WebAssembly** apps to directly send files to a remote endpoint, as HTTP is the usual way to do this. Large file support requires [different configurations]({%slug upload-overview%}#large-file-uploads), depending on the receiving web server. +* The [**FileSelect**](slug:fileselect-overview) is more suitable for **WebAssembly** apps if you want to receive and manipulate the file in the browser's .NET runtime. Uploading the file to a remote server is optional and depends on manual coding in the [`OnSelect` handler](slug:fileselect-events#onselect). The benefit is that FileSelect allows full control over the upload process. In Blazor **Server** apps, the FileSelect uses the **SignalR WebSocket** and large file support (> 32KB) requires [`MaximumReceiveMessageSize` configuration](slug:fileselect-overview#large-file-support). +* The [**Upload**](slug:upload-overview) uses the **HTTP protocol**. Prefer this component in Blazor **Server** and **WebAssembly** apps to directly send files to a remote endpoint, as HTTP is the usual way to do this. Large file support requires [different configurations](slug:upload-overview#large-file-uploads), depending on the receiving web server. #end diff --git a/_nginx.yml b/_nginx.yml deleted file mode 100644 index 323b4d93ed..0000000000 --- a/_nginx.yml +++ /dev/null @@ -1 +0,0 @@ -nginx_host: true \ No newline at end of file diff --git a/_pdf.yml b/_pdf.yml deleted file mode 100644 index ca07b67e28..0000000000 --- a/_pdf.yml +++ /dev/null @@ -1,2 +0,0 @@ -#Disable CTA panels for PDF -has_cta_panels: false \ No newline at end of file diff --git a/_staging.yml b/_staging.yml deleted file mode 100644 index 387b3458e0..0000000000 --- a/_staging.yml +++ /dev/null @@ -1,3 +0,0 @@ -baseurl: /blazor-ui -all_pages_domain: "https://kendobuild-staging.dev.progress.com" -exclude: [README.md, Gemfile, Gemfile.lock,api_sort.rb, Dockerfile, bs-config.js, build-docs.sh, copy_content.sh, copy_local.sh, docs-watcher/*, exclude_files.txt, install-npm.sh, start-docs.sh, watch.sh, src-a11y/*] diff --git a/_staging_iis.yml b/_staging_iis.yml deleted file mode 100644 index a67dba416e..0000000000 --- a/_staging_iis.yml +++ /dev/null @@ -1,3 +0,0 @@ -baseurl: /blazor-ui -all_pages_domain: "https://winslaveblazor2.dev.progress.com" -exclude: [README.md, Gemfile, Gemfile.lock,api_sort.rb, Dockerfile, bs-config.js, build-docs.sh, copy_content.sh, copy_local.sh, docs-watcher/*, exclude_files.txt, install-npm.sh, start-docs.sh, watch.sh, src-a11y/*] diff --git a/_test_iis.yml b/_test_iis.yml deleted file mode 100644 index 34c3228342..0000000000 --- a/_test_iis.yml +++ /dev/null @@ -1,3 +0,0 @@ -baseurl: /blazor-ui -all_pages_domain: "https://testdocs.telerik.com" -exclude: [README.md, Gemfile, Gemfile.lock,api_sort.rb, Dockerfile, bs-config.js, build-docs.sh, copy_content.sh, copy_local.sh, docs-watcher/*, exclude_files.txt, install-npm.sh, start-docs.sh, watch.sh, src-a11y/*] diff --git a/_test_iis_azure.yml b/_test_iis_azure.yml deleted file mode 100644 index 44dfaf24d3..0000000000 --- a/_test_iis_azure.yml +++ /dev/null @@ -1,4 +0,0 @@ -url: "https://blazor-docs-test.azurewebsites.net/blazor-ui" -baseurl: /blazor-ui -all_pages_domain: "https://blazor-docs-test.azurewebsites.net" -exclude: [README.md, Gemfile, Gemfile.lock,api_sort.rb, Dockerfile, bs-config.js, build-docs.sh, copy_content.sh, copy_local.sh, docs-watcher/*, exclude_files.txt, install-npm.sh, start-docs.sh, watch.sh, src-a11y/*] diff --git a/_test_iis_azure_prod.yml b/_test_iis_azure_prod.yml deleted file mode 100644 index 3b4e147494..0000000000 --- a/_test_iis_azure_prod.yml +++ /dev/null @@ -1,3 +0,0 @@ -baseurl: /blazor-ui -all_pages_domain: "https://blazor-docs.azurewebsites.net" -exclude: [README.md, Gemfile, Gemfile.lock,api_sort.rb, Dockerfile, bs-config.js, build-docs.sh, copy_content.sh, copy_local.sh, docs-watcher/*, exclude_files.txt, install-npm.sh, start-docs.sh, watch.sh, src-a11y/*] \ No newline at end of file diff --git a/_tools/RemoveHtmlExtensionFromApiRefSitemap/Program.cs b/_tools/RemoveHtmlExtensionFromApiRefSitemap/Program.cs deleted file mode 100644 index 959a95e273..0000000000 --- a/_tools/RemoveHtmlExtensionFromApiRefSitemap/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.IO; -using System.Xml; - -namespace RemoveHtmlExtensionFromApiRefSitemap -{ - class Program - { - static void Main(string[] args) - { - if(args.Length < 2) - { - throw new ArgumentNullException("You must provide a path to the drop folder of the API reference so we can alter the sitemap.xml file in it."); - } - string pathToApiRefSitemap = Path.Combine(args[0], "sitemap.xml"); - if (!File.Exists(pathToApiRefSitemap)) - { - throw new FileNotFoundException("API Ref sitemap file not found in the target folder"); - } - string sitemapText = File.ReadAllText(pathToApiRefSitemap); - sitemapText = sitemapText.Replace(".html", ""); - File.WriteAllText(pathToApiRefSitemap, sitemapText); - } - } -} diff --git a/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.csproj b/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.csproj deleted file mode 100644 index 41f1d5ad4b..0000000000 --- a/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - Exe - net6.0 - - - diff --git a/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.sln b/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.sln deleted file mode 100644 index 137de5bd1f..0000000000 --- a/_tools/RemoveHtmlExtensionFromApiRefSitemap/RemoveHtmlExtensionFromApiRefSitemap.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30413.136 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveHtmlExtensionFromApiRefSitemap", "RemoveHtmlExtensionFromApiRefSitemap.csproj", "{E8F2C9B0-13FA-49FB-A62E-C8824FA8D41A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E8F2C9B0-13FA-49FB-A62E-C8824FA8D41A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E8F2C9B0-13FA-49FB-A62E-C8824FA8D41A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E8F2C9B0-13FA-49FB-A62E-C8824FA8D41A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E8F2C9B0-13FA-49FB-A62E-C8824FA8D41A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {24453D53-AFFF-450A-96DA-90C729B72F1C} - EndGlobalSection -EndGlobal diff --git a/_tools/RemoveHtmlExtensionFromApiRefSitemap/global.json b/_tools/RemoveHtmlExtensionFromApiRefSitemap/global.json deleted file mode 100644 index b7aed275ae..0000000000 --- a/_tools/RemoveHtmlExtensionFromApiRefSitemap/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sdk": { - "version": "6.0.0", - "rollForward": "latestMinor" - } -} diff --git a/_tools/RemoveHtmlExtensionFromApiRefSitemap/readme.txt b/_tools/RemoveHtmlExtensionFromApiRefSitemap/readme.txt deleted file mode 100644 index 1af4e33e35..0000000000 --- a/_tools/RemoveHtmlExtensionFromApiRefSitemap/readme.txt +++ /dev/null @@ -1,12 +0,0 @@ -To execute from the console: -1. navigate your console to the folder with the .csproj file -2. execute from "dotnet run" - -dotnet run SitemapGenerator.csproj -- "C:\\TheCurrentWorkspace\\_site\\api\\" - -The first argument is the project file name, the second is the path to the API reference folder so we can get to the sitemap.xml file inside and transform it. So, this must run after the api ref build - either before, or after combining it with the conceptual docs, but before uploading to staging/test/live. - - -The "--" delimits bult-in dotnet run args from custom args. -Note the double slashes, as they are required as an escaping sequence. - diff --git a/_tools/check-redirects.sh b/_tools/check-redirects.sh deleted file mode 100644 index a0400b7a50..0000000000 --- a/_tools/check-redirects.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/bash - -# Expecting host name as first parameter -args=("$@") -host=${args[0]} - -ok_codes="200 301 302" -count=0 -err_count=0 - -# List of URLs to check: -urls=" -/kendo-ui/api/wrappers/jsp /kendo-ui/api/jsp/alert -/kendo-ui/api/web/grid /kendo-ui/api/javascript/ui/grid -/kendo-ui/api/mobile/application /kendo-ui/api/javascript/mobile/application -/kendo-ui/api/mobile/scrollview /kendo-ui/api/javascript/mobile/ui/scrollview -/kendo-ui/api/framework/fx/common /kendo-ui/api/javascript/effects/common -/kendo-ui/api/framework/class /kendo-ui/api/javascript/class -/kendo-ui/api/framework/color /kendo-ui/api/javascript/color -/kendo-ui/api/framework/kendo /kendo-ui/api/javascript/kendo -/kendo-ui/api/framework/layout /kendo-ui/api/javascript/layout -/kendo-ui/api/framework/router /kendo-ui/api/javascript/router -/kendo-ui/api/framework/binder /kendo-ui/api/javascript/data/binder -/kendo-ui/api/framework/datasource /kendo-ui/api/javascript/data/datasource -/kendo-ui/api/framework/node /kendo-ui/api/javascript/data/node -/kendo-ui/api/dataviz/chart /kendo-ui/api/javascript/dataviz/ui/chart -/kendo-ui/api/dataviz/diagram /kendo-ui/api/javascript/dataviz/ui/diagram -/kendo-ui/api/javascript/dataviz/chart /kendo-ui/api/javascript/dataviz/ui/chart -/kendo-ui/api/javascript/dataviz/diagram /kendo-ui/api/javascript/dataviz/ui/diagram -/kendo-ui/api/dataviz/map/layer /kendo-ui/api/javascript/dataviz/map/layer -/kendo-ui/api/javascript/dataviz/drawing/group /kendo-ui/api/javascript/drawing/group -/kendo-ui/api/javascript/dataviz/geometry/point /kendo-ui/api/javascript/geometry/point -/kendo-ui/web/styles-and-layout/appearance-styling /kendo-ui/styles-and-layout/appearance-styling -/kendo-ui/web/grid/overview /kendo-ui/controls/data-management/grid/overview -/kendo-ui/web/treelist/overview /kendo-ui/controls/data-management/treelist/overview -/kendo-ui/web/autocomplete/overview /kendo-ui/controls/editors/autocomplete/overview -/kendo-ui/web/upload/overview /kendo-ui/controls/editors/upload/overview -/kendo-ui/dataviz/chart/overview /kendo-ui/controls/charts/overview -/kendo-ui/dataviz/sparkline/overview /kendo-ui/controls/charts/sparkline/overview -/kendo-ui/dataviz/treemap/overview /kendo-ui/controls/charts/treemap/overview -/kendo-ui/dataviz/stockchart/overview /kendo-ui/controls/charts/stockchart/overview -/kendo-ui/dataviz/lineargauge/overview /kendo-ui/controls/gauges/lineargauge/overview -/kendo-ui/dataviz/diagram/overview /kendo-ui/controls/diagrams-and-maps/diagram/overview -/kendo-ui/dataviz/map/overview /kendo-ui/controls/diagrams-and-maps/map/overview -/kendo-ui/dataviz/barcode/overview /kendo-ui/controls/barcodes/barcode/overview -/kendo-ui/dataviz/qrcode/overview /kendo-ui/controls/barcodes/qrcode/overview -/kendo-ui/web/calendar/overview /kendo-ui/controls/scheduling/calendar/overview -/kendo-ui/web/gantt/overview /kendo-ui/controls/scheduling/gantt/overview -/kendo-ui/web/notification/overview /kendo-ui/controls/layout/notification/overview -/kendo-ui/web/splitter/overview /kendo-ui/controls/layout/splitter/overview -/kendo-ui/web/button/overview /kendo-ui/controls/navigation/button/overview -/kendo-ui/web/menu/overview /kendo-ui/controls/navigation/menu/overview -/kendo-ui/framework/draganddrop/overview /kendo-ui/controls/interactivity/draganddrop/overview -/kendo-ui/framework/fx/overview /kendo-ui/controls/interactivity/fx/overview -/kendo-ui/web/progressbar/overview /kendo-ui/controls/interactivity/progressbar/overview -/kendo-ui/web/sortable/overview /kendo-ui/controls/interactivity/sortable/overview -/kendo-ui/mobile/introduction /kendo-ui/controls/hybrid/introduction -/kendo-ui/webforms/asp-net-hello-jquery /kendo-ui/third-party/tutorials/webforms/asp-net-hello-jquery -/kendo-ui/dataviz/drawing/overview /kendo-ui/framework/drawing/overview -/kendo-ui/framework/drawing/how-to/custom-page-layout /kendo-ui/controls/data-management/grid/how-to/pdf-export/custom-page-layout -/kendo-ui/tutorials/accessibility/accessibility-overview /kendo-ui/accessibility/accessibility-overview -/kendo-ui/getting-started/introduction /kendo-ui/introduction -/kendo-ui/using-kendo-with/introduction /kendo-ui/introduction -/kendo-ui/tutorials/asp.net/kendo-music-store/kendo-music-store-intro /kendo-ui/aspnet-mvc/tutorials/tutorial-kendo-music-store/kendo-music-store-intro -/kendo-ui/aspnet-mvc/tutorial-kendo-music-store/kendo-music-store-intro /kendo-ui/aspnet-mvc/tutorials/tutorial-kendo-music-store/kendo-music-store-intro -/kendo-ui/aspnet-mvc/tutorial-saleshub/kendo-saleshub-intro /kendo-ui/aspnet-mvc/tutorials/tutorial-saleshub/kendo-saleshub-intro -/kendo-ui/ /kendo-ui/introduction -/kendo-ui/api/javascript/ui/RangeSlider /kendo-ui/api/javascript/ui/rangeslider -/kendo-ui/api/javascript/ui/Splitter /kendo-ui/api/javascript/ui/splitter -/kendo-ui/api/framework/validator /kendo-ui/api/javascript/ui/validator -/kendo-ui/controls/data-management/grid/introduction /kendo-ui/controls/data-management/grid/overview -/kendo-ui/api/javascript/mobile/ui/ButtonGroup /kendo-ui/api/javascript/mobile/ui/buttongroup -/kendo-ui/api/javascript/mobile/ui/TabStrip /kendo-ui/api/javascript/mobile/ui/tabstrip -" - -#Make `for` iterate over new lines -IFS=' -' - -echo "Checking documentation redirects on ${host}" -for line in $urls; do - let count=$count+1 - - url=`echo ${line} | awk '{print $1}'` - url="${host}${url}" - - target=`echo ${line} | awk '{print $2}'` - target="${host}${target}" - - printf '.' - result=`curl --silent --head -w 'Destination %{url_effective}' --location "${url}"` - - result_codes=`echo "${result}" | grep HTTP/1.1 | awk '{print $2}'` - destination=`echo "${result}" | grep Destination | awk '{print $2}'` - - if [[ $destination != $target ]]; then - echo "" - echo "FAIL for ${url}" - echo "Expected ${target}" - echo "Actual ${destination}" - let err_count=$err_count+1 - continue - fi - - while read code; do - if [[ !( $ok_codes =~ $code ) ]]; then - echo "" - echo "FAIL for ${url} with code ${code}" - echo "" - echo "${result}" - echo "" - let err_count=$err_count+1 - fi - done <<< "$result_codes" -done - -echo "" -echo "Checked ${count} redirects with ${err_count} failures." - -exit ${err_count} diff --git a/_tools/spider b/_tools/spider deleted file mode 100644 index 88b4c12ab2..0000000000 --- a/_tools/spider +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -usage() { - echo "Usage: $0 -u [-d ]" 1>&2; - exit 1; -} - -DEPTH=1 - -while getopts ":u:d:" o; do - case "${o}" in - u) - URL=${OPTARG} - ;; - d) - DEPTH=${OPTARG} - ;; - *) - usage - ;; - esac -done -shift $((OPTIND-1)) - -if [ -z "${URL}" ]; then - usage -fi - -wget --spider --recursive --level $DEPTH --no-verbose --page-requisites $URL - diff --git a/accessibility/accessibility-swatch.md b/accessibility/accessibility-swatch.md deleted file mode 100644 index 63d65e8131..0000000000 --- a/accessibility/accessibility-swatch.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Ocean Blue Accessibility Swatch -page_title: Default Ocean Blue Accessibility Swatch -description: Learn about the Default Ocean Blue Accessibility Swatch in the Telerik UI for Blazor suite. This is a theme color variation with enhanced accessibility that complies with accessibility standards. -slug: themes-accessibility-swatch -tags: telerik, blazor, accessibility, theme, swatch -published: True -position: 7 ---- - -# Ocean Blue Accessibility Swatch - -The [Web Content Accessibility Guidelines](https://www.w3.org/TR/WCAG21/) sections [1.4.3 Contrast (Minimum)](https://www.w3.org/TR/WCAG21/#contrast-minimum) and [1.4.6 Contrast (Enhanced)](https://www.w3.org/TR/WCAG21/#contrast-enhanced) define contrast ratios for accessibility compliance. The *Default Ocean Blue A11y* [theme swatch]({%slug themes-overview%}#basics) in Telerik UI for Blazor conforms to WCAG Level AA, which requires contrast ratios of at least: - -* 4.5:1 for normal text -* 3:1 for large text - - -## Testing the Accessibility Swatch - -To preview and test the Default Ocean Blue A11y swatch, visit the [Telerik UI for Blazor live demos](https://demos.telerik.com/blazor-ui/grid/overview). Enable the swatch from the **Change Theme** dropdown above any of the examples. - -The Default Ocean Blue A11y swatch is built on top of the Default Ocean Blue swatch. The main difference is that the Ocean Blue A11y swatch has high-contrast focus indicators to comply with WCAG requirements. - - -## Using the Accessibility Swatch - -You can [obtain and use the Default Ocean Blue A11y swatch]({%slug themes-overview%}#swatch) starting from the following component and theme versions: - -* [Telerik UI for Blazor version 4.0.1](https://www.telerik.com/support/whats-new/blazor-ui/release-history/ui-for-blazor-4-0-1) -* [Themes version 6.0.3](https://github.com/telerik/kendo-themes/releases/tag/v6.0.3) - -Check section [Theme Version Compatibility]({%slug themes-overview%}#compatibility-and-maintenance) for more information about how to align Telerik UI for Blazor versions with theme versions. - -> An existing limitation is that the ColorPalette component fails WCAG success criterion 1.4.11. "Non-text contrast for the focus indicator on its items". - - -## See Also - -* [Accessibility Overview]({%slug accessibility-overview%}) -* [Component Accessibility Compliance]({%slug accessibility-standards%}#accessibility-compliance-components-table) diff --git a/accessibility/assets/BlazorVPAT.doc b/accessibility/assets/telerik-ui-for-blazor-acr-vpat.doc similarity index 100% rename from accessibility/assets/BlazorVPAT.doc rename to accessibility/assets/telerik-ui-for-blazor-acr-vpat.doc diff --git a/accessibility/compliance.md b/accessibility/compliance.md index cd8e9edce6..b6fcfbe25a 100644 --- a/accessibility/compliance.md +++ b/accessibility/compliance.md @@ -5,35 +5,144 @@ description: Compliance with the accessibility standards and requirements in the slug: accessibility-compliance tags: telerik,blazor,accessibility,standards,compliance published: True -position: 4 +position: 10 +previous_url: /accessibility/wcag-section-508-wai-aria --- # Accessibility Standards Compliance -This article lists the compliance with the various accessibility standards that the Telerik UI for Blazor components provide. - -For details on the keyboard support, see the [Keyboard Navigation]({%slug accessibility-keyboard-navigation%}) article. - -All components implement the required WAI-ARIA attributes without the need for any extra configuration. - -Due to the complexity of some of the components in the suite, we sometimes run into scenarios not covered by the WAI-ARIA specification. In those cases, we tap into the web development accessibility know-how of the rest of the Progress organization, including feedback from accessibility-minded users, for expertise and feedback based on 10 years of creating web component libraries. This knowledge-sharing across internal teams and clients helps us ensure that UI for Blazor can reach a certain level of accessibility compliance even with its most advanced components. - -This article will be updated with details on the Section 508 and WCAG 2.2 compatibility levels. - - - - - - - - -The Telerik UI for Blazor components are highly extensible and customizable. This means that, depending on the level of customization applied, you may be introducing rendering that is not accessible. Therefore, it is recommended that you test any modifications and templates you create to ensure the components still meet the desired level of accessibility standards. Additionally, be mindful of components working with custom input (images, text, HTML content, and so on) and make sure your content is accessible, too. - - +This article lists the accessibility compliance of the Telerik UI for Blazor components. + +## Accessibility Conformance Report + +The [Accessibility Conformance Report (ACR)](https://www.section508.gov/sell/acr/) is a document that explains how information and communication technology products such as software, hardware, electronic content, and support documentation conform to leading global accessibility standards. Telerik UI for Blazor provides an ACR through the Voluntary Product Accessibility Template (VPAT®). + +>tip Download the latest version of the [Telerik UI for Blazor Accessibility Conformance Report](./assets/telerik-ui-for-blazor-acr-vpat.doc). + +## Compliance Table + +The table below specifies the level of WCAG 2.2 compliance of each Telerik component for Blazor. + +* The *Keyboard Navigation* column links to component-specific online demos or keyboard shortcut lists. For general information on how the keyboard support works, see the [Keyboard Navigation](slug:accessibility-overview#keyboard-navigation) section. +* The *Accessibility Documentation* column links to component-specific details and information about WAI-ARIA attributes. +* For information about **Section 508** of the US Rehabilitation Act, the **European Accessibility Act** in the EU, or any other national accessibility legislation, see section [Legal and Technical Compliance](slug:accessibility-overview#legal-and-technical-compliance). + +Also check the [notes below the table](#accessibility-compliance-notes). + +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) + +| Component | WCAG 2.2 | Keyboard Navigation | Accessibility Documentation | +| --- | --- | --- | --- | +| AIPrompt | AA | [Enhanced](https://demos.telerik.com/blazor-ui/aiprompt/overview) | [Documentation](slug:aiprompt-wai-aria-support) | +| AppBar | N/A | N/A | N/A | +| ArcGauge | AA | N/A | N/A | +| AutoComplete | AA | [Enhanced](https://demos.telerik.com/blazor-ui/autocomplete/keyboard-navigation) | [Documentation](slug:autocomplete-wai-aria-support) | +| Avatar | AA | N/A | N/A | +| Badge | N/A | N/A | N/A | +| Barcode | N/A | N/A | N/A | +| Breadcrumb | AAA | [Enhanced](https://demos.telerik.com/blazor-ui/breadcrumb/keyboard-navigation) | [Documentation](slug:breadcrumb-wai-aria-support) | +| Button | AAA | [Standard](https://demos.telerik.com/blazor-ui/button/keyboard-navigation) | [Documentation](slug:button-wai-aria-support) | +| ButtonGroup | AAA | [Standard](https://demos.telerik.com/blazor-ui/buttongroup/keyboard-navigation) | [Documentation](slug:buttongroup-wai-aria-support) | +| Calendar | AAA | [Enhanced](https://demos.telerik.com/blazor-ui/calendar/keyboard-navigation) | [Documentation](slug:calendar-wai-aria-support) | +| Card | AA | N/A | [Documentation](slug:card-wai-aria-support) | +| Carousel | AA | [Enhanced](https://demos.telerik.com/blazor-ui/carousel/keyboard-navigation) | [Documentation](slug:carousel-wai-aria-support) | +| Chart | AA | [Enhanced](https://demos.telerik.com/blazor-ui/chart/keyboard-navigation) | [Documentation](slug:chart-wai-aria-support ) | +| CheckBox | AA | [Standard](https://demos.telerik.com/blazor-ui/checkbox/overview) | [Documentation](slug:checkbox-wai-aria-support) | +| Chip | AA | [Enhanced](https://demos.telerik.com/blazor-ui/chip/keyboard-navigation) | [Documentation](slug:chip-wai-aria-support) | +| ChipList | AA | [Enhanced](https://demos.telerik.com/blazor-ui/chiplist/keyboard-navigation) | [Documentation](slug:chiplist-wai-aria-support) | +| ChunkProgressBar | AA | N/A | [Documentation](slug:chunkprogressbar-wai-aria-support) | +| CircularGauge | N/A | N/A | N/A | +| ColorGradient | AA | [Enhanced](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) | [Documentation](slug:colorgradient-wai-aria-support) | +| ColorPalette | AA | [Enhanced](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation) | [Documentation](slug:colorpalette-wai-aria-support) | +| ColorPicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/colorpicker/overview)
Also see [ColorGradient](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) and [ColorPalette](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation). | [Documentation](slug:colorpicker-wai-aria-support) | +| ComboBox | AA | [Enhanced](https://demos.telerik.com/blazor-ui/combobox/keyboard-navigation) | [Documentation](slug:combobox-wai-aria-support) | +| ContextMenu | AA | [Enhanced](https://demos.telerik.com/blazor-ui/contextmenu/keyboard-navigation) | [Documentation](slug:contextmenu-wai-aria-support) | +| DateInput | AA | [Enhanced](https://demos.telerik.com/blazor-ui/dateinput/keyboard-navigation) | [Documentation](slug:dateinput-wai-aria-support) | +| DatePicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/datepicker/keyboard-navigation) | [Documentation](slug:datepicker-wai-aria-support) | +| DateRangePicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/daterangepicker/keyboard-navigation) | [Documentation](slug:daterangepicker-wai-aria-support) | +| DateTimePicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/datetimepicker/keyboard-navigation) | [Documentation](slug:datetimepicker-wai-aria-support) | +| Dialog | AA | [Enhanced](https://demos.telerik.com/blazor-ui/drawer/keyboard-navigation) | [Documentation](slug:dialog-wai-aria-support) | +| Drawer | AA | [Enhanced](https://demos.telerik.com/blazor-ui/drawer/keyboard-navigation) | [Documentation](slug:drawer-wai-aria-support) | +| DropDownButton | AA | [Enhanced](https://demos.telerik.com/blazor-ui/dropdownbutton/keyboard-navigation) | [Documentation](slug:dropdownbutton-wai-aria-support) | +| DropDownList | AA | [Enhanced](https://demos.telerik.com/blazor-ui/dropdownlist/keyboard-navigation) | [Documentation](slug:dropdownlist-wai-aria-support) | +| DropZone | N/A | N/A | N/A | +| Editor | AA | [Enhanced](https://demos.telerik.com/blazor-ui/editor/keyboard-navigation) | [Documentation](slug:editor-wai-aria-support) | +| FileManager | AA |[Enhanced](https://demos.telerik.com/blazor-ui/filemanager/overview)
Also see [Grid](https://demos.telerik.com/blazor-ui/grid/keyboard-navigation), [ListView](https://demos.telerik.com/blazor-ui/listview/keyboard-navigation), [Splitter](https://demos.telerik.com/blazor-ui/splitter/keyboard-navigation), [ToolBar](https://demos.telerik.com/blazor-ui/toolbar/keyboard-navigation), [TreeView](https://demos.telerik.com/blazor-ui/treeview/keyboard-navigation) | [Documentation](slug:filemanager-wai-aria-support) | +| FileSelect | N/A | [Enhanced](https://demos.telerik.com/blazor-ui/fileselect/keyboard-navigation) | TBA | +| Filter | AA | [Enhanced](https://demos.telerik.com/blazor-ui/filter/keyboard-navigation) | [Documentation](slug:filter-wai-aria-support) | +| FlatColorPicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/flatcolorpicker/overview) | [Documentation](slug:flatcolorpicker-wai-aria-support) | +| FloatingLabel | N/A | N/A | N/A | +| FontIcon | N/A | N/A | N/A | +| Form | AA | [Standard](https://demos.telerik.com/blazor-ui/form/overview) | [Documentation](slug:form-wai-aria-support) | +| Gantt | AA | [Enhanced](https://demos.telerik.com/blazor-ui/gantt/keyboard-navigation) | [Documentation](slug:gantt-wai-aria-support) | +| Grid | AA | [Enhanced](https://demos.telerik.com/blazor-ui/grid/keyboard-navigation) | [Documentation](slug:grid-wai-aria-support) | +| GridLayout | N/A | N/A | N/A | +| LinearGauge | AA | N/A | N/A | +| ListBox | AA | [Enhanced](https://demos.telerik.com/blazor-ui/listbox/keyboard-navigation) | [Documentation](slug:listbox-wai-aria-support) | +| ListView | AAA | [Enhanced](https://demos.telerik.com/blazor-ui/listview/keyboard-navigation) | [Documentation](slug:listview-wai-aria-support) | +| Loader | N/A | N/A | N/A | +| LoaderContainer | N/A | N/A | N/A | +| Map | N/A | [Enhanced](https://demos.telerik.com/blazor-ui/map/overview) | N/A | +| MaskedTextbox | AA | [Standard](https://demos.telerik.com/blazor-ui/maskedtextbox/overview) | [Documentation](slug:maskedtextbox-wai-aria-support) | +| MediaQuery | N/A | N/A | N/A | +| Menu | AA | [Enhanced](https://demos.telerik.com/blazor-ui/menu/keyboard-navigation) | [Documentation](slug:menu-wai-aria-support) | +| MultiColumnComboBox | N/A | [Enhanced](https://demos.telerik.com/blazor-ui/multicolumncombobox/keyboard-navigation) | [Documentation](slug:multicolumncombobox-wai-aria-support) | +| MultiSelect | AA | [Enhanced](https://demos.telerik.com/blazor-ui/multiselect/keyboard-navigation) | [Documentation](slug:multiselect-wai-aria-support) | +| Notification | AA | N/A | [Documentation](slug:notification-wai-aria-support) | +| NumericTextbox | AA | [Enhanced](https://demos.telerik.com/blazor-ui/numerictextbox/keyboard-navigation) | [Documentation](slug:numerictextbox-wai-aria-support) | +| Pager | AA | [Enhanced](https://demos.telerik.com/blazor-ui/pager/keyboard-navigation) | [Documentation](slug:pager-wai-aria-support) | +| PanelBar | AA | [Enhanced](https://demos.telerik.com/blazor-ui/panelbar/keyboard-navigation) | [Documentation](slug:panelbar-wai-aria-support) | +| PdfViewer | AA | [Enhanced](https://demos.telerik.com/blazor-ui/pdfviewer/overview) | [Documentation](slug:pdfviewer-wai-aria-support) | +| PivotGrid | AA | [Enhanced](https://demos.telerik.com/blazor-ui/pivotgrid/overview) | [Documentation](slug:pivotgrid-wai-aria-support) | +| ProgressBar | AA | N/A | [Documentation](slug:progressbar-wai-aria-support) | +| Popover | AA | [Standard](https://demos.telerik.com/blazor-ui/popover/overview) | [Documentation](slug:popover-wai-aria-support) | +| Popup | AA | N/A | N/A | +| QRCode | N/A | N/A | N/A | +| RadialGauge | AA | N/A | N/A | +| RadioGroup | AA | [Standard](https://demos.telerik.com/blazor-ui/radiogroup/keyboard-navigation) | [Documentation](slug:radiogroup-wai-aria-support) | +| RangeSlider | AA | [Enhanced](https://demos.telerik.com/blazor-ui/rangeslider/keyboard-navigation) | [Documentation](slug:rangeslider-wai-aria-support) | +| Rating | AA | [Enhanced](https://demos.telerik.com/blazor-ui/rating/keyboard-navigation) | [Documentation](slug:rating-wai-aria-support) | +| Sankey | AA | [Enhanced](https://demos.telerik.com/blazor-ui/sankey/overview) | [Documentation](slug:sankey-wai-aria-support) | +| Scheduler | AA | [Enhanced](https://demos.telerik.com/blazor-ui/scheduler/keyboard-navigation) | [Documentation](slug:scheduler-wai-aria-support) | +| Signature | AA | [Enhanced](https://demos.telerik.com/blazor-ui/signature/overview) | [Documentation](slug:signature-wai-aria-support) | +| Skeleton | AAA | N/A | [Documentation](slug:skeleton-wai-aria-support) | +| Slider | AA | [Enhanced](https://demos.telerik.com/blazor-ui/slider/keyboard-navigation) | [Documentation](slug:slider-wai-aria-support) | +| SplitButton | AA | [Enhanced](https://demos.telerik.com/blazor-ui/splitbutton/keyboard-navigation) | [Documentation](slug:splitbutton-wai-aria-support) | +| Splitter | AA | [Enhanced](https://demos.telerik.com/blazor-ui/splitter/keyboard-navigation) | [Documentation](slug:splitter-wai-aria-support) | +| Spreadsheet | AA | [Enhanced](https://demos.telerik.com/blazor-ui/spreadsheet/overview) | [Documentation](slug:spreadsheet-wai-aria-support) | +| StackLayout | N/A | N/A | N/A | +| Stepper | AA | [Enhanced](https://demos.telerik.com/blazor-ui/stepper/keyboard-navigation) | [Documentation](slug:stepper-wai-aria-support) | +| StockChart | AA | [Enhanced](https://demos.telerik.com/blazor-ui/stockchart/overview) | N/A | +| SvgIcon | N/A | N/A | N/A | +| Switch | AA | [Enhanced](https://demos.telerik.com/blazor-ui/switch/keyboard-navigation) | [Documentation](slug:switch-wai-aria-support) | +| TabStrip | AA | [Enhanced](https://demos.telerik.com/blazor-ui/tabstrip/keyboard-navigation) | [Documentation](slug:tabstrip-wai-aria-support) | +| TextArea | AAA | [Standard](https://demos.telerik.com/blazor-ui/textarea/overview) | [Documentation](slug:textarea-wai-aria-support) | +| TextBox | AA | [Standard](https://demos.telerik.com/blazor-ui/textbox/overview) | [Documentation](slug:textbox-wai-aria-support) | +| TileLayout | AAA | [Enhanced](https://demos.telerik.com/blazor-ui/tilelayout/overview) | [Documentation](slug:tilelayout-wai-aria-support) | +| TimePicker | AA | [Enhanced](https://demos.telerik.com/blazor-ui/timepicker/keyboard-navigation) | [Documentation](slug:timepicker-wai-aria-support) | +| ToggleButton | AA | [Enhanced](https://demos.telerik.com/blazor-ui/togglebutton/keyboard-navigation) | [Documentation](slug:togglebutton-wai-aria-support) | +| ToolBar | AA | [Enhanced](https://demos.telerik.com/blazor-ui/toolbar/keyboard-navigation) | [Documentation](slug:toolbar-wai-aria-support) | +| Tooltip | AA | [Enhanced](https://demos.telerik.com/blazor-ui/tooltip/overview) | [Documentation](slug:tooltip-wai-aria-support) | +| TreeList | AA | [Enhanced](https://demos.telerik.com/blazor-ui/treelist/keyboard-navigation) | [Documentation](slug:treelist-wai-aria-support) | +| TreeView | AA | [Enhanced](https://demos.telerik.com/blazor-ui/treeview/keyboard-navigation) | [Documentation](slug:treeview-wai-aria-support) | +| Upload | AAA | [Enhanced](https://demos.telerik.com/blazor-ui/upload/keyboard-navigation) | [Documentation](slug:upload-wai-aria-support) | +| ValidationMessage | AA | N/A | TBA | +| ValidationTooltip | AA | N/A | TBA | +| ValidationSummary | AA | N/A | TBA | +| Window | AA | [Enhanced](https://demos.telerik.com/blazor-ui/window/keyboard-navigation) | [Documentation](slug:window-wai-aria-support) | +| Wizard | AA | [Enhanced](https://demos.telerik.com/blazor-ui/wizard/keyboard-navigation) | [Documentation](slug:wizard-wai-aria-support) | + +## Accessibility Compliance Notes + +The information in the compliance table above is subject to the following considerations: + +* All components implement the required WAI-ARIA attributes without the need for any extra configuration. Some components may provide parameters that render additional optional WAI-ARIA attributes, for example, `aria-label` or `aria-describedby`. +* The compliance levels are achievable with the [*Default Ocean Blue A11y* theme swatch](slug:accessibility-overview#color-contrast) or any other [custom theme swatch](slug:themes-customize) that provides the minimum required color contrast. +* The accessibility and compliance of some components may depend on the enabled features. In such cases, the compliance table information is based on the default component configuration. +* Component templates introduce custom markup that may not be accessible. Test any modifications to ensure the web content still meets the desired level of accessibility compliance. Be mindful of components that work with user input such as images, text, or HTML content. +* Due to the complexity of some components, there are scenarios that are not covered by the WAI-ARIA specification. ## See Also - * [Accessibility Overview]({%slug accessibility-overview%}) - * [Globalization Overview]({%slug globalization-overview%}) +* [Accessibility Overview](slug:accessibility-overview) +* [Globalization Overview](slug:globalization-overview) diff --git a/accessibility/keyboard-navigation.md b/accessibility/keyboard-navigation.md deleted file mode 100644 index c8fee231c9..0000000000 --- a/accessibility/keyboard-navigation.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Keyboard Navigation -page_title: Keyboard Navigation -description: Support for keyboard navigation in the Telerik UI for Blazor suite and components. -slug: accessibility-keyboard-navigation -tags: telerik,blazor,accessibility,keyboard,navigation,support -published: True -position: 2 ---- - -# Keyboard Navigation - -The Telerik UI for Blazor components support keyboard navigation and the end users can use the keyboard to walk through them and invoke actions such as clicking buttons, paging the Grid, and so on. - -## How it Works - -Generally, to focus a component, use the `Tab` key as the keyboard support of the page follows the normal flow of the content. Once inside a component, you can use specific keyboard shortcuts to trigger specific actions such as using the `Arrow` keys to focus different cells in the Grid, or the `Enter` key to click a button. - -Normally, users can use the keyboard to navigate only to HTML links, buttons, and form controls. The Telerik UI for Blazor library has gone to the next level and the components it delivers are focusable. In this way, even though the components represent complex structures, users can interact with them too. - -The navigation order in which interactive items receive keyboard focus has to be logical and intuitive. Generally, the focus has to follow the visual horizontal and vertical flow of the page. For example, left-to-right and top-to-bottom, header first followed by the main and, then, page navigation. - -Most of the components in the library represent a single `Tab` stop. Once users reach and focus a component, they can leave it with a single tab. If the component is more complex, users can walk though its inside elements with the `Arrow` keys, for example, Grid cells, Menu items, Toolbar buttons. Some complex components can accommodate multiple other components. For example, the Grid can host a Toolbar and a Pager. In this case, you can tab to move the focus from one nested component to another. - -## Types of Keyboard Support - -The Telerik UI for Blazor components may provide enhanced, standard, or no keyboard support. - -* *Standard keyboard support* implies similar keyboard navigation capabilities as standard HTML elements. For example, the Button components support `Enter` and `Space` for clicking them. All components with standard keyboard support are reachable through the `Tab` key and provide focus styles. -* *Enhanced keyboard support* builds on top of the standard key combinations and provides additional built-in shortcuts for improved flexibility and user experience. -* The components with no keyboard support serve a purely visualization purpose, are just content containers, provide no interaction, or provide only mouse and touch interaction by design. - -## Right-to-Left Support - -When the [right-to-left direction is enabled]({%slug rtl-support%}), the keyboard shortcuts for the components that support keyboard navigation remain unchanged except for the `Left arrow` and `Right arrow` keys—their functionality is reversed to follow the right-to-left direction. - - -## Keyboard Support per Component - -The following table lists the available Telerik UI for Blazor components with the type of keyboard support they provide. To see the combinations in action, click the desired component to see its keyboard navigation demo. - -| Component | Keyboard Navigation | Notes | -| --- | --- | --- | -| ArcGauge | - | | -| [AutoComplete](https://demos.telerik.com/blazor-ui/autocomplete/keyboard-navigation) | **Enhanced** | | -| [Breadcrumb](https://demos.telerik.com/blazor-ui/breadcrumb/keyboard-navigation) | **Enhanced** | | -| [Button](https://demos.telerik.com/blazor-ui/button/keyboard-navigation) | Standard | | -| [ButtonGroup](https://demos.telerik.com/blazor-ui/buttongroup/keyboard-navigation) | Standard | | -| [Calendar](https://demos.telerik.com/blazor-ui/calendar/keyboard-navigation) | **Enhanced** | | -| [Carousel](https://demos.telerik.com/blazor-ui/carousel/keyboard-navigation) | **Enhanced** | | -| [Chart](https://demos.telerik.com/blazor-ui/chart/keyboard-navigation) | **Enhanced** | | -| [CheckBox](https://demos.telerik.com/blazor-ui/checkbox/overview) | Standard | | -| [Chip](https://demos.telerik.com/blazor-ui/chip/keyboard-navigation) | **Enhanced** | | -| [ChipList](https://demos.telerik.com/blazor-ui/chiplist/keyboard-navigation) | **Enhanced** | | -| CircularGauge | - | | -| [ColorGradient](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) | **Enhanced** | | -| [ColorPalette](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation) | **Enhanced** | | -| [ColorPicker](https://demos.telerik.com/blazor-ui/colorpicker/overview) | **Enhanced** | See also the [ColorGradient](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) and [ColorPalette](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation). | -| [ComboBox](https://demos.telerik.com/blazor-ui/combobox/keyboard-navigation) | **Enhanced** | | -| [ContextMenu](https://demos.telerik.com/blazor-ui/contextmenu/keyboard-navigation) | **Enhanced** | | -| [DateInput](https://demos.telerik.com/blazor-ui/dateinput/keyboard-navigation) | **Enhanced** | | -| [DatePicker](https://demos.telerik.com/blazor-ui/datepicker/keyboard-navigation) | **Enhanced** | | -| [DateRangePicker](https://demos.telerik.com/blazor-ui/daterangepicker/keyboard-navigation) | **Enhanced** | | -| [DateTimePicker](https://demos.telerik.com/blazor-ui/datetimepicker/keyboard-navigation) | **Enhanced** | | -| [Dialog](https://demos.telerik.com/blazor-ui/dialog/overview) | **Enhanced** | Tab to reach and use its buttons. The Dialog restricts the focus within itself during tabbing. | -| [Drawer](https://demos.telerik.com/blazor-ui/drawer/keyboard-navigation) | **Enhanced** | | -| [DropDownButton](https://demos.telerik.com/blazor-ui/dropdownbutton/keyboard-navigation) | **Enhanced** | | -| [DropDownList](https://demos.telerik.com/blazor-ui/dropdownlist/keyboard-navigation) | **Enhanced** | | -| DropZone | - | | -| [Editor](https://demos.telerik.com/blazor-ui/editor/keyboard-navigation) | **Enhanced** | | -| [FileManager](https://demos.telerik.com/blazor-ui/filemanager/overview) | **Enhanced** | Tab to focus the different nested components. Keyboard navigation for the file list is not available yet. | -| [FileSelect](https://demos.telerik.com/blazor-ui/fileselect/keyboard-navigation) | **Enhanced** | | -| [Filter](https://demos.telerik.com/blazor-ui/filter/keyboard-navigation) | **Enhanced** | | -| [FlatColorPicker](https://demos.telerik.com/blazor-ui/flatcolorpicker/overview) | **Enhanced** | Tab to focus the different nested components. See also the [ColorGradient](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) and [ColorPalette](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation). | -| FloatingLabel | - | | -| [Form](https://demos.telerik.com/blazor-ui/form/overview) | Standard | | -| [Gantt](https://demos.telerik.com/blazor-ui/gantt/overview) | **Enhanced** | Keyboard navigation is available for the nested [TreeList](https://demos.telerik.com/blazor-ui/treelist/keyboard-navigation). | -| [Grid](https://demos.telerik.com/blazor-ui/grid/keyboard-navigation) | **Enhanced** | Set `Navigable="true"` | -| GridLayout | - | | -| Icons | - | | -| LinearGauge | - | | -| [ListView](https://demos.telerik.com/blazor-ui/listview/keyboard-navigation) | **Enhanced** | | The built-in [Pager component provides keyboard navigation](https://demos.telerik.com/blazor-ui/pager/keyboard-navigation). | -| Loader | - | | -| LoaderContainer | - | | -| [Map](https://demos.telerik.com/blazor-ui/map/overview) | **Enhanced** | | -| [MaskedTextBox](https://demos.telerik.com/blazor-ui/maskedtextbox/overview) | Standard | | -| MediaQuery | - | | -| [Menu](https://demos.telerik.com/blazor-ui/menu/keyboard-navigation) | **Enhanced** | | -| [MultiColumnComboBox](https://demos.telerik.com/blazor-ui/multicolumncombobox/keyboard-navigation) | **Enhanced** | | -| [MultiSelect](https://demos.telerik.com/blazor-ui/multiselect/keyboard-navigation) | **Enhanced** | | -| Notification | - | | -| [NumericTextBox](https://demos.telerik.com/blazor-ui/numerictextbox/keyboard-navigation) | **Enhanced** | | -| [Pager](https://demos.telerik.com/blazor-ui/pager/keyboard-navigation) | **Enhanced** | | -| [PanelBar](https://demos.telerik.com/blazor-ui/panelbar/keyboard-navigation) | **Enhanced** | | -| [PdfViewer](https://demos.telerik.com/blazor-ui/pdfviewer/overview) | **Enhanced** | Tab to focus the different components in the toolbar. The built-in [Pager provides keyboard navigation](https://demos.telerik.com/blazor-ui/pager/keyboard-navigation). | -| PivotGrid | - | Not Supported
(upcoming support) | -| ProgressBar | - | | -| QRCode | - | | -| RadialGauge | - | | -| [RadioGroup](https://demos.telerik.com/blazor-ui/radiogroup/keyboard-navigation) | Standard | | -| [RangeSlider](https://demos.telerik.com/blazor-ui/rangeslider/keyboard-navigation) | **Enhanced** | | -| [Scheduler](https://demos.telerik.com/blazor-ui/scheduler/keyboard-navigation) | **Enhanced** | | -| Signature | - | | -| Skeleton | - | | -| [Slider](https://demos.telerik.com/blazor-ui/slider/keyboard-navigation) | **Enhanced** | | -| [SplitButton](https://demos.telerik.com/blazor-ui/splitbutton/keyboard-navigation) | **Enhanced** | | -| [Splitter](https://demos.telerik.com/blazor-ui/splitter/keyboard-navigation) | **Enhanced** | | -| StackLayout | - | | -| [Stepper](https://demos.telerik.com/blazor-ui/stepper/keyboard-navigation) | **Enhanced** | | -| StockChart | - | | -| [Switch](https://demos.telerik.com/blazor-ui/switch/keyboard-navigation) | **Enhanced** | | -| [TabStrip](https://demos.telerik.com/blazor-ui/tabstrip/keyboard-navigation) | **Enhanced** | | -| [TextArea](https://demos.telerik.com/blazor-ui/textarea/overview) | Standard | | -| [TextBox](https://demos.telerik.com/blazor-ui/textbox/overview) | Standard | | -| TileLayout | - | | -| [TimePicker](https://demos.telerik.com/blazor-ui/timepicker/keyboard-navigation) | **Enhanced** | | -| [ToggleButton](https://demos.telerik.com/blazor-ui/togglebutton/keyboard-navigation) | **Enhanced** | | -| [ToolBar](https://demos.telerik.com/blazor-ui/toolbar/keyboard-navigation) | **Enhanced** | | -| Tooltip | - | | -| [TreeList](https://demos.telerik.com/blazor-ui/treelist/keyboard-navigation) | **Enhanced** | | Set `Navigable="true"` | -| [TreeView](https://demos.telerik.com/blazor-ui/treeview/keyboard-navigation) | **Enhanced** | | -| [Upload](https://demos.telerik.com/blazor-ui/upload/keyboard-navigation) | **Enhanced** | | -| Validation | - | | -| [Window](https://demos.telerik.com/blazor-ui/window/keyboard-navigation) | **Enhanced** | | -| [Wizard](https://demos.telerik.com/blazor-ui/wizard/keyboard-navigation) | **Enhanced** | | - -## See Also - -* [Accessibility Overview]({%slug accessibility-overview%}) -* [Globalization Overview]({%slug globalization-overview%}) -* [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) diff --git a/accessibility/overview.md b/accessibility/overview.md index 702ed4ee13..33948f3727 100644 --- a/accessibility/overview.md +++ b/accessibility/overview.md @@ -5,26 +5,114 @@ description: Accessibility features in the Telerik UI for Blazor suite. slug: accessibility-overview tags: telerik,blazor,accessibility,overview published: True -position: 0 +position: 1 +previous_url: /accessibility/keyboard-navigation,/accessibility/accessibility-swatch --- # Blazor Accessibility Overview -Websites and applications are accessible when they provide full control over their features by enabling users with disabilities to access their content through assistive technologies or keyboard navigation. +Web applications are accessible when they provide control over their features to users with physical or situational disabilities. These disabilities can include various categories, for example, user who are: -Accessibility consists of several aspects: +* Unable to perceive content visually or auditory. +* Unable to use a mouse or a keyboard for any reason. +* Consuming electronic content through assistive technologies. -* [The WCAG, Section 508 and WAI-ARIA standards]({%slug accessibility-standards%}) -* [Keyboard Navigation]({%slug accessibility-keyboard-navigation%}) -* [Globalization]({%slug globalization-overview%}) +>tip Accessibility compliance is a strategic and ongoing commitment for Telerik UI for Blazor. -### Voluntary Product Accessibility Template +## Legal and Technical Compliance -A [Voluntary Product Accessibility Template (VPAT®)](https://www.section508.gov/sell/vpat/) is a document that explains how information and communication technology (ICT) products such as software, hardware, electronic content, and support documentation meet (conform to) the Revised 508 Standards for IT accessibility. +Accessibility compliance can be considered from a legal and technical perspective, but these ultimately merge. Different countries have different regulations about web content accessibility compliance, for example: -> You can review and download the latest version of the Telerik UI for Blazor VPAT document [here](./assets/BlazorVPAT.doc). +* Section 508 of the US Rehabilitation Act +* The EU European Accessibility Act -## See Also +The national regulations normally share the following characteristics: - * [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) - * [Default Ocean Blue Accessibility Swatch]({%slug themes-accessibility-swatch%}) +* The legal requirements boil down to common technical standards such as a specific version of [WCAG](#web-context-accessibility-guidelines). +* The national legislations are slower to adopt newer accessibility standards, compared to Telerik UI for Blazor. + +As a result, Telerik UI for Blazor does not review or aim to comply with specific national accessibility legislations. The components [target compliance with the latest official standard WCAG 2.2](slug:accessibility-compliance#compliance-table), which is enough to claim compliance with national legal requirements. + +From technical point of view, Telerik UI for Blazor achieves accessibility through the following features: + +* [Compliance with WCAG success criteria](#web-context-accessibility-guidelines) +* [WAI-ARIA attributes](#wai-aria) +* [Keyboard navigation](#keyboard-navigation) +* [Color contrast](#color-contrast) +* [Best practices in component development and testing](#development-practices) + +## Web Context Accessibility Guidelines + +Web Context Accessibility Guidelines (WCAG) is an international standard that specifies how to make web content more accessible to people with disabilities. The guidelines are organized under four principles: perceivable, operable, understandable, and robust. + +Telerik UI for Blazor targets WCAG version 2.2. + +## WAI-ARIA + +WAI-ARIA provides a framework for adding HTML attributes to identify features for user interaction, how they relate to each other, and their current state. The WAI-ARIA standard defines HTML element roles and states, which help with dynamic content and advanced user interface controls. + +Telerik UI for Blazor targets WAI-ARIA version 1.2. The [Compliance Table](slug:accessibility-compliance#compliance-table) provides links to documentation articles, which describe the WAI-ARIA attributes of each applicable component. + +## Keyboard Navigation + +Normally, users can use the keyboard only to focus and navigate to HTML links, buttons, and form inputs. Telerik UI for Blazor has gone to the next level and provides focusable and navigable components, even though they represent complex structures. Users can use the keyboard to invoke actions such as opening DropDownLists, sorting Grid columns, resizing Splitter panes, and so on. Keyboard accessibility is part of WCAG. + +The keyboard support follows the normal flow of the web page content. Use the `Tab` key to focus a component and then use specific keyboard shortcuts to trigger specific actions. For example, use the arrow keys to move across cells in the Grid or hit `Enter` to invoke a button click. + +Most components represent a single tab stop. Once users reach and focus a component, they can leave it with a single `Tab` key press. If the component is more complex, users can walk through its inner elements with the arrow keys, for example, Grid cells, Menu items, Toolbar buttons. Some complex components can accommodate multiple other components. For example, the Grid can host a Toolbar and a Pager. In this case, tab to move the focus from one nested component to another. + +### Types of Keyboard Support + +The Telerik UI for Blazor components may provide enhanced, standard, or no keyboard support. See the [compliance table](slug:accessibility-compliance#compliance-table) for component-specific information. + +* *Standard keyboard support* implies similar keyboard navigation capabilities as standard HTML elements. For example, the Button components support `Enter` and `Space` for triggering clicks. All components with standard keyboard support are reachable through the `Tab` key and provide focus styles. +* *Enhanced keyboard support* builds on top of the standard key combinations and provides additional built-in shortcuts for improved flexibility and user experience. +* Components with no keyboard support may serve a purely visual purpose, or be containers with no available interaction. + +### Right-to-Left Support + +When using [right-to-left text direction](slug:rtl-support), the keyboard shortcuts for the components remain unchanged. The left and right arrow keys reverse their behavior to be consistent with the RTL mode. + +## Color Contrast + +WCAG sections 1.4.3 Contrast (Minimum) and 1.4.6 Contrast (Enhanced) define contrast ratios for accessibility compliance. The built-in [*Default Ocean Blue A11y* theme swatch](https://www.telerik.com/design-system/docs/themes/kendo-themes/default/swatches/#ocean-blue-accessibility-swatch) in Telerik UI for Blazor conforms to WCAG Level AA, except success criterion 1.4.11 Non-text Contrast in the ColorPalette component. + +You can [obtain and use the Default Ocean Blue A11y swatch](slug:themes-overview#what-is-a-swatch) starting from the following component and theme versions: + +* [Telerik UI for Blazor version 4.0.1](https://www.telerik.com/support/whats-new/blazor-ui/release-history/ui-for-blazor-4-0-1) +* [Themes version 6.0.3](https://github.com/telerik/kendo-themes/releases/tag/v6.0.3). Check section [Theme Version Compatibility](slug:themes-overview#compatibility-and-maintenance) on how to align Telerik UI for Blazor versions with theme versions. + +## Development Practices + +When implementing a Telerik Blazor component, the team: + +* Benefits from the know-how of dedicated accessibility professionals at Progress Software. +* Follows the WCAG standard and WAI-ARIA specification to lay the right foundation for the component accessibility. +* Implements automated unit tests to guarantee accessible and semantically correct rendering. +* Localizes messages for labels, titles, and other elements. +* Manually tests the component with regard to its keyboard navigation and usage with screen readers. + +### Screen Readers + +There are a lot of existing screen readers, for example: + +* Apple VoiceOver +* JAWS +* Microsoft Narrator +* NVDA +* and many others + +Each of them provides a different level of interoperability with the different web browsers, and some combinations may handle dynamic web content more effectively. Telerik UI for Blazor aims to comply with official accessibility standards and is not able to provide built-in fixes for missing features or non-standard behaviors in assistive technologies. + +Telerik UI for Blazor components are tested in the following environments: + +| Browser | Screen Reader | +| --- | --- | +| Chrome | JAWS | +| Microsoft Edge | JAWS | +| Firefox | NVDA | + +## Next Steps + +* [Review Telerik UI for Blazor Accessibility Compliance Table](slug:accessibility-compliance#compliance-table) +* [Download Telerik UI for Blazor Accessibility Conformance Report (ACR)](slug:accessibility-compliance#accessibility-conformance-report) diff --git a/accessibility/wcag-section-508-wai-aria.md b/accessibility/wcag-section-508-wai-aria.md deleted file mode 100644 index 033b09edba..0000000000 --- a/accessibility/wcag-section-508-wai-aria.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -title: WCAG, Section 508, WAI-ARIA -page_title: WCAG, Section 508, WAI-ARIA -description: Accessibility standards - WCAG, Section 508, WAI-ARIA. -slug: accessibility-standards -tags: telerik,blazor,accessibility,standards -published: True -position: 1 ---- - -# WCAG, Section 508, WAI-ARIA - -There are several standards, policies and principles that govern how accessible applications and components are created. This article offers an overview of them. For a list of the accessibility compliance levels support provided by the Telerik UI for Blazor components see the [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) article. - -In this article you will find information on the general topics of accessibility: - - -* [Standards and Policies](#standards-and-policies) - * [Section 508](#section-508) - * [W3C Web Content Accessibility Guidelines (WCAG) 2.2](#w3c-web-content-accessibility-guidelines-wcag-2-2) -* [Technical Specifications](#technical-specifications) - * [WAI-ARIA](#wai-aria) - * [Keyboard Navigation](#keyboard-navigation) -* [Accessibility Compliance Components Table](#accessibility-compliance-components-table) - - -## Standards and Policies - -Accessible websites and applications normally comply with some or all of the following standards: - -* [Section 508](#section-508) -* [W3C Web Content Accessibility Guidelines (WCAG) 2.2](#w3c-web-content-accessibility-guidelines-wcag-2-2) - -### Section 508 - -Since 1998, Section 508 is part of the [U.S. Rehabilitation Act of 1973](https://en.wikipedia.org/wiki/Rehabilitation_Act_of_1973). Section 508 represents a set of accessibility standards which were defined by the U.S. General Services Administration (GSA) and which initially applied to Federal agencies only with the aim to ensure that their electronic and information technology is accessible to people with disabilities. - -[In 2017, Section 508 was reorganized](https://www.access-board.gov/guidelines-and-standards/communications-and-it/about-the-ict-refresh/overview-of-the-final-rule) to meet and reflect recent communication technology innovations and nowadays the Section 508 guidelines impact not only all U.S. Federal agencies, but also affect any company which does business with a Federal agency. Such companies include vendors, private contractors, financial industry, healthcare and legal organizations, and partners of those agencies which operate in the United States or abroad. - -For more information, refer to: - -* [Rehabilitation Act of 1973 Section 508 (Latest Amendment)](https://www.access-board.gov/the-board/laws/rehabilitation-act-of-1973#508) -* [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) - - -### W3C Web Content Accessibility Guidelines (WCAG) 2.2 - -The Web Content Accessibility Guidelines (WCAG) which are set by the World Wide Web Consortium (W3C) define recommendations for making web content accessible to people with physical and cognitive disabilities. WCAG defines accessibility principles with their respective success criteria. Depending on the implemented success criteria by a web application, the WCAG provide the A, `AA`, and AAA levels of accessibility conformance. - -For more information, refer to: - -* [WCAG 2 Quick Reference Guide](https://www.w3.org/WAI/WCAG21/quickref/) -* [WCAG 2.2 Guidelines](https://www.w3.org/TR/WCAG22) -* [Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements) -* [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) - - -## Technical Specifications - -* [WAI-ARIA](#wai-aria) -* [Keyboard navigation](#keyboard-navigation) - -### WAI-ARIA - -WAI-ARIA is a set of technical specifications which were developed by the W3C and which provide the semantics for the assistive technologies to access and interpret web content and web applications. The WAI-ARIA recommendations (standards) divide the semantics into roles and into states and properties which those roles support. For example, a [`checkbox` role](https://www.w3.org/TR/wai-aria-1.1/#checkbox) supports the [`aria-checked`](https://www.w3.org/TR/wai-aria-1.1/#aria-checked) state which indicates whether a checkbox, radio button, or a similar UI element is checked. - -The WAI-ARIA framework targets web developers who create web applications by using AJAX, scripting, and other rich application techniques. - -For more information, refer to: - -* [Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria-1.1/) -* [WAI-ARIA Role Definitions](https://www.w3.org/TR/wai-aria-1.1/#role_definitions) -* [WAI-ARIA State and Property Definitions](https://www.w3.org/TR/wai-aria-1.1/#state_prop_def) -* [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) - -### Keyboard Navigation - -By default, users can only navigate to links, buttons, and form controls with a keyboard. The navigation order in which interactive items receive keyboard focus has to be logical and intuitive. Generally, keyboard navigation logic needs to follow the visual horizontal and vertical flow of the page. For example, left to right and top to bottom, header first followed by the main and then the page navigation. - -[Keyboard accessibility](https://www.w3.org/WAI/WCAG21/quickref/#keyboard-accessible) is a category under the [WCAG Operable principle](https://www.w3.org/WAI/WCAG21/quickref/#principle2). - -In WCAG 2.2, the keyboard accessible category provides the following success criteria: - -* [Keyboard](https://www.w3.org/WAI/WCAG21/quickref/#keyboard) -* [No Keyboard Trap](https://www.w3.org/WAI/WCAG21/quickref/#no-keyboard-trap) -* [Keyboard (No Exception)](https://www.w3.org/WAI/WCAG21/quickref/#keyboard-no-exception) -* [Character Key Shortcuts](https://www.w3.org/WAI/WCAG21/quickref/#character-key-shortcuts) - -See the [Keyboard Support in Telerik UI for Blazor]({%slug accessibility-keyboard-navigation%}) article for more details on using the Telerik components with the keyboard. - -> The described level of compliance in the table below is achievable with the [**Ocean Blue Sass Swatch**]({%slug themes-accessibility-swatch%}) and the **Default Ocean Blue A11Y**. - -### Accessibility Compliance Components Table -The following table lists the Section 508 and WCAG 2 compliance levels of support for the Blazor UI components. - -|Component |508|WCAG 2.2| Accessibility Example | Accessibility Documentation | -|:--- |:---|:---|:---|:--- -|`AutoComplete`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/autocomplete/keyboard-navigation) | [Documentation]({%slug autocomplete-wai-aria-support%}) | -|`Barcodes`|`No`|`n/a`| `n/a` | `n/a` | -|`Breadcrumb`|`Yes`|`AAA`| [Demo](https://demos.telerik.com/blazor-ui/breadcrumb/keyboard-navigation) | [Documentation]({%slug breadcrumb-wai-aria-support%}) | -|`Button`|`Yes`|`AAA`| [Demo](https://demos.telerik.com/blazor-ui/button/keyboard-navigation) | [Documentation]({%slug button-wai-aria-support%}) | -|`ButtonGroup`|`Yes`|`AAA`| [Demo](https://demos.telerik.com/blazor-ui/buttongroup/keyboard-navigation) | [Documentation]({%slug buttongroup-wai-aria-support%}) | -|`Calendar`|`Yes`|`AAA`| [Demo](https://demos.telerik.com/blazor-ui/calendar/keyboard-navigation) | [Documentation]({%slug calendar-wai-aria-support%}) | -|`Card`|`No`|`n/a`| `n/a` | `n/a` | -|`Carousel`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/carousel/keyboard-navigation) | [Documentation]({%slug carousel-wai-aria-support%}) | -|`Charts`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/chart/keyboard-navigation) | Documentation | -|`CheckBox`|`Yes`|`AA`| `n/a` | [Documentation]({%slug checkbox-wai-aria-support%}) | -|`ChunkProgressBar`|`Yes`|`AA`| `n/a` | [Documentation]({%slug chunkprogressbar-wai-aria-support%}) | -|`ColorGradient`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/colorgradient/keyboard-navigation) | [Documentation]({%slug colorgradient-wai-aria-support%}) | -|`ColorPalette`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/colorpalette/keyboard-navigation) | [Documentation]({%slug colorpalette-wai-aria-support%}) | -|`ColorPicker`|`Yes`|`AA`| `n/a` | [Documentation]({%slug colorpicker-wai-aria-support%}) | -|`ComboBox`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/combobox/keyboard-navigation) | [Documentation]({%slug combobox-wai-aria-support%}) | -|`Context Menu`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/contextmenu/keyboard-navigation) | [Documentation]({%slug contextmenu-wai-aria-support%}) | -|`Date Input`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/dateinput/keyboard-navigation) | [Documentation]({%slug dateinput-wai-aria-support%}) | -|`Date Picker`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/datepicker/keyboard-navigation) | [Documentation]({%slug datepicker-wai-aria-support%}) | -|`DateRange Picker`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/daterangepicker/keyboard-navigation) | [Documentation]({%slug daterangepicker-wai-aria-support%}) | -|`DateTime Picker`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/datetimepicker/keyboard-navigation) | [Documentation]({%slug datetimepicker-wai-aria-support%}) | -|`Dialog`|`Yes`|`AA`| `n/a` | [Documentation]({%slug dialog-wai-aria-support%}) | -|`Drawer`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/drawer/keyboard-navigation) | [Documentation]({%slug drawer-wai-aria-support%}) | -|`DropDownList`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/dropdownlist/keyboard-navigation) | [Documentation]({%slug dropdownlist-wai-aria-support%}) | -|`Editor`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/editor/keyboard-navigation) | [Documentation]({%slug editor-wai-aria-support%}) | -|`FileManager`|`No`|`n/a`| `n/a` | `n/a` | -|`FileSelect`|`No`|`n/a`| `n/a` | `n/a` | -|`Filter`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/filter/keyboard-navigation) | [Documentation]({%slug filter-wai-aria-support%}) | -|`FlatColorPicker`|`Yes`|`AA`| `n/a` | [Documentation]({%slug flatcolorpicker-wai-aria-support%}) | -|`FloatingLabel`|`No`|`n/a`| `n/a` | `n/a` | -|`Form`|`No`|`n/a`| `n/a` | `n/a` | -|`Gantt`|`Yes`|`AA`| `n/a` | [Documentation]({%slug gantt-wai-aria-support%}) | -|`Gauges`|`No`|`n/a`| `n/a` | `n/a` | -|`Grid`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/grid/keyboard-navigation) | [Documentation]({%slug grid-wai-aria-support%}) | -|`Grid Layout`|`No`|`n/a`| `n/a` | `n/a` | -|`ListView`|`Yes`|`AAA`| [Demo](https://demos.telerik.com/blazor-ui/listview/keyboard-navigation) | [Documentation]({%slug listview-wai-aria-support%}) | -|`Loader`|`No`|`n/a`| `n/a` | `n/a` | -|`LoaderContainer`|`No`|`n/a`| `n/a` | `n/a` | -|`Map`|`No`|`n/a`| `n/a` | `n/a` | -|`MaskedTextbox`|`Yes`|`AA`| `n/a` | [Documentation]({%slug maskedtextbox-wai-aria-support%}) | -|`MediaQuery`|`No`|`n/a`| `n/a` | `n/a` | -|`Menu`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/menu/keyboard-navigation) | [Documentation]({%slug menu-wai-aria-support%}) | -|`MultiColumnComboBox`|`No`|`n/a`| `n/a` | `n/a` | -|`MultiSelect`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/multiselect/keyboard-navigation) | [Documentation]({%slug multiselect-wai-aria-support%}) | -|`Notification`|`Yes`|`AA`| `n/a` | [Documentation]({%slug notification-wai-aria-support%}) | -|`NumericTextbox`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/numericTextbox/keyboard-navigation) | [Documentation]({%slug numerictextbox-wai-aria-support%}) | -|`Pager`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/pager/keyboard-navigation) | [Documentation]({%slug pager-wai-aria-support%}) | -|`PanelBar`|`No`|`n/a`| `n/a` | `n/a` | -|`PDF Viewer`|`No`|`n/a`| `n/a` | `n/a` | -|`ProgressBar`|`Yes`|`AA`| `n/a` | [Documentation]({%slug progressbar-wai-aria-support%}) | -|`RadioGroup`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/radiogroup/keyboard-navigation) | [Documentation]({%slug radiogroup-wai-aria-support%}) | -|`Range Slider`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/rangeslider/keyboard-navigation) | [Documentation]({%slug rangeslider-wai-aria-support%}) | -|`Scheduler`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/scheduler/keyboard-navigation) | [Documentation]({%slug scheduler-wai-aria-support%}) | -|`Signature`|`Yes`|`AA`| `n/a` | [Documentation]({%slug signature-wai-aria-support%}) | -|`Skeleton`|`No`|`n/a`| `n/a` | `n/a` | -|`Slider`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/slider/keyboard-navigation) | [Documentation]({%slug slider-wai-aria-support%}) | -|`SplitButton`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/splitbutton/keyboard-navigation) | [Documentation]({%slug splitbutton-wai-aria-support%}) | -|`Splitter`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/splitter/keyboard-navigation) | [Documentation]({%slug splitter-wai-aria-support%}) | -|`Stack Layout`|`No`|`n/a`| `n/a` | `n/a` | -|`Stepper`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/stepper/keyboard-navigation) | [Documentation]({%slug stepper-wai-aria-support%}) | -|`Stock Chart`|`No`|`n/a`| `n/a` | `n/a` | -|`Switch`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/switch/keyboard-navigation) | [Documentation]({%slug switch-wai-aria-support%}) | -|`TabStrip`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/tabstrip/keyboard-navigation) | [Documentation]({%slug tabstrip-wai-aria-support%}) | -|`TextArea`|`Yes`|`AAA`| `n/a` | [Documentation]({%slug textarea-wai-aria-support%}) | -|`TextBox`|`Yes`|`AA`| `n/a` | [Documentation]({%slug textbox-wai-aria-support%}) | -|`TileLayout`|`Yes`|`AAA`| `n/a` | [Documentation]({%slug tilelayout-wai-aria-support%}) | -|`TimePicker`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/timepicker/keyboard-navigation) | [Documentation]({%slug timepicker-wai-aria-support%}) | -|`ToggleButton`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/togglebutton/keyboard-navigation) | [Documentation]({%slug togglebutton-wai-aria-support%}) | -|`ToolBar`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/toolbar/keyboard-navigation) | [Documentation]({%slug toolbar-wai-aria-support%}) | -|`Tooltip`|`Yes`|`AA`| `n/a` | [Documentation]({%slug tooltip-wai-aria-support%}) | -|`TreeList`|`No`|`n/a`| `n/a` | `n/a` | -|`TreeView`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/treeview/keyboard-navigation) | [Documentation]({%slug treeview-wai-aria-support%}) | -|`Upload`|`No`|`n/a`| `n/a` | `n/a` | -|`Window`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/window/keyboard-navigation) | [Documentation]({%slug window-wai-aria-support%}) | -|`Wizard`|`Yes`|`AA`| [Demo](https://demos.telerik.com/blazor-ui/wizard/keyboard-navigation) | [Documentation]({%slug wizard-wai-aria-support%}) | - -## See Also - - * [GSA Government-Wide Section 508 Accessibility Program](https://www.section508.gov/) - * [WCAG 2 Quick Reference Guide](https://www.w3.org/WAI/WCAG21/quickref/) - * [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices/) - * [WCAG Keyboard Accessible Category](https://www.w3.org/WAI/WCAG21/quickref/#keyboard-accessible) - * [Telerik UI for Blazor Accessibility Overview]({%slug accessibility-overview%}) - * [Telerik UI for Blazor Globalization Overview]({%slug globalization-overview%}) - * [Telerik UI for Blazor Accessibility Compliance]({%slug accessibility-compliance%}) - diff --git a/ai/copilot-extension.md b/ai/copilot-extension.md new file mode 100644 index 0000000000..1eda87f211 --- /dev/null +++ b/ai/copilot-extension.md @@ -0,0 +1,66 @@ +--- +title: Copilot Extension +page_title: Telerik Blazor GitHub Copilot Extension +description: Learn how to add and use the Telerik Blazor GitHub Copilot extension as a Blazor AI coding assistant and code generator for better developer productivity. The Telerik Blazor GitHub Copilot extension provides proprietary context about Telerik UI for Blazor to AI-powered software. +slug: ai-copilot-extension +tags: telerik,blazor,ai +published: True +position: 10 +--- + +# Telerik Blazor GitHub Copilot Extension + +The Telerik Blazor [GitHub Copilot](https://github.com/features/copilot) extension provides proprietary context for the [Telerik UI for Blazor components](https://www.telerik.com/blazor-ui). The extension works as a Blazor AI code generator and can help you reach new levels of developer productivity. You can get useful tips and generate tailored code snippets that include Telerik UI for Blazor components and API. + +## Prerequisites + +To use the Telerik GitHub Copilot extension for Blazor, you need to have: + +* An active [GitHub Copilot](https://github.com/features/copilot) subscription. You can enable or configure GitHub Copilot on the [Copilot Settings page in your GitHub account](https://github.com/settings/copilot). +* A [Telerik user account](https://www.telerik.com/account/). +* An active [DevCraft or Telerik UI for Blazor license](https://www.telerik.com/purchase/blazor-ui) or a [Telerik UI for Blazor trial](https://www.telerik.com/blazor-ui). +* A [Blazor application that includes Telerik UI for Blazor](slug:blazor-overview#getting-started). +* Using the latest version of your [Copilot-enabled app](https://docs.github.com/en/copilot/building-copilot-extensions/about-building-copilot-extensions#supported-clients-and-ides) is recommended (for example, Visual Studio or VS Code). + +## Installation + +To install the Telerik Blazor Copilot extension: + +1. Go to the [TelerikBlazor GitHub App](https://github.com/apps/telerikblazor) page and click the **Install** button. If you have already installed the extension, you will see a **Configure** button instead. +1. You will see a list that includes your GitHub account and all GitHub organizations that you are part of. Normally, select your GitHub account. +1. Click the **Install & Authorize** button. This will authorize the GitHub Copilot extension to integrate with your GitHub account. +1. Enter your GitHub password. +1. You will be redirected to telerik.com. Enter your Telerik account credentials if prompted. This will authorize the GitHub Copilot extension to integrate with your Telerik account. +1. Upon successful Telerik authentication, you will be redirected once again to a page that confirms successful Copilot extension installation. +1. Restart your [Copilot-enabled apps](https://docs.github.com/en/copilot/building-copilot-extensions/about-building-copilot-extensions#supported-clients-and-ides) (for example, Visual Studio and VS Code). +1. Start a new chat session in Copilot. + +You can also start the installation from the Telerik UI for Blazor extensions for [Visual Studio](slug:getting-started-vs-integration-ai-configuration#install-telerik-blazor-copilot-extension) and [VS Code](slug:getting-started-vs-code-integration-ai-configuration). Then, continue the installation from step 2. + +## Usage + +To use the Telerik Blazor Copilot extension: + +1. Open the GitHub Copilot chat window in your [Copilot-enabled app](https://docs.github.com/en/copilot/building-copilot-extensions/about-building-copilot-extensions#supported-clients-and-ides) (for example, Visual Studio or VS Code). +1. Make sure you are in **Ask** mode and not in **Edit** or **Agent** mode. The Edit and Agent modes do not use the Telerik Copilot extension. However, the Agent mode can use the [Telerik Blazor MCP server](slug:ai-mcp-server). +1. Start your prompt with `@telerikblazor` and type your request. Make sure that `@telerikblazor` is recognized and highlighted, otherwise the extension may not be installed. +1. Verify that you see a label similar to **TelerikBlazor working...** or **TelerikBlazor generating response...** in the output. +1. Grant permission to the Telerik Blazor extension to read your workspace files. +1. If you want to prompt for information or code that are not related to your previous prompts, it is a good practice to start a new session in a new chat window, so that the context is not polluted by irrelevant old information. + +### Sample Prompts + +The following list describes how your prompts may look like: + +* "`@telerikblazor` Generate a Grid with sorting and paging enabled. Bind the Grid to a Person model and provide dummy data." +* "`@telerikblazor` Generate a Telerik ComboBox for Blazor that shows a list of products. Create a Product class and generate sample data." +* "`@telerikblazor` Show me sample code for a Telerik Blazor Grid with virtual scrolling for the rows and columns." + +## Number of Requests + +@[template](/_contentTemplates/common/ai-coding-assistant.md#number-of-requests) + +## See Also + +* [GitHub Copilot Tutorials](https://github.com/features/copilot/tutorials) +* [Telerik Blazor MCP Server](slug:ai-mcp-server) diff --git a/ai/mcp-server.md b/ai/mcp-server.md new file mode 100644 index 0000000000..97be23af25 --- /dev/null +++ b/ai/mcp-server.md @@ -0,0 +1,181 @@ +--- +title: MCP Server +page_title: Telerik Blazor MCP Server +description: Learn how to add and use the Telerik Blazor MCP Server as a Blazor AI coding assistant and code generator for better developer productivity. The Telerik Blazor MCP server provides proprietary context about Telerik UI for Blazor to AI-powered software. +slug: ai-mcp-server +tags: telerik,blazor,ai +published: True +position: 20 +--- + +# Telerik Blazor MCP Server + +The Telerik Blazor [MCP Server](https://modelcontextprotocol.io/introduction) lets you interact with AI and reach new levels of developer productivity. The MCP server provides proprietary context to AI-powered IDEs, apps and tools. You can use the Telerik Blazor MCP server for Blazor AI code generation and ask about [Telerik UI for Blazor components](https://www.telerik.com/blazor-ui), features, or general usage. You can successfully prompt more complex questions and tasks, and generate tailored code that includes Telerik UI for Blazor components and API. + +## Prerequisites + +To use the Telerik Blazor MCP server, you need: + +* [Node.js](https://nodejs.org/en) 18 or a newer version. +* A [compatible MCP client (IDE, code editor or app)](https://modelcontextprotocol.io/clients) that supports *MCP tools*. Using the latest version of the MCP client is highly recommended. +* A [Telerik user account](https://www.telerik.com/account/). +* An active [DevCraft or Telerik UI for Blazor license](https://www.telerik.com/purchase/blazor-ui) or a [Telerik UI for Blazor trial](https://www.telerik.com/blazor-ui). +* A [Blazor application that includes Telerik UI for Blazor](slug:blazor-overview#getting-started). + +## Installation + +There are two ways to install the Telerik Blazor MCP server: + +* Use a manual approach, which is described below. +* Use an automated process provided by the Telerik extensions for [Visual Studio](slug:getting-started-vs-integration-ai-configuration) and [VS Code](slug:getting-started-vs-code-integration-ai-configuration). + +To install the Telerik MCP server manually, use the documentation of your AI-powered MCP client. You can enable the MCP server for specific workspaces or globally. The sections below provide installation tips and examples for some popular MCP clients like [Visual Studio](#visual-studio), [VS Code](#vs-code), and [Cursor](#cursor). The generic settings of the Telerik Blazor MCP server are: + +* npm package name: `@progress/telerik-blazor-mcp` +* Type: `stdio` (standard input/output transport) +* Command: `npx` +* Arguments: `-y` +* Server name: `telerikBlazorAssistant` (depends on your preferences) +* Your [Telerik license key](#license-key) as an `env` parameter + +> * Do not use hyphens (`-`) or underscores (`_`) in the MCP server name in the MCP `.json` file, due to potential compatibility issues with some MCP clients such as Visual Studio or Windsurf. +> * Some MCP clients expect the MCP servers to be listed under a `servers` JSON key, while others expect `mcpServers`. +> * Some MCP clients expect an `mcp.json` file, while others like Visual Studio 2022 expect an `.mcp.json` file. + +### License Key + +To use the Telerik MCP Server, your configuration must provide your [Telerik licence key](slug:installation-license-key) as an `env` parameter in the MCP `.json` file. There are two options: + +* Use a `TELERIK_LICENSE_PATH` argument and point to your Telerik license file location. This approach is recommended, unless you are sharing your VS Code settings across different computers with different operating systems or user names. +* Use a `TELERIK_LICENSE` argument and paste your Telerik license key. Make sure to [update the license key](slug:installation-license-key#license-key-updates) when necessary. + +### Visual Studio + +For detailed instructions, refer to [Use MCP servers in Visual Studio](https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers). You can also install the Telerik Blazor MCP server through the [Telerik UI for Blazor Visual Studio extension](slug:getting-started-vs-integration-ai-configuration). + +> Early Visual Studio 17.14 versions require the Copilot Chat window to be open and active when you open a solution. Otherwise the Telerik MCP server is not used. + +To enable the Telerik MCP Server in a specific Blazor app, add a `.mcp.json` file to the solution folder. + +>caption .mcp.json + +````JSON.skip-repl +{ + "servers": { + "telerikBlazorAssistant": { + "type": "stdio", + "command": "npx", + "args": ["-y", "@progress/telerik-blazor-mcp@latest"], + "env": { + "TELERIK_LICENSE_PATH": "C:\\Users\\___\\AppData\\Roaming\\Telerik\\telerik-license.txt" + } + } + } +} +```` + +To enable global automatic discovery of the Telerik MCP Server in Visual Studio, add the above `.mcp.json` file to your user directory (`%USERPROFILE%`), for example, `C:\Users\____\.mcp.json`. + +> Once the Telerik MCP server is added, make sure that the `telerikBlazorAssistant` tool is [enabled (checked) in the Copilot Chat window's tool selection dropdown](https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers?view=vs-2022#configuration-example-with-github-mcp-server). The Telerik MCP server may get disabled and you may see "🔧10/11" in the selected tools dropdown when starting a new chat, changing threads, or relaunching Visual Studio. This is a known issue for MCPs that is being investigated. + +### VS Code + +For detailed instructions, refer to [Use MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/chat/mcp-servers). You can also install the Telerik Blazor MCP server through the [Telerik UI for Blazor VS Code extension](slug:getting-started-vs-code-integration-ai-configuration). + +> This section applies to VS Code 1.102.1 and newer versions. + +Make sure that [`chat.mcp.enabled`](vscode://settings/chat.mcp.enabled) is enabled in the VS Code settings. + +To enable the Telerik MCP Server in a specific [workspace](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server-to-your-workspace), Blazor app, or [globally](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server-to-your-user-configuration), add a `.vscode` folder with an `mcp.json` file at the root of the workspace, app, or your user folder, respectively. + +>caption .vscode/mcp.json + +````JSON.skip-repl +{ + "servers": { + "telerikBlazorAssistant": { + "type": "stdio", + "command": "npx", + "args": ["-y", "@progress/telerik-blazor-mcp@latest"], + "env": { + "TELERIK_LICENSE_PATH": "C:\\Users\\___\\AppData\\Roaming\\Telerik\\telerik-license.txt" + } + } + } +} +```` + +To use the Telerik MCP server in all workspaces and apps, make sure that [`chat.mcp.discovery.enabled`](vscode://settings/chat.mcp.discovery.enabled) is enabled in [`settings.json`](https://code.visualstudio.com/docs/configure/settings#_settings-json-file). + +>caption VS Code settings.json + +````JSON.skip-repl +{ + // ... + "chat.mcp.discovery.enabled": true, +} +```` + +### Cursor + +For detailed instructions, refer to [Model Context Protocol](https://docs.cursor.com/context/mcp). + +To [enable the Telerik MCP Server in a specific workspace, Blazor app, or globally](https://docs.cursor.com/context/mcp#using-mcp-json), add a `.cursor` folder with an `mcp.json` file at the root of the workspace, app, or your user folder, respectively. + +>caption .cursor/mcp.json + +````JSON.skip-repl +{ + "mcpServers": { + "telerikBlazorAssistant": { + "type": "stdio", + "command": "npx", + "args": ["-y", "@progress/telerik-blazor-mcp@latest"], + "env": { + "TELERIK_LICENSE_PATH": "C:\\Users\\___\\AppData\\Roaming\\Telerik\\telerik-license.txt" + } + } + } +} +```` + +## Usage + +To use the Telerik MCP Server: + +1. Start your prompt with one of the following: + * `telerik` + * `/telerik` + * `@telerik` + * `telerikblazor` + * `/telerikblazor` + * `@telerikblazor` +1. Confirm that the Telerik MCP server is used, because this doesn't happen deterministically. Look for a statement in the output, which is similar to: + * `Running telerikBlazorAssistant` (in VS Code) + * `Calling MCP tool telerikBlazorAssistant` (in Cursor) + + If the Telerik MCP server is not used even though it's installed and enabled, then try rephrasing your prompt and use another trigger syntax from the list in step 1. +1. Grant the Telerik tool permission to run for this session, workspace, or always. +1. If you want to prompt for information or code that are not related to your previous prompts, it is a good practice to start a new session in a new chat window, so that the context is not polluted by irrelevant old information. + +To increase the probability of the Telerik MVC Server being used, or to call it without the need to mention "telerik" explicitly, add custom instructions to your AI-powered tool. Here are examples for [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot#about-repository-custom-instructions-for-github-copilot-chat) and [Cursor](https://docs.cursor.com/context/rules). + +### Sample Prompts + +The following list describes how your prompts may look like: + +* "Telerik Generate a Blazor Grid with sorting and paging enabled. Bind the Grid to a Person model and provide dummy data." +* "Telerik Generate a ComboBox for Blazor that shows a list of products. Create a Product class and generate sample data." +* "Telerik Show me sample code for a Blazor Grid with virtual scrolling for the rows and columns." + +## Number of Requests + +@[template](/_contentTemplates/common/ai-coding-assistant.md#number-of-requests) + +## Connect to Local AI Model + +You can use the Telerik Blazor MCP server with local large language models (LLM). For example, run your local model through [Ollama](https://ollama.com) and use a third-party package such as [MCP-LLM Bridge](https://github.com/patruff/ollama-mcp-bridge) to connect the model to the Telerik MCP server. This will allow you to use the Telerik AI Coding Assistant without a cloud-based AI model. + +## See Also + +* [Telerik Blazor extension for GitHub Copilot](slug:ai-copilot-extension) diff --git a/ai/overview.md b/ai/overview.md new file mode 100644 index 0000000000..7994c31afd --- /dev/null +++ b/ai/overview.md @@ -0,0 +1,60 @@ +--- +title: Overview +page_title: Telerik Blazor AI Tooling Overview +description: Learn about the AI-powered developer tools that integrate with your IDE or code editor for greater productivity and enhanced developer experience. +slug: ai-overview +tags: telerik,blazor,ai +published: True +position: 1 +--- + +# Telerik Blazor AI Coding Assistant Overview + +The Telerik Blazor AI Coding Assistant improves your developer experience and increases your productivity when implementing Blazor apps that include Telerik UI for Blazor. The coding assistant is an AI code generator that provides proprietary context to AI models in order to produce higher quality code samples with the [Telerik UI for Blazor components](https://www.telerik.com/blazor-ui) and API. + +The Telerik AI Coding Assistant is integrated in: + +* The [Telerik Blazor GitHub Copilot Extension](slug:ai-copilot-extension) +* The [Telerik Blazor MCP Server](slug:ai-mcp-server) + +The major differences between these tools are: + +* The MCP server is more powerful and can handle more complex prompts that require several requests to the AI model. An MCP-enabled client like Cursor or GitHub Copilot in **Agent** mode can directly suggest changes to your app and even rebuild it to verify the new AI generated code. +* The responses of the GitHub Copilot extension may contain more explanations how to accomplish the task, and shorter or partial code snippets. When using the MCP server, the AI response is mostly code. + +## Getting Started + +To use the Telerik Blazor AI Coding Assistant, you need: + +* A [Telerik user account](https://www.telerik.com/account/). +* An active [DevCraft or Telerik UI for Blazor license](https://www.telerik.com/purchase/blazor-ui) or a [Telerik UI for Blazor trial](https://www.telerik.com/blazor-ui). +* A [Blazor application that includes Telerik UI for Blazor](slug:blazor-overview#getting-started). +* @[template](/_contentTemplates/common/ai-coding-assistant.md#number-of-requests) + +## Number of Requests + +The Telerik Blazor AI Conding Assistant allows the following maximum number of requests, depending on your [Telerik license type](https://www.telerik.com/purchase/faq/licensing-purchasing): + +* Perpetual licenses: 50 requests per year +* Subscription licenses: virtually unlimited number of requests with a fair use threshold of 300 requests per day +* Trial licenses: 300 requests per trial per year. Activating the same trial for a new release does not grant additional 300 requests. + +> All Telerik AI tools share a single request limit for your Telerik account. For example, the [Telerik Copilot extension](slug:ai-copilot-extension) and the [Telerik MCP server](slug:ai-mcp-server) both take up from the same usage quota. +> When using the Telerik MCP server, one prompt may trigger several requests, depending on the prompt complexity. + +## Privacy + +The Telerik Blazor AI Coding Assistant operates under the following conditions: + +* The Assistant does not have access to your workspace and application code. Note that when using the Telerik MCP server (or any other MCP server), the LLM generates parameters for the MCP server request, which may include parts of your application code. +* The Assistant does not use your prompts to train Telerik AI models. +* The Assistant does not generate the actual responses and has no access to these responses. The Assistant only provides a better context that helps your selected model (for example, GPT, Gemini, Claude) provide better responses. +* The Assistant does not associate your prompts to your Telerik user account. Your prompts and generated context are anonymized and stored for statistical and troubleshooting purposes. +* The Assistant stores metrics about how often and how much you use it in order to ensure compliance with the [allowed number of requests that correspond to your current license](#number-of-requests). + +Make sure to also get familiar with the terms and privacy policy of your selected AI model and AI client. + +## Next Steps + +* Install the [Telerik Blazor GitHub Copilot Extension](slug:ai-copilot-extension). +* Add the [Telerik Blazor MCP Server](slug:ai-mcp-server) to an MCP-enabled client. diff --git a/api_sort.rb b/api_sort.rb deleted file mode 100644 index 82a8dd7bcc..0000000000 --- a/api_sort.rb +++ /dev/null @@ -1,42 +0,0 @@ -filename = ARGV.first - -def sections_as_key_values(text, re) - text = text.strip - - keys = text.scan(re).reject { |value| value.empty? } - - values = text.split(re).reject { |value| value.empty? } - - raise "keys and values don't match" unless keys.size == values.size - - keys.each_with_index.map { |key, index| { :key => key, :value => values[index] } } -end - -markdown = File.read(filename) - -start = markdown.index("## ") - -head = markdown[0..start-1] - -markdown = markdown[start..-1] - -sections = sections_as_key_values(markdown, /^## .*/) - -File.open(filename, "w") do |file| - file.puts(head) - - sections.each do |section| - subsections = sections_as_key_values(section[:value], /^### .*/).sort { |a,b| a[:key] <=> b[:key] } - - file.puts(section[:key]) - file.puts() - - subsections.each do |subsection| - file.write(subsection[:key]) - file.puts() - file.puts() - file.puts(subsection[:value].strip) - file.puts() - end - end -end diff --git a/common-features/adaptive-rendering.md b/common-features/adaptive-rendering.md index cd5907d4e4..aecf8baa70 100644 --- a/common-features/adaptive-rendering.md +++ b/common-features/adaptive-rendering.md @@ -5,7 +5,7 @@ description: Explore how the components with popup elements can react to the cha slug: adaptive-rendering tags: telerik,blazor,adaptive,rendering,mobile published: True -position: 1 +position: 10 --- # Adaptive Rendering @@ -17,21 +17,23 @@ Telerik UI for Blazor supports adaptive rendering for the components that incorp * [Supported components](#supported-components) * [Basics](#basics) * [Rendering specifics](#rendering-specifics) +* [Customize the Default Adaptive Breakpoints](#customize-the-default-adaptive-breakpoints) * [Limitations](#limitations) ## Supported Components The adaptive rendering functionality is supported by the following components: -* [AutoComplete]({%slug autocomplete-overview%}) -* [ComboBox]({%slug components/combobox/overview%}) -* [DatePicker]({%slug components/datepicker/overview%}) -* [DateRangePicker]({%slug daterangepicker-overview%}) -* [DateTimePicker]({%slug components/datetimepicker/overview%}) -* [DropDownList]({%slug components/dropdownlist/overview%}) -* [MultiColumnComboBox]({%slug multicolumncombobox-overview%}) -* [MultiSelect]({%slug multiselect-overview%}) -* [TimePicker]({%slug components/timepicker/overview%}) +* [AutoComplete](slug:autocomplete-overview) +* [ColorPicker](slug:colorpicker-overview) +* [ComboBox](slug:components/combobox/overview) +* [DatePicker](slug:components/datepicker/overview) +* [DateRangePicker](slug:daterangepicker-overview) +* [DateTimePicker](slug:components/datetimepicker/overview) +* [DropDownList](slug:components/dropdownlist/overview) +* [MultiColumnComboBox](slug:multicolumncombobox-overview) +* [MultiSelect](slug:multiselect-overview) +* [TimePicker](slug:components/timepicker/overview) ## Basics @@ -65,14 +67,49 @@ Three breakpoints define the rendering options as follows: **Dimensions** | up to 500px | 501px to 768px | over 768px | **Rendering** | The popup is rendered as a fullscreen action sheet. | The popup is rendered as an action sheet docked to the bottom of the screen. | The popup is rendered as an animation container docked to the main element of the component. | +## Customize the Default Adaptive Breakpoints + +You can customize the [above-listed default adaptive breakpoints](#rendering-specifics) at the root level by configuring the [``](slug:rootcomponent-overview). To specify your desired breakpoints: + +1. Wrap the content of the `` (`@Body` and potentially other elements) in `` tag. +1. Add the `` component inside the [``](slug:rootcomponent-overview). +1. Add the `` component inside the `` tag and configure its properties: + +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) + +| Parameter | Type | Description | +| ----------- | ----------- | ----------- | +| `Small` | `int`
(`500`) | The upper boundary of the small threshold. Sets the `max-width` of the small media query in `px`. | +| `Medium` | `int`
(`768`) | The upper boundary of the medium threshold. Sets the `max-width` of the medium media query in `px`.| + +>caption Customize the default adaptive breakpoints + +
+````RAZOR +@* The below configuration sets the following thresholds: +- Small: 0 to 400px +- Medium: 401px to 900px +- Large: over 900px *@ + + + + + + + @Body + + +```` + ## Limitations -Some of the [supported components](#supported-components) allow custom values, for example, [ComboBox]({%slug components/combobox/custom-value%}) and [MultiColumnComboBox]({%slug multicolumncombobox-custom-value%}). Using custom values with `AdaptiveMode.Auto` is currently not supported. To expedite the development of this feature, vote for the related feature request in the Blazor Feedback Portal: [Support for custom values in `AdaptiveMode`](https://feedback.telerik.com/blazor/1611829-support-for-custom-values-in-adaptivemode). +Some of the [supported components](#supported-components) allow custom values, for example, [ComboBox](slug:components/combobox/custom-value) and [MultiColumnComboBox](slug:multicolumncombobox-custom-value). Using custom values with `AdaptiveMode.Auto` is supported in Telerik UI for Blazor version 9.0.0 and later. ## See also * [Live Demo: AutoComplete](https://demos.telerik.com/blazor-ui/autocomplete/adaptive) * [Live Demo: ComboBox](https://demos.telerik.com/blazor-ui/combobox/adaptive) +* [Live Demo: ColorPicker](https://demos.telerik.com/blazor-ui/colorpicker/appearance) * [Live Demo: DatePicker](https://demos.telerik.com/blazor-ui/datepicker/adaptive) * [Live Demo: DateRangePicker](https://demos.telerik.com/blazor-ui/daterangepicker/adaptive) * [Live Demo: DateTimePicker](https://demos.telerik.com/blazor-ui/datetimepicker/adaptive) diff --git a/common-features/cdn.md b/common-features/cdn.md index 7d1e6a9212..97c552a9b8 100644 --- a/common-features/cdn.md +++ b/common-features/cdn.md @@ -20,10 +20,10 @@ The CDN hosts two kinds of static client assets for the Telerik UI for Blazor co ## CSS Theme URLs -The [Telerik CSS themes]({%slug themes-overview%}) are available on two CDN hosts: +The [Telerik CSS themes](slug:themes-overview) are available on two CDN hosts: -* `unpkg.com` provides [all built-in theme swatches]({%slug themes-overview%}#swatch). The version number in the theme URL matches the version of the theme itself. Make sure to [use compatible theme and component versions]({%slug themes-overview%}#compatibility-and-maintenance). For example, use theme version `{{site.themesVersion}}` with UI for Blazor version `{{site.uiForBlazorLatestVersion}}`. -* `blazor.cdn.telerik.com` provides a limited set of popular [theme swatches]({%slug themes-overview%}#basics). The version number in the theme URL matches the version of the Telerik UI for Blazor components, for example, `{{site.uiForBlazorLatestVersion}}`. +* `unpkg.com` provides [all built-in theme swatches](slug:themes-overview#what-is-a-swatch). The version number in the theme URL matches the version of the theme itself. Make sure to [use compatible theme and component versions](slug:themes-overview#compatibility-and-maintenance). For example, use theme version `{{site.themesVersion}}` with UI for Blazor version `{{site.uiForBlazorLatestVersion}}`. +* `blazor.cdn.telerik.com` provides a limited set of popular [theme swatches](slug:themes-overview#basics). The version number in the theme URL matches the version of the Telerik UI for Blazor components, for example, `{{site.uiForBlazorLatestVersion}}`. ### UNPKG CDN @@ -31,7 +31,7 @@ The CSS file URLs on `unpkg.com` look like this: unpkg.com/@progress/kendo-theme-**<THEME-NAME>**@**<THEME-VERSION>**/dist/**<SWATCH-NAME>**.css -The separate [font icons]({%slug common-features-icons%}) stylesheet URL looks like this: +The separate [font icons](slug:common-features-icons) stylesheet URL looks like this: unpkg.com/@progress/kendo-font-icons@**<PACKAGE-VERSION>**/dist/index.css @@ -58,7 +58,7 @@ The CSS file URLs on `blazor.cdn.telerik.com` look like this: blazor.cdn.telerik.com/blazor/**<COMPONENT-VERSION>**/kendo-theme-**<THEME-NAME>**/swatches/**<THEME-NAME>**-**<SWATCH-NAME>**.css -The separate [font icons]({%slug common-features-icons%}) stylesheet URL looks like this: +The separate [font icons](slug:common-features-icons) stylesheet URL looks like this: blazor.cdn.telerik.com/blazor/**<COMPONENT-VERSION>**/kendo-font-icons/font-icons.css @@ -82,7 +82,7 @@ Here are a few examples: ## JavaScript URLs -The CDN hosts the [JavaScript (JSInterop) file of Telerik UI for Blazor]({%slug getting-started/what-you-need%}#javascript-file). The file URL looks like this: +The CDN hosts the [JavaScript (JSInterop) file of Telerik UI for Blazor](slug:getting-started/what-you-need#javascript-file). The file URL looks like this: blazor.cdn.telerik.com/blazor/**<COMPONENT-VERSION>**/telerik-blazor.min.js @@ -94,7 +94,7 @@ The CDN hosts the [JavaScript (JSInterop) file of Telerik UI for Blazor]({%slug ```` -> When using the `telerik-blazor.js` file from CDN and with a `defer` attribute, [start the client-side Blazor framework manually]({%slug getting-started/what-you-need%}#javascript-file). +> When using the `telerik-blazor.js` file from CDN and with a `defer` attribute, [start the client-side Blazor framework manually](slug:getting-started/what-you-need#javascript-file). ## Pros and Cons of Using CDN @@ -102,19 +102,19 @@ The CDN hosts the [JavaScript (JSInterop) file of Telerik UI for Blazor]({%slug The benefits of using a CDN in Blazor apps are: * Possible performance gains in the application loading time. Blazor apps are single page applications and browsers rely on cache by default, so this benefit is marginal and relates only to users that open the application for the first time. -* Avoidance of [browser caching issues after component version upgrades]({%slug common-kb-browser-cache-buster%}). The CSS and JS files change with every component version, and so do the CDN URLs. This URL change guarantees that browsers will reload the static assets. +* Avoidance of [browser caching issues after component version upgrades](slug:common-kb-browser-cache-buster). The CSS and JS files change with every component version, and so do the CDN URLs. This URL change guarantees that browsers will reload the static assets. The drawbacks of using a CDN are: -* Additional [component version upgrade steps]({%slug upgrade-tutorial%}). You must change the version number in the URL, otherwise the application can display broken UI or throw [JavaScript errors]({%slug troubleshooting-js-errors%}). -* A CDN is a critical external dependency for your app. Regardless of the claimed uptime, you must [implement a CDN fallback]({%slug common-kb-cdn-fallback%}) for cases when the CDN is not accessible to your users due to geographical, networking or system issues. +* Additional [component version upgrade steps](slug:upgrade-tutorial). You must change the version number in the URL, otherwise the application can display broken UI or throw [JavaScript errors](slug:troubleshooting-js-errors). +* A CDN is a critical external dependency for your app. Regardless of the claimed uptime, you must [implement a CDN fallback](slug:common-kb-cdn-fallback) for cases when the CDN is not accessible to your users due to geographical, networking or system issues. ## Next Steps -* [Implement CDN Fallback]({%slug common-kb-cdn-fallback%}) +* [Implement CDN Fallback](slug:common-kb-cdn-fallback) ## See also -* [Implement CDN Fallback]({%slug common-kb-cdn-fallback%}) +* [Implement CDN Fallback](slug:common-kb-cdn-fallback) diff --git a/common-features/data-binding/cloud-services.md b/common-features/data-binding/cloud-services.md index de14435860..a00a8cd2ab 100644 --- a/common-features/data-binding/cloud-services.md +++ b/common-features/data-binding/cloud-services.md @@ -12,7 +12,7 @@ position: 30 This article suggests options for data binding the Telerik Blazor components to cloud data services. Applicable scenarios may include serverless Blazor apps, or any web apps that use cloud data. The article provides an overview of a series of posts on the [Telerik Blazor blog](https://www.telerik.com/blogs/web-blazor) and links to specific points of interest. ->tip [Telerik Blazor components are datasource-agnostic]({%slug common-features-data-binding-overview%}#how-to-provide-data). The data-binding integrations below are not subject to technical support. +>tip [Telerik Blazor components are datasource-agnostic](slug:common-features-data-binding-overview#how-to-provide-data). The data-binding integrations below are not subject to technical support. This article contains the following sections, which map to blog posts from the series: diff --git a/common-features/data-binding/descriptors.md b/common-features/data-binding/descriptors.md index 7505abd354..d2dd439905 100644 --- a/common-features/data-binding/descriptors.md +++ b/common-features/data-binding/descriptors.md @@ -13,10 +13,10 @@ position: 10 This article explains how to retrieve the applied filtering, searching, sorting, and grouping criteria in Blazor components. The article applies to components that support these features. The components that offer one or all of the functionalities are: -* Components that [expose an `OnRead` event]({%slug common-features-data-binding-onread%}#components-with-onread-event), excluding the [ListView]({%slug listview-overview%}), because the ListView doesn't support built-in filtering, searching, sorting, and grouping. -* [Filter]({%slug filter-overview%}) -* [Gantt]({%slug gantt-overview%}) -* [TreeList]({%slug treelist-overview%}) +* Components that [expose an `OnRead` event](slug:common-features-data-binding-onread#components-with-onread-event), excluding the [ListView](slug:listview-overview), because the ListView doesn't support built-in filtering, searching, sorting, and grouping. +* [Filter](slug:filter-overview) +* [Gantt](slug:gantt-overview) +* [TreeList](slug:treelist-overview) ## Get Sort, Filter, Group, and Search Descriptors @@ -27,7 +27,7 @@ You can obtain the applied filtering, searching, sorting, and grouping criteria ### Through the OnRead Event -Use the [`Request` property]({%slug common-features-data-binding-onread%}#event-argument) of the [`OnRead` event argument object](/blazor-ui/api/Telerik.Blazor.Components.ReadEventArgs): +Use the [`Request` property](slug:common-features-data-binding-onread#event-argument) of the [`OnRead` event argument object](slug:Telerik.Blazor.Components.ReadEventArgs):
@@ -83,17 +83,17 @@ See the [complete example](#example-with-component-state) at the bottom of the a ## Filtering -The `args.Request.Filters` and the `args....State.FilterDescriptors` are collections of [`IFilterDescriptor`](/blazor-ui/api/Telerik.DataSource.IFilterDescriptor). To access the filtering criteria, such as the user input to filter by, cast each `IFilterDescriptor` from the respective collection: +The `args.Request.Filters` and the `args....State.FilterDescriptors` are collections of [`IFilterDescriptor`](slug:Telerik.DataSource.IFilterDescriptor). To access the filtering criteria, such as the user input to filter by, cast each `IFilterDescriptor` from the respective collection: -* If the component is of type input or select, such as the AutoComplete, ComboBox, DropDownList, MultiColumnComboBox, MultiSelect, cast the first `IFilterDescriptor` from the collection to [`FilterDescriptor`](/blazor-ui/api/telerik.datasource.filterdescriptor). -* Otherwise, cast each `IFilterDescriptor` from the `args.Request.Filters` collection, respectively from the `args....State.FilterDescriptors` collection, to [`CompositeFilterDescriptor`](/blazor-ui/api/Telerik.DataSource.CompositeFilterDescriptor). +* If the component is of type input or select, such as the AutoComplete, ComboBox, DropDownList, MultiColumnComboBox, MultiSelect, cast the first `IFilterDescriptor` from the collection to [`FilterDescriptor`](slug:telerik.datasource.filterdescriptor). +* Otherwise, cast each `IFilterDescriptor` from the `args.Request.Filters` collection, respectively from the `args....State.FilterDescriptors` collection, to [`CompositeFilterDescriptor`](slug:Telerik.DataSource.CompositeFilterDescriptor). ### CompositeFilterDescriptor The `CompositeFilterDescriptor` exposes: -* The [`FilterDescriptors`](/blazor-ui/api/telerik.datasource.compositefilterdescriptor#Telerik_DataSource_CompositeFilterDescriptor_FilterDescriptors) property. This property represents another collection of `IFilterDescriptor`. To access the filtering criteria, cast each `IFilterDescriptor` to a `FilterDescriptor`. When the Filter component gets groupable filtering, cast each `IFilterDescriptor` to another `CompositeFilterDescriptor`. -* The [`LogicalOperator`](/blazor-ui/api/telerik.datasource.compositefilterdescriptor#Telerik_DataSource_CompositeFilterDescriptor_LogicalOperator) property. This property can be either `AND` or `OR`. This property represents the logical operator applied between the instances in the `FilterDescriptors` collection. +* The [`FilterDescriptors`](slug:telerik.datasource.compositefilterdescriptor#Telerik_DataSource_CompositeFilterDescriptor_FilterDescriptors) property. This property represents another collection of `IFilterDescriptor`. To access the filtering criteria, cast each `IFilterDescriptor` to a `FilterDescriptor`. When the Filter component gets groupable filtering, cast each `IFilterDescriptor` to another `CompositeFilterDescriptor`. +* The [`LogicalOperator`](slug:telerik.datasource.compositefilterdescriptor#Telerik_DataSource_CompositeFilterDescriptor_LogicalOperator) property. This property can be either `AND` or `OR`. This property represents the logical operator applied between the instances in the `FilterDescriptors` collection. When the filtering is initiated, the `CompositeFilterDescriptor` properties get different values depending on the filter mode: @@ -112,16 +112,16 @@ The searching criteria in a Grid or TreeList are stored in an individual `IFilte ## Sorting -The sorting criteria in a Grid, TreeList or Gantt are stored in a collection of [`SortDescriptor`](/blazor-ui/api/telerik.datasource.sortdescriptor) objects. Each `SortDescriptor` instance gives access to: +The sorting criteria in a Grid, TreeList or Gantt are stored in a collection of [`SortDescriptor`](slug:telerik.datasource.sortdescriptor) objects. Each `SortDescriptor` instance gives access to: * The `Member`—The field where the user sorts. * The `SortDirection`—The sort direction for this sort descriptor. -When the [`SortMode`](/blazor-ui/api/Telerik.Blazor.SortMode) is `Multiple`, you may need to consider the order of the `SortDescriptor` instances. The first applied sorting criteria take precedence over all others. If there are equal values in the first sorted items, then those items are sorted by the following sorting criteria. +When the [`SortMode`](slug:Telerik.Blazor.SortMode) is `Multiple`, you may need to consider the order of the `SortDescriptor` instances. The first applied sorting criteria take precedence over all others. If there are equal values in the first sorted items, then those items are sorted by the following sorting criteria. ## Grouping -Тhe grouping criteria for each group are stored in an individual collection of [`GroupDescriptor`](/blazor-ui/api/telerik.datasource.groupdescriptor) objects. The `GroupDescriptor` class inherits the `SortDescriptor` class and gives access to the same properties as the `SortDescriptor` class. +Тhe grouping criteria for each group are stored in an individual collection of [`GroupDescriptor`](slug:telerik.datasource.groupdescriptor) objects. The `GroupDescriptor` class inherits the `SortDescriptor` class and gives access to the same properties as the `SortDescriptor` class. The user may group by multiple fields. The groups for subsequent fields will be nested within their parent groups. The grouping criteria from the parent group are stored in the first `GroupDescriptor` instance from the collection. @@ -335,13 +335,13 @@ You can obtain the FilterDescriptor, SearchFilter, SortDescriptor, and GroupDesc ## See Also -* [AutoComplete OnRead Event]({%slug autocomplete-events%}#onread) -* [ComboBox OnRead Event]({%slug components/combobox/events%}#onread) -* [DropDownList OnRead Event]({%slug components/dropdownlist/events%}#onread) -* [Filter Overview]({%slug filter-overview%}) -* [Gantt State]({%slug gantt-state%}) -* [Grid OnRead Event]({%slug components/grid/manual-operations%}) -* [Grid State]({%slug grid-state%}) -* [MultiColumnComboBox OnRead Event]({%slug multicolumncombobox-events%}#onread) -* [MultiSelect OnRead Event]({%slug multiselect-events%}#onread) -* [TreeList State]({%slug treelist-state%}) \ No newline at end of file +* [AutoComplete OnRead Event](slug:autocomplete-events#onread) +* [ComboBox OnRead Event](slug:components/combobox/events#onread) +* [DropDownList OnRead Event](slug:components/dropdownlist/events#onread) +* [Filter Overview](slug:filter-overview) +* [Gantt State](slug:gantt-state) +* [Grid OnRead Event](slug:components/grid/manual-operations) +* [Grid State](slug:grid-state) +* [MultiColumnComboBox OnRead Event](slug:multicolumncombobox-events#onread) +* [MultiSelect OnRead Event](slug:multiselect-events#onread) +* [TreeList State](slug:treelist-state) \ No newline at end of file diff --git a/common-features/data-binding/observable-data.md b/common-features/data-binding/observable-data.md index 68f57d2a02..c8c59f2098 100644 --- a/common-features/data-binding/observable-data.md +++ b/common-features/data-binding/observable-data.md @@ -32,34 +32,34 @@ In this article: The following components support observable data for their `Data` parameter. Note that observable data is not supported with manual data binding via the `OnRead` event. -* [AutoComplete]({%slug autocomplete-refresh-data%}) +* [AutoComplete](slug:autocomplete-refresh-data) -* [Carousel]({%slug carousel-refresh-data%}) +* [Carousel](slug:carousel-refresh-data) -* [ComboBox]({%slug combobox-refresh-data%}) +* [ComboBox](slug:combobox-refresh-data) -* [DropDownList]({%slug dropdownlist-refresh-data%}) +* [DropDownList](slug:dropdownlist-refresh-data) -* [Grid documentation]({%slug grid-refresh-data%}), [live demo](https://demos.telerik.com/blazor-ui/grid/observable-data) +* [Grid documentation](slug:grid-refresh-data), [live demo](https://demos.telerik.com/blazor-ui/grid/observable-data) -* [ListView]({%slug listview-refresh-data%}) +* [ListView](slug:listview-refresh-data) -* [MultiSelect]({%slug multiselect-refresh-data%}) +* [MultiSelect](slug:multiselect-refresh-data) -* [TreeList]({%slug treelist-refresh-data%}) +* [TreeList](slug:treelist-refresh-data) -* [TreeView]({%slug treeview-refresh-data%}) +* [TreeView](slug:treeview-refresh-data) You can refresh other components that do not support observable data by creating a [New collection reference](#refresh-data). -* [Scheduler]({%slug scheduler-refresh-data%}) +* [Scheduler](slug:scheduler-refresh-data) -* [Menu]({%slug menu-refresh-data%}) +* [Menu](slug:menu-refresh-data) -* [Drawer]({%slug drawer-refresh-data%}) +* [Drawer](slug:drawer-refresh-data) -* [ContextMenu]({%slug context-menu-refresh-data%}) +* [ContextMenu](slug:context-menu-refresh-data) ## See Also diff --git a/common-features/data-binding/onread.md b/common-features/data-binding/onread.md index 4d42293bf3..266de66b87 100644 --- a/common-features/data-binding/onread.md +++ b/common-features/data-binding/onread.md @@ -36,12 +36,12 @@ Large amounts of data require loading in chunks and on demand. This improves the `OnRead` allows full control over the data operations. For example, it is possible to use custom sorting and filtering algorithms, if the built-in ones do not fit a given scenario. Here are just a few examples, but there are many more possible scenarios: -* [Search by multiple data fields in ComboBox and DropDownList]({%slug dropdowns-kb-search-in-multiple-fields%}) -* [Search in hidden Grid columns]({%slug grid-kb-search-in-hidden-fields%}) -* [Debounce Grid data requests]({%slug grid-kb-debounce-operations%}) -* [Debounce ComboBox filter requests]({%slug combo-kb-debounce-onread%}) +* [Search by multiple data fields in ComboBox and DropDownList](slug:dropdowns-kb-search-in-multiple-fields) +* [Search in hidden Grid columns](slug:grid-kb-search-in-hidden-fields) +* [Debounce Grid data requests](slug:grid-kb-debounce-operations) +* [Debounce ComboBox filter requests](slug:combo-kb-debounce-onread) -`OnRead` enables [data binding to **OData** services]({%slug common-kb-odata%}). +`OnRead` enables [data binding to **OData** services](slug:common-kb-odata). `OnRead` also allows the application to know the exact data items, which the user is currently seeing. @@ -54,20 +54,20 @@ Each component name points to component-specific `OnRead` documentation and exam | Component | Supports Paging | Supports Virtualization | | --- | --- | --- | -| [AutoComplete]({%slug autocomplete-events%}#onread) | - | [AutoComplete virtualization]({%slug autocomplete-virtualization%}) | -| [ComboBox]({%slug components/combobox/events%}#onread) | - | [ComboBox virtualization]({%slug combobox-virtualization%}) | -| [DropDownList]({%slug components/dropdownlist/events%}#onread) | - | [DropDownList virtualization]({%slug dropdownlist-virtualization%}) | -| [Grid]({%slug components/grid/manual-operations%}) | [Grid paging]({%slug components/grid/features/paging%}) | [Grid row virtualization]({%slug components/grid/virtual-scrolling%}) | -| [ListView]({%slug listview-manual-operations%}) | [ListView paging]({%slug listview-paging%}) | - | -| [MultiColumnComboBox]({%slug multicolumncombobox-events%}#onread) | - | [MultiColumnComboBox virtualization]({%slug multicolumncombobox-virtualization%}) | -| [MultiSelect]({%slug multiselect-events%}#onread) | - | [MultiSelect virtualization]({%slug multiselect-virtualization%}) | +| [AutoComplete](slug:autocomplete-events#onread) | - | [AutoComplete virtualization](slug:autocomplete-virtualization) | +| [ComboBox](slug:components/combobox/events#onread) | - | [ComboBox virtualization](slug:combobox-virtualization) | +| [DropDownList](slug:components/dropdownlist/events#onread) | - | [DropDownList virtualization](slug:dropdownlist-virtualization) | +| [Grid](slug:components/grid/manual-operations) | [Grid paging](slug:components/grid/features/paging) | [Grid row virtualization](slug:components/grid/virtual-scrolling) | +| [ListView](slug:listview-manual-operations) | [ListView paging](slug:listview-paging) | - | +| [MultiColumnComboBox](slug:multicolumncombobox-events#onread) | - | [MultiColumnComboBox virtualization](slug:multicolumncombobox-virtualization) | +| [MultiSelect](slug:multiselect-events#onread) | - | [MultiSelect virtualization](slug:multiselect-virtualization) | -Components like the [**TreeList**]({%slug treelist-data-binding-load-on-demand%}) and the [**TreeView**]({%slug components/treeview/data-binding/load-on-demand%}) don't have an `OnRead` event. Instead, they load data on demand via `OnExpand` events. +Components like the [**TreeList**](slug:treelist-data-binding-load-on-demand) and the [**TreeView**](slug:components/treeview/data-binding/load-on-demand) don't have an `OnRead` event. Instead, they load data on demand via `OnExpand` events. ## Event Argument -The `OnRead` event handler receives an argument, which inherits from [`ReadEventArgs`](/blazor-ui/api/Telerik.Blazor.Components.ReadEventArgs). The exact type depends on the component. For example, the Grid handler receives `GridReadEventArgs`. The ComboBox handler receives `ComboBoxReadEventArgs`, and so on. +The `OnRead` event handler receives an argument, which inherits from [`ReadEventArgs`](slug:Telerik.Blazor.Components.ReadEventArgs). The exact type depends on the component. For example, the Grid handler receives `GridReadEventArgs`. The ComboBox handler receives `ComboBoxReadEventArgs`, and so on. The following properties of the event argument object are common for all [components with an `OnRead` event](#components-with-onread-event). Other properties are discussed in component-specific articles. @@ -75,7 +75,7 @@ The following properties of the event argument object are common for all [compon | Property | Type | Description | | --- | --- | --- | -| `Request` | [`DataSourceRequest`](/blazor-ui/api/Telerik.DataSource.DataSourceRequest) | This object carries information about the requested data items. It will reveal the page index or virtual scroll offset, the sorting and filtering state, etc. | +| `Request` | [`DataSourceRequest`](slug:Telerik.DataSource.DataSourceRequest) | This object carries information about the requested data items. It will reveal the page index or virtual scroll offset, the sorting and filtering state, etc. | | `Data` | `IEnumerable` | Set it to the **chunk** of data items, which the component will **render**. | | `Total` | `int` | Set it to the **total number** of items. This value will help the component generate its **pager** or **virtual scrollbar** correctly. | @@ -102,11 +102,11 @@ async Task GridReadHandler(GridReadEventArgs args) ## ToDataSourceResult Method -The [`DataSourceRequest` object](/blazor-ui/api/Telerik.DataSource.DataSourceRequest) provides information about the needed data. The question is how to retrieve this data most easily. Sometimes `OnRead` data binding is called "manual", but in most cases it doesn't have to be manual at all. The solution is **`ToDataSourceResult`**. +The [`DataSourceRequest` object](slug:Telerik.DataSource.DataSourceRequest) provides information about the needed data. The question is how to retrieve this data most easily. Sometimes `OnRead` data binding is called "manual", but in most cases it doesn't have to be manual at all. The solution is **`ToDataSourceResult`**. -The `ToDataSourceResult` extension method is able to extract the requested data items from `IEnumerable`, `IQueryable` and `DataTable`. The method is part of the [Telerik.DataSource.Extensions](/blazor-ui/api/Telerik.DataSource.Extensions) namespace. It expects a `DataSourceRequest` argument. +The `ToDataSourceResult` extension method is able to extract the requested data items from `IEnumerable`, `IQueryable` and `DataTable`. The method is part of the [Telerik.DataSource.Extensions](slug:Telerik.DataSource.Extensions) namespace. It expects a `DataSourceRequest` argument. -`ToDataSourceResult` returns a [`DataSourceResult` object](/blazor-ui/api/Telerik.DataSource.DataSourceResult). Its most important properties are: +`ToDataSourceResult` returns a [`DataSourceResult` object](slug:Telerik.DataSource.DataSourceResult). Its most important properties are: | Property | Type | Description | | --- | --- | --- | @@ -213,14 +213,20 @@ The components fire an `OnRead` event when the user performs an action, such as All components with an `OnRead` event have a `Rebind` method as well. To refresh the component data programmatically, call this method. It will force the component to fire `OnRead` and receive new data. -Also check [how to rebind and refresh a component with a `Timer`]({%slug common-kb-rebind-timer%}). +Also check [how to rebind and refresh a component with a `Timer`](slug:common-kb-rebind-timer). >caption Rebind DropDownList and Grid when using OnRead ````RAZOR @using Telerik.DataSource.Extensions -Rebind Components + +
+
+ + -Rebind Components -

- @code { - TelerikGrid TheGrid { get; set; } - TelerikDropDownList TheDropDown { get; set; } + private TelerikGrid? GridRef { get; set; } + private TelerikDropDownList? DropDownListRef { get; set; } - List GridData { get; set; } - List DropDownData { get; set; } + private List GridData { get; set; } = new(); + private List DropDownData { get; set; } = new(); - int DropDownValue { get; set; } = 1; + private int DropDownValue { get; set; } = 1; - int ItemCounter { get; set; } = 3; + private int ItemCounter { get; set; } = 3; - void RebindComponents() + private void RebindComponents() { - GenerateData(); // simulate change in the data + GenerateData(); // simulate data change - TheGrid.Rebind(); - TheDropDown.Rebind(); + GridRef?.Rebind(); + DropDownListRef?.Rebind(); } - async Task OnGridRead(GridReadEventArgs args) + private async Task OnGridRead(GridReadEventArgs args) { - var result = GridData.ToDataSourceResult(args.Request); + var result = await GridData.ToDataSourceResultAsync(args.Request); args.Data = result.Data; args.Total = result.Total; } - async Task OnDropDownRead(DropDownListReadEventArgs args) + private async Task OnDropDownRead(DropDownListReadEventArgs args) { - var result = DropDownData.ToDataSourceResult(args.Request); + var result = await DropDownData.ToDataSourceResultAsync(args.Request); args.Data = result.Data; args.Total = result.Total; } @@ -290,17 +293,15 @@ Also check [how to rebind and refresh a component with a `Timer`]({%slug common- base.OnInitialized(); } - void GenerateData() + private void GenerateData() { GridData = new List(); DropDownData = new List(); - var rnd = new Random(); - for (int i = 1; i <= ItemCounter; i++) { - GridData.Add(new SampleModel() { Id = i, Text = $"Text {rnd.Next(1, 100)}" }); - DropDownData.Add(new SampleModel() { Id = i, Text = $"Text {rnd.Next(1, 100)}" }); + GridData.Add(new SampleModel() { Id = i, Text = $"Text {(char)Random.Shared.Next(65, 91)}{(char)Random.Shared.Next(65, 91)}" }); + DropDownData.Add(new SampleModel() { Id = i, Text = $"Text {(char)Random.Shared.Next(65, 91)}{(char)Random.Shared.Next(65, 91)}" }); } ItemCounter++; @@ -309,12 +310,12 @@ Also check [how to rebind and refresh a component with a `Timer`]({%slug common- public class SampleModel { public int Id { get; set; } - public string Text { get; set; } + public string Text { get; set; } = string.Empty; } } ```` ## See Also -* [Using the Grid with OnRead]({%slug components/grid/manual-operations%}) -* [Data Binding to cloud services]({%slug common-features-data-binding-cloud%}) +* [Using the Grid with OnRead](slug:components/grid/manual-operations) +* [Data Binding to cloud services](slug:common-features-data-binding-cloud) diff --git a/common-features/data-binding/overview.md b/common-features/data-binding/overview.md index be48c7d554..0296050fd5 100644 --- a/common-features/data-binding/overview.md +++ b/common-features/data-binding/overview.md @@ -10,7 +10,7 @@ position: 0 # Data Binding Overview -This article describes the fundamentals of data binding the Telerik Blazor components. For the sake of clarity, also check article [Value Binding vs Data Binding]({%slug get-started-value-vs-data-binding%}). +This article describes the fundamentals of data binding the Telerik Blazor components. For the sake of clarity, also check article [Value Binding vs Data Binding](slug:get-started-value-vs-data-binding). * [Data binding options](#how-to-provide-data) * [Supported data types](#data-type) @@ -25,7 +25,7 @@ The Telerik Blazor components are detached from the application's data layer. Th There are two main ways to provide data to the components: * `Data` parameter - use it to provide all the data at once. -* [`OnRead` event]({%slug common-features-data-binding-onread%}) - use it to load data on demand in chunks. +* [`OnRead` event](slug:common-features-data-binding-onread) - use it to load data on demand in chunks. Hierarchy components like the TreeList and the TreeView don't have an `OnRead` event. Instead, they load data on demand via `OnExpand` events. @@ -95,11 +95,11 @@ Some components handle properties with specific names in a predefined way. For e There are three ways to refresh the component data: -* [Bind the component to Observable data]({%slug common-features-observable-data%}). **This option applies only** if the `Data` parameter is set. The component will refresh automatically when items are **added or removed**. -* Call the component's `Rebind()` method. UI for Blazor version **3.3.0** exposed `Rebind()` for all databound components. Until then, the method was available only for the [components that have an `OnRead` event]({%slug common-features-data-binding-onread%}#components-with-onread-event). If the component is databound via `OnRead`, the [`Rebind()` method will fire the `OnRead` event]({%slug common-features-data-binding-onread%}#refresh-data). +* [Bind the component to Observable data](slug:common-features-observable-data). **This option applies only** if the `Data` parameter is set. The component will refresh automatically when items are **added or removed**. +* Call the component's `Rebind()` method. UI for Blazor version **3.3.0** exposed `Rebind()` for all databound components. Until then, the method was available only for the [components that have an `OnRead` event](slug:common-features-data-binding-onread#components-with-onread-event). If the component is databound via `OnRead`, the [`Rebind()` method will fire the `OnRead` event](slug:common-features-data-binding-onread#refresh-data). * Reset the `Data` parameter reference. Sometimes, you may also need to call `StateHasChanged()` - for example, if the refreshing occurs in `OnAfterRenderAsync`. -The [example below](#example) demonstrates the second and third option. Also check [how to rebind and refresh a component with a `Timer`]({%slug common-kb-rebind-timer%}). +The [example below](#example) demonstrates the second and third option. Also check [how to rebind and refresh a component with a `Timer`](slug:common-kb-rebind-timer). ### Reset the Collection Reference @@ -115,31 +115,36 @@ Thus, you will usually need to create a new reference for `Data` value in order >caption Call `Rebind()` or create new Data reference ````RAZOR -

- Refresh Grid Data -

- + AutoGenerateColumns="true"> + + Modify Grid Data And Refresh + + @code { - TelerikGrid GridRef { get; set; } - List GridData { get; set; } + private TelerikGrid? GridRef { get; set; } + + private List GridData { get; set; } = new(); + + private int LastId { get; set; } - void RefreshGridData() + private void RefreshGridData() { - var newId = GridData.Count + 1; + GridData.RemoveAt(0); - GridData.FirstOrDefault().Text = DateTime.Now.Ticks.ToString(); + GridData.ElementAt(Random.Shared.Next(0, GridData.Count)).Text = DateTime.Now.Ticks.ToString(); - GridData.Add(new SampleModel() { - Id = newId, - Text = "Text " + newId + GridData.Add(new SampleModel() + { + Id = ++LastId, + Text = "Text " + LastId }); // Call Rebind... - GridRef.Rebind(); + GridRef?.Rebind(); // ...OR... @@ -152,13 +157,12 @@ Thus, you will usually need to create a new reference for `Data` value in order protected override void OnInitialized() { - GridData = new List(); - - for (int i = 1; i <= 3; i++) + for (int i = 1; i <= 5; i++) { - GridData.Add(new SampleModel() { - Id = i, - Text = "Text " + i + GridData.Add(new SampleModel() + { + Id = ++LastId, + Text = $"Text {LastId}" }); } @@ -168,7 +172,7 @@ Thus, you will usually need to create a new reference for `Data` value in order public class SampleModel { public int Id { get; set; } - public string Text { get; set; } + public string Text { get; set; } = string.Empty; } } ```` @@ -176,6 +180,6 @@ Thus, you will usually need to create a new reference for `Data` value in order ## Next Steps -* [Data Binding with the OnRead event]({%slug common-features-data-binding-onread%}) -* [Data Binding to Observable Data]({%slug common-features-observable-data%}) -* [Data Binding to cloud data services]({%slug common-features-data-binding-cloud%}) +* [Data Binding with the OnRead event](slug:common-features-data-binding-onread) +* [Data Binding to Observable Data](slug:common-features-observable-data) +* [Data Binding to cloud data services](slug:common-features-data-binding-cloud) diff --git a/common-features/data-binding/telerik-datasource-package.md b/common-features/data-binding/telerik-datasource-package.md index 8713063727..6d0e5cb3f9 100644 --- a/common-features/data-binding/telerik-datasource-package.md +++ b/common-features/data-binding/telerik-datasource-package.md @@ -25,7 +25,7 @@ In this article: ## Basics -The `Telerik.DataSource` package is distributed through the [Telerik NuGet package source]({%slug installation/nuget%}) and is available to both trial and commercial licenses. It is also available as a resource in the [offline installer]({%slug installation/msi%}) and [resources archive]({%slug installation/zip%}) of Telerik UI for Blazor and some other Telerik suites, such as UI for ASP.NET Core. +The `Telerik.DataSource` package is distributed through the [Telerik NuGet package source](slug:installation/nuget) and is available to both trial and commercial licenses. It is also available as a resource in the [offline installer](slug:installation-msi) and [resources archive](slug:installation-zip) of Telerik UI for Blazor and some other Telerik suites, such as UI for ASP.NET Core. The `Telerik.DataSource` package targets `netstandard2.1`. @@ -37,15 +37,15 @@ If you are using an EntityFramework backend that provides an `IQueryable` collec The following classes and extension methods are the key components to the package: -* The `ToDataSourceResult(DataSourceRequest request)` [extension method](/blazor-ui/api/Telerik.DataSource.Extensions.QueryableExtensions) - this method is in the `Telerik.DataSource.Extensions` namespace, and is available for `IQueryable`, `IEnumerable` and `DataTable`. It receives a `DataSourceRequest` argument and returns a `DataSourceResult` object. It also has an async version (with the standard `Async` suffix to the method name). This is the method that facilitates the data operations itself so you don't have to implement them. These methods are in the `Telerik.DataSource.Extensions` namespace. +* The `ToDataSourceResult(DataSourceRequest request)` [extension method](slug:Telerik.DataSource.Extensions.QueryableExtensions) - this method is in the `Telerik.DataSource.Extensions` namespace, and is available for `IQueryable`, `IEnumerable` and `DataTable`. It receives a `DataSourceRequest` argument and returns a `DataSourceResult` object. It also has an async version (with the standard `Async` suffix to the method name). This is the method that facilitates the data operations itself so you don't have to implement them. These methods are in the `Telerik.DataSource.Extensions` namespace. * The `ToDataSourceResult` method generates a LINQ expressions based on the `DataSourceRequest` and passes them to the `IQueryable.Provider`. It is up to the provider (collection) to resolve it and execute it against the database (for example, an `IQueryable` coming from an EntityFrameworkCore context will create and run an SQL query for you). -* [`DataSourceRequest`](/blazor-ui/api/Telerik.DataSource.DataSourceRequest) - the class that describes the request for data - what page index, page size, filters and sorts, groups and aggregates are required by the client. You can receive it from Telerik components (such as the [Blazor grid in its manual data operations mode]({%slug components/grid/manual-operations%})), or over the wire and deserialize it (such as for requests coming from widgets like the [UI for ASP.NET Core Grid with remote data](https://demos.telerik.com/aspnet-core/grid/remote-data-binding)). You can even create a `new` instance of the object and populate its fields according to some other business logic (like an OData query string or some other case). This object is in the `Telerik.DataSource` namespace. +* [`DataSourceRequest`](slug:Telerik.DataSource.DataSourceRequest) - the class that describes the request for data - what page index, page size, filters and sorts, groups and aggregates are required by the client. You can receive it from Telerik components (such as the [Blazor grid in its manual data operations mode](slug:components/grid/manual-operations)), or over the wire and deserialize it (such as for requests coming from widgets like the [UI for ASP.NET Core Grid with remote data](https://demos.telerik.com/aspnet-core/grid/remote-data-binding)). You can even create a `new` instance of the object and populate its fields according to some other business logic (like an OData query string or some other case). This object is in the `Telerik.DataSource` namespace. * When you receive such an object from a Telerik component, you can iterate over the information it provides and implement you own data source operations, you are not obliged to use the `ToDataSourceResult` method (but it helps shape the data accordingly, so you may want to examine its `DataSourceResult` from a simple run to see what it contains). -* [`DataSourceResult`](/blazor-ui/api/Telerik.DataSource.DataSourceResult) - the resulting data set from the operations on the data source. It will contain the current page of data, for its appropriate index, according to the designated filters, sorts, groups; and it will also contain the total number of items in the data source. It will also contain aggregate data. This is what you would normally serialize over the wire to send back to the client (or pass by reference in case of C#-only services). This object is in the `Telerik.DataSource` namespace. +* [`DataSourceResult`](slug:Telerik.DataSource.DataSourceResult) - the resulting data set from the operations on the data source. It will contain the current page of data, for its appropriate index, according to the designated filters, sorts, groups; and it will also contain the total number of items in the data source. It will also contain aggregate data. This is what you would normally serialize over the wire to send back to the client (or pass by reference in case of C#-only services). This object is in the `Telerik.DataSource` namespace. diff --git a/common-features/dimensions.md b/common-features/dimensions.md index 6aa35438f9..6781031818 100644 --- a/common-features/dimensions.md +++ b/common-features/dimensions.md @@ -5,7 +5,7 @@ description: How dimensions work and are set in the Telerik UI for Blazor compon slug: common-features/dimensions tags: telerik,blazor,dimensions,width,height,percent,pixel published: True -position: 7 +position: 80 --- # Dimensions @@ -28,7 +28,7 @@ When setting percentage dimensions to elements with special positioning (such as ## Position -When using positioning parameters, for example `Top` or `Left`, the component placement may be affected by CSS styles on the component's parent. If you experience issues, [inspect the rendered HTML to see what elements are present and what their CSS styles are]({%slug themes-override%}#tools). +When using positioning parameters, for example `Top` or `Left`, the component placement may be affected by CSS styles on the component's parent. If you experience issues, [inspect the rendered HTML to see what elements are present and what their CSS styles are](slug:themes-override#tools). >tip You can set dimensions in percentage (such as `Width="100%"`) to make the components responsive and let them resize according to the app layout and browser viewport. A lot of components expand to 100% width by default, for example, the Grid, Form, Scheduler, Spreadsheet, all input components, and others. @@ -95,5 +95,5 @@ The examples here showcase different units and examples of using them to set dim ## See Also -* [Themes]({%slug themes-overview%}) -* [Override Theme Styles]({%slug themes-override%}) +* [Themes](slug:themes-overview) +* [Override Theme Styles](slug:themes-override) diff --git a/common-features/icons.md b/common-features/icons.md index 3e0c444a6a..4d55273ae7 100644 --- a/common-features/icons.md +++ b/common-features/icons.md @@ -1,17 +1,17 @@ --- title: Icons page_title: Font and SVG Icons -description: How to use the built-in font icons in the UI for Blazor suite. +description: Blazor Icons are customizable, scalable icons for Blazor apps that enhance UI design with easy styling. slug: common-features-icons tags: telerik,blazor,icon,font,built-in published: True previous_url: /common-features/font-icons -position: 1 +position: 20 --- -# Built-in Font and SVG Icons +# Blazor SVG and Font Icons -Telerik UI for Blazor provides a large set of built-in icons. There are two ways to consume and render them: as font icons or as SVG icons. It is also possible to use custom icons, or define an application-wide setting, which affects the type of icons in all Telerik Blazor components. +Telerik UI for Blazor provides a large set of built-in icons. There are two ways to consume and render them: as font icons or as SVG icons. It is also possible to use custom Blazor icons, or define an application-wide setting, which affects the type of icons in all Telerik Blazor components. The Telerik Blazor components generate the same type of icons (font icons or SVG icons), [depending on the `TelerikRootComponent` configuration](#set-global-icon-type). However, Telerik UI for Blazor includes standalone [`FontIcon`](#fonticon-component) and [`SvgIcon`](#svgicon-component) components, which can be used at the same time. @@ -19,7 +19,7 @@ In general, font icons produce a smaller HTML footprint and the glyph can be ove This article contains the following sections: -* [How do icons work](#how-icons-work) +* [How do icons work](#how-blazor-icons-work) * [Install icon NuGet packages](#icon-nuget-packages) * [Import icon namespaces](#icon-namespaces) * [Register font icon stylesheet](#font-icon-stylesheet) (SVG icons don't need it) @@ -29,12 +29,15 @@ This article contains the following sections: * [`SvgIcon` component](#svgicon-component) * [Render custom SVG Icons with HTML](#render-custom-svg-icons-with-html) * [Use custom SVG icon collection](#use-custom-svg-icon-collection) -* [Set global icon type for the whole application](#set-global-icon-type) +* [Set global icon type for the whole application](#set-global-blazor-icon-type) * [Complete list of built-in icons](#icons-list) -* [How to use custom icons](#custom-icon-support) +* [How to use custom icons](#custom-blazor-icon-support) +{% if site.has_cta_panels == true %} +{% include cta-panel-introduction.html %} +{% endif %} -## How Icons Work +## How Blazor Icons Work The Telerik Blazor icons have three prerequisites to work: @@ -46,10 +49,10 @@ The Telerik Blazor icons have three prerequisites to work: The Telerik Blazor components use built-in icons with the help of two NuGet packages. They are installed **automatically** as dependencies of the `Telerik.UI.for.Blazor` package: -* `Telerik.FontIcons` - defines the `FontIcon` `enum` for easier usage of built-in **font** icons +* `Telerik.FontIcons` - defines the `FontIcon` `enum` for easier usage of built-in **font** Blazor icons * `Telerik.SvgIcons` - defines the `ISvgIcon` interface and the `SvgIcon` static class for built-in **SVG** icons ->tip Unlike the `Telerik.UI.for.Blazor` package, the icon packages are available on the `nuget.org` source. Keep this in mind when using [`packageSourceMapping`]({%slug installation/nuget%}#package-source-mapping). +>tip Unlike the `Telerik.UI.for.Blazor` package, the icon packages are available on the `nuget.org` source. Keep this in mind when using [`packageSourceMapping`](slug:installation/nuget#package-source-mapping). ### Icon Namespaces @@ -86,8 +89,6 @@ In version 4.6.0 of Telerik UI for Blazor, the font icon styles were separated i ````RAZOR - - @@ -105,8 +106,8 @@ The `TelerikFontIcon` component can show a [built-in Telerik Blazor font icon](# | `Flip` | `IconFlip` `enum`
(`None`) | The icon's flip direction, which allows to mirror (turn over) the image horizontally, vertically, or in both directions. | | `Icon` | `FontIcon` `enum` | Any of the [built-in Telerik Blazor font icons](#icons-list). This parameter takes precedence over `IconClass`, if both are set. | | `IconClass` | `string` | Custom CSS class for a custom third-party icon. Do not use together with the `Icon` parameter. | -| `Size` | `string`
(`"md"`) | Any of the predefined icon sizes (from `"xs"` to `"xxxl"`). It is possible to set the parameter value to raw strings such as `"lg"`, `"md"`, or `"sm"`. However, the recommended practice is to use the properties of the static [`ThemeConstants.FontIcon.Size` class](/blazor-ui/api/telerik.blazor.themeconstants.fonticon.size). | -| `ThemeColor` | `string` | Any of the predefined icon colors. Use the static [`ThemeConstants.FontIcon.ThemeColor` class](/blazor-ui/api/telerik.blazor.themeconstants.fonticon.themecolor) properties. By default, the icon color will inherit the current CSS text color. | +| `Size` | `string`
(`"md"`) | Any of the predefined icon sizes (from `"xs"` to `"xxxl"`). It is possible to set the parameter value to raw strings such as `"lg"`, `"md"`, or `"sm"`. However, the recommended practice is to use the properties of the static [`ThemeConstants.FontIcon.Size` class](slug:telerik.blazor.themeconstants.fonticon.size). | +| `ThemeColor` | `string` | Any of the predefined icon colors. Use the static [`ThemeConstants.FontIcon.ThemeColor` class](slug:telerik.blazor.themeconstants.fonticon.themecolor) properties. By default, the icon color will inherit the current CSS text color. | >caption Using TelerikFontIcon @@ -172,7 +173,7 @@ Our font icons are designed on a 16px grid base. For better display quality, use ### Render Font Icons with HTML -Telerik UI for Blazor shares the same [themes]({%slug themes-overview%}) with several other Telerik and Kendo UI web component suites. All these products use the same font icons. +Telerik UI for Blazor shares the same [themes](slug:themes-overview) with several other Telerik and Kendo UI web component suites. All these products use the same font icons. You can use the built-in font icons directly with HTML tags, without the `` component. Such direct HTML usage may provide more flexibility, but if you don't really need it, we recommend using `FontIcon` objects and the `` component instead. @@ -200,9 +201,9 @@ The `TelerikSvgIcon` component can show a [built-in Telerik Blazor SVG icon](#ic |---|---|---| | `Flip` | `IconFlip` `enum`
(`None`) | The icon's flip direction, which allows to mirror (turn over) the image horizontally, vertically, or in both directions. | | `Icon` | `ISvgIcon` | Assign a property of the `SvgIcon` static class to use any of the [built-in Telerik Blazor font icons](#icons-list). Alternatively, [implement your own custom SVG Icon class](#use-custom-svg-icon-collection). | -| `Size` | `string`
(`"md"`) | Any of the predefined icon sizes (from `"xs"` to `"xxxl"`). It is possible to set the parameter value to raw strings such as `"lg"`, `"md"`, or `"sm"`. However, the recommended practice is to use the properties of the static [`ThemeConstants.SvgIcon.Size` class](/blazor-ui/api/telerik.blazor.themeconstants.svgicon.size). | +| `Size` | `string`
(`"md"`) | Any of the predefined icon sizes (from `"xs"` to `"xxxl"`). It is possible to set the parameter value to raw strings such as `"lg"`, `"md"`, or `"sm"`. However, the recommended practice is to use the properties of the static [`ThemeConstants.SvgIcon.Size` class](slug:telerik.blazor.themeconstants.svgicon.size). | | `ChildContent` | `RenderFragment` | The HTML markup of a custom SVG icon. Do not use together with `Icon`. | -| `ThemeColor` | `string` | Any of the predefined icon colors. Use the static [`ThemeConstants.SvgIcon.ThemeColor` class](/blazor-ui/api/telerik.blazor.themeconstants.svgicon.themecolor) properties. | +| `ThemeColor` | `string` | Any of the predefined icon colors. Use the static [`ThemeConstants.SvgIcon.ThemeColor` class](slug:telerik.blazor.themeconstants.svgicon.themecolor) properties. | >caption Using TelerikSvgIcon @@ -289,12 +290,12 @@ The `ISvgIcon` interface members are: ```` -## Set Global Icon Type +## Set Global Blazor Icon Type It is possible to configure the icon type for the whole application: -1. Locate the [``]({%slug rootcomponent-overview%}) tag in the Blazor app. Normally, it's in a layout file such as `MainLayout.razor` or `TelerikLayout.razor`. -2. Set the RootComponent `IconType` parameter to an [`IconType` enum](/blazor-ui/api/telerik.blazor.icontype) value (`Svg` or `Font`). The default icon type is `Svg`. +1. Locate the [``](slug:rootcomponent-overview) tag in the Blazor app. Normally, it's in a layout file such as `MainLayout.razor` or `TelerikLayout.razor`. +2. Set the RootComponent `IconType` parameter to an [`IconType` enum](slug:telerik.blazor.icontype) value (`Svg` or `Font`). The default icon type is `Svg`. >caption Define global icon type via TelerikRootComponent @@ -328,13 +329,13 @@ Each icon box in the icon list is clickable and reveals the following details: The icon list may contain icons which are not available in older versions of Telerik UI for Blazor or even in the latest one. Such icons will be added in the next product version. -## Custom Icon Support +## Custom Blazor Icon Support Telerik UI for Blazor supports using custom (third-party) icons: * [In the `SvgIcon` component](#use-custom-svg-icon-collection). * [In the `FontIcon` component](#fonticon-component). -* In [Buttons]({%slug button-icons%}), [Menu items]({%slug menu-icons%}), [Drawer items]({%slug drawer-icons%}) and other [navigation components]({%slug blazor-overview%}#list-of-components). +* In [Buttons](slug:button-icons), [Menu items](slug:menu-icons), [Drawer items](slug:drawer-icons) and other [navigation components](slug:blazor-overview#list-of-components). [Using custom icons for the automatically rendered icons is not supported yet](https://feedback.telerik.com/blazor/1641361-ability-to-change-the-built-in-icons). For example, the sort and filter icons in the Grid header cells, or the open arrow in the DropDownList. @@ -343,4 +344,6 @@ Telerik UI for Blazor supports using custom (third-party) icons: * Built-in Icon List * [Blazor Live Demos](https://demos.telerik.com/blazor-ui) -* [CSS Themes]({%slug themes-overview%}) +* [Blazor FontIcon](https://demos.telerik.com/blazor-ui/fonticon/overview) +* [Blazor SVGIcon](https://demos.telerik.com/blazor-ui/svgicon/overview) +* [CSS Themes](slug:themes-overview) diff --git a/common-features/input-adornments.md b/common-features/input-adornments.md index e59d46cee4..695bbf1c6d 100644 --- a/common-features/input-adornments.md +++ b/common-features/input-adornments.md @@ -5,7 +5,7 @@ description: How to add prefix and suffix adornments in the input elements of th slug: common-features/input-adornments tags: telerik,blazor,input,adornments,prefix,suffix published: True -position: 2 +position: 30 --- # Input Adornments @@ -29,14 +29,14 @@ A prefix input adornment refers to an element placed before the user input field The following input components support prefix and suffix adornments: -* [AutoComplete]({%slug autocomplete-overview%}) -* [ComboBox]({%slug components/combobox/overview%}) -* [MaskedTextbox]({%slug maskedtextbox-overview%}) -* [MultiColumnComboBox]({%slug multicolumncombobox-overview%}) -* [MultiSelect]({%slug multiselect-overview%}) -* [NumericTextBox]({%slug components/numerictextbox/overview%}) -* [TextArea]({%slug textarea-overview%}) -* [TextBox]({%slug components/textbox/overview%}) +* [AutoComplete](slug:autocomplete-overview) +* [ComboBox](slug:components/combobox/overview) +* [MaskedTextbox](slug:maskedtextbox-overview) +* [MultiColumnComboBox](slug:multicolumncombobox-overview) +* [MultiSelect](slug:multiselect-overview) +* [NumericTextBox](slug:components/numerictextbox/overview) +* [TextArea](slug:textarea-overview) +* [TextBox](slug:components/textbox/overview) ## Adding a Prefix Adornment @@ -357,10 +357,10 @@ In addition to the common configuration settings listed in this article, the Tex This section applies to the components that incorporate popup element: -* [AutoComplete]({%slug autocomplete-overview%}) -* [ComboBox]({%slug components/combobox/overview%}) -* [MultiColumnComboBox]({%slug multicolumncombobox-overview%}) -* [MultiSelect]({%slug multiselect-overview%}) +* [AutoComplete](slug:autocomplete-overview) +* [ComboBox](slug:components/combobox/overview) +* [MultiColumnComboBox](slug:multicolumncombobox-overview) +* [MultiSelect](slug:multiselect-overview) By design, `Alt` + `Down` key combination opens the popup element when the component is focused. If you have added another dropdown component as a prefix or suffix adornment, focusing that component and pressing `Alt` + `Down` keys will open both popup elements - the one that belongs to the main component and the other associated with the dropdown in the prefix/suffix template. diff --git a/common-features/input-validation.md b/common-features/input-validation.md index 74bc0df82d..39ae8a8c3e 100644 --- a/common-features/input-validation.md +++ b/common-features/input-validation.md @@ -5,7 +5,7 @@ description: How to validate Blazor inputs. slug: common-features/input-validation tags: telerik,blazor,validation,data,annotation,form published: True -position: 3 +position: 40 --- # Input Validation @@ -40,7 +40,7 @@ This article provides examples of validating the Telerik Blazor components. The * [Sliders](#sliders) ->tip Telerik offers the [Form Component]({%slug form-overview%}) that lets you generate and manage forms with predefined layouts and less code. +>tip Telerik offers the [Form Component](slug:form-overview) that lets you generate and manage forms with predefined layouts and less code. ### Simple Inputs @@ -514,11 +514,11 @@ Unlike other components, the editor does not trigger form validation on every ke ### MaskedTextbox -The Masked Textbox prompts the user for their input and restricts it according to its [Mask]({%slug maskedtextbox-mask-prompt%}). +The Masked Textbox prompts the user for their input and restricts it according to its [Mask](slug:maskedtextbox-mask-prompt). The Blazor validation is, however, controlled by data annotation attributes on the model and so the application must have the appropriate rules set that match the desired input and masks. The RegularExpression annotation is commonly used to require a specific input format and values, or you can implement custom data annotation attributes too. -You may want to set the [`IncludeLiterals`]({%slug maskedtextbox-mask-prompt%}#include-literals-in-the-value) parameter to `true` and/or set the [`PromptPlaceholder`]({%slug maskedtextbox-mask-prompt%}#prompt) parameter accordingly to keep the prompt characters in the `Value` so you can validate the content more easily. +You may want to set the [`IncludeLiterals`](slug:maskedtextbox-mask-prompt#include-literals-in-the-value) parameter to `true` and/or set the [`PromptPlaceholder`](slug:maskedtextbox-mask-prompt#prompt) parameter accordingly to keep the prompt characters in the `Value` so you can validate the content more easily. >caption Sample DataAnnotation rules that match masks to validate user input @@ -920,8 +920,8 @@ The feature is supported by the following components treated as simple textbox-l ## See Also * [Data annotation attributes](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation) -* [Conditional validation]({%slug form-kb-conditional-validation%}) -* [ValueChanged and validation]({%slug value-changed-validation-model%}) -* [Validate on blur or change]({%slug textbox-validate-on-change%}) -* [Error: Requires a value for ValueExpression]({%slug common-kb-requires-valueexpression%}) -* [Form component]({%slug form-overview%}) +* [Conditional validation](slug:form-kb-conditional-validation) +* [ValueChanged and validation](slug:value-changed-validation-model) +* [Validate on blur or change](slug:textbox-validate-on-change) +* [Error: Requires a value for ValueExpression](slug:common-kb-requires-valueexpression) +* [Form component](slug:form-overview) diff --git a/common-features/loading-sign.md b/common-features/loading-sign.md index b2e8467ec8..813b357413 100644 --- a/common-features/loading-sign.md +++ b/common-features/loading-sign.md @@ -5,14 +5,14 @@ description: Components that peform long running operations can show a loading i slug: common-features-loading-sign tags: telerik,blazor,loading,sign,busy,indicator,data published: True -position: 5 +position: 70 --- # Loading Sign Many times a component loads or saves data and that can take some time. To show your users the app is working, and to prevent them from performing the same action multiple times, the Telerik Blazor components can show a busy indicator while such an operation is under way. -The Telerik components use the Telerik [Loader]({%slug loader-overview%}) and [LoaderContainer]({%slug loadercontainer-overview%}) components internally to match the theme and design. +The Telerik components use the Telerik [Loader](slug:loader-overview) and [LoaderContainer](slug:loadercontainer-overview) components internally to match the theme and design. There are three patterns for showing a loading indicator: @@ -342,7 +342,7 @@ Another example could be a slow calculation (for example, grouping a large amoun A fourth example could be a dropdown that has far too many items in it - expanding the dropdown will take some time to render because the DOM operation itself takes time. This would affect server-side Blazor apps too. -To combat such performance issues, see the [Slow Performance]({%slug troubleshooting-general-issues%}#slow-performance) section of the documentation. +To combat such performance issues, see the [Slow Performance](slug:troubleshooting-general-issues#slow-performance) section of the documentation. Truly asynchronous operations will still allow for a loading sign - such as the grid's `OnRead` event that is really `async` (for example, calls some WebAPI) will let the framework release the UI thread and re-render the component with a loading sign until the data response comes back. diff --git a/common-features/microsoft-extensions-ai-integration.md b/common-features/microsoft-extensions-ai-integration.md new file mode 100644 index 0000000000..9f401a807e --- /dev/null +++ b/common-features/microsoft-extensions-ai-integration.md @@ -0,0 +1,31 @@ +--- +title: Integration with Microsoft.Extensions.AI +page_title: Integration with Microsoft.Extensions.AI +description: How to integrate the UI for Blazor components with Microsoft.Extensions.AI +slug: common-features-microsoft-extensions-ai-integration +tags: telerik,blazor,aiprompt,ai,extensions,integration +published: True +position: 50 +--- + +# Integration with Microsoft.Extensions.AI + +The [AIPrompt component](slug:aiprompt-overview) incorporates the [Microsoft.Extensions.AI package](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai?view=net-9.0-pp) to simplify your AI model integration, provide flexibility and let you easily use and test various AI providers. + +Other components will support similar integration in future versions of UI for Blazor. + +## Integration + +To integrate the **Microsoft.Extensions.AI** library with your AIPrompt component, register an [`IChatClient`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai.ichatclient?view=net-9.0-pp) service and configure it according to the model you are using. The AIPrompt is designed to automatically use the registered `IChatClient`. + +> When using the Telerik AIPrompt component with the Microsoft AI library, do not subscribe to the `OnPromptRequest` event. + +**Microsoft.Extensions.AI** provides a simple integration with various models where the configuration slightly differs depending on the model. [Explore examples with different models in this sample application](https://github.com/telerik/blazor-ui/tree/master/common/microsoft-extensions-ai-integration/AIPromptIntegration). + +## See Also + +* [AIPrompt Overview - Documenation](slug:aiprompt-overview) +* [AIPrompt - Live Demo](https://demos.telerik.com/blazor-ui/aiprompt/overview) +* [Microsoft.Extensions.AI](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai?view=net-9.0-pp) +* [Introducing Microsoft.Extensions.AI Preview – Unified AI Building Blocks for .NET](https://devblogs.microsoft.com/dotnet/introducing-microsoft-extensions-ai-preview/) +* [AIPrompt Integration with Microsoft.Extensions.AI - Sample Application](https://github.com/telerik/blazor-ui/tree/master/common/microsoft-extensions-ai-integration/AIPromptIntegration) diff --git a/components/aiprompt/accessibility/wai-aria-support.md b/components/aiprompt/accessibility/wai-aria-support.md new file mode 100644 index 0000000000..986efb8bb5 --- /dev/null +++ b/components/aiprompt/accessibility/wai-aria-support.md @@ -0,0 +1,96 @@ +--- +title: Wai-Aria Support +page_title: Telerik UI for Blazor AIPrompt Documentation | AIPrompt Accessibility +description: "Get started with the Telerik UI for Blazor AIPrompt and learn about its accessibility support for WAI-ARIA, Section 508, and WCAG 2.2." +tags: telerik,blazor,accessibility,wai-aria,wcag +slug: aiprompt-wai-aria-support +position: 50 +--- + +# Blazor AIPrompt Accessibility + +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) + + + +Out of the box, the Telerik UI for Blazor AI Prompt provides extensive accessibility support and enables users with disabilities to acquire complete control over its features. + + +The AI Prompt is compliant with the [Web Content Accessibility Guidelines (WCAG) 2.2 AA](https://www.w3.org/TR/WCAG22/) standards and [Section 508](https://www.section508.gov/) requirements, follows the [Web Accessibility Initiative - Accessible Rich Internet Applications (WAI-ARIA)](https://www.w3.org/WAI/ARIA/apg/) best practices for implementing the [keyboard navigation](#keyboard-navigation) for its `component` role, provides options for managing its focus and is tested against the most popular screen readers. + +## WAI-ARIA + + +This section lists the selectors, attributes, and behavior patterns supported by the component and its composite elements, if any. + +### AI Prompt + + +The AI Prompt component is a composite one and integrates the accessibility of the Toolbar, TextArea, Card List container + +### TextArea Component + +[TextArea accessibility specification]({{textarea_a11y_link}}) + +### Prompt Suggestion Component + + +The Prompt suggestion list implements roving tabindex navigation. Meaning that only one suggestion has tabindex=0. The display of the suggestion list is controlled by the expand button. + +| Selector | Attribute | Usage | +| -------- | --------- | ----- | +| `.k-prompt-expander .k-button` | `aria-controls=.k-prompt-expander-content id` | Points to the controlled element based on the given `id`. | +| | `aria-expanded=true/false` | Indicates the expanded state of the prompt expander content. | +| `.k-prompt-expander .k-prompt-expander-content` | `role=list` | Indicates that the suggestion container element is a list. | +| `.k-prompt-expander .k-prompt-suggestion` | `role=listitem` | Indicates that the suggestion element is a listitem. | +| | `tabindex=0/-1` | The element should be focusable. | + +### Toolbar Component + +[ToolBar accessibility specification]({{toolbar_a11y_link}}) + +### Card List Container + +[CardList accessibility specification]({{cardlist_a11y_link}}) + +### Card Component + +[Card accessibility specification]({{card_a11y_link}}) + +### More Actions View - PanelBar Component + +[PanelBar accessibility specification]({{panelbar_a11y_link}}) + +## Section 508 + + +The AI Prompt is fully compliant with the [Section 508 requirements](http://www.section508.gov/). + +## Testing + + +The AI Prompt has been extensively tested automatically with [axe-core](https://github.com/dequelabs/axe-core) and manually with the most popular screen readers. + +> To report any accessibility issues, contact the team through the [Telerik Support System](https://www.telerik.com/account/support-center). + +### Screen Readers + + +The AI Prompt has been tested with the following screen readers and browsers combinations: + +| Environment | Tool | +| ----------- | ---- | +| Firefox | NVDA | +| Chrome | JAWS | +| Microsoft Edge | JAWS | + + + +## Keyboard Navigation + +For details on how the keyboard navigation works in Telerik UI for Blazor, refer to the [Accessibility Overview](slug:accessibility-overview#keyboard-navigation) article. + +## See Also + +* [Blazor AIPrompt Demos](https://demos.telerik.com/blazor-ui/aiprompt/overview) +* [Accessibility in Telerik UI for Blazor](slug:accessibility-overview) \ No newline at end of file diff --git a/components/aiprompt/events.md b/components/aiprompt/events.md index 9ad59d803e..9fb7d4d2e0 100644 --- a/components/aiprompt/events.md +++ b/components/aiprompt/events.md @@ -21,7 +21,7 @@ This article explains the events available in the Telerik AIPrompt for Blazor: The `OnPromptRequest` event fires when the user clicks on the **Generate** button within the Prompt view or retries a prompt from the Output view. -The event handler receives an argument of type [`AIPromptPromptRequestEventArgs`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptPromptRequestEventArgs). See the [example below](#example). +The event handler receives an argument of type [`AIPromptPromptRequestEventArgs`](slug:Telerik.Blazor.Components.AIPromptPromptRequestEventArgs). See the [example below](#example). @[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) @@ -30,14 +30,15 @@ The event handler receives an argument of type [`AIPromptPromptRequestEventArgs` | `Prompt` | `string` | The prompt text of the request. | | `Output` | `string` | The output of the request. The output is based on the prompt text. | | `IsCancelled` | `bool` | Whether the event is cancelled and the built-in action is prevented. | -| `OutputItem` | `AIPromptOutputItemDescriptor` | The output item. This property will be populated only when the user retries an existing output. See [`AIPromptOutputItemDescriptor`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | +| `OutputItem` | `AIPromptOutputItemDescriptor` | The output item. This property will be populated only when the user retries an existing output. See [`AIPromptOutputItemDescriptor`](slug:Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | +> Do not use the `OnPromptRequest` event when [integrating the AIPrompt component with `Microsoft.Extensions.AI`](slug:common-features-microsoft-extensions-ai-integration). The `OnPromptRequest` event disables such integration. ## OnCommandExecute The `OnCommandExecute` event fires when the user clicks on a command within the Commands view. -The event handler receives an argument of type [`AIPromptCommandExecuteEventArgs`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptCommandExecuteEventArgs). See the [example below](#example). +The event handler receives an argument of type [`AIPromptCommandExecuteEventArgs`](slug:Telerik.Blazor.Components.AIPromptCommandExecuteEventArgs). See the [example below](#example). @[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) @@ -46,20 +47,20 @@ The event handler receives an argument of type [`AIPromptCommandExecuteEventArgs | `Command` | `AIPromptCommandDescriptor` | The executed command. | | `Output` | `string` | The output based on the executed command. | | `IsCancelled` | `bool` | Whether the event is cancelled and the built-in action is prevented. | -| `OutputItem` | `AIPromptOutputItemDescriptor` | The output item. This property will be populated only when the user retries an existing output. See [`AIPromptOutputItemDescriptor`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | +| `OutputItem` | `AIPromptOutputItemDescriptor` | The output item. This property will be populated only when the user retries an existing output. See [`AIPromptOutputItemDescriptor`](slug:Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | ## OnOutputRate The `OnOutputRate` event fires when the user rates an output. -The event handler receives an argument of type [`AIPromptOutputRateEventArgs`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptOutputRateEventArgs). See the [example below](#example). +The event handler receives an argument of type [`AIPromptOutputRateEventArgs`](slug:Telerik.Blazor.Components.AIPromptOutputRateEventArgs). See the [example below](#example). @[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) | Property | Type | Description | | --- | --- | --- | -| `OutputItem` | `AIPromptOutputItemDescriptor` | Specifies the output item that is being rated. See [`AIPromptOutputItemDescriptor`](/blazor-ui/api/Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | +| `OutputItem` | `AIPromptOutputItemDescriptor` | Specifies the output item that is being rated. See [`AIPromptOutputItemDescriptor`](slug:Telerik.Blazor.Components.AIPromptOutputItemDescriptor). | ## PromptTextChanged diff --git a/components/aiprompt/overview.md b/components/aiprompt/overview.md index 8a78addc5b..58ba1593e5 100644 --- a/components/aiprompt/overview.md +++ b/components/aiprompt/overview.md @@ -61,30 +61,33 @@ The component allows you to interact with the output from the AI and execute a s } ```` +## Integration with Microsoft.Extensions.AI + +The AIPrompt supports using the [Microsoft.Extensions.AI library](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai?view=net-9.0-pp) to provide seamless integration with various AI models and boost your workflow when connecting the AIPrompt with AI models. [Learn how to integrate Microsoft.Extensions.AI with your AIPrompt component...](slug:common-features-microsoft-extensions-ai-integration) ## ToolBar -The AIPrompt includes a toolbar with built-in buttons that activate the view they are related to. The component also exposes the option to add custom tools, which may be associated with arbitrary handlers. [Read more about the AIPrompt's ToolBar...]({%slug aiprompt-toolbar%}) +The AIPrompt includes a toolbar with built-in buttons that activate the view they are related to. The component also exposes the option to add custom tools, which may be associated with arbitrary handlers. [Read more about the AIPrompt's ToolBar...](slug:aiprompt-toolbar) ## Views -The AIPrompt component offers the Prompt, Output, and Commands views that relate to the current state of the prompt-response lifecycle. You can also customize the component through custom views. [Read more about the AIPrompt views...]({%slug aiprompt-views-overview%}) +The AIPrompt component offers the Prompt, Output, and Commands views that relate to the current state of the prompt-response lifecycle. You can also customize the component through custom views. [Read more about the AIPrompt views...](slug:aiprompt-views-overview) ## Templates -The AIPrompt component provides templates that enable developers to customize the rendering and appearance of the component. [Read more about the AIPrompt templates...]({%slug aiprompt-templates%}) +The AIPrompt component provides templates that enable developers to customize the rendering and appearance of the component. [Read more about the AIPrompt templates...](slug:aiprompt-templates) ## Events -The various AIPrompt events allow you to implement custom functionality and handle user interactions with the component's ToolBar. [Read more about the AIPrompt events...]({%slug aiprompt-events%}) +The various AIPrompt events allow you to implement custom functionality and handle user interactions with the component's ToolBar. [Read more about the AIPrompt events...](slug:aiprompt-events) ## AIPrompt Parameters -The table below lists the AIPrompt parameters. For a full list of the AIPrompt API members (parameters, methods, and events), check the [AIPrompt API Reference](/blazor-ui/api/Telerik.Blazor.Components.TelerikAIPrompt). +The table below lists the AIPrompt parameters. For a full list of the AIPrompt API members (parameters, methods, and events), check the [AIPrompt API Reference](slug:Telerik.Blazor.Components.TelerikAIPrompt). @[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) @@ -92,15 +95,17 @@ The table below lists the AIPrompt parameters. For a full list of the AIPrompt A | --- | --- | --- | | `AIPromptViews` | `RenderFragment` | Allows control over the views of the content. Use it to set the visibility of a predefined view or to create custom views. If a render fragment is not provided, the AIPrompt will display its default views. | | `AIPromptToolBar` | `RenderFragment` | Any additional buttons that will be rendered within the ToolBar. This parameter will append the new items, rather than override buttons related to existing views. | +| `Class` | `string` | The `class` attribute of the `
` element. Use it to apply custom styles or [override the theme](slug:themes-override). | +| `Commands` | `List` | The predefined commands displayed within the Commands view. | +| `Height` | `string` | The `height` style of the component in any [supported CSS unit](slug:common-features/dimensions). The default AIPrompt dimensions depend on the CSS theme. | +| `PromptContext` | `string` | This text is appended to the prompt when sending the request. This is required in order to allow the component to work with external context, which is not visible in the prompt box. | `PromptText` | `string` | The value of the text within the prompt view. Use it when you need to add some form of transformation to the prompt. The parameter supports two-way binding. | | `PromptTextChanged` | `EventCallback` | The handler called whenever the `PromptText` changes. | | `PromptSuggestions` | `List` | The prompt suggestions displayed within the Prompt view. | | `PromptSuggestionItemTemplate` | `RenderFragment` | The Prompt Suggestion Item template of the AIPrompt. | -| `Commands` | `List` | The predefined commands displayed within the Commands view. | | `ShowOutputRating` | `bool`
(`false`) | Controls the visibility of the rating buttons within the output card. | -| `Class` | `string` | The `class` attribute of the `
` element. Use it to apply custom styles or [override the theme]({%slug themes-override%}). | -| `Height` | `string` | The `height` style of the component in any [supported CSS unit]({%slug common-features/dimensions%}). The default AIPrompt dimensions depend on the CSS theme. | -| `Width` | `string` | The `width` style of the component in any [supported CSS unit]({%slug common-features/dimensions%}). The default AIPrompt dimensions depend on the CSS theme. | +| `SystemPrompt` | `string`
(See "Description" column) | Defines the system prompt that is passed to the [Microsoft `ChatMessage`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai.chatmessage) object constructor.

The default `SystemPrompt` value is: `"You are a helpful assistant designed to assist users. Your goal is to provide helpful, accurate, and contextually appropriate information in a clear and concise manner. Avoid discussing harmful, illegal, or inappropriate topics."`. +| `Width` | `string` | The `width` style of the component in any [supported CSS unit](slug:common-features/dimensions). The default AIPrompt dimensions depend on the CSS theme. | ## AIPrompt Reference and Methods @@ -147,14 +152,14 @@ The AIPrompt exposes methods for programmatic operation. To use them, define a r ## Next Steps -* [Configure the AIPrompt ToolBar]({%slug aiprompt-toolbar%}) -* [Customize the AIPrompt Views]({%slug aiprompt-views-overview%}) -* [Make the AIPrompt Your Own through Custom Commands]({%slug aiprompt-views-commands%}) -* [Implement AIPrompt Views Templates]({%slug aiprompt-views-templates%}) -* [Implement AIPrompt Templates]({%slug aiprompt-templates%}) -* [Handle the AIPrompt Events]({%slug aiprompt-events%}) +* [Configure the AIPrompt ToolBar](slug:aiprompt-toolbar) +* [Customize the AIPrompt Views](slug:aiprompt-views-overview) +* [Make the AIPrompt Your Own through Custom Commands](slug:aiprompt-views-commands) +* [Implement AIPrompt Views Templates](slug:aiprompt-views-templates) +* [Implement AIPrompt Templates](slug:aiprompt-templates) +* [Handle the AIPrompt Events](slug:aiprompt-events) ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) -* [AIPrompt API Reference](/blazor-ui/api/Telerik.Blazor.Components.TelerikAIPrompt) +* [AIPrompt API Reference](slug:Telerik.Blazor.Components.TelerikAIPrompt) diff --git a/components/aiprompt/templates.md b/components/aiprompt/templates.md index f7b5eb6885..79b274e14b 100644 --- a/components/aiprompt/templates.md +++ b/components/aiprompt/templates.md @@ -12,11 +12,11 @@ position: 30 The AIPrompt component provides the `PromptSuggestionItemTemplate` that allows you to change the appearance of the prompt suggestions made by the component. ->tip The AIPrompt component also implements [View templates]({%slug aiprompt-templates%}) that control the rendering of the Prompt, Output, and Command views. +>tip The AIPrompt component also implements [View templates](slug:aiprompt-templates) that control the rendering of the Prompt, Output, and Command views. The Prompt view of the AIPrompt renders any suggestions passed to the `PromptSuggestions` parameter in the form of elevated bubbles within a collapsible section. The `PromptSuggestionItemTemplate` allows you to control the rendering of individual suggestions. ->note By default, clicking on a suggestion will populate the prompt's input with the suggestion's value and also trigger a `PromptTextChanged` event. If you use the `PromptSuggestionItemTemplate`, you should also handle [any event]({%slug aiprompt-events%}) you deem necessary (such as `onclick`). +>note By default, clicking on a suggestion will populate the prompt's input with the suggestion's value and also trigger a `PromptTextChanged` event. If you use the `PromptSuggestionItemTemplate`, you should also handle [any event](slug:aiprompt-events) you deem necessary (such as `onclick`). >caption Using the `PromptSuggestionItemTemplate` to alter the appearance of the suggestions @@ -71,4 +71,4 @@ The Prompt view of the AIPrompt renders any suggestions passed to the `PromptSug ## See Also -* [Views Templates]({%slug aiprompt-views-templates%}) +* [Views Templates](slug:aiprompt-views-templates) diff --git a/components/aiprompt/toolbar.md b/components/aiprompt/toolbar.md index 140e7280ac..69a9ffb984 100644 --- a/components/aiprompt/toolbar.md +++ b/components/aiprompt/toolbar.md @@ -34,7 +34,7 @@ The `AIPromptToolBarButton` tag exposes parameters that allow you to customize t | Parameter | Type and Default Value | Description | | ----------- | ----------- | ----------- | | `Class` | `string` | The CSS class that will be rendered on the main wrapping element of the AIPromptToolBarButton. You could use that class to cascade styles. | -| `Icon` | `object` | Adds a font icon to the button. You can find more information on adding a font icon to a Telerik Component in [Telerik Font and Svg Icons article]({%slug common-features-icons%}#icon-namespaces). | +| `Icon` | `object` | Adds a font icon to the button. You can find more information on adding a font icon to a Telerik Component in [Telerik Font and Svg Icons article](slug:common-features-icons#icon-namespaces). | | `OnClick` | `EventCallback` | The onclick event handler. | | `ChildContent` | `RenderFragment` | The child content rendered within the button. | @@ -88,11 +88,11 @@ The example below omits any event handlers for brevity. Custom buttons are to be ## Next Steps -* [Customize the AIPrompt Views]({%slug aiprompt-views-overview%}) -* [Implement AIPrompt Templates]({%slug aiprompt-templates%}) -* [Handle AIPrompt Events]({%slug aiprompt-events%}) +* [Customize the AIPrompt Views](slug:aiprompt-views-overview) +* [Implement AIPrompt Templates](slug:aiprompt-templates) +* [Handle AIPrompt Events](slug:aiprompt-events) ## See Also -* [Views Templates]({%slug aiprompt-views-templates%}) +* [Views Templates](slug:aiprompt-views-templates) * [Live Demo: AIPrompt Overview](https://demos.telerik.com/blazor-ui/aiprompt/overview) \ No newline at end of file diff --git a/components/aiprompt/views/commands.md b/components/aiprompt/views/commands.md index 70465f5a4e..ded90a1f1f 100644 --- a/components/aiprompt/views/commands.md +++ b/components/aiprompt/views/commands.md @@ -24,7 +24,8 @@ The following properties enable you to customize each command: | ----------- | ----------- | ----------- | | `Id` | `string` | The `Id` of the command. | | `Title` | `string` | The title of the command. Rendered as text within the Command view. | -| `Icon` | `object` | The [Telerik Font or SVG icon]({%slug common-features-icons%}) rendered before the title within the Command view. | +| `Icon` | `object` | The [Telerik Font or SVG icon](slug:common-features-icons) rendered before the title within the Command view. | +| `Prompt` | `string` | The text to send as the prompt when this command is executed by the AIPrompt. | | `Children` | `List` | The nested commands (if any) of the command. | >caption Using the `Commands` parameter to pass a collection of predefined commands to the AIPrompt for Blazor @@ -42,31 +43,31 @@ The following properties enable you to customize each command: new AIPromptCommandDescriptor() { Id = "2", Title = "Change Tone", Icon = SvgIcon.TellAFriend, Children = new List { - new AIPromptCommandDescriptor() { Id = "3", Title = "Professional" }, - new AIPromptCommandDescriptor() { Id = "4", Title = "Conversational" }, - new AIPromptCommandDescriptor() { Id = "5", Title = "Humorous" }, - new AIPromptCommandDescriptor() { Id = "6", Title = "Empathic" }, - new AIPromptCommandDescriptor() { Id = "7", Title = "Academic" }, + new AIPromptCommandDescriptor() { Id = "3", Title = "Professional", Prompt = "Change the tone of the following text to professional" }, + new AIPromptCommandDescriptor() { Id = "4", Title = "Conversational", Prompt = "Change the tone of the following text to conversational" }, + new AIPromptCommandDescriptor() { Id = "5", Title = "Humorous", Prompt = "Change the tone of the following text to humorous" }, + new AIPromptCommandDescriptor() { Id = "6", Title = "Empathic", Prompt = "Change the tone of the following text to empathic" }, + new AIPromptCommandDescriptor() { Id = "7", Title = "Academic", Prompt = "Change the tone of the following text to academic" }, } }, new AIPromptCommandDescriptor() { Id = "8", Title = "Change Formality", Icon = SvgIcon.ApplyFormat, Children = new List { - new AIPromptCommandDescriptor() { Id = "9", Title = "Casual" }, - new AIPromptCommandDescriptor() { Id = "10", Title = "Neutral" }, - new AIPromptCommandDescriptor() { Id = "11", Title = "Formal" }, + new AIPromptCommandDescriptor() { Id = "9", Title = "Casual", Prompt = "Change the formality of the following text to casual" }, + new AIPromptCommandDescriptor() { Id = "10", Title = "Neutral", Prompt = "Change the formality of the following text to neutral" }, + new AIPromptCommandDescriptor() { Id = "11", Title = "Formal", Prompt = "Change the formality of the following text to formal" }, } }, new AIPromptCommandDescriptor() { Id = "12", Title = "Translate", Icon = SvgIcon.EditTools, Children = new List { - new AIPromptCommandDescriptor() { Id = "13", Title = "English" }, - new AIPromptCommandDescriptor() { Id = "14", Title = "Bulgarian" }, - new AIPromptCommandDescriptor() { Id = "15", Title = "Spanish" }, + new AIPromptCommandDescriptor() { Id = "13", Title = "English", Prompt = "Translate the following text to English" }, + new AIPromptCommandDescriptor() { Id = "14", Title = "Bulgarian", Prompt = "Translate the following text to Bulgarian" }, + new AIPromptCommandDescriptor() { Id = "15", Title = "Spanish", Prompt = "Translate the following text to Spanish" }, } }, - new AIPromptCommandDescriptor() { Id = "16", Title = "Simplify", Icon = SvgIcon.MinWidth }, - new AIPromptCommandDescriptor() { Id = "17", Title = "Expand", Icon = SvgIcon.MaxWidth }, + new AIPromptCommandDescriptor() { Id = "16", Title = "Simplify", Icon = SvgIcon.MinWidth, Prompt = "Simplify the following text" }, + new AIPromptCommandDescriptor() { Id = "17", Title = "Expand", Icon = SvgIcon.MaxWidth, Prompt = "Expand the following text" }, }; private void HandlePromptRequest(AIPromptPromptRequestEventArgs args) @@ -86,7 +87,7 @@ The following properties enable you to customize each command: ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) - * [Views Overview]({%slug aiprompt-views-overview%}) - * [Prompt View]({%slug aiprompt-views-prompt%}) - * [Output View]({%slug aiprompt-views-output%}) - * [Views Templates]({%slug aiprompt-views-templates%}) \ No newline at end of file + * [Views Overview](slug:aiprompt-views-overview) + * [Prompt View](slug:aiprompt-views-prompt) + * [Output View](slug:aiprompt-views-output) + * [Views Templates](slug:aiprompt-views-templates) \ No newline at end of file diff --git a/components/aiprompt/views/output.md b/components/aiprompt/views/output.md index e82ede7b05..6c9740903b 100644 --- a/components/aiprompt/views/output.md +++ b/components/aiprompt/views/output.md @@ -12,7 +12,7 @@ position: 20 The Output view shows the responses generated by the underlying AI service. Each response renders in its dedicated output card and provides two options to the user—to copy the content of the response or to retry the request. The Output view is activated through interaction—once the user fills out a prompt within the Prompt view and requests a response, the Output view will become active. -If the `ShowOutputRating` is enabled on the component level, the output card will also feature two additional options-to upvote or downvote the response. To handle this interaction, you can use the `OnOutputRate` event. For more information on how to handle the event, refer to the [AIPrompt events]({%slug aiprompt-events%}) article. +If the `ShowOutputRating` is enabled on the component level, the output card will also feature two additional options-to upvote or downvote the response. To handle this interaction, you can use the `OnOutputRate` event. For more information on how to handle the event, refer to the [AIPrompt events](slug:aiprompt-events) article. By default, the Output view is rendered and is part of the predefined views. However, if you provide a render fragment of type `AIPromptViews` to the `TelerikAIPrompt` tag, you override the default rendering, meaning you must explicitly add `AIPromptOutputView` tag within it. @@ -54,7 +54,7 @@ By default, the Output view is rendered and is part of the predefined views. How ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) - * [Views Overview]({%slug aiprompt-views-overview%}) - * [Prompt View]({%slug aiprompt-views-prompt%}) - * [Commands View]({%slug aiprompt-views-commands%}) - * [Views Templates]({%slug aiprompt-views-templates%}) \ No newline at end of file + * [Views Overview](slug:aiprompt-views-overview) + * [Prompt View](slug:aiprompt-views-prompt) + * [Commands View](slug:aiprompt-views-commands) + * [Views Templates](slug:aiprompt-views-templates) \ No newline at end of file diff --git a/components/aiprompt/views/overview.md b/components/aiprompt/views/overview.md index a827db238d..c2cd597eb2 100644 --- a/components/aiprompt/views/overview.md +++ b/components/aiprompt/views/overview.md @@ -14,9 +14,9 @@ The AIPrompt component provides three predefined views and also lets you create The available built-in views are: -* [Prompt View]({%slug aiprompt-views-prompt%}) -* [Output View]({%slug aiprompt-views-output%}) -* [Commands View]({%slug aiprompt-views-commands%}) +* [Prompt View](slug:aiprompt-views-prompt) +* [Output View](slug:aiprompt-views-output) +* [Commands View](slug:aiprompt-views-commands) ## Parameters @@ -27,9 +27,9 @@ The AIPrompt views provide various parameters that allow you to configure the co | Parameter | Type | Description | | --- | --- | --- | | `ButtonText` | `string` | The text rendered within the toolbar button associated with the view. | -| `ButtonIcon` | `object` | The [Telerik Font or SVG icon]({%slug common-features-icons%}) rendered within the toolbar button associated with the view. | -| `ViewTemplate` | `RenderFragment` | The template controlling the rendering of the view's content. Read more in the [Templates]({%slug aiprompt-views-templates%}#view-template) article. | -| `FooterTemplate` | `RenderFragment` | The template controlling the rendering of the view's footer. Read more in the [Templates]({%slug aiprompt-views-templates%}#footer-template) article. | +| `ButtonIcon` | `object` | The [Telerik Font or SVG icon](slug:common-features-icons) rendered within the toolbar button associated with the view. | +| `ViewTemplate` | `RenderFragment` | The template controlling the rendering of the view's content. Read more in the [Templates](slug:aiprompt-views-templates#view-template) article. | +| `FooterTemplate` | `RenderFragment` | The template controlling the rendering of the view's footer. Read more in the [Templates](slug:aiprompt-views-templates#footer-template) article. | By default, the AIPrompt will always render both the Prompt and the Output view. The Commands view will be rendered only if you pass a custom set of commands through the `Commands` parameter: @@ -74,8 +74,8 @@ By default, the AIPrompt will always render both the Prompt and the Output view. ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) - * [Prompt View]({%slug aiprompt-views-prompt%}) - * [Output View]({%slug aiprompt-views-output%}) - * [Commands View]({%slug aiprompt-views-commands%}) - * [Views Templates]({%slug aiprompt-views-templates%}) + * [Prompt View](slug:aiprompt-views-prompt) + * [Output View](slug:aiprompt-views-output) + * [Commands View](slug:aiprompt-views-commands) + * [Views Templates](slug:aiprompt-views-templates) diff --git a/components/aiprompt/views/prompt.md b/components/aiprompt/views/prompt.md index d4abf0c9c2..8e6c9673f6 100644 --- a/components/aiprompt/views/prompt.md +++ b/components/aiprompt/views/prompt.md @@ -38,7 +38,7 @@ Additionally, the Prompt view can display prompt suggestions related to the prom ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) - * [Views Overview]({%slug aiprompt-views-overview%}) - * [Prompt View]({%slug aiprompt-views-prompt%}) - * [Output View]({%slug aiprompt-views-output%}) - * [Views Templates]({%slug aiprompt-views-templates%}) \ No newline at end of file + * [Views Overview](slug:aiprompt-views-overview) + * [Prompt View](slug:aiprompt-views-prompt) + * [Output View](slug:aiprompt-views-output) + * [Views Templates](slug:aiprompt-views-templates) \ No newline at end of file diff --git a/components/aiprompt/views/templates.md b/components/aiprompt/views/templates.md index aa77fe973a..efc4db98d7 100644 --- a/components/aiprompt/views/templates.md +++ b/components/aiprompt/views/templates.md @@ -83,7 +83,7 @@ The `FooterTemplate` allows you to control the rendering of the footer within in ## See Also * [Live Demo: AIPrompt](https://demos.telerik.com/blazor-ui/aiprompt/overview) - * [Views Overview]({%slug aiprompt-views-overview%}) - * [Prompt View]({%slug aiprompt-views-prompt%}) - * [Output View]({%slug aiprompt-views-output%}) - * [Commands View]({%slug aiprompt-views-commands%}) \ No newline at end of file + * [Views Overview](slug:aiprompt-views-overview) + * [Prompt View](slug:aiprompt-views-prompt) + * [Output View](slug:aiprompt-views-output) + * [Commands View](slug:aiprompt-views-commands) \ No newline at end of file diff --git a/components/animationcontainer/overview.md b/components/animationcontainer/overview.md index 8a776c64c2..725f6ae308 100644 --- a/components/animationcontainer/overview.md +++ b/components/animationcontainer/overview.md @@ -12,7 +12,7 @@ position: 0 The Blazor Animation Container component enables you to create messages and popups or expandable containers. It lets you define its animation, size and position, and arbitrary content. ->tip If you are looking for an option to create [Notification]({%slug notification-overview%}), [Tooltip]({%slug tooltip-overview%}) or expandable container such as [Drawer]({%slug drawer-overview%}), you may use the dedicated components. +>tip The `AnimationContainer` animates and renders content in-place and does not have all the features of a true popup. [Compare the abilities of all Telerik Blazor popup components](slug:common-kb-popup-component-comparison) to verify if the [Popup](slug:popup-overview) or [Popover](slug:popover-overview) components are more suitable for your needs. If you are looking for an option to create [Notification](slug:notification-overview), [Tooltip](slug:tooltip-overview) or expandable container such as [Drawer](slug:drawer-overview), you may use the dedicated components. ## Creating Blazor AnimationContainer @@ -51,7 +51,7 @@ The Blazor ## AppBar Sections -Use the AppBar Sections to render arbitrary HTML content to match the UI and UX needs of your application. [Read more about the Blazor AppBar sections...]({%slug appbar-sections%}) +Use the AppBar Sections to render arbitrary HTML content to match the UI and UX needs of your application. [Read more about the Blazor AppBar sections...](slug:appbar-sections) ## Content Dividers -The AppBar features separators and spacers that can visually divide the component items. [Read more about the Blazor AppBar separators and spacers.]({%slug appbar-separators%}). +The AppBar features separators and spacers that can visually divide the component items. [Read more about the Blazor AppBar separators and spacers.](slug:appbar-separators). ## Positioning -You can control the position of the AppBar and how the component behaves according to the flow of the page. [Read more about the Blazor AppBar positioning.]({%slug appbar-position%}). +You can control the position of the AppBar and how the component behaves according to the flow of the page. [Read more about the Blazor AppBar positioning.](slug:appbar-position). ## AppBar Parameters -The Blazor AppBar provides parameters to configure the component. Also check the [AppBar API Reference](/blazor-ui/api/Telerik.Blazor.Components.TelerikAppBar) for a full list of properties. +The Blazor AppBar provides parameters to configure the component. Also check the [AppBar API Reference](slug:Telerik.Blazor.Components.TelerikAppBar) for a full list of properties. @[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) | Parameter | Type | Description | | ----------- | ----------- | ----------- | -| `Position` | `AppBarPosition`
(`None`) | The position of the AppBar on the page. [Read more about AppBar positioning.]({%slug appbar-position%}) | -| `PositionMode` | `AppBarPosition`
(`Static`) | Sets how the AppBar is positioned according to the flow of the document. [Read more about AppBar positioning.]({%slug appbar-position%}) | +| `Position` | `AppBarPosition`
(`None`) | The position of the AppBar on the page. [Read more about AppBar positioning.](slug:appbar-position) | +| `PositionMode` | `AppBarPosition`
(`Static`) | Sets how the AppBar is positioned according to the flow of the document. [Read more about AppBar positioning.](slug:appbar-position) | ### Styling and Appearance @@ -87,12 +87,12 @@ The following parameters enable you to customize the appearance of the Blazor Ap | Parameter | Type | Description | | --- | --- | --- | -| `Class` | `string` | The CSS class to be rendered on the main wrapping element of the AppBar component, which is `
`. Use for [styling customizations]({%slug themes-override%}). | +| `Class` | `string` | The CSS class to be rendered on the main wrapping element of the AppBar component, which is `
`. Use for [styling customizations](slug:themes-override). | | `Height` | `string` | The height of the AppBar. | | `ThemeColor` | `Telerik.Blazor.ThemeConstants.AppBar.ThemeColor` | Adjust the color of the AppBar | | `Width` | `string` | The width of the AppBar. | -You can find more information for customizing the AppBar appearance in the [Appearance article]({%slug appbar-appearance%}). +You can find more information for customizing the AppBar appearance in the [Appearance article](slug:appbar-appearance). ## AppBar Reference and Methods @@ -121,11 +121,11 @@ To execute AppBar methods, obtain reference to the component instance with `@ref ## Next Steps -* [Explore the AppBar Sections]({%slug appbar-sections%}) -* [Use the AppBar Sections]({%slug appbar-separators%}) -* [Customize the AppBar position]({%slug appbar-position%}) +* [Explore the AppBar Sections](slug:appbar-sections) +* [Use the AppBar Sections](slug:appbar-separators) +* [Customize the AppBar position](slug:appbar-position) ## See Also * [Live AppBar Demos](https://demos.telerik.com/blazor-ui/appbar/overview) -* [AppBar API Reference](/blazor-ui/api/Telerik.Blazor.Components.TelerikAppBar) +* [AppBar API Reference](slug:Telerik.Blazor.Components.TelerikAppBar) diff --git a/components/appbar/sections.md b/components/appbar/sections.md index 3d377cf1c2..e8117b843d 100644 --- a/components/appbar/sections.md +++ b/components/appbar/sections.md @@ -56,4 +56,4 @@ The nested `AppBarSection` tag exposes parameters: ## See Also * [Live Demo: AppBar Overview](https://demos.telerik.com/blazor-ui/appbar/overview) - * [AppBar Overview]({%slug appbar-overview%}) + * [AppBar Overview](slug:appbar-overview) diff --git a/components/appbar/separators.md b/components/appbar/separators.md index 85ace98537..b185948ac9 100644 --- a/components/appbar/separators.md +++ b/components/appbar/separators.md @@ -38,7 +38,7 @@ The nested `AppBarSpacer` tag exposes the following parameters: | Parameter | Type and Default Value | Description | | ----------- | ----------- | ----------- | | `Class` | `string` | The CSS class that will be rendered on the main wrapping element of the AppBar spacer. Use that class to cascade styles. | -| `Size` | `string` | The width of the spacer. All `AppBarSpacer` tags without Size will take up the same amount of the remaining space between the [Sections]({%slug appbar-sections%}). | +| `Size` | `string` | The width of the spacer. All `AppBarSpacer` tags without Size will take up the same amount of the remaining space between the [Sections](slug:appbar-sections). | | `Visible` | `bool`
`true` | Specifies if the spacer will be visible in the AppBar. | >caption The AppBar separators @@ -87,4 +87,4 @@ The nested `AppBarSpacer` tag exposes the following parameters: ## See Also * [Live Demo: AppBar Overview](https://demos.telerik.com/blazor-ui/appbar/overview) - * [AppBar Overview]({%slug appbar-overview%}) + * [AppBar Overview](slug:appbar-overview) diff --git a/components/autocomplete/accessibility/wai-aria-support.md b/components/autocomplete/accessibility/wai-aria-support.md index 08700b0ee0..2e5656ac3f 100644 --- a/components/autocomplete/accessibility/wai-aria-support.md +++ b/components/autocomplete/accessibility/wai-aria-support.md @@ -16,7 +16,7 @@ position: 50 Out of the box, the Telerik UI for Blazor AutoComplete provides extensive accessibility support and enables users with disabilities to acquire complete control over its features. -The AutoComplete is compliant with the [Web Content Accessibility Guidelines (WCAG) 2.2 AA](https://www.w3.org/TR/WCAG22/) standards and [Section 508](https://www.section508.gov/) requirements, follows the [Web Accessibility Initiative - Accessible Rich Internet Applications (WAI-ARIA)](https://www.w3.org/WAI/ARIA/apg/) best practices for implementing the [keyboard navigation]({%slug accessibility-keyboard-navigation%}) for its `component` role, provides options for managing its focus and is tested against the most popular screen readers. +The AutoComplete is compliant with the [Web Content Accessibility Guidelines (WCAG) 2.2 AA](https://www.w3.org/TR/WCAG22/) standards and [Section 508](https://www.section508.gov/) requirements, follows the [Web Accessibility Initiative - Accessible Rich Internet Applications (WAI-ARIA)](https://www.w3.org/WAI/ARIA/apg/) best practices for implementing the [keyboard navigation](#keyboard-navigation) for its `component` role, provides options for managing its focus and is tested against the most popular screen readers. ## WAI-ARIA @@ -95,8 +95,10 @@ The AutoComplete has been tested with the following screen readers and browsers +## Keyboard Navigation + +For details on how the AutoComplete keyboard navigation works, refer to the [Blazor AutoComplete Accessibility and Keyboard Navigation Demo](https://demos.telerik.com/blazor-ui/autocomplete/keyboard-navigation). + ## See Also -* [Blazor AutoComplete Accessibility and Keyboard Navigation (Demo)](https://demos.telerik.com/blazor-ui/autocomplete/keyboard-navigation) -* [Accessibility in Telerik UI for Blazor]({% slug accessibility-overview %}) -* [Accessibility Theme]({% slug themes-accessibility-swatch %}) \ No newline at end of file +* [Accessibility in Telerik UI for Blazor](slug:accessibility-overview) \ No newline at end of file diff --git a/components/autocomplete/data-bind.md b/components/autocomplete/data-bind.md index 20cb8c0cdd..f380ecd47d 100644 --- a/components/autocomplete/data-bind.md +++ b/components/autocomplete/data-bind.md @@ -92,57 +92,7 @@ To bind the AutoComplete to a model: } ```` -## Considerations - -### Reference - -The AutoComplete is a generic component and its type depends on the type of its `Data` and `Value`. - -
-````RAZOR String -@*Reference when binding to a string collection*@ - - - -@code{ - private TelerikAutoComplete AutoCompleteRef { get; set; } - - private string AutoCompleteValue { get; set; } - - private List Suggestions { get; set; } = new List { "first", "second", "third" }; -} -```` -````RAZOR Model -@*Reference when binding to a model collection*@ - - - -@code{ - private TelerikAutoComplete AutoCompleteRef { get; set; } - - private string AutoCompleteValue { get; set; } - - private List Suggestions { get; set; } = new List - { - new SuggestionsModel { Suggestion = "first", SomeOtherField = 1 }, - new SuggestionsModel { Suggestion = "second", SomeOtherField = 2 }, - new SuggestionsModel { Suggestion = "third", SomeOtherField = 3 } - }; - - public class SuggestionsModel - { - public string Suggestion { get; set; }//the auto complete needs only the string field - public int SomeOtherField { get; set; } - } -} -```` - -### Missing Data +## Missing Data The AutoComplete is, essentially, a textbox. This means that its `Value` is always a string and it is up to you to bind and/or use it. The `Data` parameter, however, is required for the functionality of the component, and it must never be `null`. If there are no suggestions that you wish to provide to the user, consider using a regular TextBox, or creating an empty collection. @@ -160,5 +110,5 @@ The AutoComplete is, essentially, a textbox. This means that its `Value` is alwa ## See Also -* [AutoComplete Overview]({%slug autocomplete-overview%}) +* [AutoComplete Overview](slug:autocomplete-overview) * [Live Demo: AutoComplete](https://demos.telerik.com/blazor-ui/autocomplete/overview) diff --git a/components/autocomplete/events.md b/components/autocomplete/events.md index fef08b189d..9863672b8e 100644 --- a/components/autocomplete/events.md +++ b/components/autocomplete/events.md @@ -116,15 +116,15 @@ from model: @Role ## OnRead -You can use the [`OnRead` event]({%slug common-features-data-binding-onread%}) to provide data to the component based on custom logic and the current user input and/or scroll position (when using [virtualization]({%slug autocomplete-virtualization%})). The event fires when: +You can use the [`OnRead` event](slug:common-features-data-binding-onread) to provide data to the component based on custom logic and the current user input and/or scroll position (when using [virtualization](slug:autocomplete-virtualization)). The event fires when: * The component initializes. -* The user [filters]({%slug autocomplete-filter%}). -* The user scrolls with [virtualization]({%slug autocomplete-virtualization%}) enabled. +* The user [filters](slug:autocomplete-filter). +* The user scrolls with [virtualization](slug:autocomplete-virtualization) enabled. You can also call remote data through async operations. -Find out how to [get the applied filtering and grouping criteria]({%slug common-features-descriptors%}). +Find out how to [get the applied filtering and grouping criteria](slug:common-features-descriptors). When using `OnRead`, make sure to set `TItem` and `TValue`. @@ -380,7 +380,7 @@ The `OnBlur` event fires when the component loses focus. ## See Also -* [ValueChanged and Validation]({%slug value-changed-validation-model%}) -* [Fire OnChange Only Once]({%slug ddl-kb-onchange-fires-twice%}) -* [Filter AutoComplete Items]({%slug autocomplete-filter%}) -* [Refresh AutoComplete Data]({%slug autocomplete-refresh-data%}) +* [ValueChanged and Validation](slug:value-changed-validation-model) +* [Fire OnChange Only Once](slug:ddl-kb-onchange-fires-twice) +* [Filter AutoComplete Items](slug:autocomplete-filter) +* [Refresh AutoComplete Data](slug:autocomplete-refresh-data) diff --git a/components/autocomplete/filter.md b/components/autocomplete/filter.md index 0b3c64d64c..8a325dae16 100644 --- a/components/autocomplete/filter.md +++ b/components/autocomplete/filter.md @@ -14,8 +14,8 @@ The AutoComplete component can filter the available suggestions, according to th To enable filtering, set the `Filterable` parameter to `true`. The filtering is case insensitive. -You can also use the [`OnRead` event]({%slug autocomplete-events%}#onread) to: -* Get the [applied filtering criteria]({%slug common-features-descriptors%}#through-the-onread-event). +You can also use the [`OnRead` event](slug:autocomplete-events#onread) to: +* Get the [applied filtering criteria](slug:common-features-descriptors#through-the-onread-event). * Implement custom (server) filtering and set data dynamically. ## Filter Operator @@ -28,7 +28,7 @@ To control when the filter list appears, set the `MinLength` parameter. This can ## Performance -By default, the filtering is debounced with 150ms. Configure that with the [`DebounceDelay`]({%slug autocomplete-overview%}#autocomplete-parameters) parameter of the component. +By default, the filtering is debounced with 150ms. Configure that with the [`DebounceDelay`](slug:autocomplete-overview#autocomplete-parameters) parameter of the component. ## Filtering Example @@ -92,4 +92,4 @@ By default, the filtering is debounced with 150ms. Configure that with the [`Deb * [Live Demo: AutoComplete Filtering](https://demos.telerik.com/blazor-ui/autocomplete/filtering) -* [Custom Filtering by Multiple Fields]({%slug dropdowns-kb-search-in-multiple-fields%}) +* [Custom Filtering by Multiple Fields](slug:dropdowns-kb-search-in-multiple-fields) diff --git a/components/autocomplete/grouping.md b/components/autocomplete/grouping.md index 864d30f703..359a35b20b 100644 --- a/components/autocomplete/grouping.md +++ b/components/autocomplete/grouping.md @@ -66,7 +66,7 @@ The group headers can stick to the top of the dropdown during scrolling. In othe # Notes * One level of grouping is supported. -* A grouped AutoComplete will provide a `Groups` property with a single [`GroupDescriptor`](/blazor-ui/api/Telerik.DataSource.GroupDescriptor) in the [`DataSourceRequest`](/blazor-ui/api/Telerik.DataSource.DataSourceRequest) argument of its [OnRead event]({%slug autocomplete-events%}#onread). This will allow the developer to apply grouping with [manual data operations]({%slug components/grid/manual-operations%}). +* A grouped AutoComplete will provide a `Groups` property with a single [`GroupDescriptor`](slug:Telerik.DataSource.GroupDescriptor) in the [`DataSourceRequest`](slug:Telerik.DataSource.DataSourceRequest) argument of its [OnRead event](slug:autocomplete-events#onread). This will allow the developer to apply grouping with [manual data operations](slug:components/grid/manual-operations). ## See Also diff --git a/components/autocomplete/overview.md b/components/autocomplete/overview.md index 80e96565e4..92d6411f52 100644 --- a/components/autocomplete/overview.md +++ b/components/autocomplete/overview.md @@ -10,13 +10,13 @@ position: 0 # Blazor AutoComplete Overview -The
Blazor AutoComplete component is a textbox that offers the users hints as they type. These suggestions can be [filtered]({%slug autocomplete-filter%}) as the user types. The user can write their own value or click a suggestion from the dropdown to select it and populate the input. You can control the list of suggestions through [data binding]({%slug autocomplete-databind%}), various appearance settings like [dimensions]({%slug common-features/dimensions%}) and [templates]({%slug autocomplete-templates%}). +The Blazor AutoComplete component is a textbox that offers the users hints as they type. These suggestions can be [filtered](slug:autocomplete-filter) as the user types. The user can write their own value or click a suggestion from the dropdown to select it and populate the input. You can control the list of suggestions through [data binding](slug:autocomplete-databind), various appearance settings like [dimensions](slug:common-features/dimensions) and [templates](slug:autocomplete-templates). ## Creating AutoComplete 1. Use the `TelerikAutoComplete` tag to add the component to your razor page. 1. Populate the `Data` property with the collection of items that you want to appear in the dropdown. -1. [Bind the value of the component]({%slug get-started-value-vs-data-binding %}#value-binding) to the same type as the member of the `ValueField` parameter. +1. [Bind the value of the component](slug:get-started-value-vs-data-binding#value-binding) to the same type as the member of the `ValueField` parameter. 1. (Optional) Enable features like placeholder text and clear button. >caption AutoComplete with two-way value binding and data binding to collection of strings @@ -41,25 +41,25 @@ User input: @AutoCompleteValue } ```` ->tip If you want to get a value identifier for the items in the dropdown instead of their text, consider the [ComboBox component](slug://components/combobox/overview). The **AutoComplete** is a **free text** input that accepts any text the user writes, not just the suggestions from the dropdown. Thus, the `Value` of the AutoComplete is always a `string`, while the ComboBox can provide you with a `number` or a `Guid`, not only a `string`. +>tip If you want to get a value identifier for the items in the dropdown instead of their text, consider the [ComboBox component](slug:components/combobox/overview). The **AutoComplete** is a **free text** input that accepts any text the user writes, not just the suggestions from the dropdown. Thus, the `Value` of the AutoComplete is always a `string`, while the ComboBox can provide you with a `number` or a `Guid`, not only a `string`. ## Data Binding -The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#data-binding) [Read more about the Blazor AutoComplete data binding...]({%slug autocomplete-databind%}) +The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#data-binding) [Read more about the Blazor AutoComplete data binding...](slug:autocomplete-databind) ## Filtering -The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#filtering) [Read more about the Blazor AutoComplete filter...]({%slug autocomplete-filter%}) +The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#filtering) [Read more about the Blazor AutoComplete filter...](slug:autocomplete-filter) ## Grouping -The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#grouping) [Read more about the Blazor AutoComplete grouping...]({%slug components/autocomplete/grouping%}) +The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#grouping) [Read more about the Blazor AutoComplete grouping...](slug:components/autocomplete/grouping) @[template](/_contentTemplates/common/inputs.md#adornments) ## Templates -@[template](/_contentTemplates/dropdowns/features.md#templates) [Read more about the Blazor AutoComplete templates...]({%slug autocomplete-templates%}) +@[template](/_contentTemplates/dropdowns/features.md#templates) [Read more about the Blazor AutoComplete templates...](slug:autocomplete-templates) ## Validation @@ -67,10 +67,12 @@ The Blazor AutoComplete @[template](/_contentTemplates/dropdowns/features.md#gro ## Virtualization -@[template](/_contentTemplates/dropdowns/features.md#virtualization) [Read more about the Blazor AutoComplete virtualization...]({% slug autocomplete-virtualization %}) +@[template](/_contentTemplates/dropdowns/features.md#virtualization) [Read more about the Blazor AutoComplete virtualization...](slug:autocomplete-virtualization) ## Adaptive Rendering + + @[template](/_contentTemplates/dropdowns/adaptive-rendering.md#intro) ## AutoComplete Parameters @@ -81,23 +83,24 @@ The Blazor AutoComplete provides various parameters that allow you to configure | Parameter | Type | Description | | ----------- | ----------- | -------| -| `AdaptiveMode` | `AdaptiveMode`
(`None`) | The [adaptive mode]({%slug adaptive-rendering%}) of the component. | +| `AdaptiveMode` | `AdaptiveMode`
(`None`) | The [adaptive mode](slug:adaptive-rendering) of the component. | | `Data` | `IEnumerable` | allows you to provide the data source. Required. | | `DebounceDelay` | `int`
150 | Time in milliseconds between the last typed symbol and the internal `oninput` event firing. Applies when the user types and filters. Use it to balance between client-side performance and number of database queries. | | `Enabled` | `bool` | Whether the component is enabled. | -| `Filterable` | `bool` | Whether [filtering]({%slug multiselect-filter%}) is enabled for the end user (suggestions will get narrowed down as they type). | -| `FilterOperator` | `StringFilterOperator`
(`StartsWith`) | The string operation that will be used for [filtering]({%slug multiselect-filter%}). | +| `Filterable` | `bool` | Whether [filtering](slug:multiselect-filter) is enabled for the end user (suggestions will get narrowed down as they type). | +| `FilterOperator` | `StringFilterOperator`
(`StartsWith`) | The string operation that will be used for [filtering](slug:multiselect-filter). | | `Id` | `string` | Renders as the `id` attribute on the `` element, so you can attach a `