diff --git a/BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor.cs b/BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor.cs index e076eb178..64f809290 100644 --- a/BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor.cs +++ b/BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor.cs @@ -6,95 +6,100 @@ internal override IEnumerable GetNavItems() { navItems ??= new List { - new (){ Id = "1", Text = "Getting Started", Href = "/getting-started", IconName = IconName.HouseDoorFill }, + new (){ Id = "1", Text = "Getting Started", Href = RouteConstants.Demos_GettingStarted_Documentation, IconName = IconName.HouseDoorFill }, new (){ Id = "2", Text = "Layout", IconName = IconName.LayoutTextWindowReverse, IconColor = IconColor.Success }, new (){ Id = "200", Text = "Blazor WebAssembly", Href = "/layout-setup/blazor-webassembly", IconName = IconName.BrowserEdge, ParentId = "2" }, new (){ Id = "201", Text = "Blazor Server", Href = "/layout-setup/blazor-server", IconName = IconName.Server, ParentId = "2" }, new (){ Id = "3", Text = "Content", IconName = IconName.BodyText, IconColor = IconColor.Primary }, - new (){ Id = "300", Text = "Icons", Href = "/icons", IconName = IconName.PersonSquare, ParentId = "3" }, - new (){ Id = "301", Text = "Images", Href = "/images", IconName = IconName.Image, ParentId = "3" }, + new (){ Id = "300", Text = "Icons", Href = RouteConstants.Demos_Icons_Documentation, IconName = IconName.PersonSquare, ParentId = "3" }, + new (){ Id = "301", Text = "Images", Href = RouteConstants.Demos_Images_Documentation, IconName = IconName.Image, ParentId = "3" }, new (){ Id = "4", Text = "Forms", IconName = IconName.InputCursorText, IconColor = IconColor.Success }, - new (){ Id = "400", Text = "Auto Complete", Href = "/form/autocomplete", IconName = IconName.InputCursorText, ParentId = "4" }, - new (){ Id = "401", Text = "Currency Input", Href = "/form/currency-input", IconName = IconName.CurrencyDollar, ParentId = "4" }, - new (){ Id = "402", Text = "Date Input", Href = "/form/date-input", IconName = IconName.CalendarDate, ParentId = "4" }, - new (){ Id = "403", Text = "Number Input", Href = "/form/number-input", IconName = IconName.InputCursor, ParentId = "4" }, - new (){ Id = "404", Text = "Range Input", Href = "/form/range-input", IconName = IconName.Sliders, ParentId = "4" }, - new (){ Id = "405", Text = "Switch", Href = "/form/switch", IconName = IconName.ToggleOn, ParentId = "4" }, - new (){ Id = "406", Text = "Time Input", Href = "/form/time-input", IconName = IconName.ClockFill, ParentId = "4" }, + new (){ Id = "400", Text = "Auto Complete", Href = RouteConstants.Demos_AutoComplete_Documentation, IconName = IconName.InputCursorText, ParentId = "4" }, + new (){ Id = "400", Text = "Checkbox Input", Href = RouteConstants.Demos_CheckboxInput_Documentation, IconName = IconName.CheckSquareFill, ParentId = "4" }, + new (){ Id = "401", Text = "Currency Input", Href = RouteConstants.Demos_CurrencyInput_Documentation, IconName = IconName.CurrencyDollar, ParentId = "4" }, + new (){ Id = "402", Text = "Date Input", Href = RouteConstants.Demos_DateInput_Documentation, IconName = IconName.CalendarDate, ParentId = "4" }, + new (){ Id = "403", Text = "Number Input", Href = RouteConstants.Demos_NumberInput_Documentation, IconName = IconName.InputCursor, ParentId = "4" }, + new (){ Id = "403", Text = "Radio Input", Href = RouteConstants.Demos_RadioInput_Documentation, IconName = IconName.RecordCircle, ParentId = "4" }, + new (){ Id = "404", Text = "Range Input", Href = RouteConstants.Demos_RangeInput_Documentation, IconName = IconName.Sliders, ParentId = "4" }, + //new (){ Id = "404", Text = "Select Input", Href = RouteConstants.Demos_SelectInput_Documentation, IconName = IconName.MenuButtonWideFill, ParentId = "4" }, + new (){ Id = "405", Text = "Switch", Href = RouteConstants.Demos_Switch_Documentation, IconName = IconName.ToggleOn, ParentId = "4" }, + new (){ Id = "406", Text = "Text Input", Href = RouteConstants.Demos_TextInput_Documentation, IconName = IconName.InputCursorText, ParentId = "4" }, + new (){ Id = "407", Text = "Text Area Input", Href = RouteConstants.Demos_TextAreaInput_Documentation, IconName = IconName.InputCursorText, ParentId = "4" }, + new (){ Id = "408", Text = "Time Input", Href = RouteConstants.Demos_TimeInput_Documentation, IconName = IconName.ClockFill, ParentId = "4" }, new (){ Id = "5", Text = "Components", IconName = IconName.GearFill, IconColor = IconColor.Danger }, - new (){ Id = "500", Text = "Accordion", Href = "/accordion", IconName = IconName.ChevronBarExpand, ParentId = "5" }, - new (){ Id = "501", Text = "Alerts", Href = "/alerts", IconName = IconName.CheckCircleFill, ParentId = "5" }, - new (){ Id = "502", Text = "Badge", Href = "/badge", IconName = IconName.AppIndicator, ParentId = "5" }, - new (){ Id = "503", Text = "Breadcrumb", Href = "/breadcrumb", IconName = IconName.SegmentedNav, ParentId = "5" }, - new (){ Id = "504", Text = "Buttons", Href = "/buttons", IconName = IconName.ToggleOn, ParentId = "5" }, - new (){ Id = "505", Text = "Callout", Href = "/callout", IconName = IconName.StickyFill, ParentId = "5" }, - new (){ Id = "506", Text = "Card", Href = "/card", IconName = IconName.CardHeading, ParentId = "5" }, - new (){ Id = "507", Text = "Carousel", Href = "/carousel", IconName = IconName.CollectionPlayFill, ParentId = "5" }, - new (){ Id = "508", Text = "Charts", Href = "/charts", IconName = IconName.BarChartLineFill, ParentId = "5", Match = NavLinkMatch.All }, - new (){ Id = "509", Text = "Collapse", Href = "/collapse", IconName = IconName.ArrowsCollapse, ParentId = "5" }, - new (){ Id = "510", Text = "Confirm Dialog", Href = "/confirm-dialog", IconName = IconName.QuestionDiamondFill, ParentId = "5" }, - new (){ Id = "511", Text = "Dropdown", Href = "/dropdown", IconName = IconName.MenuButtonWideFill, ParentId = "5" }, - new (){ Id = "512", Text = "Google Map", Href = "/google-map", IconName = IconName.Map, ParentId = "5" }, + new (){ Id = "500", Text = "Accordion", Href = RouteConstants.Demos_Accordion_Documentation, IconName = IconName.ChevronBarExpand, ParentId = "5" }, + new (){ Id = "501", Text = "Alerts", Href = RouteConstants.Demos_Alerts_Documentation, IconName = IconName.CheckCircleFill, ParentId = "5" }, + new (){ Id = "502", Text = "Badge", Href = RouteConstants.Demos_Badge_Documentation, IconName = IconName.AppIndicator, ParentId = "5" }, + new (){ Id = "503", Text = "Breadcrumb", Href = RouteConstants.Demos_Breadcrumb_Documentation, IconName = IconName.SegmentedNav, ParentId = "5" }, + new (){ Id = "504", Text = "Buttons", Href = RouteConstants.Demos_Buttons_Documentation, IconName = IconName.ToggleOn, ParentId = "5" }, + new (){ Id = "505", Text = "Callout", Href = RouteConstants.Demos_Callout_Documentation, IconName = IconName.StickyFill, ParentId = "5" }, + new (){ Id = "506", Text = "Card", Href = RouteConstants.Demos_Card_Documentation, IconName = IconName.CardHeading, ParentId = "5" }, + new (){ Id = "507", Text = "Carousel", Href = RouteConstants.Demos_Carousel_Documentation, IconName = IconName.CollectionPlayFill, ParentId = "5" }, + new (){ Id = "508", Text = "Charts", Href = RouteConstants.Demos_Charts_Documentation, IconName = IconName.BarChartLineFill, ParentId = "5", Match = NavLinkMatch.All }, + new (){ Id = "509", Text = "Collapse", Href = RouteConstants.Demos_Collapse_Documentation, IconName = IconName.ArrowsCollapse, ParentId = "5" }, + new (){ Id = "510", Text = "Confirm Dialog", Href = RouteConstants.Demos_ConfirmDialog_Documentation, IconName = IconName.QuestionDiamondFill, ParentId = "5" }, + new (){ Id = "511", Text = "Dropdown", Href = RouteConstants.Demos_Dropdown_Documentation, IconName = IconName.MenuButtonWideFill, ParentId = "5" }, + new (){ Id = "512", Text = "Google Map", Href = RouteConstants.Demos_GoogleMap_Documentation, IconName = IconName.Map, ParentId = "5" }, #region Grid new (){ Id = "513", Text = "Grid", IconName = IconName.Grid, ParentId = "5" }, - new (){ Id = "51101", Text = "Overview", Href = "/grid/overview", IconName = IconName.Grid, ParentId = "513" }, // first item - do not change - new (){ Id = "51102", Text = "Alignment", Href = "/grid/alignment", IconName = IconName.Justify, ParentId = "513" }, - new (){ Id = "51103", Text = "Custom CSS Class", Href = "/grid/custom-css-class", IconName = IconName.FileTypeCss, ParentId = "513" }, - new (){ Id = "51104", Text = "Data Binding", Href = "/grid/data-binding", IconName = IconName.GridFill, ParentId = "513" }, - new (){ Id = "51106", Text = "Detail View", Href = "/grid/detail-view", IconName = IconName.ListNested, ParentId = "513" }, - new (){ Id = "51107", Text = "Events", Href = "/grid/events", IconName = IconName.LightningChargeFill, ParentId = "513" }, - new (){ Id = "51107", Text = "Filters", Href = "/grid/filters", IconName = IconName.FunnelFill, ParentId = "513" }, - new (){ Id = "51108", Text = "Fixed Header", Href = "/grid/fixed-header", IconName = IconName.Table, ParentId = "513" }, - new (){ Id = "51109", Text = "Freeze Columns", Href = "/grid/freeze-columns", IconName = IconName.LayoutThreeColumns, ParentId = "513" }, - new (){ Id = "51110", Text = "Grid Settings", Href = "/grid/settings", IconName = IconName.GearFill, ParentId = "513" }, - new (){ Id = "51111", Text = "Nested Grid", Href = "/grid/nested-grid", IconName = IconName.Pip, ParentId = "513" }, - new (){ Id = "51112", Text = "Paging", Href = "/grid/paging", IconName = IconName.ChevronBarRight, ParentId = "513" }, - new (){ Id = "51113", Text = "Selection", Href = "/grid/selection", IconName = IconName.CheckSquareFill, ParentId = "513" }, - new (){ Id = "51114", Text = "Sorting", Href = "/grid/sorting", IconName = IconName.ArrowDownUp, ParentId = "513" }, - new (){ Id = "51115", Text = "Translations", Href = "/grid/translations", IconName = IconName.Translate, ParentId = "513" }, - new (){ Id = "51199", Text = "Other", Href = "/grid/other", IconName = IconName.PlusSquareFill, ParentId = "513" }, // last item - do not change + new (){ Id = "51101", Text = "Overview", Href = RouteConstants.Demos_Grid_Overview_Documentation, IconName = IconName.Grid, ParentId = "513" }, // first item - do not change + new (){ Id = "51102", Text = "Alignment", Href = RouteConstants.Demos_Grid_Alignment_Documentation, IconName = IconName.Justify, ParentId = "513" }, + new (){ Id = "51103", Text = "Custom CSS Class", Href = RouteConstants.Demos_Grid_CustomCSSClass_Documentation, IconName = IconName.FileTypeCss, ParentId = "513" }, + new (){ Id = "51104", Text = "Data Binding", Href = RouteConstants.Demos_Grid_DataBinding_Documentation, IconName = IconName.GridFill, ParentId = "513" }, + new (){ Id = "51106", Text = "Detail View", Href = RouteConstants.Demos_Grid_DetailView_Documentation, IconName = IconName.ListNested, ParentId = "513" }, + new (){ Id = "51107", Text = "Events", Href = RouteConstants.Demos_Grid_Events_Documentation, IconName = IconName.LightningChargeFill, ParentId = "513" }, + new (){ Id = "51107", Text = "Filters", Href = RouteConstants.Demos_Grid_Filters_Documentation, IconName = IconName.FunnelFill, ParentId = "513" }, + new (){ Id = "51108", Text = "Fixed Header", Href = RouteConstants.Demos_Grid_FixedHeader_Documentation, IconName = IconName.Table, ParentId = "513" }, + new (){ Id = "51109", Text = "Freeze Columns", Href = RouteConstants.Demos_Grid_FreezeColumns_Documentation, IconName = IconName.LayoutThreeColumns, ParentId = "513" }, + new (){ Id = "51110", Text = "Grid Settings", Href = RouteConstants.Demos_Grid_Settings_Documentation, IconName = IconName.GearFill, ParentId = "513" }, + new (){ Id = "51111", Text = "Nested Grid", Href = RouteConstants.Demos_Grid_NestedGrid_Documentation, IconName = IconName.Pip, ParentId = "513" }, + new (){ Id = "51112", Text = "Paging", Href = RouteConstants.Demos_Grid_Paging_Documentation, IconName = IconName.ChevronBarRight, ParentId = "513" }, + new (){ Id = "51113", Text = "Selection", Href = RouteConstants.Demos_Grid_Selection_Documentation, IconName = IconName.CheckSquareFill, ParentId = "513" }, + new (){ Id = "51114", Text = "Sorting", Href = RouteConstants.Demos_Grid_Sorting_Documentation, IconName = IconName.ArrowDownUp, ParentId = "513" }, + new (){ Id = "51115", Text = "Translations", Href = RouteConstants.Demos_Grid_Translations_Documentation, IconName = IconName.Translate, ParentId = "513" }, + new (){ Id = "51199", Text = "Other", Href = RouteConstants.Demos_Grid_OtherExamples_Documentation, IconName = IconName.PlusSquareFill, ParentId = "513" }, // last item - do not change #endregion Grid - new (){ Id = "514", Text = "Markdown", Href = "/markdown", IconName = IconName.MarkdownFill, ParentId = "5" }, - new (){ Id = "514", Text = "Modals", Href = "/modals", IconName = IconName.WindowStack, ParentId = "5" }, - new (){ Id = "515", Text = "Offcanvas", Href = "/offcanvas", IconName = IconName.LayoutSidebarReverse, ParentId = "5" }, - new (){ Id = "516", Text = "Pagination", Href = "/pagination", IconName = IconName.ThreeDots, ParentId = "5" }, - new (){ Id = "517", Text = "PDF Viewer", Href = "/pdf-viewer", IconName = IconName.FilePdfFill, ParentId = "5" }, - new (){ Id = "518", Text = "Placeholders", Href = "/placeholders", IconName = IconName.ColumnsGap, ParentId = "5" }, - new (){ Id = "519", Text = "Preload", Href = "/preload", IconName = IconName.ArrowClockwise, ParentId = "5" }, - new (){ Id = "520", Text = "Progress", Href = "/progress", IconName = IconName.UsbC, ParentId = "5" }, - new (){ Id = "521", Text = "Ribbon", Href = "/ribbon", IconName = IconName.WindowStack, ParentId = "5" }, - new (){ Id = "522", Text = "Script Loader", Href = "/script-loader", IconName = IconName.CodeSlash, ParentId = "5" }, - new (){ Id = "523", Text = "Sidebar", Href = "/sidebar", IconName = IconName.LayoutSidebar, ParentId = "5" }, - new (){ Id = "524", Text = "Sidebar 2", Href = "/sidebar2", IconName = IconName.ListNested, ParentId = "5" }, - new (){ Id = "525", Text = "Sortable List", Href = "/sortable-list", IconName = IconName.ArrowsMove, ParentId = "5" }, - new (){ Id = "526", Text = "Spinner", Href = "/spinners", IconName = IconName.ArrowRepeat, ParentId = "5" }, - new (){ Id = "527", Text = "Tabs", Href = "/tabs", IconName = IconName.WindowPlus, ParentId = "5" }, - new (){ Id = "528", Text = "Theme Switcher", Href = "/theme-switcher", IconName = IconName.NintendoSwitch, ParentId = "5" }, - new (){ Id = "529", Text = "Toasts", Href = "/toasts", IconName = IconName.ExclamationTriangleFill, ParentId = "5" }, - new (){ Id = "530", Text = "Tooltips", Href = "/tooltips", IconName = IconName.ChatSquareDotsFill, ParentId = "5" }, + new (){ Id = "514", Text = "Markdown", Href = RouteConstants.Demos_Markdown_Documentation, IconName = IconName.MarkdownFill, ParentId = "5" }, + new (){ Id = "514", Text = "Modals", Href = RouteConstants.Demos_Modal_Documentation, IconName = IconName.WindowStack, ParentId = "5" }, + new (){ Id = "515", Text = "Offcanvas", Href = RouteConstants.Demos_Offcanvas_Documentation, IconName = IconName.LayoutSidebarReverse, ParentId = "5" }, + new (){ Id = "516", Text = "Pagination", Href = RouteConstants.Demos_Pagination_Documentation, IconName = IconName.ThreeDots, ParentId = "5" }, + new (){ Id = "517", Text = "PDF Viewer", Href = RouteConstants.Demos_PDFViewer_Documentation, IconName = IconName.FilePdfFill, ParentId = "5" }, + new (){ Id = "518", Text = "Placeholders", Href = RouteConstants.Demos_Placeholders_Documentation, IconName = IconName.ColumnsGap, ParentId = "5" }, + new (){ Id = "519", Text = "Preload", Href = RouteConstants.Demos_Preload_Documentation, IconName = IconName.ArrowClockwise, ParentId = "5" }, + new (){ Id = "520", Text = "Progress", Href = RouteConstants.Demos_Progress_Documentation, IconName = IconName.UsbC, ParentId = "5" }, + new (){ Id = "521", Text = "Ribbon", Href = RouteConstants.Demos_Ribbon_Documentation, IconName = IconName.WindowStack, ParentId = "5" }, + new (){ Id = "522", Text = "Script Loader", Href = RouteConstants.Demos_ScriptLoader_Documentation, IconName = IconName.CodeSlash, ParentId = "5" }, + new (){ Id = "523", Text = "Sidebar", Href = RouteConstants.Demos_Sidebar_Documentation, IconName = IconName.LayoutSidebar, ParentId = "5" }, + new (){ Id = "524", Text = "Sidebar 2", Href = RouteConstants.Demos_Sidebar2_Documentation, IconName = IconName.ListNested, ParentId = "5" }, + new (){ Id = "525", Text = "Sortable List", Href = RouteConstants.Demos_SortableList_Documentation, IconName = IconName.ArrowsMove, ParentId = "5" }, + new (){ Id = "526", Text = "Spinner", Href = RouteConstants.Demos_Spinners_Documentation, IconName = IconName.ArrowRepeat, ParentId = "5" }, + new (){ Id = "527", Text = "Tabs", Href = RouteConstants.Demos_Tabs_Documentation, IconName = IconName.WindowPlus, ParentId = "5" }, + new (){ Id = "528", Text = "Theme Switcher", Href = RouteConstants.Demos_ThemeSwitcher_Documentation, IconName = IconName.NintendoSwitch, ParentId = "5" }, + new (){ Id = "529", Text = "Toasts", Href = RouteConstants.Demos_Toasts_Documentation, IconName = IconName.ExclamationTriangleFill, ParentId = "5" }, + new (){ Id = "530", Text = "Tooltips", Href = RouteConstants.Demos_Tooltips_Documentation, IconName = IconName.ChatSquareDotsFill, ParentId = "5" }, new (){ Id = "6", Text = "Data Visualization", IconName = IconName.BarChartFill, IconColor = IconColor.Warning }, - new (){ Id = "600", Text = "Bar Chart", Href = "/charts/bar-chart", IconName = IconName.BarChartFill, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "601", Text = "Doughnut Chart", Href = "/charts/doughnut-chart", IconName = IconName.CircleFill, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "602", Text = "Line Chart", Href = "/charts/line-chart", IconName = IconName.GraphUp, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "603", Text = "Pie Chart", Href = "/charts/pie-chart", IconName = IconName.PieChartFill, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "604", Text = "Polar Area Chart", Href = "/charts/polar-area-chart", IconName = IconName.PieChartFill, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "605", Text = "Radar Chart", Href = "/charts/radar-chart", IconName = IconName.Radar, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "605", Text = "Scatter Chart", Href = "/charts/scatter-chart", IconName = IconName.GraphUpArrow, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "600", Text = "Bar Chart", Href = RouteConstants.Demos_BarChart_Documentation, IconName = IconName.BarChartFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "601", Text = "Doughnut Chart", Href = RouteConstants.Demos_DoughnutChart_Documentation, IconName = IconName.CircleFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "602", Text = "Line Chart", Href = RouteConstants.Demos_LineChart_Documentation, IconName = IconName.GraphUp, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "603", Text = "Pie Chart", Href = RouteConstants.Demos_PieChart_Documentation, IconName = IconName.PieChartFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "604", Text = "Polar Area Chart", Href = RouteConstants.Demos_PolarAreaChart_Documentation, IconName = IconName.PieChartFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "605", Text = "Radar Chart", Href = RouteConstants.Demos_RadarChart_Documentation, IconName = IconName.Radar, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "605", Text = "Scatter Chart", Href = RouteConstants.Demos_ScatterChart_Documentation, IconName = IconName.GraphUpArrow, ParentId = "6", Match = NavLinkMatch.All }, new(){ Id = "7", Text = "Services", IconName = IconName.WrenchAdjustableCircleFill, IconColor = IconColor.Success }, - new (){ Id = "700", Text = "Modal Service", Href = "/services/modal-service", IconName = IconName.WindowStack, ParentId = "7" }, + new (){ Id = "700", Text = "Modal Service", Href = RouteConstants.Demos_ModalService_Documentation, IconName = IconName.WindowStack, ParentId = "7" }, new(){ Id = "19", Text = "Utilities", IconName = IconName.GearWideConnected, IconColor = IconColor.Info }, - new (){ Id = "1900", Text = "Color Utility", Href = "/utils/color-utility", IconName = IconName.Palette2, ParentId = "19" }, + new (){ Id = "1900", Text = "Color Utility", Href = RouteConstants.Demos_ColorUtils_Documentation, IconName = IconName.Palette2, ParentId = "19" }, }; return navItems; diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChatDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChatDocumentation.razor deleted file mode 100644 index fffd2c360..000000000 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChatDocumentation.razor +++ /dev/null @@ -1,26 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - @pageDescription - - - - -
-
Alerts are available for any length of text, as well as an optional close button. For proper styling, use one of the eight colors.
- -
- -@code{ - private const string pageUrl = RouteConstants.Demos_AI_Chat_Documentation; - private const string pageTitle = "Blazor Open AI Chat Component"; - private const string pageDescription = "Provide contextual feedback messages for typical user actions with the handful of available and flexible Blazor Bootstrap alert messages."; // TODO: update - private const string metaTitle = "Blazor Open AI Chat Component"; - private const string metaDescription = "Provide contextual feedback messages for typical user actions with the handful of available and flexible Blazor Bootstrap alert messages."; // TODO: update - private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update -} \ No newline at end of file diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChat_Demo_01_Examples.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChat_Demo_01_Examples.razor deleted file mode 100644 index a9cdd295b..000000000 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/AI/AIChat/AIChat_Demo_01_Examples.razor +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInputDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInputDocumentation.razor new file mode 100644 index 000000000..cbea8ebf1 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInputDocumentation.razor @@ -0,0 +1,42 @@ +@page "/checkbox-input" + +@attribute [Route(pageUrl)] + + + + + @pageDescription + + + + +
+ +
+ +
+
Use the Disabled parameter to disable the CheckboxInput.
+ +
Also, use Enable() and Disable() methods to enable and disable the CheckboxInput.
+ + Do not use both the Disabled parameter and Enable() & Disable() methods. + + +
+ +
+
This event fires when the CheckboxInput value changes, but not on every keystroke.
+ +
+ +@code { + private const string pageUrl = RouteConstants.Demos_CheckboxInput_Documentation; + private const string pageTitle = "Blazor CheckboxInput"; + private const string pageDescription = "The Blazor Bootstrap CheckboxInput component is constructed using an HTML input of type 'checkbox'."; + private const string metaTitle = "Blazor CheckboxInput Component"; + private const string metaDescription = "The Blazor Bootstrap CheckboxInput component is constructed using an HTML input of type 'checkbox'."; + private const string imageUrl = "https://i.imgur.com/1mVjqQv.png"; // TODO: Update image URL +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_01_Basic_Usage.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_01_Basic_Usage.razor new file mode 100644 index 000000000..4e6861f3a --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_01_Basic_Usage.razor @@ -0,0 +1,8 @@ + + + +@code +{ + private bool isChecked; + private bool isChecked2 = true; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_A.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_A.razor new file mode 100644 index 000000000..0966297e2 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_A.razor @@ -0,0 +1,22 @@ + + + +
+ + + +
+ +@code +{ + private bool isChecked; + private bool isChecked2 = true; + + private bool disabled = true; + + private void Enable() => disabled = false; + + private void Disable() => disabled = true; + + private void Toggle() => disabled = !disabled; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_B.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_B.razor new file mode 100644 index 000000000..4ca9f8739 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_02_Disable_B.razor @@ -0,0 +1,28 @@ + + + +
+ + +
+ +@code +{ + private CheckboxInput? checkboxInputRef1; + private CheckboxInput? checkboxInputRef2; + + private bool isChecked; + private bool isChecked2 = true; + + private void Disable() + { + checkboxInputRef1.Disable(); + checkboxInputRef2.Disable(); + } + + private void Enable() + { + checkboxInputRef1.Enable(); + checkboxInputRef2.Enable(); + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_03_Events_ValueChanged.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_03_Events_ValueChanged.razor new file mode 100644 index 000000000..ad0f2601a --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/CheckboxInput/CheckboxInput_Demo_03_Events_ValueChanged.razor @@ -0,0 +1,13 @@ + +Current value: @isChecked +@code +{ + private bool isChecked; + + private void CheckboxValueChanged(bool value) + { + isChecked = value; + + // do something + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInputDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInputDocumentation.razor new file mode 100644 index 000000000..e597dcf66 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInputDocumentation.razor @@ -0,0 +1,42 @@ +@page "/radio-input" + +@attribute [Route(pageUrl)] + + + + + @pageDescription + + + + +
+ +
+ +
+
Use the Disabled parameter to disable the RadioInput.
+ +
Also, use Enable() and Disable() methods to enable and disable the RadioInput.
+ + Do not use both the Disabled parameter and Enable() & Disable() methods. + + +
+ +
+
This event fires when the RadioInput value changes, but not on every keystroke.
+ +
+ +@code { + private const string pageUrl = RouteConstants.Demos_RadioInput_Documentation; + private const string pageTitle = "Blazor RadioInput"; + private const string pageDescription = "The Blazor Bootstrap RadioInput component is constructed using an HTML input of type 'radio'."; + private const string metaTitle = "Blazor RadioInput Component"; + private const string metaDescription = "The Blazor Bootstrap RadioInput component is constructed using an HTML input of type 'radio'."; + private const string imageUrl = "https://i.imgur.com/1mVjqQv.png"; // TODO: Update image URL +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_01_Basic_Usage.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_01_Basic_Usage.razor new file mode 100644 index 000000000..1cf04d678 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_01_Basic_Usage.razor @@ -0,0 +1,9 @@ +

Would you like to receive notifications?

+ + + +@code +{ + private bool isChecked; + private bool isChecked2 = true; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_A.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_A.razor new file mode 100644 index 000000000..6260b867d --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_A.razor @@ -0,0 +1,23 @@ +

Would you like to receive notifications?

+ + + +
+ + + +
+ +@code +{ + private bool isChecked; + private bool isChecked2 = true; + + private bool disabled = true; + + private void Enable() => disabled = false; + + private void Disable() => disabled = true; + + private void Toggle() => disabled = !disabled; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_B.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_B.razor new file mode 100644 index 000000000..b0a91473c --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_02_Disable_B.razor @@ -0,0 +1,29 @@ +

Would you like to receive notifications?

+ + + +
+ + +
+ +@code +{ + private RadioInput? radioInputRef; + private RadioInput? radioInputRef2; + + private bool isChecked; + private bool isChecked2 = true; + + private void Disable() + { + radioInputRef.Disable(); + radioInputRef2.Disable(); + } + + private void Enable() + { + radioInputRef.Enable(); + radioInputRef2.Enable(); + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_03_Events_ValueChanged.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_03_Events_ValueChanged.razor new file mode 100644 index 000000000..db9459ad1 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/RadioInput/RadioInput_Demo_03_Events_ValueChanged.razor @@ -0,0 +1,22 @@ + + + +@code +{ + private bool isYesChecked; + private bool isNoChecked; + + private void YesOptionSelectionChanged(bool value) + { + isYesChecked = value; + + // do something + } + + private void NoOptionSelectionChanged(bool value) + { + isYesChecked = value; + + // do something + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInputDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInputDocumentation.razor new file mode 100644 index 000000000..abd8a76bc --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInputDocumentation.razor @@ -0,0 +1,60 @@ +@page "/text-area-input" + +@attribute [Route(pageUrl)] + + + + + @pageDescription + + + + +
+ +
+ +
+
You can change the text alignment according to your need. Use the TextAlignment parameter to set the alignment. In the below example, alignment is set to center and end.
+ +
+ +
+
Use the Disabled parameter to disable the TextAreaInput.
+ +
Also, use Enable() and Disable() methods to enable and disable the TextAreaInput.
+ + Do not use both the Disabled parameter and Enable() & Disable() methods. + + +
+ +
+ +
+ +
+
+ Like any other blazor input component, TextAreaInput supports validations. + Add the DataAnnotations on the TextAreaInput component to validate the user input before submitting the form. + In the below example, we used Required attribute. +
+ +
+ +
+
This event fires when the TextAreaInput value changes, but not on every keystroke.
+ +
+ +@code { + private const string pageUrl = RouteConstants.Demos_TextAreaInput_Documentation; + private const string pageTitle = "Blazor TextAreaInput"; + private const string pageDescription = "The Blazor Bootstrap TextAreaInput component provides a multi-line plain-text editing control, ideal for scenarios requiring users to input substantial amounts of free-form text. Common use cases include comment sections on reviews or feedback forms."; + private const string metaTitle = "Blazor TextAreaInput Component"; + private const string metaDescription = "The Blazor Bootstrap TextAreaInput component provides a multi-line plain-text editing control, ideal for scenarios requiring users to input substantial amounts of free-form text. Common use cases include comment sections on reviews or feedback forms."; + private const string imageUrl = "https://i.imgur.com/1mVjqQv.png"; // TODO: Update image URL +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_01_Basic_Usage.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_01_Basic_Usage.razor new file mode 100644 index 000000000..9f919c39e --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_01_Basic_Usage.razor @@ -0,0 +1,8 @@ +
+ +
+
Entered text: @enteredText
+ +@code { + private string? enteredText = null; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_02_Text_Alignment.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_02_Text_Alignment.razor new file mode 100644 index 000000000..9e69ca909 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_02_Text_Alignment.razor @@ -0,0 +1,13 @@ +
+ +
+
Entered text: @enteredText
+
+ +
+
Entered text: @enteredText2
+ +@code { + private string? enteredText = "sample text"; + private string? enteredText2 = "sample text 2"; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_A.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_A.razor new file mode 100644 index 000000000..be32069bd --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_A.razor @@ -0,0 +1,20 @@ +
+ +
+
Entered text: @enteredText
+ + + + + +@code { + private string? enteredText = null; + + private bool disabled = true; + + private void Enable() => disabled = false; + + private void Disable() => disabled = true; + + private void Toggle() => disabled = !disabled; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_B.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_B.razor new file mode 100644 index 000000000..24bf642c3 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_03_Disable_B.razor @@ -0,0 +1,17 @@ +
+ +
+
Entered text: @enteredText
+ + + + +@code { + private TextAreaInput? textAreaInputRef; + + private string? enteredText = null; + + private void Disable() => textAreaInputRef.Disable(); + + private void Enable() => textAreaInputRef.Enable(); +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_04_MaxLength.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_04_MaxLength.razor new file mode 100644 index 000000000..44e93ce26 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_04_MaxLength.razor @@ -0,0 +1,8 @@ +
+ +
+
Entered text: @enteredText
+ +@code { + private string? enteredText = null; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_05_Validations.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_05_Validations.razor new file mode 100644 index 000000000..3c4c8f77d --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_05_Validations.razor @@ -0,0 +1,80 @@ +@using System.ComponentModel.DataAnnotations + + + + + + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+
+ + +
+
+ +
+ +@code { + private Product product = new(); + private EditContext? editContext; + + protected override void OnInitialized() + { + editContext = new EditContext(product); + base.OnInitialized(); + } + + public void HandleOnValidSubmit() + { + // additional check + if (editContext.Validate()) + { + // do something + // submit the form + Console.WriteLine("Form submitted successfully"); + } + } + + private void ResetForm() + { + product = new(); + editContext = new EditContext(product); + } + + public class Product + { + [Required(ErrorMessage = "Product name required.")] + public string? Name { get; set; } + + [Required(ErrorMessage = "Product description required.")] + public string? Description { get; set; } + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_06_Events_ValueChanged.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_06_Events_ValueChanged.razor new file mode 100644 index 000000000..34a9fe2bf --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextAreaInput/TextAreaInput_Demo_06_Events_ValueChanged.razor @@ -0,0 +1,15 @@ +
+ +
+
Entered text: @enteredText
+ +@code { + private string? enteredText = null; + + private void TextChanged(string? value) + { + enteredText = value; + + // do something + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInputDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInputDocumentation.razor new file mode 100644 index 000000000..59c2a3cb3 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInputDocumentation.razor @@ -0,0 +1,60 @@ +@page "/text-input" + +@attribute [Route(pageUrl)] + + + + + @pageDescription + + + + +
+ +
+ +
+
You can change the text alignment according to your need. Use the TextAlignment parameter to set the alignment. In the below example, alignment is set to center and end.
+ +
+ +
+
Use the Disabled parameter to disable the TextInput.
+ +
Also, use Enable() and Disable() methods to enable and disable the TextInput.
+ + Do not use both the Disabled parameter and Enable() & Disable() methods. + + +
+ +
+ +
+ +
+
+ Like any other blazor input component, TextInput supports validations. + Add the DataAnnotations on the TextInput component to validate the user input before submitting the form. + In the below example, we used Required attribute. +
+ +
+ +
+
This event fires when the TextInput value changes, but not on every keystroke.
+ +
+ +@code { + private const string pageUrl = RouteConstants.Demos_TextInput_Documentation; + private const string pageTitle = "Blazor TextInput"; + private const string pageDescription = "The Blazor Bootstrap TextInput component is constructed using an HTML input of type 'text'."; + private const string metaTitle = "Blazor TextInput Component"; + private const string metaDescription = "The Blazor Bootstrap TextInput component is constructed using an HTML input of type 'text'."; + private const string imageUrl = "https://i.imgur.com/1mVjqQv.png"; // TODO: Update image URL +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_01_Basic_Usage.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_01_Basic_Usage.razor new file mode 100644 index 000000000..7153b870c --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_01_Basic_Usage.razor @@ -0,0 +1,8 @@ +
+ +
+
Entered text: @enteredText
+ +@code { + private string? enteredText = null; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_02_Text_Alignment.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_02_Text_Alignment.razor new file mode 100644 index 000000000..3c0b5b535 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_02_Text_Alignment.razor @@ -0,0 +1,13 @@ +
+ +
+
Entered text: @enteredText
+
+ +
+
Entered text: @enteredText2
+ +@code { + private string? enteredText = "sample text"; + private string? enteredText2 = "sample text 2"; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_A.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_A.razor new file mode 100644 index 000000000..456b47d32 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_A.razor @@ -0,0 +1,20 @@ +
+ +
+
Entered text: @enteredText
+ + + + + +@code { + private string? enteredText = null; + + private bool disabled = true; + + private void Enable() => disabled = false; + + private void Disable() => disabled = true; + + private void Toggle() => disabled = !disabled; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_B.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_B.razor new file mode 100644 index 000000000..17f0e35f3 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_03_Disable_B.razor @@ -0,0 +1,17 @@ +
+ +
+
Entered text: @enteredText
+ + + + +@code { + private TextInput? textInputRef; + + private string? enteredText = null; + + private void Disable() => textInputRef.Disable(); + + private void Enable() => textInputRef.Enable(); +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_04_MaxLength.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_04_MaxLength.razor new file mode 100644 index 000000000..118d5d557 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_04_MaxLength.razor @@ -0,0 +1,8 @@ +
+ +
+
Entered text: @enteredText
+ +@code { + private string? enteredText = null; +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_05_Validations.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_05_Validations.razor new file mode 100644 index 000000000..9a6b848e4 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_05_Validations.razor @@ -0,0 +1,80 @@ +@using System.ComponentModel.DataAnnotations + + + + + + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+
+ + +
+
+ +
+ +@code { + private Employee employee = new(); + private EditContext? editContext; + + protected override void OnInitialized() + { + editContext = new EditContext(employee); + base.OnInitialized(); + } + + public void HandleOnValidSubmit() + { + // additional check + if (editContext.Validate()) + { + // do something + // submit the form + Console.WriteLine("Form submitted successfully"); + } + } + + private void ResetForm() + { + employee = new(); + editContext = new EditContext(employee); + } + + public class Employee + { + [Required(ErrorMessage = "First name required.")] + public string? FirstName { get; set; } + + [Required(ErrorMessage = "Last name required.")] + public string? LastName { get; set; } + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_06_Events_ValueChanged.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_06_Events_ValueChanged.razor new file mode 100644 index 000000000..32832d708 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Form/TextInput/TextInput_Demo_06_Events_ValueChanged.razor @@ -0,0 +1,15 @@ +
+ +
+
Entered employee name: @employeeName
+ +@code { + private string? employeeName = null; + + private void EmployeeNameChanged(string? value) + { + employeeName = value; + + // do something + } +} diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Index.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Index.razor index 7f65a9275..feb8706c4 100644 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/Index.razor +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Index.razor @@ -85,6 +85,11 @@

Charts

+
@@ -175,6 +180,11 @@

Progress

+ + @* *@ + +
@@ -243,20 +268,6 @@
-@*
-
-

AI Components

-
- - -
*@ -

Form Components

@@ -268,6 +279,11 @@

Auto Complete

+ + + @* *@ + +

Time Input

diff --git a/BlazorBootstrap.Demo.RCL/Constants/RouteConstants.cs b/BlazorBootstrap.Demo.RCL/Constants/RouteConstants.cs index bc6ddfca0..874eb6775 100644 --- a/BlazorBootstrap.Demo.RCL/Constants/RouteConstants.cs +++ b/BlazorBootstrap.Demo.RCL/Constants/RouteConstants.cs @@ -12,8 +12,8 @@ public static class RouteConstants public const string Demos_GettingStarted_Documentation = Demos_Prefix + "/getting-started"; // AI - public const string Demos_AI_Prefix = Demos_Prefix + "/ai"; - public const string Demos_AI_Chat_Documentation = Demos_AI_Prefix + "/open-ai-chat"; + //public const string Demos_AI_Prefix = Demos_Prefix + "/ai"; + //public const string Demos_AI_Chat_Documentation = Demos_AI_Prefix + "/open-ai-chat"; // Content public const string Demos_Icons_Documentation = Demos_Prefix + "/icons"; @@ -22,11 +22,16 @@ public static class RouteConstants // Forms public const string Demos_Forms_Prefix = Demos_Prefix + "/form"; public const string Demos_AutoComplete_Documentation = Demos_Forms_Prefix + "/autocomplete"; + public const string Demos_CheckboxInput_Documentation = Demos_Forms_Prefix + "/checkbox-input"; public const string Demos_CurrencyInput_Documentation = Demos_Forms_Prefix + "/currency-input"; public const string Demos_DateInput_Documentation = Demos_Forms_Prefix + "/date-input"; public const string Demos_NumberInput_Documentation = Demos_Forms_Prefix + "/number-input"; + public const string Demos_RadioInput_Documentation = Demos_Forms_Prefix + "/radio-input"; public const string Demos_RangeInput_Documentation = Demos_Forms_Prefix + "/range-input"; + public const string Demos_SelectInput_Documentation = Demos_Forms_Prefix + "/select-input"; public const string Demos_Switch_Documentation = Demos_Forms_Prefix + "/switch"; + public const string Demos_TextInput_Documentation = Demos_Forms_Prefix + "/text-input"; + public const string Demos_TextAreaInput_Documentation = Demos_Forms_Prefix + "/text-area-input"; public const string Demos_TimeInput_Documentation = Demos_Forms_Prefix + "/time-input"; // Components diff --git a/blazorbootstrap/BlazorBootstrap.csproj b/blazorbootstrap/BlazorBootstrap.csproj index ba6f40e44..dde59ea39 100644 --- a/blazorbootstrap/BlazorBootstrap.csproj +++ b/blazorbootstrap/BlazorBootstrap.csproj @@ -46,17 +46,14 @@ - - - \ No newline at end of file diff --git a/blazorbootstrap/Components/AI/Chat/AIChat.razor b/blazorbootstrap/Components/AI/Chat/AIChat.razor deleted file mode 100644 index 254561235..000000000 --- a/blazorbootstrap/Components/AI/Chat/AIChat.razor +++ /dev/null @@ -1,63 +0,0 @@ -@namespace BlazorBootstrap -@inherits BlazorBootstrapComponentBase - - \ No newline at end of file diff --git a/blazorbootstrap/Components/AI/Chat/AIChat.razor.cs b/blazorbootstrap/Components/AI/Chat/AIChat.razor.cs deleted file mode 100644 index cc8c1ec77..000000000 --- a/blazorbootstrap/Components/AI/Chat/AIChat.razor.cs +++ /dev/null @@ -1,156 +0,0 @@ -namespace BlazorBootstrap; - -public partial class AIChat : BlazorBootstrapComponentBase -{ - #region Fields and Constants - - private readonly List conversationHistory = new(); - private string? apiKey; - private string? apiVersion; - private string? currentCompletion; - private string? deploymentName; - private string? endpoint; - private bool isRequestInProgress; - private DotNetObjectReference? objRef; - private string userPrompt = string.Empty; - - #endregion - - #region Methods - - protected override async Task OnInitializedAsync() - { - var configurationSection = Configuration.GetSection("AzureOpenAI"); - - if (Configuration is null) - throw new ArgumentException("`AzureOpenAI` section was not found in the application configuration."); - - endpoint = configurationSection["Endpoint"]; - - if (endpoint is null) - throw new ArgumentException("`Endpoint` key/value was not found in the 'AzureOpenAI' section of the application configuration."); - - deploymentName = configurationSection["DeploymentName"]; - - if (deploymentName is null) - throw new ArgumentException("`DeploymentName` key/value was not found in the 'AzureOpenAI' section of the application configuration."); - - apiKey = configurationSection["ApiKey"]; - - if (apiKey is null) - throw new ArgumentException("`ApiKey` key/value was not found in the 'AzureOpenAI' section of the application configuration."); - - apiVersion = configurationSection["ApiVersion"]; - - if (apiVersion is null) - throw new ArgumentException("`ApiVersion` key/value was not found in the 'AzureOpenAI' section of the application configuration."); - - objRef ??= DotNetObjectReference.Create(this); - - await base.OnInitializedAsync(); - } - - [JSInvokable] - public async Task ChartCompletetionsStreamJs(string content, bool done) - { - ClearInput(); - - if (isRequestInProgress) - isRequestInProgress = false; - - if (done) - { - conversationHistory.Add(new OpenAIChatMessage("system", currentCompletion!)); - currentCompletion = ""; - await InvokeAsync(StateHasChanged); - await JSRuntime.InvokeVoidAsync(BlazorBootstrapInterop.ScrollToElementBottom, Id); - - return; - } - - currentCompletion += content; - await InvokeAsync(StateHasChanged); - await JSRuntime.InvokeVoidAsync(BlazorBootstrapInterop.ScrollToElementBottom, Id); - } - - private void ClearInput() => userPrompt = string.Empty; - - private async Task CreateCompletionAsync(List messages) - { - isRequestInProgress = true; - - var payload = new OpenAIChatPayload { Messages = messages, MaximumTokens = MaximumTokens, Temperature = Temperature, TopP = TopP }; - - try - { - await JSRuntime.InvokeVoidAsync( - AIChatInterop.AzureOpenAIChatCompletions, - $"{endpoint}openai/deployments/{deploymentName}/chat/completions?api-version={apiVersion}", - apiKey, - payload, - objRef! - ); - } - catch - { - isRequestInProgress = false; - } - } - - private async Task SendPromptAsync() - { - if (string.IsNullOrWhiteSpace(userPrompt)) - return; - - var message = new OpenAIChatMessage("user", userPrompt); - conversationHistory.Add(message); - - await CreateCompletionAsync(new List { message }); - } - - #endregion - - #region Properties, Indexers - - protected override string? ClassNames => - BuildClassNames( - Class, - (BootstrapClass.Container, true) - ); - - protected override string? StyleNames => - BuildStyleNames( - Style, - //("min-height:200px", true), - //("max-height:400px", true), - ("overflow-x:hidden", true), - ("overflow-y:auto", true) - ); - - /// - /// The maximum number of tokens to generate shared between the prompt and completion. - /// The exact limit varies by model. (One token is roughly 4 characters for standard English text) - /// Minimum 1 and the maximum tokens is 4096. - /// - /// Default value is 2048. This value is limited by gpt-3.5-turbo. - [Parameter] - public long MaximumTokens { get; set; } = 2048; - - /// - /// Controls randomness: Lowering results in less random completions. - /// As the temperature approaches zero, the model will become deterministic and repetitive. - /// Minimum 1 and the maximum is 2. - /// - /// Default value is 1. - [Parameter] - public double Temperature { get; set; } = 1; - - /// - /// Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. - /// - /// Default value is 1. - [Parameter] - public double TopP { get; set; } = 1; - - #endregion -} diff --git a/blazorbootstrap/Components/AI/Chat/AIChatInterop.cs.cs b/blazorbootstrap/Components/AI/Chat/AIChatInterop.cs.cs deleted file mode 100644 index 8dc241100..000000000 --- a/blazorbootstrap/Components/AI/Chat/AIChatInterop.cs.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace BlazorBootstrap; - -public class AIChatInterop -{ - #region Fields and Constants - - private const string Prefix = "window.blazorBootstrap.ai."; - - public const string AzureOpenAIChatCompletions = Prefix + "azureOpenAI.chat.completions"; - - #endregion -} diff --git a/blazorbootstrap/Components/Core/BlazorBootstrapComponentBase.cs b/blazorbootstrap/Components/Core/BlazorBootstrapComponentBase.cs index a8bfe8dfa..e5386389f 100644 --- a/blazorbootstrap/Components/Core/BlazorBootstrapComponentBase.cs +++ b/blazorbootstrap/Components/Core/BlazorBootstrapComponentBase.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Configuration; - -namespace BlazorBootstrap; +namespace BlazorBootstrap; public abstract class BlazorBootstrapComponentBase : ComponentBase, IDisposable, IAsyncDisposable { @@ -143,8 +141,6 @@ protected virtual ValueTask DisposeAsyncCore(bool disposing) protected virtual string? ClassNames => Class; - [Inject] protected IConfiguration Configuration { get; set; } = default!; - public ElementReference Element { get; set; } [Parameter] public string? Id { get; set; } diff --git a/blazorbootstrap/Components/Core/BlazorBootstrapLayoutComponentBase.cs b/blazorbootstrap/Components/Core/BlazorBootstrapLayoutComponentBase.cs index d4fd797d5..2e1e299b8 100644 --- a/blazorbootstrap/Components/Core/BlazorBootstrapLayoutComponentBase.cs +++ b/blazorbootstrap/Components/Core/BlazorBootstrapLayoutComponentBase.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Configuration; - -namespace BlazorBootstrap; +namespace BlazorBootstrap; public abstract class BlazorBootstrapLayoutComponentBase : LayoutComponentBase, IDisposable, IAsyncDisposable { @@ -138,8 +136,6 @@ protected virtual ValueTask DisposeAsyncCore(bool disposing) protected virtual string? ClassNames => Class; - [Inject] protected IConfiguration Configuration { get; set; } = default!; - public ElementReference Element { get; set; } [Parameter] public string? Id { get; set; } diff --git a/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor b/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor new file mode 100644 index 000000000..2f802c5dc --- /dev/null +++ b/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor @@ -0,0 +1,20 @@ +@namespace BlazorBootstrap +@inherits BlazorBootstrapComponentBase + +
+ + + @if (!string.IsNullOrWhiteSpace(Label)) + { + + } +
\ No newline at end of file diff --git a/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor.cs b/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor.cs new file mode 100644 index 000000000..3916ba00d --- /dev/null +++ b/blazorbootstrap/Components/Form/CheckboxInput/CheckboxInput.razor.cs @@ -0,0 +1,89 @@ +namespace BlazorBootstrap; + +public partial class CheckboxInput : BlazorBootstrapComponentBase +{ + #region Fields and Constants + + private FieldIdentifier fieldIdentifier; + + #endregion + + #region Methods + + protected override void OnInitialized() + { + AdditionalAttributes ??= new Dictionary(); + + fieldIdentifier = FieldIdentifier.Create(ValueExpression); + + base.OnInitialized(); + } + + /// + /// Disables number input. + /// + public void Disable() => Disabled = true; + + /// + /// Enables number input. + /// + public void Enable() => Disabled = false; + + private async Task OnChange(ChangeEventArgs e) + { + var oldValue = Value; + var newValue = e.Value is not null && (bool)e.Value; + + await ValueChanged.InvokeAsync(newValue); + + EditContext?.NotifyFieldChanged(fieldIdentifier); + } + + #endregion + + #region Properties, Indexers + + protected override string? ClassNames => + BuildClassNames( + Class, + (BootstrapClass.FormCheckInput, true), + (EditContext?.FieldCssClass(fieldIdentifier) ?? string.Empty, true) + ); + + /// + /// Gets or sets the disabled state. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool Disabled { get; set; } + + /// + /// Gets the associated . + /// + [CascadingParameter] + private EditContext? EditContext { get; set; } = default!; + + /// + /// Gets or sets the label. + /// + [Parameter] + public string? Label { get; set; } + + /// + /// Gets or sets the value. + /// + [Parameter] + public bool Value { get; set; } + + /// + /// This event fired on every user keystroke that changes the NumberInput value. + /// + [Parameter] + public EventCallback ValueChanged { get; set; } + + [Parameter] public Expression> ValueExpression { get; set; } = default!; + + #endregion +} diff --git a/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor b/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor new file mode 100644 index 000000000..df18b0ba7 --- /dev/null +++ b/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor @@ -0,0 +1,20 @@ +@namespace BlazorBootstrap +@inherits BlazorBootstrapComponentBase + +
+ + + @if (!string.IsNullOrWhiteSpace(Label)) + { + + } +
\ No newline at end of file diff --git a/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor.cs b/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor.cs new file mode 100644 index 000000000..902ddf906 --- /dev/null +++ b/blazorbootstrap/Components/Form/RadioInput/RadioInput.razor.cs @@ -0,0 +1,97 @@ +namespace BlazorBootstrap; + +public partial class RadioInput : BlazorBootstrapComponentBase +{ + #region Fields and Constants + + private FieldIdentifier fieldIdentifier; + + #endregion + + #region Methods + + protected override void OnInitialized() + { + AdditionalAttributes ??= new Dictionary(); + + fieldIdentifier = FieldIdentifier.Create(ValueExpression); + + base.OnInitialized(); + } + + /// + /// Disables number input. + /// + public void Disable() => Disabled = true; + + /// + /// Enables number input. + /// + public void Enable() => Disabled = false; + + private async Task OnChange(ChangeEventArgs e) + { + var oldValue = Value; + var newValue = string.Equals(e.Value?.ToString(), "on"); + + await ValueChanged.InvokeAsync(newValue); + + Console.WriteLine($"Old value: {oldValue}, New value: {e.Value}"); + + EditContext?.NotifyFieldChanged(fieldIdentifier); + } + + #endregion + + #region Properties, Indexers + + protected override string? ClassNames => + BuildClassNames( + Class, + (BootstrapClass.FormCheckInput, true), + (EditContext?.FieldCssClass(fieldIdentifier) ?? string.Empty, true) + ); + + /// + /// Gets or sets the disabled state. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool Disabled { get; set; } + + /// + /// Gets the associated . + /// + [CascadingParameter] + private EditContext EditContext { get; set; } = default!; + + /// + /// Gets or sets the label. + /// + [Parameter] + public string? Label { get; set; } + + /// + /// Gets or sets the name. + /// + [Parameter] + public string? Name { get; set; } + + /// + /// Gets or sets the value. + /// + [Parameter] + public bool Value { get; set; } = default!; + + /// + /// This event fired on every user keystroke that changes the NumberInput value. + /// + [Parameter] + public EventCallback ValueChanged { get; set; } + + [Parameter] public Expression> ValueExpression { get; set; } = default!; + + #endregion +} diff --git a/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor b/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor new file mode 100644 index 000000000..9e3df9654 --- /dev/null +++ b/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor @@ -0,0 +1,15 @@ +@* @namespace BlazorBootstrap +@inherits BlazorBootstrapComponentBase + + *@ \ No newline at end of file diff --git a/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor.cs b/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor.cs new file mode 100644 index 000000000..c22fc7617 --- /dev/null +++ b/blazorbootstrap/Components/Form/SelectInput/SelectInput.razor.cs @@ -0,0 +1,116 @@ +//namespace BlazorBootstrap; + +//public partial class SelectInput : BlazorBootstrapComponentBase +//{ +// #region Fields and Constants + +// private FieldIdentifier fieldIdentifier; + +// #endregion + +// #region Methods + +// protected override void OnInitialized() +// { +// AdditionalAttributes ??= new Dictionary(); + +// fieldIdentifier = FieldIdentifier.Create(ValueExpression); + +// base.OnInitialized(); +// } + +// /// +// /// Disables number input. +// /// +// public void Disable() => Disabled = true; + +// /// +// /// Enables number input. +// /// +// public void Enable() => Disabled = false; + +// private async Task OnChange(ChangeEventArgs e) +// { +// var oldValue = Value; +// var newValue = e.Value?.ToString() ?? string.Empty; // object + +// await ValueChanged.InvokeAsync(newValue); + +// EditContext?.NotifyFieldChanged(fieldIdentifier); +// } + +// #endregion + +// #region Properties, Indexers + +// protected override string? ClassNames => +// BuildClassNames( +// Class, +// (BootstrapClass.FormControl, true), +// (TextAlignment.ToTextAlignmentClass(), TextAlignment != Alignment.None) +// ); + +// private string autoComplete => AutoComplete ? "true" : "false"; + +// /// +// /// If , NumberInput can complete the values automatically by the browser. +// /// +// /// +// /// Default value is false. +// /// +// [Parameter] +// public bool AutoComplete { get; set; } + +// /// +// /// Gets or sets the disabled state. +// /// +// /// +// /// Default value is false. +// /// +// [Parameter] +// public bool Disabled { get; set; } + +// [CascadingParameter] private EditContext EditContext { get; set; } = default!; + +// private string fieldCssClasses => EditContext?.FieldCssClass(fieldIdentifier) ?? ""; + +// /// +// /// Gets or sets the maximum length of the input. +// /// +// [Parameter] +// public int? MaxLength { get; set; } + +// /// +// /// Gets or sets the placeholder. +// /// +// /// +// /// Default value is null. +// /// +// [Parameter] +// public string? Placeholder { get; set; } + +// /// +// /// Gets or sets the text alignment. +// /// +// /// +// /// Default value is . +// /// +// [Parameter] +// public Alignment TextAlignment { get; set; } = Alignment.None; + +// /// +// /// Gets or sets the value. +// /// +// [Parameter] +// public string Value { get; set; } = default!; + +// /// +// /// This event fired on every user keystroke that changes the NumberInput value. +// /// +// [Parameter] +// public EventCallback ValueChanged { get; set; } + +// [Parameter] public Expression> ValueExpression { get; set; } = default!; + +// #endregion +//} diff --git a/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor b/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor new file mode 100644 index 000000000..3a3cff244 --- /dev/null +++ b/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor @@ -0,0 +1,17 @@ +@namespace BlazorBootstrap +@inherits BlazorBootstrapComponentBase + + \ No newline at end of file diff --git a/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor.cs b/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor.cs new file mode 100644 index 000000000..fff52731f --- /dev/null +++ b/blazorbootstrap/Components/Form/TextAreaInput/TextAreaInput.razor.cs @@ -0,0 +1,128 @@ +namespace BlazorBootstrap; + +public partial class TextAreaInput : BlazorBootstrapComponentBase +{ + #region Fields and Constants + + private FieldIdentifier fieldIdentifier; + + #endregion + + #region Methods + + protected override void OnInitialized() + { + AdditionalAttributes ??= new Dictionary(); + + fieldIdentifier = FieldIdentifier.Create(ValueExpression); + + base.OnInitialized(); + } + + /// + /// Disables number input. + /// + public void Disable() => Disabled = true; + + /// + /// Enables number input. + /// + public void Enable() => Disabled = false; + + private async Task OnChange(ChangeEventArgs e) + { + var oldValue = Value; + var newValue = e.Value?.ToString() ?? string.Empty; // object + + await ValueChanged.InvokeAsync(newValue); + + EditContext?.NotifyFieldChanged(fieldIdentifier); + } + + #endregion + + #region Properties, Indexers + + protected override string? ClassNames => + BuildClassNames( + Class, + (BootstrapClass.FormControl, true), + (TextAlignment.ToTextAlignmentClass(), TextAlignment != Alignment.None) + ); + + private string autoComplete => AutoComplete ? "true" : "false"; + + /// + /// If , NumberInput can complete the values automatically by the browser. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool AutoComplete { get; set; } + + /// + /// Gets or sets the number of columns. + /// + [Parameter] + public int? Cols { get; set; } + + /// + /// Gets or sets the disabled state. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool Disabled { get; set; } + + [CascadingParameter] private EditContext EditContext { get; set; } = default!; + + private string fieldCssClasses => EditContext?.FieldCssClass(fieldIdentifier) ?? ""; + + /// + /// Gets or sets the maximum length of the input. + /// + [Parameter] + public int? MaxLength { get; set; } + + /// + /// Gets or sets the placeholder. + /// + /// + /// Default value is null. + /// + [Parameter] + public string? Placeholder { get; set; } + + /// + /// Gets or sets the number of rows. + /// + [Parameter] + public int? Rows { get; set; } + + /// + /// Gets or sets the text alignment. + /// + /// + /// Default value is . + /// + [Parameter] + public Alignment TextAlignment { get; set; } = Alignment.None; + + /// + /// Gets or sets the value. + /// + [Parameter] + public string Value { get; set; } = default!; + + /// + /// This event fired on every user keystroke that changes the NumberInput value. + /// + [Parameter] + public EventCallback ValueChanged { get; set; } + + [Parameter] public Expression> ValueExpression { get; set; } = default!; + + #endregion +} diff --git a/blazorbootstrap/Components/Form/TextInput/TextInput.razor b/blazorbootstrap/Components/Form/TextInput/TextInput.razor new file mode 100644 index 000000000..795fbbbc6 --- /dev/null +++ b/blazorbootstrap/Components/Form/TextInput/TextInput.razor @@ -0,0 +1,15 @@ +@namespace BlazorBootstrap +@inherits BlazorBootstrapComponentBase + + \ No newline at end of file diff --git a/blazorbootstrap/Components/Form/TextInput/TextInput.razor.cs b/blazorbootstrap/Components/Form/TextInput/TextInput.razor.cs new file mode 100644 index 000000000..535ade3d5 --- /dev/null +++ b/blazorbootstrap/Components/Form/TextInput/TextInput.razor.cs @@ -0,0 +1,116 @@ +namespace BlazorBootstrap; + +public partial class TextInput : BlazorBootstrapComponentBase +{ + #region Fields and Constants + + private FieldIdentifier fieldIdentifier = default!; + + #endregion + + #region Methods + + protected override void OnInitialized() + { + AdditionalAttributes ??= new Dictionary(); + + fieldIdentifier = FieldIdentifier.Create(ValueExpression); + + base.OnInitialized(); + } + + /// + /// Disables number input. + /// + public void Disable() => Disabled = true; + + /// + /// Enables number input. + /// + public void Enable() => Disabled = false; + + private async Task OnChange(ChangeEventArgs e) + { + var oldValue = Value; + var newValue = e.Value?.ToString() ?? string.Empty; // object + + await ValueChanged.InvokeAsync(newValue); + + EditContext?.NotifyFieldChanged(fieldIdentifier); + } + + #endregion + + #region Properties, Indexers + + protected override string? ClassNames => + BuildClassNames( + Class, + (BootstrapClass.FormControl, true), + (TextAlignment.ToTextAlignmentClass(), TextAlignment != Alignment.None) + ); + + private string autoComplete => AutoComplete ? "true" : "false"; + + /// + /// If , NumberInput can complete the values automatically by the browser. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool AutoComplete { get; set; } + + /// + /// Gets or sets the disabled state. + /// + /// + /// Default value is false. + /// + [Parameter] + public bool Disabled { get; set; } + + [CascadingParameter] private EditContext EditContext { get; set; } = default!; + + private string fieldCssClasses => EditContext?.FieldCssClass(fieldIdentifier) ?? ""; + + /// + /// Gets or sets the maximum length of the input. + /// + [Parameter] + public int? MaxLength { get; set; } + + /// + /// Gets or sets the placeholder. + /// + /// + /// Default value is null. + /// + [Parameter] + public string? Placeholder { get; set; } + + /// + /// Gets or sets the text alignment. + /// + /// + /// Default value is . + /// + [Parameter] + public Alignment TextAlignment { get; set; } = Alignment.None; + + /// + /// Gets or sets the value. + /// + [Parameter] + public string Value { get; set; } = default!; + + /// + /// This event fired on every user keystroke that changes the NumberInput value. + /// + [Parameter] + public EventCallback ValueChanged { get; set; } + + [Parameter] public Expression> ValueExpression { get; set; } = default!; + + #endregion +} diff --git a/blazorbootstrap/Config.cs b/blazorbootstrap/Config.cs index 0a26e404a..32198bbb2 100644 --- a/blazorbootstrap/Config.cs +++ b/blazorbootstrap/Config.cs @@ -1,5 +1,4 @@ using BlazorBootstrap; -using Microsoft.Extensions.Configuration; namespace Microsoft.Extensions.DependencyInjection; @@ -12,7 +11,7 @@ public static class Config /// /// /// IServiceCollection - public static IServiceCollection AddBlazorBootstrap(this IServiceCollection services, IConfiguration configuration = null!) + public static IServiceCollection AddBlazorBootstrap(this IServiceCollection services) { services.AddScoped(); services.AddScoped(); diff --git a/blazorbootstrap/Constants/BootstrapClass.cs b/blazorbootstrap/Constants/BootstrapClass.cs index 73919b3ad..76e7ae0dc 100644 --- a/blazorbootstrap/Constants/BootstrapClass.cs +++ b/blazorbootstrap/Constants/BootstrapClass.cs @@ -92,9 +92,12 @@ public static class BootstrapClass public const string FormCheck = "form-check"; public const string FormCheckInput = "form-check-input"; + public const string FormCheckLabel = "form-check-label"; public const string FormCheckReverse = "form-check-reverse"; public const string FormControl = "form-control"; + public const string FormLabel = "form-label"; public const string FormRange = "form-range"; + public const string FormSelect = "form-select"; public const string FormSwitch= "form-switch"; public const string ImageFluid = "img-fluid"; diff --git a/blazorbootstrap/Models/AI/OpenAIChatMessage.cs b/blazorbootstrap/Models/AI/OpenAIChatMessage.cs deleted file mode 100644 index 4a3950e63..000000000 --- a/blazorbootstrap/Models/AI/OpenAIChatMessage.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace BlazorBootstrap; - -public record OpenAIChatMessage(string Role, string Content); diff --git a/blazorbootstrap/Models/AI/OpenAIChatPayload.cs b/blazorbootstrap/Models/AI/OpenAIChatPayload.cs deleted file mode 100644 index 92f69887d..000000000 --- a/blazorbootstrap/Models/AI/OpenAIChatPayload.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace BlazorBootstrap; - -public record OpenAIChatPayload -{ - #region Properties, Indexers - - /// - /// How much to penalize new tokens based on their existing frequency in the text so far. - /// Decreases the model's likelihood to repeat the same line verbatim. - /// Minimum 1 and the maximum is 2. - /// - /// Default value is 0. - [JsonPropertyName("frequency_penalty")] - public double FrequencyPenalty { get; set; } = 0; - - /// - /// The maximum number of tokens to generate shared between the prompt and completion. - /// The exact limit varies by model. (One token is roughly 4 characters for standard English text) - /// Minimum 1 and the maximum tokens is 4096. - /// - /// Default value is 2048. This value is limited by gpt-3.5-turbo. - [JsonPropertyName("max_tokens")] - public long MaximumTokens { get; set; } = 2048; - - [JsonPropertyName("messages")] - public List? Messages { get; set; } - - /// - /// How much to penalize new tokens based on whether they appear in the text so far. - /// Increases the model's likelihood to talk about new topics. - /// Minimum 1 and the maximum is 2. - /// - /// Default value is 0. - [JsonPropertyName("presence_penalty")] - public float PresencePenalty { get; set; } = 0; - - [JsonPropertyName("stream")] public bool Stream { get; } = true; - - /// - /// Controls randomness: Lowering results in less random completions. - /// As the temperature approaches zero, the model will become deterministic and repetitive. - /// Minimum 1 and the maximum is 2. - /// - /// Default value is 1. - [JsonPropertyName("temperature")] - public double Temperature { get; set; } = 1; - - /// - /// Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. - /// - /// Default value is 1. - [JsonPropertyName("top_p")] - public double TopP { get; set; } = 1; - - #endregion -} diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.ai.js b/blazorbootstrap/wwwroot/blazor.bootstrap.ai.js deleted file mode 100644 index f9241c524..000000000 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.ai.js +++ /dev/null @@ -1,57 +0,0 @@ -export async function createChatCompletions(key, messages, dotNetHelper) { - const API_KEY = key; - const API_URL = 'https://api.openai.com/v1/chat/completions'; - - try { - // Fetch the response from the OpenAI API with the signal from AbortController - const response = await fetch(API_URL, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${API_KEY}`, - }, - body: JSON.stringify({ - model: "gpt-3.5-turbo", //"gpt-4", - messages: messages, - max_tokens: 200, - stream: true, // For streaming responses - }) - }); - - // Read the response as a stream of data - const reader = response.body.getReader(); - const decoder = new TextDecoder("utf-8"); - let i = 0; - while (true) { - const { done, value } = await reader.read(); - if (done) { - break; - } - - // Massage and parse the chunk of data - const chunk = decoder.decode(value); - const lines = chunk.split("\n"); - - for (const payload of lines) { - - if (payload.includes('[DONE]')) { - dotNetHelper.invokeMethodAsync('ChartCompletetionsStreamJs', '', true); - return; - } - - if (payload.startsWith("data:")) { - const data = JSON.parse(payload.replace("data:", "")); - const content = data.choices[0].delta.content; - if (content) { - dotNetHelper.invokeMethodAsync('ChartCompletetionsStreamJs', content, false); - } - } - } - } - } catch (error) { - // Handle fetch request errors - console.log(error); - } finally { - // TODO: cleanup - } -} diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 055742f0d..94922a648 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -2002,83 +2002,3 @@ window.blazorChart.scatter = { } } } - -if (!window.blazorBootstrap.ai) { - window.blazorBootstrap.ai = {}; -} - -window.blazorBootstrap.ai = { - azureOpenAI: { - chat: { - completions: async (url, key, payload, dotNetHelper) => { - let contentArray = []; - let notificationTriggered = false; - let streamComplete = false; - - try { - const response = await fetch(url, { - method: "POST", - headers: { - "Content-Type": "application/json", - "api-key": `${key}`, - }, - body: JSON.stringify(payload) - }); - - // Read the response as a stream of data - const reader = response.body.getReader(); - const decoder = new TextDecoder("utf-8"); - let i = 0; - while (true) { - const { done, value } = await reader.read(); - if (done) { - break; - } - - // Message and parse the chunk of data - const chunk = decoder.decode(value); - const lines = chunk.split("\n"); - - for (const line of lines) { - - if (line.includes('[DONE]')) { - streamComplete = true; - return; - } - - if (line.startsWith("data:")) { - const data = JSON.parse(line.replace("data:", "")); - const content = data.choices[0]?.delta?.content; - if (content) { - contentArray.push(content); - if (!notificationTriggered) { - notificationTriggered = true; - triggerNotify(); - } - } - } - } - } - - function triggerNotify() { - let handler = setInterval(() => { - const content = contentArray.shift(); - if (content && content.length > 0) - dotNetHelper.invokeMethodAsync('ChartCompletetionsStreamJs', content, false); - - if (streamComplete && contentArray.length === 0) { - clearInterval(handler); - dotNetHelper.invokeMethodAsync('ChartCompletetionsStreamJs', '', true); - } - }, 100); - } - - } catch (error) { - console.log(error); - } finally { - // TODO: cleanup - } - } - } - } -}