Compare commits

...

374 Commits

Author SHA1 Message Date
Vladimir Enchev
45a1ce4b55 Version updated 2023-03-07 11:22:21 +02:00
Atanas Korchev
3e5cb2e30b Persist changes in the code editor. 2023-03-07 10:55:11 +02:00
yordanov
d0a4c6aaf1 Improve Button focus state 2023-03-07 10:44:19 +02:00
John Gold Inc
be4bcb7390 Add Density Parameter to DropDownDataGrid (#848)
Co-authored-by: John Gold <john.gold@haulerhub.com>
2023-03-07 08:54:07 +02:00
Vladimir Enchev
a63c3aa4c2 Fixed ContextMenu click event 2023-03-07 08:50:43 +02:00
yordanov
e8e43d97f2 Update ColorPicker demo 2023-03-06 16:49:28 +02:00
yordanov
9939ff4452 Fix ColorPicker disabled state. Resolves #803 2023-03-06 15:32:02 +02:00
Vladimir Enchev
b69bbc899e ColumnWidth and resizing enabled 2023-03-06 15:29:05 +02:00
Vladimir Enchev
f0cba24cc7 demo fixed 2023-03-06 15:07:53 +02:00
Vladimir Enchev
fd5fa0e798 attempt to fix online demo 2023-03-06 14:41:47 +02:00
yordanov
1ba1d53884 Remove LoginConfig page 2023-03-06 12:29:15 +02:00
yordanov
00a118b901 Update Login demo 2023-03-06 12:27:57 +02:00
Vladimir Enchev
ba2ea55884 demo fixed 2023-03-06 10:34:28 +02:00
Vladimir Enchev
70b4c3dd0f Version updated 2023-03-06 10:30:26 +02:00
Vladimir Enchev
412e19252c Demo updated with row index 2023-03-06 10:29:10 +02:00
Paul Ruston
73e1974583 Addition of a Source View for Html Editor (#838)
* Creation of a Source View for Html Editor

* Updated changes #1 as per conversations

* Make the view source tool last. Use the private mode field to track the state as parameters should not do that. View Source should blur the editor in order to update its state when switching modes. Simplify the CSS.

* Change GetMode() access to Public

* Add comment for GetMode() method

---------

Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-03-06 09:07:30 +02:00
Vladimir Enchev
25c57d645b .rz-navigation-item-link added to checks 2023-03-03 11:46:00 +02:00
Vladimir Enchev
a6c6021923 version updated 2023-03-03 11:32:27 +02:00
Vladimir Enchev
2886ac9d7c DataGrid should not reset settings on Reset() if using LoadData 2023-03-03 11:32:02 +02:00
Vladimir Enchev
c121414767 Numeric demo source code fixed 2023-03-03 09:58:58 +02:00
Conduci
35f02ef7a9 Added SelectView(ISchedulerView) to RadzenScheduler which allows consumers to programatically change the selected view (#842) 2023-03-02 18:36:10 +02:00
Vladimir Enchev
ffeb972a82 demo improved 2023-03-02 17:15:08 +02:00
Vladimir Enchev
f20a74674f demo code improved 2023-03-02 16:50:51 +02:00
Vladimir Enchev
03396fbbe2 Fixed error with Tooltip and navigating to a page with a different layout 2023-03-02 16:36:24 +02:00
Vladimir Enchev
54a5c0805e demo fixed 2023-03-02 11:39:54 +02:00
Vladimir Enchev
486cb66b6c SplitButton demo updated 2023-03-02 10:28:31 +02:00
Vladimir Enchev
e5d7a344c7 Fixed SplitButton disabled state when Busy 2023-03-02 10:00:00 +02:00
Vladimir Enchev
60fe0ed25f SplitButton demos updated 2023-03-02 09:56:22 +02:00
Vladimir Enchev
04741c702a Version updated 2023-03-02 09:35:51 +02:00
Vladimir Enchev
6e190fe903 SplitButton demo updated 2023-03-02 09:33:54 +02:00
yordanov
5bb3e65eb9 Add Density property to RadzenPager 2023-03-02 08:23:20 +02:00
yordanov
c3b29ffcd1 Fix text align in ListBox 2023-03-01 17:33:14 +02:00
yordanov
a889c3e97b Document text wrap css classes 2023-03-01 17:17:59 +02:00
Vladimir Enchev
bd578ca7cd SplitButton IsBusy property added
Fix #802
2023-03-01 15:33:36 +02:00
Atanas Korchev
2a9a115c31 Stacked bar and column charts (#837)
* Initial stack column series.

* Better maximum. Rounded corners only on the last series.

* Tooltips.

* Fix the offset of the first series.

* Actually make it correct.

* Optimizations.

* Update the demo.

* Add stacked bar files.

* Stacked bar tooltip.

* Data labels.

* Update the headings.
2023-03-01 13:54:33 +02:00
Vladimir Enchev
4d1848a5e1 demo code fixed
Fix #836
2023-03-01 11:54:04 +02:00
Vladimir Enchev
4bd8f777e0 Dialog demo updated 2023-03-01 10:21:18 +02:00
yordanov
4654a9011b Fix text align of DropDown value 2023-02-28 18:12:01 +02:00
yordanov
22a5dc148a Fix white-space after RadzenLink 2023-02-28 17:25:48 +02:00
yordanov
88dc4c0607 Radzen link text should inherit vertical alignment from parent 2023-02-28 17:25:11 +02:00
yordanov
0a7c47fa70 Remove obsolete chart styles 2023-02-28 16:41:19 +02:00
yordanov
e6f311ebba Update code tag styles 2023-02-28 11:58:30 +02:00
yordanov
88d09f0fef Add Chart demos for Series, Axis, Legend, and Tooltip 2023-02-28 11:58:30 +02:00
Zak Kohler
7467d87e36 Allow for zero width stroke (#834) 2023-02-28 08:37:16 +02:00
yordanov
b50e793a9c Fix wrapping of badges 2023-02-27 11:12:09 +02:00
yordanov
1147390576 Add social badges to demos homepage and footer 2023-02-27 11:07:12 +02:00
Vladimir Enchev
539785f079 isLoading check added 2023-02-27 11:03:11 +02:00
Vladimir Enchev
b99b516346 demo fixed 2023-02-27 10:41:35 +02:00
Vladimir Enchev
c0dc4f4236 delay removed 2023-02-27 10:29:11 +02:00
Vladimir Enchev
5b8f664530 Version updated 2023-02-27 10:12:39 +02:00
Vladimir Enchev
cc490692ad Revert "Show arrow icon when ChildContent exists (#832)"
This reverts commit 582a9bae31.
2023-02-27 10:12:11 +02:00
Vladimir Enchev
5ef415c87d Revert "DataGrid SaveSettings made awaitable"
This reverts commit 95f51ed935.
2023-02-27 10:12:04 +02:00
Vladimir Enchev
ff3c67409d Version updated 2023-02-27 09:49:18 +02:00
Ben Ghaner
582a9bae31 Show arrow icon when ChildContent exists (#832) 2023-02-27 09:14:32 +02:00
Vladimir Enchev
95f51ed935 DataGrid SaveSettings made awaitable
Fix #831
2023-02-27 09:13:37 +02:00
yordanov
0dca22c219 Fix DataGrid frozen-cell hover and selection background colors 2023-02-24 16:25:59 +02:00
yordanov
eaf67e197b Update Area chart demo 2023-02-24 15:50:18 +02:00
Vladimir Enchev
b8db918348 DataGrid save/load settings with LoadData demo fixed
Fix #824
2023-02-24 15:29:35 +02:00
Vladimir Enchev
c865073605 DataGrid KeyProperty added 2023-02-24 14:31:51 +02:00
yordanov
192ccbec25 Update pager demo 2023-02-24 12:35:35 +02:00
yordanov
b8b3b29d01 Update DataFilter demos 2023-02-24 12:06:20 +02:00
yordanov
00ea9a4393 Update DataList demo 2023-02-24 12:06:20 +02:00
Vladimir Enchev
267392d0b7 Fixed Splitter cannot be expanded runtime if Collapsed set to true 2023-02-24 09:37:33 +02:00
Atanas Korchev
e5f041208f SeriesClick event is sometimes not fired when clicking a marker. 2023-02-23 17:58:39 +02:00
Atanas Korchev
82010353c6 Missing ; after clip-path in bar charts. 2023-02-23 17:58:39 +02:00
yordanov
7daf4d1f58 Add Chart to popular components list 2023-02-23 17:25:00 +02:00
Vladimir Enchev
ebb940ee0e DataGrid inline edit demo updated 2023-02-23 16:35:12 +02:00
Dave Bagler
1ce8c98837 Adding an autocomplete type parameter. (#827)
* Adding an autocomplete type parameter.

* Converting the static class to an enum with an extension method.

* undoing some file changes that shouldn't have been included in the last commit
2023-02-23 13:27:29 +02:00
mderoo
257948cbe1 RadzenRequiredValidator firing on duplicate property names (#829)
* Update ValidatorBase.cs

fix for:
https://forum.radzen.com/t/required-validator-issue/13224/3
https://github.com/radzenhq/radzen-blazor/issues/395

* Invert the if.

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-02-23 11:33:08 +02:00
Vladimir Enchev
8971e0aa1a Fixed DataGrid column visibility out of sync with column picker when Visible changed runtime 2023-02-23 09:46:36 +02:00
Vladimir Enchev
2209b050b0 Version updated 2023-02-23 08:59:44 +02:00
yordanov
b5a876a93e Improve responsiveness of demos homepage layout 2023-02-22 18:58:13 +02:00
Vladimir Enchev
4c64ee24d5 Added RadzenTreeItem support for arbitrary attributes 2023-02-22 18:36:09 +02:00
Vladimir Enchev
1a3376374f Fixed DataFilter error with DateTimeOffset 2023-02-22 15:53:11 +02:00
Vladimir Enchev
ee88560090 Fixed DataGrid is skipping to last page when PageSize option selected greater than data present.
Fix #828
2023-02-22 11:39:10 +02:00
Vladimir Enchev
aae7eba068 MarkupString support added for DialogService Confirm and Alert 2023-02-22 11:21:57 +02:00
Vladimir Enchev
6715bc34d8 SpeechToTextButton demo updated 2023-02-22 10:21:41 +02:00
Vladimir Enchev
55d0ea5e22 obsolete file deleted 2023-02-21 16:22:25 +02:00
Vladimir Enchev
11c692b146 Slider demo updated 2023-02-21 16:21:54 +02:00
Vladimir Enchev
ab47bd2e7b obsolete files deleted 2023-02-21 16:10:20 +02:00
Vladimir Enchev
6dd9933d55 SelectBar demo updated 2023-02-21 16:08:20 +02:00
Vladimir Enchev
d08d398b47 Rating demo updated 2023-02-21 15:26:27 +02:00
Vladimir Enchev
aa3903d8f0 Fixed DataGrid column SecondFilterValue not set correctly when using FilterTemplate
Fix #826
2023-02-21 15:16:05 +02:00
Vladimir Enchev
26f9030cef Fixed RadzenCheckBoxList AllowSelectAll doesn't work when using Data Property
Fix #823
2023-02-21 15:12:49 +02:00
tecxx
0500a10671 add ClearSelection method to RadzenTree (#822)
Co-authored-by: Robert Rostek <robert@rostech.at>
2023-02-21 15:02:31 +02:00
WoodyJ007
c3ae2d3eda Added option to stop auto focus on filter input on DropDownDatagrid. This improves user experience on mobile devices. (#825)
Co-authored-by: John Wood <john.wood@woodstarsoftware.co.uk>
2023-02-21 15:01:27 +02:00
Artur Madjidov
e502c51886 Add parameters for the example texts in RadzenHtmlEditorFormatBlock. (#821) 2023-02-21 12:15:40 +02:00
Vladimir Enchev
063c1aa6c0 Password updated 2023-02-21 11:25:51 +02:00
Vladimir Enchev
5e5db9193e Numeric demo updated 2023-02-21 10:40:46 +02:00
Vladimir Enchev
26a38fc56c RadioButtonList demo updated 2023-02-21 10:10:58 +02:00
Vladimir Enchev
aad0558a9c ListBox demo updated 2023-02-21 09:41:09 +02:00
yordanov
a911f975da Update Column demo 2023-02-20 20:12:04 +02:00
yordanov
a99c8fbc88 Update Image demo 2023-02-20 17:05:07 +02:00
yordanov
79525227a9 Update Gravatar demo 2023-02-20 17:05:07 +02:00
Vladimir Enchev
66b8eb72bf DropDownDataGrid demo updated 2023-02-20 16:39:00 +02:00
yordanov
1eff269b80 Update Tabs demo 2023-02-20 14:27:09 +02:00
Vladimir Enchev
2dc01b528c DropDownCustomObjects updated 2023-02-20 12:56:13 +02:00
Vladimir Enchev
30e200896d DropDownGrouping updated 2023-02-20 12:47:24 +02:00
Vladimir Enchev
7d2e827e6f DropDownFiltering demo updated 2023-02-20 12:38:35 +02:00
Vladimir Enchev
94e6b3086b DropDownVirtualization demo updated 2023-02-20 12:31:33 +02:00
Vladimir Enchev
0849e90574 DropDown multiple selection demo reworked 2023-02-20 11:10:48 +02:00
Vladimir Enchev
d3eef33371 DropDown single selection demo updated 2023-02-20 10:53:57 +02:00
yordanov
1cee0d10e5 Update Steps demo 2023-02-20 10:43:34 +02:00
Vladimir Enchev
3f044b407a DatePicker demo updated 2023-02-20 10:16:05 +02:00
Vladimir Enchev
b25ce3760b Obsolete demo removed 2023-02-20 09:44:54 +02:00
Vladimir Enchev
6e810761f8 CheckBoxList demo updated 2023-02-20 09:34:13 +02:00
yordanov
6dea80e13e Update PanelMenu demo 2023-02-17 15:36:59 +02:00
yordanov
a715616a6a Update ProfileMenu demo 2023-02-17 15:17:09 +02:00
yordanov
e87db432d5 Update Menu demo 2023-02-17 15:15:12 +02:00
yordanov
0b4b89dcbd Update Link description 2023-02-17 14:48:14 +02:00
yordanov
0e980051e3 Update Link demo 2023-02-17 14:46:35 +02:00
yordanov
4bd489a530 Update breadcrumb template description and remove config page 2023-02-17 14:18:03 +02:00
yordanov
ed02c0dbc1 Update BreadCrumb demo 2023-02-17 14:08:53 +02:00
yordanov
81e2432426 Update texts in Tooltip demo 2023-02-17 14:08:53 +02:00
Vladimir Enchev
3a14099831 Card removed from CheckBox demos 2023-02-17 12:55:51 +02:00
Vladimir Enchev
84712967b0 AutoCompleteConfig removed 2023-02-17 12:54:51 +02:00
yordanov
1fc70b7591 Update AutoComplete demos 2023-02-17 11:39:50 +02:00
Vladimir Enchev
b9f8345964 CheckBox demo reworked 2023-02-17 11:18:21 +02:00
yordanov
fcd9e674d5 Update Tooltip demo 2023-02-17 11:02:40 +02:00
Vladimir Enchev
2cf2dfaea5 AutoComplete reworked 2023-02-17 10:36:39 +02:00
yordanov
797be4e57c Update console log 2023-02-17 09:48:03 +02:00
yordanov
2478f1478f Update ProgressBar demo 2023-02-16 17:11:13 +02:00
Vladimir Enchev
58cd508be4 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-16 16:39:31 +02:00
Vladimir Enchev
9ca094f4f8 demo updated 2023-02-16 16:39:21 +02:00
yordanov
9ed9878193 Update Alert demos 2023-02-16 16:39:18 +02:00
Vladimir Enchev
c878a47f92 Save/Load settings demo category added 2023-02-16 16:21:15 +02:00
Vladimir Enchev
42d7a8860a DataGrid Save/Load settings with LoadData demo added 2023-02-16 15:41:20 +02:00
yordanov
718824f359 Revert body translateZ. Animations require a new stacking context under WebKit. 2023-02-16 12:16:12 +02:00
yordanov
3b5b649530 Remove will-change property from rz-body 2023-02-16 11:38:03 +02:00
Vladimir Enchev
8702af0c42 IsBusy added on run 2023-02-16 11:22:28 +02:00
yordanov
b038157f2f Remove rz-body translateZ transform to prevent new stacking context 2023-02-16 10:55:22 +02:00
Vladimir Enchev
0033bdd570 Heading and Documentation removed from all examples 2023-02-16 10:48:45 +02:00
Vladimir Enchev
99b40cac43 Version updated 2023-02-16 09:32:05 +02:00
Vladimir Enchev
7fa91f98c6 Extended Blazor server buffer size 2023-02-16 09:29:41 +02:00
yordanov
a6e3f48044 Update spacing in MainLayout sidebar 2023-02-15 19:00:06 +02:00
Vladimir Enchev
d25921f6c8 Look for inner filter expressions recursive 2023-02-15 18:16:35 +02:00
yordanov
e1986dc8eb Fix spacing in MainLayout 2023-02-15 17:03:30 +02:00
yordanov
ebba5b860f Introduce Radzden Blazor Studio 2023-02-15 16:58:36 +02:00
yordanov
4beff8932e Update Layout demo 2023-02-15 11:55:19 +02:00
yordanov
e26bd9adfb Update panel demo IDs 2023-02-15 11:55:19 +02:00
Vladimir Enchev
2eadc7b5ea code fixed 2023-02-15 10:58:18 +02:00
Vladimir Enchev
a15aeade6a RequiredValidator demo updated 2023-02-15 10:53:29 +02:00
Vladimir Enchev
1990b7fad5 NumericRangeValidator demo updated 2023-02-15 10:52:05 +02:00
Vladimir Enchev
d81d5a37f8 LengthValidator demo updated 2023-02-15 10:51:02 +02:00
Vladimir Enchev
1c1da0b080 EmailValidator demo updated 2023-02-15 10:49:45 +02:00
Vladimir Enchev
4063bce178 CompareValidator demo updated 2023-02-15 10:48:35 +02:00
Vladimir Enchev
b4d33c6472 Tooltip demo updated 2023-02-15 10:46:55 +02:00
Vladimir Enchev
44005c607d AlertStylingConfig demo updated 2023-02-15 10:45:33 +02:00
Vladimir Enchev
c17852a583 Alert demo updated 2023-02-15 10:44:26 +02:00
Vladimir Enchev
f94b22666b Notification demo updated 2023-02-15 10:43:09 +02:00
Vladimir Enchev
3c8c690a79 StylingGaugeConfig updated 2023-02-15 10:40:54 +02:00
Vladimir Enchev
6f416ffe79 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-15 10:39:22 +02:00
Vladimir Enchev
e4f8fe9ea2 ArcGauge demo updated 2023-02-15 10:39:14 +02:00
yordanov
003738149e Update Panel info 2023-02-15 10:38:18 +02:00
Vladimir Enchev
6f39223787 StylingChartConfig updated 2023-02-15 10:37:28 +02:00
Vladimir Enchev
06649c2207 ChartInterpolationConfig demo updated 2023-02-15 10:36:02 +02:00
Vladimir Enchev
18f51becd8 ChartTrendsConfig updated 2023-02-15 10:33:11 +02:00
Vladimir Enchev
916792abea PieChartConfig updated 2023-02-15 10:31:26 +02:00
Vladimir Enchev
c8f8e019f6 LineChartConfig updated 2023-02-15 10:30:09 +02:00
Vladimir Enchev
7b6c6bb930 DonutChartConfig updated 2023-02-15 10:28:52 +02:00
Vladimir Enchev
b826993a0d ColumnChartConfig updated 2023-02-15 10:27:36 +02:00
Vladimir Enchev
00385c8e15 BarChart demo updated 2023-02-15 10:26:11 +02:00
Vladimir Enchev
5b982766fb AreaChart demo updated 2023-02-15 10:24:34 +02:00
Vladimir Enchev
be27dfd918 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-15 10:22:10 +02:00
Vladimir Enchev
a82089aff3 HtmlEditorCustomTools updated 2023-02-15 10:22:00 +02:00
yordanov
215ba8bfbf Update Panel demo 2023-02-15 10:20:52 +02:00
Vladimir Enchev
7b1e9185f7 HtmlEditor demo updated 2023-02-15 10:20:20 +02:00
Vladimir Enchev
8c756e99c1 Upload demo updated 2023-02-15 10:18:13 +02:00
Vladimir Enchev
d2384e74cd TextBox demo updated 2023-02-15 10:17:03 +02:00
Vladimir Enchev
b2ff2852bd TextArea updated 2023-02-15 10:16:16 +02:00
Vladimir Enchev
3b4505af27 TemplateForm demo fixed 2023-02-15 10:11:42 +02:00
Vladimir Enchev
87eee126e5 Switch demo updated 2023-02-15 10:09:29 +02:00
Vladimir Enchev
6234f04457 SplitButton updated 2023-02-15 10:08:22 +02:00
Vladimir Enchev
c8e808082f SpeechToTextButton demo updated 2023-02-15 10:06:56 +02:00
Vladimir Enchev
b2f2642c82 Slider demo updated 2023-02-15 10:05:52 +02:00
Vladimir Enchev
0f77730011 SelectBar demo updated 2023-02-15 10:04:52 +02:00
Vladimir Enchev
b062d56928 Rating demo updated 2023-02-15 10:03:30 +02:00
Vladimir Enchev
a3f8552b80 RadioButtonList demo updated 2023-02-15 10:02:16 +02:00
Vladimir Enchev
8faf5a81ca Numeric demo updated 2023-02-15 10:01:03 +02:00
Vladimir Enchev
7d7c0ae320 Mask demo updated 2023-02-15 09:59:57 +02:00
Vladimir Enchev
2bd8b71927 ListBox demo updated 2023-02-15 09:58:54 +02:00
Vladimir Enchev
19a323ec77 DropDownDataGrid demo updated 2023-02-15 09:57:19 +02:00
Vladimir Enchev
29ee95165e DatePicker demo updated 2023-02-15 09:55:23 +02:00
Vladimir Enchev
c618a31e44 ColorPicker demo updated 2023-02-15 09:53:07 +02:00
Vladimir Enchev
f972de507f CheckBoxList demo updated 2023-02-15 09:51:45 +02:00
Vladimir Enchev
51a0be31d5 CheckBox demo updated 2023-02-15 09:50:18 +02:00
Vladimir Enchev
d986c12564 AutoComplete demo updated 2023-02-15 09:47:52 +02:00
Vladimir Enchev
1ae17b121e Steps demo updated 2023-02-15 09:41:41 +02:00
Vladimir Enchev
afb294f170 Login demo updated 2023-02-15 09:40:08 +02:00
Vladimir Enchev
2b63fa343a ContextMenu demo updated 2023-02-15 09:38:45 +02:00
Vladimir Enchev
35121f1141 BreadCrumb demo updated 2023-02-15 09:37:37 +02:00
Vladimir Enchev
9d0f26fede Accordion demo updated 2023-02-15 09:36:07 +02:00
Vladimir Enchev
f0289b73b8 Dialog demo updated 2023-02-15 09:34:38 +02:00
Vladimir Enchev
1009619ecd Column demo updated 2023-02-15 09:31:55 +02:00
Vladimir Enchev
f30b1b1e08 Row demo updated 2023-02-15 09:30:09 +02:00
Vladimir Enchev
d151f39a22 Stack demo updated 2023-02-15 09:28:30 +02:00
Vladimir Enchev
be6d4accff Layout demo updated 2023-02-15 09:26:19 +02:00
yordanov
69e71202ee Update Card demo 2023-02-15 09:09:31 +02:00
yordanov
fece284aee Update badge usage demo 2023-02-15 09:09:08 +02:00
yordanov
4bcb44bcb2 Update Badge demo 2023-02-14 20:04:15 +02:00
Paul Ruston
0891dbf5a8 Pie and Donut render errors (#813)
* Pie and Donut render errors

* Take into account negative values. Added property ItemsGreaterZero

* Moved ItemsGreaterZero to RadzenPieSeries

* Rename the property and set it once to avoid multiple allocations.

---------

Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-02-14 18:08:32 +02:00
Vladimir Enchev
b5b5a86025 Splitter demo updated 2023-02-14 16:43:05 +02:00
Vladimir Enchev
3fcbe831d7 Image demo updated 2023-02-14 16:39:52 +02:00
Vladimir Enchev
d253151296 Scheduler demo updated 2023-02-14 16:36:03 +02:00
Vladimir Enchev
4e9beb86b0 DropDown demo updated 2023-02-14 16:31:21 +02:00
Vladimir Enchev
7f85b49f3f DropDownVirtualization updated 2023-02-14 16:29:10 +02:00
Vladimir Enchev
1ea8c56631 DropDownMultiple updated 2023-02-14 16:27:48 +02:00
Vladimir Enchev
5d76cbee26 DropDownGrouping updated 2023-02-14 16:26:38 +02:00
Vladimir Enchev
682e4af619 DropDownFiltering updated 2023-02-14 16:25:32 +02:00
Vladimir Enchev
c446476fbc DropDownCustomObjects updated 2023-02-14 16:23:48 +02:00
Vladimir Enchev
e18a05001e RegexValidator updated 2023-02-14 16:19:51 +02:00
Vladimir Enchev
0685f8b9c0 TreeCheckBoxes updated 2023-02-14 16:16:45 +02:00
Vladimir Enchev
bdd1d4e8c1 TreeDataBinding updated 2023-02-14 16:15:50 +02:00
Vladimir Enchev
bf6923f909 TreeFileSystem demo reworked 2023-02-14 16:14:43 +02:00
Vladimir Enchev
faa37c3322 TreeSelection updated 2023-02-14 15:46:02 +02:00
Vladimir Enchev
1fe5b07f86 Tree demo updated 2023-02-14 15:44:44 +02:00
Vladimir Enchev
7a9ad3933b TemplateForm demo updated 2023-02-14 15:42:07 +02:00
Vladimir Enchev
df2e447362 Tabs demo updated 2023-02-14 15:39:25 +02:00
Vladimir Enchev
b2033f3dcd RadialGauge demo updated 2023-02-14 15:37:00 +02:00
Vladimir Enchev
186bce852d ProgressBar demo updated 2023-02-14 15:34:56 +02:00
Vladimir Enchev
e1494441b0 ProfileMenu demo updated 2023-02-14 15:33:28 +02:00
Vladimir Enchev
1b67c130c7 Password demo updated 2023-02-14 15:31:52 +02:00
yordanov
628b980655 Update Dashboard demo 2023-02-14 12:00:32 +02:00
Vladimir Enchev
0e04a17380 Panel demo updated 2023-02-14 11:53:16 +02:00
Vladimir Enchev
cee1a14ebd PanelMenu demo updated 2023-02-14 11:51:14 +02:00
Vladimir Enchev
3862205053 Pager demo updated 2023-02-14 11:49:35 +02:00
Vladimir Enchev
9696f044a0 Menu demo reworked 2023-02-14 11:46:53 +02:00
Vladimir Enchev
b61a0f2c94 Link demo updated 2023-02-14 11:44:23 +02:00
Vladimir Enchev
afb2e3a8a2 Card demo updated 2023-02-14 11:39:38 +02:00
Vladimir Enchev
65cc0a0ed5 ChartAnnotations updated 2023-02-14 11:37:47 +02:00
Vladimir Enchev
dba6f2ec6a GravatarConfig updated 2023-02-14 11:35:52 +02:00
Vladimir Enchev
b39ea03ba6 FileInputConfig reworked 2023-02-14 11:33:56 +02:00
Vladimir Enchev
528483b905 GoogleMapConfig reworked 2023-02-14 11:32:04 +02:00
Vladimir Enchev
fb7434f1b4 Fieldset demo updated 2023-02-14 11:26:58 +02:00
Vladimir Enchev
a239e6405b FieldsetConfig reworked 2023-02-14 11:25:37 +02:00
Vladimir Enchev
d5c00b81d7 ExportToExcelCsv reworked 2023-02-14 11:23:28 +02:00
Vladimir Enchev
590f6c8c8b CascadingDropDowns reworked 2023-02-14 11:22:05 +02:00
Vladimir Enchev
edf2495a9f DataGridMasterDetail reworked 2023-02-14 11:20:04 +02:00
Vladimir Enchev
ed0a034414 DataGridMasterDetailHierarchy reworked 2023-02-14 11:17:49 +02:00
Vladimir Enchev
3e33e0d0e1 DataGridMasterDetailHierarchyOnDemand reworked 2023-02-14 11:14:53 +02:00
Vladimir Enchev
c9e1c2711e code fixed 2023-02-14 11:11:39 +02:00
Vladimir Enchev
1f0420dc1f DataList page reworked 2023-02-14 10:52:48 +02:00
Vladimir Enchev
f0320c6ff9 DataGridVirtualization reworked 2023-02-14 10:49:29 +02:00
Vladimir Enchev
904eb1364c DataGridVirtualizationLoadData reworked 2023-02-14 10:48:31 +02:00
Vladimir Enchev
e5ef184515 DataGridSort reworked 2023-02-14 10:47:30 +02:00
Vladimir Enchev
2a4111643c DataGridSortApi reworked 2023-02-14 10:46:34 +02:00
Vladimir Enchev
53ffe057b2 DataGridSingleSelection reworked 2023-02-14 10:45:42 +02:00
Vladimir Enchev
b2632e1727 DataGridSimpleFilterWithMenu reworked 2023-02-14 10:44:51 +02:00
Vladimir Enchev
84554d6dea DataGridSimpleFilter reworked 2023-02-14 10:43:57 +02:00
Vladimir Enchev
6fd8f8380b DataGridSelfReferenceHierarchy reworked 2023-02-14 10:43:00 +02:00
Vladimir Enchev
5330929efd DataGridSaveSettings reworked 2023-02-14 10:41:30 +02:00
Vladimir Enchev
c67bc9938c DataGridPerformance reworked 2023-02-14 10:40:40 +02:00
Vladimir Enchev
f41f0e94be DataGridPagerPosition reworked 2023-02-14 10:39:45 +02:00
Vladimir Enchev
74b1c6f4ed DataGridPagerHorizontalAlign reworked 2023-02-14 10:38:51 +02:00
Vladimir Enchev
54d7e20baa DataGridPagerApi reworked 2023-02-14 10:38:02 +02:00
Vladimir Enchev
221d88c52c DataGridOData reworked 2023-02-14 10:37:00 +02:00
Vladimir Enchev
eb3c8050fe DataGridMultipleSort reworked 2023-02-14 10:36:01 +02:00
Vladimir Enchev
fdab854799 DataGridMultipleSelection reworked 2023-02-14 10:34:59 +02:00
Vladimir Enchev
ba32761a0c DataGridLoadData reworked 2023-02-14 10:33:53 +02:00
Vladimir Enchev
6d002838a5 DataGridInLineEdit reworked 2023-02-14 10:32:38 +02:00
Vladimir Enchev
d8f53db387 DataGridGroupingApi reworked 2023-02-14 10:31:15 +02:00
Vladimir Enchev
f15db1637e DataGridGroupHeaderTemplate reworked 2023-02-14 10:29:11 +02:00
Vladimir Enchev
5f98e2fdc5 DataGridGroupFooterTemplate reworked 2023-02-14 10:28:13 +02:00
Vladimir Enchev
603dc9f9c6 DataGridGridLines reworked 2023-02-14 10:27:11 +02:00
Vladimir Enchev
0692079384 DataGridFrozenColumns reworked 2023-02-14 10:24:51 +02:00
Vladimir Enchev
e046cdce45 DataGridFooterTotals reworked 2023-02-14 10:23:48 +02:00
Vladimir Enchev
595419df77 DataGridFilterApi reworked 2023-02-14 10:22:52 +02:00
Vladimir Enchev
1a641afaa8 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-14 10:21:37 +02:00
Vladimir Enchev
29c73ae90f DataGridEmpty reworked 2023-02-14 10:21:27 +02:00
yordanov
e055f99f63 Update spacing in UI fundamentals demos 2023-02-14 10:20:52 +02:00
Vladimir Enchev
888d4797d0 DataGridDynamicData reworked 2023-02-14 10:20:04 +02:00
Vladimir Enchev
b95d63e974 DataGridDensity reworked 2023-02-14 10:19:08 +02:00
Vladimir Enchev
195abb59ff DataGridConditionalTemplate reworked 2023-02-14 10:18:07 +02:00
Vladimir Enchev
306ceba474 DataGridCompositeColumns reworked 2023-02-14 10:17:04 +02:00
Vladimir Enchev
2be1476130 DataGridColumnTemplate reworked 2023-02-14 10:16:05 +02:00
Vladimir Enchev
ca80356c27 DataGridColumnResizing reworked 2023-02-14 10:15:03 +02:00
Vladimir Enchev
eed34d9b7d DataGridColumnReoder reworked 2023-02-14 10:14:00 +02:00
Vladimir Enchev
1144ab32b7 DataGridColumnPicking reworked 2023-02-14 10:12:55 +02:00
Vladimir Enchev
0061e609d4 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-14 10:11:32 +02:00
Vladimir Enchev
680b64c98f DataGridColumnFilterTemplate reworked 2023-02-14 10:11:21 +02:00
yordanov
325048efcb Update RadzenText demo 2023-02-14 10:09:59 +02:00
Vladimir Enchev
aedb293d50 DataGridColumnEnumFilter example reworked 2023-02-14 10:09:45 +02:00
Vladimir Enchev
6cdc1943fb DataGrid cell select page reworked 2023-02-14 10:07:25 +02:00
Vladimir Enchev
9ff40875c2 DataGrid cell context menu demo reworked 2023-02-14 10:02:31 +02:00
Vladimir Enchev
3a851d59fe DataGrid advanced filter mode demo reworked 2023-02-14 09:46:50 +02:00
Vladimir Enchev
64de7abada DataFilter page updated 2023-02-14 09:42:31 +02:00
yordanov
6d9feebedd Update ripple demo 2023-02-14 09:15:12 +02:00
yordanov
441658eb7a Update shadows demo 2023-02-14 09:01:36 +02:00
yordanov
01a441a99c Update borders demo 2023-02-14 08:41:40 +02:00
yordanov
1d10141c1d Update icons demo 2023-02-13 19:51:05 +02:00
Vladimir Enchev
952313acee demo updated 2023-02-13 17:04:07 +02:00
Vladimir Enchev
d537b742dc Export demo update to handle sub properties as alias 2023-02-13 16:55:12 +02:00
Vladimir Enchev
f3b706bcc2 themes updated 2023-02-13 14:37:36 +02:00
Vladimir Enchev
2a57af944f Version updated 2023-02-13 14:30:38 +02:00
Sergiu Ciudin
3f42b93300 Fixed DatePicker Kind getting lost when type is DateTime (#807)
* Update RadzenDatePicker.razor.cs

Fixed DatePicker Kind getting lost when type is DateTime

* Fixed DatePicker Kind getting lost when type is DateTime

* Update RadzenDatePicker.razor.cs

The right version

* Probably i should check type also
2023-02-13 14:27:50 +02:00
Vladimir Enchev
59a58eb886 DataGrid AllowFilterDateInput property added
Fix #811
2023-02-13 14:04:18 +02:00
yordanov
d91d5bcd9b Add new views to Scheduler demo 2023-02-13 12:01:49 +02:00
yordanov
c6a08c79e1 Fix scheduler planner view overflow 2023-02-13 12:00:52 +02:00
yordanov
d550b65bc7 Update other month and weekend slot styles 2023-02-13 10:34:12 +02:00
yordanov
42418ef393 Update year view styles in material theme 2023-02-13 10:34:12 +02:00
yordanov
12f4156ae0 Refactor year view styles 2023-02-13 10:34:12 +02:00
yordanov
ff58873fcb Refactor timeline view styles 2023-02-13 10:34:12 +02:00
yordanov
925c72f6aa Refactor planner view styles 2023-02-13 10:34:12 +02:00
Paul Ruston
345d853e2d Creation of new views for scheduler 2023-02-13 10:34:12 +02:00
Vladimir Enchev
10b064dc40 Added title to DataFilter with OData 2023-02-10 11:51:42 +02:00
Vladimir Enchev
75a7187a87 DataFilter OData page reworked for source edit 2023-02-10 10:15:18 +02:00
Vladimir Enchev
6182e00c31 code fixed 2023-02-10 10:13:40 +02:00
Vladimir Enchev
e3ba93a6b8 VirtualizationOverscanCount added to DropDown, DropDownDataGrid and ListBox 2023-02-10 09:28:49 +02:00
Vladimir Enchev
109d8cacbc code viewer fixed 2023-02-09 17:40:35 +02:00
Vladimir Enchev
3bcc18f035 DataGrid binding to IQueryable reworked 2023-02-09 17:22:11 +02:00
Vladimir Enchev
92baa1affb Version updated 2023-02-09 15:56:30 +02:00
Vladimir Enchev
32a9457de3 Fixed DataGrid filter popup will not open after column Visible change
`
2023-02-09 15:56:10 +02:00
Vladimir Enchev
32c147fa16 Title, subtitle and class attribute improved for all demos 2023-02-09 15:23:54 +02:00
Vladimir Enchev
d61d75f8bb PublishTrimmed set to false 2023-02-09 09:50:22 +02:00
Vladimir Enchev
eae6cd5396 themes updated 2023-02-09 09:26:04 +02:00
Vladimir Enchev
6f16f230d1 Version updated 2023-02-09 09:04:20 +02:00
Emil Nachev
f458a057e8 Last order date: From OrderByDescending take First (#801)
Last order date: 
From OrderByDescending take First item
or 
from OrderBy take Last item
2023-02-09 08:57:52 +02:00
yordanov
d013300fa3 Update example source tab text and title 2023-02-08 16:01:55 +02:00
yordanov
d6b8394044 Update Support page 2023-02-08 16:01:55 +02:00
yordanov
c1fa630602 Update Get Started page 2023-02-08 16:01:55 +02:00
Emil Nachev
28a03dadaf Update DataGridVirtualizationLoadDataPage.razor (#799) 2023-02-08 14:54:15 +02:00
Vladimir Enchev
29cfc2ea6b Fixed closing dialogs logic
Fix #791
2023-02-08 10:10:31 +02:00
Vladimir Enchev
f4c776f10e Fixed DataGrid filter popup no working correctly after column Visible change runtime 2023-02-07 14:57:15 +02:00
tecxx
04be6bc38b workaround for HTMLEditor innerHTML exception (#728) (#795)
Co-authored-by: Robert Rostek <robert@rostech.at>
2023-02-07 11:36:45 +02:00
Vladimir Enchev
4f0bbeeab0 Fixed DataGridColumn and DataFilterProperty FormatString logic 2023-02-07 11:18:53 +02:00
Vladimir Enchev
5a356a8d75 DataGrid ExpandRows() and CollapseRows() methods added 2023-02-07 09:31:20 +02:00
yordanov
7f35f46eaa Remove invalid --rz-paginator-button-size css variable. Resolves #794 2023-02-06 17:33:17 +02:00
yordanov
ea7be67d83 Update Support page 2023-02-06 16:48:05 +02:00
yordanov
8f0d65766d Update Colors page layout 2023-02-06 16:48:05 +02:00
yordanov
a140f318a2 Update MainLayout padding and remove TOC 2023-02-06 16:48:05 +02:00
yordanov
d0a2d1644f Add ComponentName parameter to RadzenExample 2023-02-06 16:48:05 +02:00
yordanov
e69b153e1c Add initial TOC styles 2023-02-06 16:48:05 +02:00
yordanov
d19d383738 Update Spacing page 2023-02-06 16:48:05 +02:00
yordanov
253f288323 Update Breakpoints page 2023-02-06 16:48:05 +02:00
yordanov
d6ce0536ca Update Button demo page 2023-02-06 16:48:05 +02:00
yordanov
0168c01915 Style RadzenExample tabs and source code editor 2023-02-06 16:48:05 +02:00
Atanas Korchev
7329fec67a Add copy button and error handling. 2023-02-06 16:48:05 +02:00
Atanas Korchev
5fea22294e Update branch name. 2023-02-06 16:48:05 +02:00
Atanas Korchev
669124a6b3 Runnable snippets. 2023-02-06 16:48:05 +02:00
Atanas Korchev
c44d141c07 Add monaco editor. 2023-02-06 16:48:05 +02:00
Atanas Korchev
0b30e00b8c Compile examples. 2023-02-06 16:48:05 +02:00
Vladimir Enchev
1e7bd1bf48 AsODataEnumerable() removed from the demo 2023-02-06 13:02:49 +02:00
Vladimir Enchev
c2c4d6aa02 Version updated 2023-02-06 11:27:07 +02:00
Vladimir Enchev
7e0c64191c DataGrid advanced filter mode reworked with form to handle submit on enter key 2023-02-06 11:24:26 +02:00
Vladimir Enchev
323e4e971a DataGrid advanced filter mode will apply filter on enter key
Fix #786
2023-02-06 10:07:50 +02:00
Vladimir Enchev
99b4f8f8fc Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-06 09:53:10 +02:00
Vladimir Enchev
7c1cf76c5c Fixed DialogOptions.CloseDialogOnEsc behavior
Fix #791
2023-02-06 09:52:53 +02:00
Atanas Korchev
305e1b7af6 Paste images as data URI if the UploadUrl property of RadzenHtmlEditor is not set. 2023-02-06 09:46:51 +02:00
Vladimir Enchev
6880a70227 Tabs component select with RenderMode Client should not set display:block
Fix #792
2023-02-06 09:41:39 +02:00
yordanov
0482969755 Add text transform utility css classes 2023-02-02 14:27:46 +02:00
Atanas Korchev
4c9b429dae Update performance demo. 2023-02-02 10:09:16 +02:00
Vladimir Enchev
60b8400e29 DataFilter OData demo should not inherit from DbContextPage 2023-02-01 15:36:01 +02:00
Vladimir Enchev
7260be98d6 Version updated 2023-02-01 15:25:07 +02:00
Vladimir Enchev
be94094de7 DataFilter OData support added 2023-02-01 14:23:06 +02:00
Vladimir Enchev
645077f39b DataGrid VirtualizationOverscanCount property added 2023-01-31 13:55:10 +02:00
Vladimir Enchev
b42940441d Version updated 2023-01-30 12:30:40 +02:00
yordanov
fc7071c04e Update main demos layouts 2023-01-27 19:01:27 +02:00
yordanov
de887a4e3f Generate display utility classes with responsive breakpoints 2023-01-27 15:59:25 +02:00
yordanov
7f629309c7 Add mixin for utility classes with responsive breakpoints 2023-01-27 15:59:25 +02:00
yordanov
fa45e209d5 Add text-align with responsive breakpoints and classes for white-space 2023-01-27 15:59:25 +02:00
Vladimir Enchev
40aec6cd0d Set FilterPopupRenderMode="PopupRenderMode.OnDemand" for various DataGrid examples 2023-01-27 13:58:35 +02:00
Vladimir Enchev
969ae7aeca DataGrid FilterPopupRenderMode Initial improved 2023-01-27 13:50:17 +02:00
Vladimir Enchev
a64bbd34f3 DataGrid advanced filtering demo updated 2023-01-27 13:42:02 +02:00
Vladimir Enchev
79acf83d6f Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-01-27 13:39:54 +02:00
Vladimir Enchev
786e8d0be1 FilterPopupRenderMode default value changed to Initial 2023-01-27 13:39:45 +02:00
Foitn
2757850f28 #748 Added methods to edit a range of rows and cancel a range of rows (#784)
Co-authored-by: DEMCON\MFE <marijn.feijten@demcon.com>
2023-01-27 13:36:48 +02:00
Vladimir Enchev
7c6f39f3b5 DataGrid FilterPopupRenderMode property added with OnDemand as default value 2023-01-27 12:04:00 +02:00
Vladimir Enchev
70723d0437 Fixed RadzenDataFilterProperty FilterTemplate context to be the underling Filter 2023-01-26 15:56:47 +02:00
Vladimir Enchev
bd9b0f798b Version updated 2023-01-26 10:52:35 +02:00
Bruno Silva
0c406b2ad8 Update DataGridInLineEditPage.razor (#783)
After inserting a new object the insert button was disabled.
2023-01-26 09:26:02 +02:00
Vladimir Enchev
822891541c check if event is present 2023-01-25 10:05:47 +02:00
Vladimir Enchev
bf064fd4e3 Added MarkupString support for Accordion item Text property 2023-01-24 15:55:22 +02:00
Vladimir Enchev
6c9e055d42 Added Template support for DropDown and DropDownDataGrid chips 2023-01-24 15:50:14 +02:00
Vladimir Enchev
7455d1bfb2 Fixed popups will steal focus in some cases
Fix #774
2023-01-24 10:29:09 +02:00
595 changed files with 20586 additions and 13609 deletions

View File

@@ -0,0 +1,74 @@
using Xunit;
namespace Radzen.Blazor.Tests
{
public class AutoCompleteTests
{
[Fact]
public void AutoComplete_Enum_Converts_To_Attr_Value()
{
// Options
Assert.Equal("off", AutoCompleteType.Off.GetAutoCompleteValue());
Assert.Equal("on", AutoCompleteType.On.GetAutoCompleteValue());
Assert.Equal("name", AutoCompleteType.Name.GetAutoCompleteValue());
Assert.Equal("honorific-prefix", AutoCompleteType.HonorificPrefix.GetAutoCompleteValue());
Assert.Equal("given-name", AutoCompleteType.GivenName.GetAutoCompleteValue());
Assert.Equal("additional-name", AutoCompleteType.AdditionalName.GetAutoCompleteValue());
Assert.Equal("family-name", AutoCompleteType.FamilyName.GetAutoCompleteValue());
Assert.Equal("honorific-suffix", AutoCompleteType.HonorificSuffix.GetAutoCompleteValue());
Assert.Equal("nickname", AutoCompleteType.Nickname.GetAutoCompleteValue());
Assert.Equal("email", AutoCompleteType.Email.GetAutoCompleteValue());
Assert.Equal("username", AutoCompleteType.Username.GetAutoCompleteValue());
Assert.Equal("new-password", AutoCompleteType.NewPassword.GetAutoCompleteValue());
Assert.Equal("current-password", AutoCompleteType.CurrentPassword.GetAutoCompleteValue());
Assert.Equal("one-time-code", AutoCompleteType.OneTimeCode.GetAutoCompleteValue());
Assert.Equal("organization-title", AutoCompleteType.OrganizationTitle.GetAutoCompleteValue());
Assert.Equal("organization", AutoCompleteType.Organization.GetAutoCompleteValue());
Assert.Equal("street-address", AutoCompleteType.StreetAddress.GetAutoCompleteValue());
Assert.Equal("address-line1", AutoCompleteType.AddressLine1.GetAutoCompleteValue());
Assert.Equal("address-line2", AutoCompleteType.AddressLine2.GetAutoCompleteValue());
Assert.Equal("address-line3", AutoCompleteType.AddressLine3.GetAutoCompleteValue());
Assert.Equal("address-level1", AutoCompleteType.AddressLevel1.GetAutoCompleteValue());
Assert.Equal("address-level2", AutoCompleteType.AddressLevel2.GetAutoCompleteValue());
Assert.Equal("address-level3", AutoCompleteType.AddressLevel3.GetAutoCompleteValue());
Assert.Equal("address-level4", AutoCompleteType.AddressLevel4.GetAutoCompleteValue());
Assert.Equal("country", AutoCompleteType.Country.GetAutoCompleteValue());
Assert.Equal("country-name", AutoCompleteType.CountryName.GetAutoCompleteValue());
Assert.Equal("postal-code", AutoCompleteType.PostalCode.GetAutoCompleteValue());
Assert.Equal("cc-name", AutoCompleteType.CcName.GetAutoCompleteValue());
Assert.Equal("cc-given-name", AutoCompleteType.CcGivenName.GetAutoCompleteValue());
Assert.Equal("cc-additional-name", AutoCompleteType.CcAdditionalName.GetAutoCompleteValue());
Assert.Equal("cc-family-name", AutoCompleteType.CcFamilyName.GetAutoCompleteValue());
Assert.Equal("cc-number", AutoCompleteType.CcNumber.GetAutoCompleteValue());
Assert.Equal("cc-exp", AutoCompleteType.CcExp.GetAutoCompleteValue());
Assert.Equal("cc-exp-month", AutoCompleteType.CcExpMonth.GetAutoCompleteValue());
Assert.Equal("cc-exp-year", AutoCompleteType.CcExpYear.GetAutoCompleteValue());
Assert.Equal("cc-csc", AutoCompleteType.CcCsc.GetAutoCompleteValue());
Assert.Equal("cc-type", AutoCompleteType.CcType.GetAutoCompleteValue());
Assert.Equal("transaction-currency", AutoCompleteType.TransactionCurrency.GetAutoCompleteValue());
Assert.Equal("transaction-amount", AutoCompleteType.TransactionAmount.GetAutoCompleteValue());
Assert.Equal("language", AutoCompleteType.Language.GetAutoCompleteValue());
Assert.Equal("bday", AutoCompleteType.Bday.GetAutoCompleteValue());
Assert.Equal("bday-day", AutoCompleteType.BdayDay.GetAutoCompleteValue());
Assert.Equal("bday-month", AutoCompleteType.BdayMonth.GetAutoCompleteValue());
Assert.Equal("bday-year", AutoCompleteType.BdayYear.GetAutoCompleteValue());
Assert.Equal("sex", AutoCompleteType.Sex.GetAutoCompleteValue());
Assert.Equal("tel", AutoCompleteType.Tel.GetAutoCompleteValue());
Assert.Equal("tel-country-code", AutoCompleteType.TelCountryCode.GetAutoCompleteValue());
Assert.Equal("tel-national", AutoCompleteType.TelNational.GetAutoCompleteValue());
Assert.Equal("tel-area-code", AutoCompleteType.TelAreaCode.GetAutoCompleteValue());
Assert.Equal("tel-local", AutoCompleteType.TelLocal.GetAutoCompleteValue());
Assert.Equal("tel-extension", AutoCompleteType.TelExtension.GetAutoCompleteValue());
Assert.Equal("impp", AutoCompleteType.Impp.GetAutoCompleteValue());
Assert.Equal("url", AutoCompleteType.Url.GetAutoCompleteValue());
Assert.Equal("photo", AutoCompleteType.Photo.GetAutoCompleteValue());
// Synonyms
Assert.Equal("address-level1", AutoCompleteType.State.GetAutoCompleteValue());
Assert.Equal("address-level1", AutoCompleteType.Province.GetAutoCompleteValue());
Assert.Equal("postal-code", AutoCompleteType.ZipCode.GetAutoCompleteValue());
Assert.Equal("given-name", AutoCompleteType.FirstName.GetAutoCompleteValue());
Assert.Equal("additional-name", AutoCompleteType.MiddleName.GetAutoCompleteValue());
Assert.Equal("family-name", AutoCompleteType.LastName.GetAutoCompleteValue());
}
}
}

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Mask_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenMask>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Email));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.Email.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Mask_Renders_MaxLengthParameter()
{

View File

@@ -193,6 +193,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Numeric_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumeric<double>>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayMonth));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayMonth.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayYear));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayYear.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Numeric_Raises_ChangedEvent()
{

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Password_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenPassword>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""new-password""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.CurrentPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.CurrentPassword.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.NewPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.NewPassword.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Password_Renders_UnmatchedParameter()
{

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void TextBox_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenTextBox>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.FamilyName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.FamilyName.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void TextBox_Renders_MaxLengthParameter()
{

View File

@@ -0,0 +1,81 @@
namespace Radzen.Blazor
{
/// <summary>
/// The <c>AutomCompleteType</c> is a string-associated enum of
/// browser-supported autocomplete attribute values.
/// </summary>
/// <remarks>
/// This class lists the autocomplete attirbute options allowing
/// developers to provide the browser with guidance on how to pre-populate
/// the form fields. It is a class rather than a simpler enum to associate
/// each option with the string the browser expects. For more information
/// please review the list of options (https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)
/// and the spec (https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
/// </remarks>
public enum AutoCompleteType
{
// Options
Off,
On,
Name,
HonorificPrefix,
GivenName,
AdditionalName,
FamilyName,
HonorificSuffix,
Nickname,
Email,
Username,
NewPassword,
CurrentPassword,
OneTimeCode,
OrganizationTitle,
Organization,
StreetAddress,
AddressLine1,
AddressLine2,
AddressLine3,
AddressLevel1,
AddressLevel2,
AddressLevel3,
AddressLevel4,
Country,
CountryName,
PostalCode,
CcName,
CcGivenName,
CcAdditionalName,
CcFamilyName,
CcNumber,
CcExp,
CcExpMonth,
CcExpYear,
CcCsc,
CcType,
TransactionCurrency,
TransactionAmount,
Language,
Bday,
BdayDay,
BdayMonth,
BdayYear,
Sex,
Tel,
TelCountryCode,
TelNational,
TelAreaCode,
TelLocal,
TelExtension,
Impp,
Url,
Photo,
// Synonyms
State,
Province,
ZipCode,
FirstName,
MiddleName,
LastName,
}
}

View File

@@ -687,7 +687,7 @@ namespace Radzen.Blazor
public virtual IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
var list = new List<ChartDataLabel>();
foreach (var d in Data)
{
list.Add(new ChartDataLabel

View File

@@ -17,6 +17,22 @@ using System.Threading.Tasks;
namespace Radzen
{
/// <summary>
/// Html editor mode (Rendered or Raw). Also used for toolbar buttons to enable/disable according to mode.
/// </summary>
[Flags]
public enum HtmlEditorMode
{
/// <summary>
/// The editor is in Design mode.
/// </summary>
Design = 1,
/// <summary>
/// The editor is in Source mode.
/// </summary>
Source = 2,
}
/// <summary>
/// DataGrid settings class used to Save/Load settings.
/// </summary>

View File

@@ -323,7 +323,7 @@ namespace Radzen
var i = 0;
b.OpenElement(i++, "p");
b.AddAttribute(i++, "class", "rz-dialog-confirm-message");
b.AddContent(i++, message);
b.AddContent(i++, (MarkupString)message);
b.CloseElement();
b.OpenElement(i++, "div");
@@ -381,7 +381,7 @@ namespace Radzen
var i = 0;
b.OpenElement(i++, "p");
b.AddAttribute(i++, "class", "rz-dialog-alert-message");
b.AddContent(i++, message);
b.AddContent(i++, (MarkupString)message);
b.CloseElement();
b.OpenElement(i++, "div");

View File

@@ -17,6 +17,12 @@ namespace Radzen
public class DropDownBase<T> : DataBoundFormComponent<T>
{
#if NET5_0_OR_GREATER
/// <summary>
/// Gets or sets a value that determines how many additional items will be rendered before and after the visible region. This help to reduce the frequency of rendering during scrolling. However, higher values mean that more elements will be present in the page.
/// </summary>
[Parameter]
public int VirtualizationOverscanCount { get; set; }
internal Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object> virtualize;
/// <summary>
@@ -85,6 +91,15 @@ namespace Radzen
#endif
}
internal int GetVirtualizationOverscanCount()
{
#if NET5_0_OR_GREATER
return VirtualizationOverscanCount;
#else
return 0;
#endif
}
/// <summary>
/// Renders the items.
/// </summary>
@@ -106,6 +121,11 @@ namespace Radzen
});
}));
if(VirtualizationOverscanCount != default(int))
{
builder.AddAttribute(3, "OverscanCount", VirtualizationOverscanCount);
}
builder.AddComponentReferenceCapture(7, c => { virtualize = (Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object>)c; });
builder.CloseComponent();

View File

@@ -1,8 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace Radzen.Blazor
{
@@ -30,6 +34,36 @@ namespace Radzen.Blazor
return Enum.GetValues(enumType).Cast<Enum>().Distinct().Select(val => new { Value = Convert.ToInt32(val), Text = val.GetDisplayDescription() });
}
/// <summary>
/// Converts the autocomplete type enum value to the expected
/// autocomplete attribute value.
/// </summary>
/// <returns>The autocomplete attribute string value.</returns>
public static string GetAutoCompleteValue(this AutoCompleteType typeValue)
{
// Handle synonyms.
switch (typeValue)
{
case AutoCompleteType.FirstName:
return "given-name";
case AutoCompleteType.LastName:
return "family-name";
case AutoCompleteType.MiddleName:
return "additional-name";
case AutoCompleteType.ZipCode:
return "postal-code";
case AutoCompleteType.Province:
return "address-level1";
case AutoCompleteType.State:
return "address-level1";
}
// Handle standard values.
var value = typeValue.ToString();
value = Regex.Replace(value, "([^A-Z])([A-Z])", "$1-$2");
return Regex.Replace(value, "([A-Z]+)([A-Z][^A-Z$])", "$1-$2")
.Trim().ToLower();
}
}
}

View File

@@ -0,0 +1,13 @@
namespace Radzen.Blazor
{
/// <summary>
/// Marker interface for <see cref="RadzenStackedBarSeries{TItem}" />.
/// </summary>
public interface IChartStackedBarSeries : IChartBarSeries
{
/// <summary>
/// Gets the value at the specified index.
/// </summary>
double ValueAt(int index);
}
}

View File

@@ -0,0 +1,19 @@
namespace Radzen.Blazor
{
/// <summary>
/// Marker interface for <see cref="RadzenStackedColumnSeries{TItem}" />.
/// </summary>
public interface IChartStackedColumnSeries
{
/// <summary>
/// Gets the count.
/// </summary>
/// <value>The count.</value>
int Count { get; }
/// <summary>
/// Gets the value at the specified index.
/// </summary>
double ValueAt(int index);
}
}

View File

@@ -1048,7 +1048,7 @@ namespace Radzen
|| c.FilterOperator == FilterOperator.IsEmpty || c.FilterOperator == FilterOperator.IsNotEmpty)
&& c.Property != null;
if (dataFilter.Filters.Where(canFilter).Any())
if (dataFilter.Filters.Concat(dataFilter.Filters.SelectManyRecursive(i => i.Filters ?? Enumerable.Empty<CompositeFilterDescriptor>())).Where(canFilter).Any())
{
var index = 0;
var filterExpressions = new List<string>();
@@ -1158,13 +1158,151 @@ namespace Radzen
}
else if (!(IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string)))
{
var value = filter.FilterValue;
if (column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?))
{
value = filter.FilterValue != null ? (object)(new DateTimeOffset((DateTime)filter.FilterValue, TimeSpan.Zero)) : null;
}
filterExpressions.Add($@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}");
filterValues.Add(new object[] { filter.FilterValue });
filterValues.Add(new object[] { value });
index++;
}
}
}
/// <summary>
/// Converts to OData filter expression.
/// </summary>
/// <param name="dataFilter">The DataFilter.</param>
/// <returns>System.String.</returns>
public static string ToODataFilterString<T>(this RadzenDataFilter<T> dataFilter)
{
Func<CompositeFilterDescriptor, bool> canFilter = (c) => dataFilter.properties.Where(col => col.Property == c.Property).FirstOrDefault()?.FilterPropertyType != null &&
(!(c.FilterValue == null || c.FilterValue as string == string.Empty)
|| c.FilterOperator == FilterOperator.IsNotNull || c.FilterOperator == FilterOperator.IsNull
|| c.FilterOperator == FilterOperator.IsEmpty || c.FilterOperator == FilterOperator.IsNotEmpty)
&& c.Property != null;
if (dataFilter.Filters.Concat(dataFilter.Filters.SelectManyRecursive(i => i.Filters ?? Enumerable.Empty<CompositeFilterDescriptor>())).Where(canFilter).Any())
{
var filterExpressions = new List<string>();
foreach (var filter in dataFilter.Filters)
{
AddODataExpression(canFilter, filter, ref filterExpressions, dataFilter);
}
return filterExpressions.Any() ?
string.Join($" {dataFilter.LogicalFilterOperator.ToString().ToLower()} ", filterExpressions)
: "";
}
return "";
}
private static void AddODataExpression<T>(Func<CompositeFilterDescriptor, bool> canFilter, CompositeFilterDescriptor filter, ref List<string> filterExpressions, RadzenDataFilter<T> dataFilter)
{
if (filter.Filters != null)
{
var innerFilterExpressions = new List<string>();
foreach (var f in filter.Filters)
{
AddODataExpression(canFilter, f, ref innerFilterExpressions, dataFilter);
}
if (innerFilterExpressions.Any())
{
filterExpressions.Add("(" + string.Join($" {filter.LogicalFilterOperator.ToString().ToLower()} ", innerFilterExpressions) + ")");
}
}
else
{
if (filter.Property == null || (filter.FilterValue == null &&
filter.FilterOperator != FilterOperator.IsNull && filter.FilterOperator != FilterOperator.IsNotNull))
{
return;
}
var property = filter.Property.Replace('.', '/');
var column = dataFilter.properties.Where(c => c.Property == filter.Property).FirstOrDefault();
if (column == null) return;
if (dataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive && column.FilterPropertyType == typeof(string))
{
property = $"tolower({property})";
}
if (filter.FilterOperator == FilterOperator.StartsWith || filter.FilterOperator == FilterOperator.EndsWith
|| filter.FilterOperator == FilterOperator.Contains || filter.FilterOperator == FilterOperator.DoesNotContain)
{
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
(filter.FilterOperator == FilterOperator.Contains || filter.FilterOperator == FilterOperator.DoesNotContain))
{
var enumerableValue = ((IEnumerable)(filter.FilterValue != null ? filter.FilterValue : Enumerable.Empty<object>())).AsQueryable();
var enumerableValueAsString = "(" + String.Join(",",
(enumerableValue.ElementType == typeof(string) ? enumerableValue.Cast<string>().Select(i => $@"'{i}'").Cast<object>() : enumerableValue.Cast<object>())) + ")";
if (enumerableValue.Any() && filter.FilterOperator == FilterOperator.Contains)
{
filterExpressions.Add($"{property} in {enumerableValueAsString}");
}
else if (enumerableValue.Any() && filter.FilterOperator == FilterOperator.DoesNotContain)
{
filterExpressions.Add($"not({property} in {enumerableValueAsString})");
}
}
else
{
var expression = dataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"{ODataFilterOperators[filter.FilterOperator]}({property}, tolower('{filter.FilterValue}'))" :
$"{ODataFilterOperators[filter.FilterOperator]}({property}, '{filter.FilterValue}')";
if (filter.FilterOperator == FilterOperator.DoesNotContain)
{
expression = $"not({expression})";
}
filterExpressions.Add(expression);
}
}
else
{
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
return;
var value = $"{filter.FilterValue}";
if (filter.FilterOperator == FilterOperator.IsNull || filter.FilterOperator == FilterOperator.IsNotNull)
{
value = $"null";
}
else if (filter.FilterOperator == FilterOperator.IsEmpty || filter.FilterOperator == FilterOperator.IsNotEmpty)
{
value = $"''";
}
else if (column.FilterPropertyType == typeof(string))
{
value = $"'{value}'";
}
else if (column.FilterPropertyType == typeof(DateTime) || column.FilterPropertyType == typeof(DateTime?))
{
value = $"{DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")}";
}
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
{
value = $"{value?.ToLower()}";
}
filterExpressions.Add($@"{property} {ODataFilterOperators[filter.FilterOperator]} {value}");
}
}
}
/// <summary>
/// Ases the o data enumerable.
/// </summary>

View File

@@ -8,7 +8,7 @@
<IsPackable>true</IsPackable>
<PackageId>Radzen.Blazor</PackageId>
<Product>Radzen.Blazor</Product>
<Version>4.6.2</Version>
<Version>4.7.8</Version>
<Copyright>Radzen Ltd.</Copyright>
<Authors>Radzen Ltd.</Authors>
<Description>Radzen Blazor is a set of 70+ free native Blazor UI controls packed with DataGrid, Scheduler, Charts and robust theming including Material design and Fluent UI.</Description>

View File

@@ -34,7 +34,7 @@
}
@if (!string.IsNullOrEmpty(item.Text))
{
<span>@item.Text</span>
<span>@((MarkupString)item.Text)</span>
}
</a>
</div>

View File

@@ -14,7 +14,7 @@
var pathGenerator = GetPathGenerator();
var data = Items.Select(item =>
var data = Items.Select(item =>
{
var x = category(item);
var y = value(item);
@@ -26,7 +26,7 @@
var index = Chart.Series.IndexOf(this);
var className = $"rz-area-series rz-series-{index}";
return
return
@<g class="@className">
@if (Items.Any())
{
@@ -43,7 +43,7 @@
<path @key="@area" style="@style" d="@area" fill="@Fill" stroke="none"></path>
<Path @key="@line" D="@line" Stroke="@Stroke" StrokeWidth="@StrokeWidth" LineType="@LineType" Style="@style" Fill="none" />
}
<Markers Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
<Markers Series="@this" Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
</g>;
}
}

View File

@@ -42,13 +42,13 @@ namespace Radzen.Blazor
public ColorScheme ColorScheme { get; set; }
/// <summary>
/// A callback that will be invoked when the user clicks on a series.
/// A callback that will be invoked when the user clicks on a series.
/// </summary>
[Parameter]
public EventCallback<SeriesClickEventArgs> SeriesClick { get; set; }
/// <summary>
/// A callback that will be invoked when the user clicks on a legend.
/// A callback that will be invoked when the user clicks on a legend.
/// </summary>
[Parameter]
public EventCallback<LegendClickEventArgs> LegendClick { get; set; }
@@ -311,7 +311,7 @@ namespace Radzen.Blazor
tooltip = overlay.RenderTooltip(mouseX, mouseY, MarginLeft, MarginTop);
chartTooltipContainer.Refresh();
await Task.Yield();
return;
}
}

View File

@@ -83,7 +83,7 @@ namespace Radzen.Blazor
if (value == true)
{
Value = items.Select(i => i.Value);
Value = allItems.Select(i => i.Value);
}
else if (value == false)
{
@@ -100,8 +100,8 @@ namespace Radzen.Blazor
bool? IsAllSelected()
{
Func<RadzenCheckBoxListItem<TValue>, bool> predicate = i => Value != null && Value.Contains(i.Value);
var all = items.All(predicate);
var any = items.Any(predicate);
var all = allItems.All(predicate);
var any = allItems.Any(predicate);
if (all)
{

View File

@@ -349,7 +349,7 @@ namespace Radzen.Blazor
if (Disabled)
{
classList.Add("rz-disabled");
classList.Add("rz-state-disabled");
}
return string.Join(" ", classList);

View File

@@ -42,7 +42,7 @@ else
@if (property.FilterTemplate != null)
{
<div class="rz-datafilter-editor" style="display:flex">
@property.FilterTemplate(property)
@property.FilterTemplate(Filter)
</div>
}
else if (PropertyAccess.IsNullableEnum(property.FilterPropertyType) || PropertyAccess.IsEnum(property.FilterPropertyType))
@@ -250,15 +250,7 @@ else
{
if (property != null && !string.IsNullOrEmpty(property.FormatString))
{
var formats = property.FormatString.Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
if (formats.Length > 0)
{
var format = formats[0].Trim().Split(':');
if (format.Length > 1)
{
return format[1].Trim();
}
}
return property.FormatString.Replace("{0:", "").Replace("}", "");
}
return DataFilter.FilterDateFormat;

View File

@@ -130,7 +130,7 @@ namespace Radzen.Blazor
/// </summary>
/// <value>The filter template.</value>
[Parameter]
public RenderFragment<RadzenDataFilterProperty<TItem>> FilterTemplate { get; set; }
public RenderFragment<CompositeFilterDescriptor> FilterTemplate { get; set; }
/// <summary>
/// Gets or sets the data type.

View File

@@ -60,7 +60,7 @@
@if (AllowPaging && (PagerPosition == PagerPosition.Top || PagerPosition == PagerPosition.TopAndBottom))
{
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" />
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" Density="@Density" />
}
<div class="rz-data-grid-data">
@@ -231,7 +231,7 @@
</div>
</div>
<RadzenDatePicker TValue="@object"
<RadzenDatePicker TValue="@object" AllowInput=@(AllowFilterDateInput)
ShowTime="@column.ShowTimeForDateTimeFilter()" ShowTimeOkButton="false" Inline="true" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => { column.SetFilterValue(args.Value); SaveSettings(); })" />
@@ -251,7 +251,7 @@
else
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
<RadzenDatePicker Disabled=@column.CanSetFilterValue() TValue="@object" Style="width:100%" AllowInput="false" AllowClear="true"
<RadzenDatePicker Disabled=@column.CanSetFilterValue() TValue="@object" Style="width:100%" AllowInput=@(AllowFilterDateInput) AllowClear="true"
ShowTime="false" ShowTimeOkButton="false" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => { if(!args.HasValue) { ClearFilter(column, true); } else {column.SetFilterValue(args.Value); ApplyFilter(column, true);} })" />
}
@@ -378,7 +378,7 @@
@if (AllowPaging && (PagerPosition == PagerPosition.Bottom || PagerPosition == PagerPosition.TopAndBottom))
{
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" />
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" Density="@Density" />
}
</div>
}

View File

@@ -31,6 +31,19 @@ namespace Radzen.Blazor
public partial class RadzenDataGrid<TItem> : PagedDataBoundComponent<TItem>
{
#if NET5_0_OR_GREATER
/// <summary>
/// Gets or sets a value indicating whether this instance is virtualized.
/// </summary>
/// <value><c>true</c> if this instance is virtualized; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowVirtualization { get; set; }
/// <summary>
/// Gets or sets a value that determines how many additional items will be rendered before and after the visible region. This help to reduce the frequency of rendering during scrolling. However, higher values mean that more elements will be present in the page.
/// </summary>
[Parameter]
public int VirtualizationOverscanCount { get; set; }
internal void SetAllowVirtualization(bool allowVirtualization)
{
AllowVirtualization = allowVirtualization;
@@ -134,7 +147,7 @@ namespace Radzen.Blazor
b.AddAttribute(8, "InEditMode", IsRowInEditMode(context));
b.AddAttribute(9, "Index", virtualDataItems.IndexOf(context));
if (editContexts.ContainsKey(context))
if (editContexts.Keys.Any(i => ItemEquals(i, context)))
{
b.AddAttribute(10, nameof(RadzenDataGridRow<TItem>.EditContext), editContexts[context]);
}
@@ -144,6 +157,11 @@ namespace Radzen.Blazor
});
}));
if(VirtualizationOverscanCount != default(int))
{
builder.AddAttribute(1, "OverscanCount", VirtualizationOverscanCount);
}
builder.AddComponentReferenceCapture(8, c => { virtualize = (Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<TItem>)c; });
}
@@ -484,15 +502,7 @@ namespace Radzen.Blazor
{
if (column != null && !string.IsNullOrEmpty(column.FormatString))
{
var formats = column.FormatString.Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
if (formats.Length > 0)
{
var format = formats[0].Trim().Split(':');
if (format.Length > 1)
{
return format[1].Trim();
}
}
return column.FormatString.Replace("{0:", "").Replace("}", "");
}
return FilterDateFormat;
@@ -665,6 +675,13 @@ namespace Radzen.Blazor
[Parameter]
public EventCallback<DataGridColumnFilterEventArgs<TItem>> FilterCleared { get; set; }
/// <summary>
/// Gets or sets the render mode.
/// </summary>
/// <value>The render mode.</value>
[Parameter]
public PopupRenderMode FilterPopupRenderMode { get; set; } = PopupRenderMode.Initial;
internal async Task ClearFilter(RadzenDataGridColumn<TItem> column, bool closePopup = false)
{
if (closePopup)
@@ -964,6 +981,13 @@ namespace Radzen.Blazor
[Parameter]
public string FilterDateFormat { get; set; }
/// <summary>
/// Gets or sets a value indicating whether input is allowed in filter DatePicker.
/// </summary>
/// <value><c>true</c> if input is allowed in filter DatePicker; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowFilterDateInput { get; set; }
/// <summary>
/// Gets or sets the width of all columns.
/// </summary>
@@ -995,14 +1019,7 @@ namespace Radzen.Blazor
/// <value>The empty template.</value>
[Parameter]
public RenderFragment EmptyTemplate { get; set; }
#if NET5_0_OR_GREATER
/// <summary>
/// Gets or sets a value indicating whether this instance is virtualized.
/// </summary>
/// <value><c>true</c> if this instance is virtualized; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowVirtualization { get; set; }
#endif
/// <summary>
/// Gets or sets a value indicating whether this instance loading indicator is shown.
/// </summary>
@@ -1511,6 +1528,11 @@ namespace Radzen.Blazor
/// </summary>
protected override void OnDataChanged()
{
if (!string.IsNullOrEmpty(KeyProperty) && keyPropertyGetter == null)
{
keyPropertyGetter = PropertyAccess.Getter<TItem, object>(KeyProperty);
}
Reset(!IsOData() && !LoadData.HasDelegate);
if (!IsOData() && !LoadData.HasDelegate && !Page.HasDelegate)
@@ -1551,7 +1573,10 @@ namespace Radzen.Blazor
sorts.Clear();
}
SaveSettings();
if (!LoadData.HasDelegate)
{
SaveSettings();
}
}
/// <summary>
@@ -1704,6 +1729,19 @@ namespace Radzen.Blazor
[Parameter]
public EventCallback<bool?> AllGroupsExpandedChanged { get; set; }
/// <summary>
/// Gets or sets the key property.
/// </summary>
/// <value>The key property.</value>
[Parameter]
public string KeyProperty { get; set; }
internal Func<TItem, object> keyPropertyGetter;
bool ItemEquals(TItem item, TItem otherItem)
{
return keyPropertyGetter != null ? keyPropertyGetter(item).Equals(keyPropertyGetter(otherItem)) : item.Equals(otherItem);
}
internal bool? allGroupsExpanded;
internal async System.Threading.Tasks.Task ExpandGroupItem(RadzenDataGridGroupRow<TItem> item, bool? expandedOnLoad)
@@ -1732,7 +1770,7 @@ namespace Radzen.Blazor
internal string ExpandedItemStyle(TItem item)
{
return expandedItems.Keys.Contains(item) ? "rz-row-toggler rzi-chevron-circle-down" : "rz-row-toggler rzi-chevron-circle-right";
return expandedItems.Keys.Any(i => ItemEquals(i, item)) ? "rz-row-toggler rzi-chevron-circle-down" : "rz-row-toggler rzi-chevron-circle-right";
}
internal Dictionary<TItem, bool> selectedItems = new Dictionary<TItem, bool>();
@@ -1741,7 +1779,7 @@ namespace Radzen.Blazor
{
var isInEditMode = IsRowInEditMode(item) ? "rz-datatable-edit" : "";
return (RowSelect.HasDelegate || ValueChanged.HasDelegate || SelectionMode == DataGridSelectionMode.Multiple) && selectedItems.Keys.Contains(item) ? $"rz-state-highlight rz-data-row {isInEditMode} " : $"rz-data-row {isInEditMode} ";
return (RowSelect.HasDelegate || ValueChanged.HasDelegate || SelectionMode == DataGridSelectionMode.Multiple) && selectedItems.Keys.Any(i => ItemEquals(i, item)) ? $"rz-state-highlight rz-data-row {isInEditMode} " : $"rz-data-row {isInEditMode} ";
}
internal Tuple<Radzen.RowRenderEventArgs<TItem>, IReadOnlyDictionary<string, object>> RowAttributes(TItem item)
@@ -1875,6 +1913,61 @@ namespace Radzen.Blazor
await ExpandItem(item);
}
/// <summary>
/// Expands a range of rows.
/// </summary>
/// <param name="items">The range of rows.</param>
public async System.Threading.Tasks.Task ExpandRows(IEnumerable<TItem> items)
{
// Only allow the functionality when multiple row expand is allowed
if (this.ExpandMode != DataGridExpandMode.Multiple) return;
foreach (TItem item in items)
{
if (!expandedItems.Keys.Any(i => ItemEquals(i, item)))
{
expandedItems.Add(item, true);
await RowExpand.InvokeAsync(item);
var args = new DataGridLoadChildDataEventArgs<TItem>() { Item = item };
await LoadChildData.InvokeAsync(args);
if (args.Data != null && !childData.ContainsKey(item))
{
childData.Add(item, new DataGridChildData<TItem>() { Data = args.Data, ParentChildData = childData.Where(c => c.Value.Data.Contains(item)).Select(c => c.Value).FirstOrDefault() });
_view = null;
}
}
}
await InvokeAsync(StateHasChanged);
}
/// <summary>
/// Collapse a range of rows.
/// </summary>
/// <param name="items">The range of rows.</param>
public async System.Threading.Tasks.Task CollapseRows(IEnumerable<TItem> items)
{
// Only allow the functionality when multiple row expand is allowed
if (this.ExpandMode != DataGridExpandMode.Multiple) return;
foreach (TItem item in items)
{
if (expandedItems.Keys.Any(i => ItemEquals(i, item)))
{
expandedItems.Remove(item);
await RowCollapse.InvokeAsync(item);
if (childData.ContainsKey(item))
{
childData.Remove(item);
_view = null;
}
}
}
await InvokeAsync(StateHasChanged);
}
internal async System.Threading.Tasks.Task ExpandItem(TItem item)
{
if (ExpandMode == DataGridExpandMode.Single && expandedItems.Keys.Any() && !LoadChildData.HasDelegate)
@@ -1893,7 +1986,7 @@ namespace Radzen.Blazor
}
}
if (!expandedItems.Keys.Contains(item))
if (!expandedItems.Keys.Any(i => ItemEquals(i, item)))
{
expandedItems.Add(item, true);
await RowExpand.InvokeAsync(item);
@@ -1996,9 +2089,9 @@ namespace Radzen.Blazor
}
}
internal async System.Threading.Tasks.Task OnRowSelect(object item, bool raiseChange = true)
internal async System.Threading.Tasks.Task OnRowSelect(TItem item, bool raiseChange = true)
{
if (SelectionMode == DataGridSelectionMode.Single && item != null && selectedItems.Keys.Contains((TItem)item))
if (SelectionMode == DataGridSelectionMode.Single && item != null && selectedItems.Keys.Any(i => ItemEquals(i, item)))
{
// Legacy RowSelect raise
if (raiseChange)
@@ -2020,7 +2113,7 @@ namespace Radzen.Blazor
if (item != null)
{
if (!selectedItems.Keys.Contains((TItem)item))
if (!selectedItems.Keys.Any(i => ItemEquals(i, item)))
{
selectedItems.Add((TItem)item, true);
if (raiseChange)
@@ -2118,7 +2211,7 @@ namespace Radzen.Blazor
}
}
if (!editedItems.Keys.Contains(item))
if (!editedItems.Keys.Any(i => ItemEquals(i, item)))
{
editedItems.Add(item, true);
@@ -2131,13 +2224,37 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Edits a range of rows.
/// </summary>
/// <param name="items">The range of rows.</param>
public async System.Threading.Tasks.Task EditRows(IEnumerable<TItem> items)
{
// Only allow the functionality when multiple row edits is allowed
if (this.EditMode != DataGridEditMode.Multiple) return;
foreach (TItem item in items)
{
if (!editedItems.Keys.Any(i => ItemEquals(i, item)))
{
editedItems.Add(item, true);
var editContext = new EditContext(item);
editContexts.Add(item, editContext);
await RowEdit.InvokeAsync(item);
}
}
StateHasChanged();
}
/// <summary>
/// Updates the row.
/// </summary>
/// <param name="item">The item.</param>
public async System.Threading.Tasks.Task UpdateRow(TItem item)
{
if (editedItems.Keys.Contains(item))
if (editedItems.Keys.Any(i => ItemEquals(i, item)))
{
var editContext = editContexts[item];
@@ -2198,7 +2315,7 @@ namespace Radzen.Blazor
{
int hash = item.GetHashCode();
if (editedItems.Keys.Contains(item))
if (editedItems.Keys.Any(i => ItemEquals(i, item)))
{
editedItems.Remove(item);
editContexts.Remove(item);
@@ -2208,6 +2325,23 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Cancels the edit of a range of rows.
/// </summary>
/// <param name="items">The range of rows.</param>
public void CancelEditRows(IEnumerable<TItem> items)
{
foreach (TItem item in items)
{
if (editedItems.Keys.Any(i => ItemEquals(i, item)))
{
editedItems.Remove(item);
editContexts.Remove(item);
}
}
StateHasChanged();
}
/// <summary>
/// Determines whether row in edit mode.
/// </summary>
@@ -2215,7 +2349,7 @@ namespace Radzen.Blazor
/// <returns><c>true</c> if row in edit mode; otherwise, <c>false</c>.</returns>
public bool IsRowInEditMode(TItem item)
{
return editedItems.Keys.Contains(item);
return editedItems.Keys.Any(i => ItemEquals(i, item));
}
TItem itemToInsert;

View File

@@ -169,7 +169,7 @@ namespace Radzen.Blazor
if (visible != value)
{
visible = value;
_visible = visible;
if (Grid != null)
{
Grid.UpdatePickableColumn(this, visible);
@@ -707,6 +707,32 @@ namespace Radzen.Blazor
}
}
if (parameters.DidParameterChange(nameof(SecondFilterValue), SecondFilterValue))
{
secondFilterValue = parameters.GetValueOrDefault<object>(nameof(SecondFilterValue));
if (FilterTemplate != null)
{
SecondFilterValue = secondFilterValue;
Grid.SaveSettings();
if (Grid.IsVirtualizationAllowed())
{
#if NET5_0_OR_GREATER
if (Grid.virtualize != null)
{
await Grid.virtualize.RefreshDataAsync();
}
#endif
}
else
{
await Grid.Reload();
}
return;
}
}
if (parameters.DidParameterChange(nameof(FilterOperator), FilterOperator))
{
filterOperator = parameters.GetValueOrDefault<FilterOperator>(nameof(FilterOperator));

View File

@@ -1,4 +1,5 @@
@typeparam TItem
@using Radzen.Blazor.Rendering
@if (RowIndex == Column.GetLevel())
{
<th rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@Column.GetStyle(true, true)" @onmouseup=@(args => Grid.EndColumnReorder(args, ColumnIndex)) >
@@ -53,18 +54,19 @@
}
@if (Grid.AllowFiltering && Column.Filterable && Grid.FilterMode == FilterMode.Advanced)
{
<i @onclick:stopPropagation="true" onclick="@($"Radzen.togglePopup(this, '{getColumnPopupID()}')")"
class="@getFilterIconCss(Column)" />
<i @ref=@filterButton @onclick:stopPropagation="true" @onmousedown=@ToggleFilter
class="@getFilterIconCss(Column)" onclick=@getFilterOpen() />
<div id="@($"{getColumnPopupID()}")" class="rz-overlaypanel"
<Popup Lazy=@(Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand) @ref=popup id="@($"{getColumnPopupID()}")" class="rz-overlaypanel"
style="display:none;min-width:250px;" tabindex="0">
<div class="rz-grid-filter rz-overlaypanel-content">
<div class="rz-overlaypanel-content">
@if (Column.FilterTemplate != null)
{
@Column.FilterTemplate(Column)
}
else
{
<form id="@($"{getColumnPopupID()}-form")" @onsubmit="@(args => ApplyFilter())" class="rz-grid-filter">
<RadzenLabel Text="@Grid.FilterText" class="rz-grid-filter-label" />
<RadzenDropDown @onclick:preventDefault="true" Data="@(Column.GetFilterOperators().Select(t => new { Value = Column.GetFilterOperatorText(t), Key = t }))" TextProperty="Value" ValueProperty="Key" TValue="FilterOperator" Value="@Column.GetFilterOperator()" Change="@(args => Column.SetFilterOperator((FilterOperator)args))" />
@if (PropertyAccess.IsNullableEnum(Column.FilterPropertyType) || PropertyAccess.IsEnum(Column.FilterPropertyType))
@@ -80,7 +82,7 @@
else if (PropertyAccess.IsDate(Column.FilterPropertyType))
{
<RadzenDatePicker TValue="@object" ShowTime="true" ShowTimeOkButton="true" DateFormat="@Grid.getFilterDateFormat(Column)"
Value="@Column.GetFilterValue()" Change="@(args => Column.SetFilterValue(args.Value))" />
Value="@Column.GetFilterValue()" Change="@(args => Column.SetFilterValue(args.Value))" AllowInput=@(Grid.AllowFilterDateInput) />
}
else if (Column.FilterPropertyType == typeof(bool) || Column.FilterPropertyType == typeof(bool?))
@@ -110,27 +112,28 @@
{
<RadzenDatePicker TValue="@object"
ShowTime="@Column.ShowTimeForDateTimeFilter()" ShowTimeOkButton="true" DateFormat="@Grid.getFilterDateFormat(Column)"
Value="@Column.GetSecondFilterValue()" Change="@(args => Column.SetFilterValue(args.Value, false))" />
Value="@Column.GetSecondFilterValue()" Change="@(args => Column.SetFilterValue(args.Value, false))" AllowInput=@(Grid.AllowFilterDateInput) />
}
else if (Column.FilterPropertyType == typeof(bool) || Column.FilterPropertyType == typeof(bool?))
{
<RadzenCheckBox TriState="true" TValue="@object" Value="@Column.GetSecondFilterValue()" Change="@(args => { Column.SetFilterValue(args, false); Grid.SaveSettings(); })" />
<RadzenCheckBox TriState="true" TValue="@object" Value="@Column.GetSecondFilterValue()" Change="@(args => { Column.SetFilterValue(args, false); Grid.SaveSettings(); })" />
}
else
{
<RadzenTextBox Value="@($"{Column.GetSecondFilterValue()}")" Change="@(args => Column.SetFilterValue(args, false))" />
}
</form>
}
</div>
@if (Column.FilterTemplate == null)
{
<div class="rz-grid-filter-buttons">
<RadzenButton ButtonStyle="ButtonStyle.Secondary" Text=@Grid.ClearFilterText Click="@((args) => Grid.ClearFilter(Column, true))" />
<RadzenButton ButtonStyle="ButtonStyle.Primary" Text=@Grid.ApplyFilterText Click="@((args) => Grid.ApplyFilter(Column, true))" />
<RadzenButton ButtonStyle="ButtonStyle.Secondary" Text=@Grid.ClearFilterText Click="@ClearFilter" />
<RadzenButton form="@($"{getColumnPopupID()}-form")" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Primary" Text=@Grid.ApplyFilterText Click="@ApplyFilter" />
</div>
}
</div>
</Popup>
}
</div>
</th>
@@ -144,6 +147,40 @@ else
}
}
@code {
Radzen.Blazor.Rendering.Popup popup;
ElementReference filterButton;
string getFilterOpen()
{
return Grid.FilterPopupRenderMode == PopupRenderMode.Initial ? $"Radzen.togglePopup(this, '{getColumnPopupID()}')" : "";
}
async Task ToggleFilter()
{
if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
{
await popup.ToggleAsync(filterButton);
}
}
async Task ClearFilter()
{
if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
{
await popup.CloseAsync();
}
await Grid.ClearFilter(Column, true);
}
async Task ApplyFilter()
{
if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
{
await popup.CloseAsync();
}
await Grid.ApplyFilter(Column, true);
}
[Parameter(CaptureUnmatchedValues = true)]
public IReadOnlyDictionary<string, object> Attributes { get; set; }

View File

@@ -547,6 +547,10 @@ namespace Radzen.Blazor
DateTimeOffset? offset = DateTime.SpecifyKind((DateTime)Value, Kind);
await ValueChanged.InvokeAsync((TValue)(object)offset);
}
else if ((typeof(TValue) == typeof(DateTime) || typeof(TValue) == typeof(DateTime?)) && Value != null)
{
await ValueChanged.InvokeAsync((TValue)(object)DateTime.SpecifyKind((DateTime)Value, Kind));
}
else
{
await ValueChanged.InvokeAsync((TValue)Value);

View File

@@ -25,26 +25,27 @@
return @<div style="position: absolute;left: @(left)px;top: @(top)px;width: @(width.ToInvariantString())px; height: @(height.ToInvariantString())px;">
@TitleTemplate
</div>;
}
</div>
;
}
public override RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale)
{
public override RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale)
{
var className = $"rz-donut-series rz-series-{Chart.Series.IndexOf(this)}";
var x = CenterX;
var y = CenterY;
var radius = CurrentRadius;
var innerRadius = InnerRadius ?? radius / 2;
return
return
@<g>
<g class="@className">
@if (Items.Any())
@if (PositiveItems.Any())
{
var sum = Items.Sum(Value);
var sum = PositiveItems.Sum(Value);
double startAngle = -90;
@foreach(var data in Items)
@foreach (var data in PositiveItems)
{
var value = Value(data);
var angle = (value / sum) * 360;
@@ -53,7 +54,7 @@
var d = Segment(x, y, radius, innerRadius, startAngle, endAngle);
startAngle = endAngle;
var index = Items.IndexOf(data);
var arcClassName = $"rz-series-item-{index}";
var fill = PickColor(index, Fills);
@@ -64,8 +65,18 @@
</g>
}
}
else
{
var arcClassName = $"rz-series-item-0";
var d = Segment(x, y, radius, radius - 1, -90, 270);
var fill = PickColor(0, Fills);
var stroke = PickColor(0, Strokes);
<g class="@arcClassName">
<Path D="@d" Fill="@fill" StrokeWidth="@StrokeWidth" Stroke="@stroke" />
</g>
}
</g>
@if (!string.IsNullOrEmpty(Title) && TitleTemplate == null)
{
<g class="rz-donut-title">

View File

@@ -42,7 +42,14 @@
{
<div class="rz-chip">
<span class="rz-chip-text">
@GetItemOrValueFromProperty(item, TextProperty)
@if(Template != null)
{
@Template(item)
}
else
{
@GetItemOrValueFromProperty(item, TextProperty)
}
</span>
<button type=button class="rz-button rz-button-sm rz-button-icon-only rz-light @(Disabled ?"rz-state-disabled":"")" @onclick:preventDefault @onclick:stopPropagation @onclick="() => OnChipRemove(item)"><RadzenIcon Icon="close" /></button>
</div>

View File

@@ -46,7 +46,14 @@
{
<div class="rz-chip">
<span class="rz-chip-text">
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
@if (Template != null)
{
@Template(item)
}
else
{
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
}
</span>
<button type="button" class="rz-button rz-button-sm rz-button-icon-only rz-light @(Disabled ?"rz-state-disabled":"")" @onclick:preventDefault @onclick:stopPropagation @onclick="() => OnChipRemove(item)"><RadzenIcon Icon="close" /></button>
</div>
@@ -118,8 +125,8 @@
}
@if (Template != null)
{
<RadzenDataGrid AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
<RadzenDataGrid VirtualizationOverscanCount="@GetVirtualizationOverscanCount()" AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")" Density="@Density">
<Columns>
<RadzenDataGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="typeof(string)">
<Template>
@@ -136,8 +143,8 @@
{
if (!string.IsNullOrEmpty(TextProperty) || Columns != null)
{
<RadzenDataGrid AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
<RadzenDataGrid VirtualizationOverscanCount="@GetVirtualizationOverscanCount()" AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")" Density="@Density">
<Columns>
@if (Columns != null)
{
@@ -155,8 +162,8 @@
}
else
{
<RadzenDataGrid AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
<RadzenDataGrid VirtualizationOverscanCount="@GetVirtualizationOverscanCount()" AllowRowSelectOnRowClick="@AllowRowSelectOnRowClick" PagerHorizontalAlign="@PagerHorizontalAlign" PagerAlwaysVisible="@PagerAlwaysVisible" Responsive="@Responsive" AllowColumnResize="@AllowColumnResize" ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
TItem="object" CellRender="@OnCellRender" RowRender="@OnRowRender" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")" Density="@Density">
<Columns>
<RadzenDataGridColumn TItem="object" Property="it" Title="Item" Type="typeof(string)">
<Template>

View File

@@ -97,7 +97,11 @@ namespace Radzen.Blazor
return;
await JSRuntime.InvokeVoidAsync(OpenOnFocus ? "Radzen.openPopup" : "Radzen.togglePopup", Element, PopupID, true);
await JSRuntime.InvokeVoidAsync("Radzen.focusElement", isFilter ? UniqueID : SearchID);
if (FocusFilterOnPopup)
{
await JSRuntime.InvokeVoidAsync("Radzen.focusElement", isFilter ? UniqueID : SearchID);
}
if (list != null)
{
@@ -110,7 +114,13 @@ namespace Radzen.Blazor
/// </summary>
/// <value>The value template.</value>
[Parameter]
public RenderFragment<dynamic> ValueTemplate { get; set; }
public RenderFragment<dynamic> ValueTemplate { get; set; }
/// <summary>
/// Gets or sets a value indicating DataGrid density.
/// </summary>
[Parameter]
public Density Density { get; set; }
/// <summary>
/// Gets or sets the empty template shown when Data is empty collection.
@@ -244,6 +254,13 @@ namespace Radzen.Blazor
[Parameter]
public string SelectedItemsText { get; set; } = "items selected";
/// <summary>
/// Gets or sets whether popup automatically focuses on filter input.
/// </summary>
/// <value><c>true</c> if filter input should auto focus when opened; otherwise, <c>false</c>.</value>
[Parameter]
public bool FocusFilterOnPopup { get; set; } = true;
/// <summary>
/// Gets popup element reference.
/// </summary>

View File

@@ -497,15 +497,7 @@
{
if (column != null && !string.IsNullOrEmpty(column.FormatString))
{
var formats = column.FormatString.Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
if (formats.Length > 0)
{
var format = formats[0].Trim().Split(':');
if (format.Length > 1)
{
return format[1].Trim();
}
}
return column.FormatString.Replace("{0:", "").Replace("}", "");
}
return FilterDateFormat;

View File

@@ -46,9 +46,12 @@
<RadzenHtmlEditorFontName />
<RadzenHtmlEditorFontSize />
<RadzenHtmlEditorFormatBlock />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorSource />
}
</CascadingValue>
</div>
<div @ref=@ContentEditable class="rz-html-editor-content" contenteditable=@(!Disabled) @onfocus=@OnFocus @onblur=@OnBlur></div>
<RadzenTextArea spellcheck="false" Visible=@(mode == HtmlEditorMode.Source) class="rz-html-editor-source" Value=@Html Change=@SourceChanged />
<div hidden="@(mode != HtmlEditorMode.Design)" @ref=@ContentEditable class="rz-html-editor-content" contenteditable=@(!Disabled) @onfocus=@OnFocus @onblur=@OnBlur></div>
</div>
}

View File

@@ -12,12 +12,18 @@ namespace Radzen.Blazor
/// <code>
/// &lt;RadzenHtmlEditor @bind-Value=@html /&gt;
/// @code {
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// }
/// </code>
/// </example>
public partial class RadzenHtmlEditor : FormComponent<string>
{
/// <summary>
/// Gets or sets the mode of the editor.
/// </summary>
[Parameter]
public HtmlEditorMode Mode { get; set; } = HtmlEditorMode.Design;
private HtmlEditorMode mode { get; set; }
/// <summary>
/// Gets or sets the child content.
/// </summary>
@@ -38,7 +44,7 @@ namespace Radzen.Blazor
/// <code>
/// &lt;RadzenHtmlEditor @bind-Value=@html Paste=@OnPaste /&gt;
/// @code {
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// void OnPaste(HtmlEditorPasteEventArgs args)
/// {
/// // Set args.Html to filter unwanted tags.
@@ -58,7 +64,7 @@ namespace Radzen.Blazor
/// &lt;RadzenHtmlEditorCustomTool CommandName="InsertToday" Icon="today" Title="Insert today" /&gt;
/// &lt;/RadzenHtmlEditor&gt;
/// @code {
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// string html = "@lt;strong&gt;Hello&lt;/strong&gt; world!";
/// async Task OnExecute(HtmlEditorExecuteEventArgs args)
/// {
/// if (args.CommandName == "InsertToday")
@@ -117,6 +123,14 @@ namespace Radzen.Blazor
await OnChange();
}
private async Task SourceChanged(string html)
{
Html = html;
await JSRuntime.InvokeVoidAsync("Radzen.innerHTML", ContentEditable, Html);
await OnChange();
StateHasChanged();
}
async Task OnChange()
{
await Change.InvokeAsync(Html);
@@ -191,12 +205,28 @@ namespace Radzen.Blazor
}
}
internal void SetMode(HtmlEditorMode value)
{
mode = value;
StateHasChanged();
}
/// <summary>
/// Returns the current mode of the editor.
/// </summary>
public HtmlEditorMode GetMode()
{
return mode;
}
string Html { get; set; }
/// <inheritdoc />
protected override void OnInitialized()
{
Html = Value;
mode = Mode;
}
/// <summary>
@@ -233,6 +263,11 @@ namespace Radzen.Blazor
valueChanged = Html != parameters.GetValueOrDefault<string>(nameof(Value));
}
if (parameters.DidParameterChange(nameof(Mode), Mode))
{
mode = Mode;
}
visibleChanged = parameters.DidParameterChange(nameof(Visible), Visible);
await base.SetParametersAsync(parameters);

View File

@@ -4,10 +4,10 @@
{
@if (Template == null)
{
<EditorButton Title=@Title Click=@OnClick Icon=@Icon Selected=@Selected Disabled=@Disabled />
<EditorButton Title=@Title Click=@OnClick Icon=@Icon Selected=@Selected Disabled=@Disabled EnabledModes="@EnabledModes"/>
}
else
{
<div class="rz-html-editor-custom-tool">@Template(Editor)</div>
}
}
}

View File

@@ -36,6 +36,12 @@ namespace Radzen.Blazor
[Parameter]
public string Icon { get; set; } = "settings";
/// <summary>
/// Specifies the modes that this tool will be enabled in.
/// </summary>
[Parameter]
public HtmlEditorMode EnabledModes { get; set; } = HtmlEditorMode.Design;
/// <summary>
/// The template of the tool. Use to render a custom tool.
/// </summary>

View File

@@ -2,25 +2,25 @@
<EditorDropDown Title=@Title Value=@Editor.State.FormatBlock Change=@OnChange Placeholder="@Placeholder"
PopupStyle="width: 200px; max-height: 200px; overflow: auto;">
<EditorDropDownItem Text="Normal" Value="p">
<EditorDropDownItem Text=@NormalText Value="p">
<p style="margin:0">@context.Text</p>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 1" Value="h1">
<EditorDropDownItem Text=@Heading1Text Value="h1">
<h1>@context.Text</h1>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 2" Value="h2">
<EditorDropDownItem Text=@Heading2Text Value="h2">
<h2>@context.Text</h2>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 3" Value="h3">
<EditorDropDownItem Text=@Heading3Text Value="h3">
<h3>@context.Text</h3>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 4" Value="h4">
<EditorDropDownItem Text=@Heading4Text Value="h4">
<h4>@context.Text</h4>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 5" Value="h5">
<EditorDropDownItem Text=@Heading5Text Value="h5">
<h5>@context.Text</h5>
</EditorDropDownItem>
<EditorDropDownItem Text="Heading 6" Value="h6">
<EditorDropDownItem Text=@Heading6Text Value="h6">
<h6>@context.Text</h6>
</EditorDropDownItem>
</EditorDropDown>

View File

@@ -36,6 +36,48 @@ namespace Radzen.Blazor
[Parameter]
public string Title { get; set; } = "Text style";
/// <summary>
/// Specifies the text displayed for the normal text example. Set to <c>"Normal"</c> by default.
/// </summary>
[Parameter]
public string NormalText { get; set; } = "Normal";
/// <summary>
/// Specifies the text displayed for the h1 example. Set to <c>"Heading 1"</c> by default.
/// </summary>
[Parameter]
public string Heading1Text { get; set; } = "Heading 1";
/// <summary>
/// Specifies the text displayed for the h2 example. Set to <c>"Heading 2"</c> by default.
/// </summary>
[Parameter]
public string Heading2Text { get; set; } = "Heading 2";
/// <summary>
/// Specifies the text displayed for the h3 example. Set to <c>"Heading 3"</c> by default.
/// </summary>
[Parameter]
public string Heading3Text { get; set; } = "Heading 3";
/// <summary>
/// Specifies the text displayed for the h4 example. Set to <c>"Heading 4"</c> by default.
/// </summary>
[Parameter]
public string Heading4Text { get; set; } = "Heading 4";
/// <summary>
/// Specifies the text displayed for the h5 example. Set to <c>"Heading 5"</c> by default.
/// </summary>
[Parameter]
public string Heading5Text { get; set; } = "Heading 5";
/// <summary>
/// Specifies the text displayed for the h6 example. Set to <c>"Heading 6"</c> by default.
/// </summary>
[Parameter]
public string Heading6Text { get; set; } = "Heading 6";
async Task OnChange(string value)
{
await Editor.ExecuteCommandAsync("formatBlock", value);

View File

@@ -0,0 +1,22 @@
@using System.Text
@using Radzen.Blazor.Rendering
@using Microsoft.JSInterop
@inherits RadzenHtmlEditorButtonBase
@inject DialogService DialogService
@inject IJSRuntime JSRuntime
<EditorButton Title=@Title Click=@OnClick Icon="code" PreventBlur=false Selected=@(Editor.GetMode() == HtmlEditorMode.Source) EnabledModes="HtmlEditorMode.Design | HtmlEditorMode.Source" />
@code {
protected override async Task OnClick()
{
if (Editor.GetMode() == HtmlEditorMode.Design)
{
Editor.SetMode(HtmlEditorMode.Source);
}
else
{
Editor.SetMode(HtmlEditorMode.Design);
}
}
}

View File

@@ -0,0 +1,20 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
namespace Radzen.Blazor
{
/// <summary>
/// A tool which switches between rendered and source views in <see cref="RadzenHtmlEditor" />.
/// </summary>
public partial class RadzenHtmlEditorSource
{
/// <summary>
/// Specifies the title (tooltip) displayed when the user hovers the tool. Set to <c>"View source"</c> by default.
/// </summary>
[Parameter]
public string Title { get; set; } = "View source";
}
}

View File

@@ -15,7 +15,7 @@
var pathGenerator = GetPathGenerator();
var data = Items.Select(item =>
var data = Items.Select(item =>
{
var x = category(item);
var y = value(item);
@@ -27,7 +27,7 @@
var index = Chart.Series.IndexOf(this);
var className = $"rz-line-series rz-series-{index}";
return
return
@<g class="@className">
@if (Items.Any())
{
@@ -35,7 +35,7 @@
var key = $"{path}-{LineType}";
<Path @key=@key Style="@style" D="@path" StrokeWidth="@StrokeWidth" Stroke="@Stroke" LineType="@LineType" Fill="none" />
}
<Markers Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
<Markers Series="@this" Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
</g>;
}
}

View File

@@ -6,15 +6,4 @@
{
<i class="rzi">@((MarkupString)Icon)</i>
}
<span @ref="@Element" class="rz-link-text">
@if (ChildContent != null)
{
@ChildContent
}
else
{
@Text
}
</span>
</Microsoft.AspNetCore.Components.Routing.NavLink>
}
<span @ref="@Element" class="rz-link-text">@if (ChildContent != null) {@ChildContent} else {@Text}</span></Microsoft.AspNetCore.Components.Routing.NavLink>}

View File

@@ -7,14 +7,14 @@
<div class="rz-form-row">
<label class="rz-label" for=@Id("username")>@UserText</label>
<div class="rz-form-input-wrapper">
<RadzenTextBox AutoComplete=@AutoComplete id=@Id("username") Name="Username" @bind-Value=@username />
<RadzenTextBox AutoComplete=@AutoComplete AutoCompleteType=@UserNameAutoCompleteType id=@Id("username") Name="Username" @bind-Value=@username />
<RadzenRequiredValidator Component="Username" Text=@UserRequired />
</div>
</div>
<div class="rz-form-row">
<label class="rz-label" for=@Id("password")>@PasswordText</label>
<div class="rz-form-input-wrapper">
<RadzenPassword id=@Id("password") AutoComplete=@AutoComplete Name="Password" @bind-Value=@password />
<RadzenPassword id=@Id("password") AutoComplete=@AutoComplete AutoCompleteType=@PasswordAutoCompleteType Name="Password" @bind-Value=@password />
<RadzenRequiredValidator Component="Password" Text=@PasswordRequired />
</div>
</div>

View File

@@ -42,6 +42,28 @@ namespace Radzen.Blazor
[Parameter]
public bool AutoComplete { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType UserNameAutoCompleteType { get; set; } = AutoCompleteType.Username;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType PasswordAutoCompleteType { get; set; } = AutoCompleteType.CurrentPassword;
/// <inheritdoc />
protected override string GetComponentCssClass()
{

View File

@@ -6,6 +6,6 @@
@if (Visible)
{
<input @ref="@Element" disabled="@Disabled" readonly="@ReadOnly" name="@Name" style="@Style" @attributes="Attributes" class="@GetCssClass()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")"
placeholder="@Placeholder" maxlength="@MaxLength" autocomplete="@(AutoComplete ? "on" : "off")" value="@Value" @onchange="@OnChange" id="@GetId()"
placeholder="@Placeholder" maxlength="@MaxLength" autocomplete="@AutoCompleteAttribute" value="@Value" @onchange="@OnChange" id="@GetId()"
oninput="Radzen.mask('@GetId()', '@Mask', '@Pattern', '@CharacterPattern')"/>
}

View File

@@ -27,6 +27,17 @@ namespace Radzen.Blazor
[Parameter]
public bool AutoComplete { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType AutoCompleteType { get; set; } = AutoCompleteType.On;
/// <summary>
/// Gets or sets the maximum length.
/// </summary>
@@ -84,5 +95,18 @@ namespace Radzen.Blazor
JSRuntime.InvokeVoidAsync("eval", $"Radzen.mask('{GetId()}', '{Mask}', '{Pattern}', '{CharacterPattern}')");
}
}
/// <summary>
/// Gets the autocomplete attribute's string value.
/// </summary>
/// <value>
/// <c>off</c> if the AutoComplete parameter is false or the
/// AutoCompleteType parameter is "off". When the AutoComplete
/// parameter is true, the value is <c>on</c> or, if set, the value of
/// AutoCompleteType.</value>
public string AutoCompleteAttribute
{
get => !AutoComplete ? "off" : AutoCompleteType.GetAutoCompleteValue();
}
}
}

View File

@@ -9,7 +9,7 @@
<span @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<input @ref="@input" type="text" inputmode="decimal" name="@Name" disabled="@Disabled" readonly="@ReadOnly"
class="@GetInputCssClass()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")"
placeholder="@Placeholder" autocomplete="@(AutoComplete ? "on" : "off")" value="@FormattedValue" @onchange="@OnChange"
placeholder="@Placeholder" autocomplete="@AutoCompleteAttribute" value="@FormattedValue" @onchange="@OnChange"
onkeypress="Radzen.numericKeyPress(event, @IsInteger().ToString().ToLower())"
onblur="@getOnInput()" onpaste="@getOnPaste()" />
@if (ShowUpDown)

View File

@@ -189,6 +189,30 @@ namespace Radzen.Blazor
[Parameter]
public bool AutoComplete { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType AutoCompleteType { get; set; } = AutoCompleteType.On;
/// <summary>
/// Gets the autocomplete attribute's string value.
/// </summary>
/// <value>
/// <c>off</c> if the AutoComplete parameter is false or the
/// AutoCompleteType parameter is "off". When the AutoComplete
/// parameter is true, the value is <c>on</c> or, if set, the value of
/// AutoCompleteType.</value>
public string AutoCompleteAttribute
{
get => !AutoComplete ? "off" : AutoCompleteType.GetAutoCompleteValue();
}
/// <summary>
/// Gets or sets a value indicating whether up down buttons are shown.
/// </summary>

View File

@@ -27,7 +27,14 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return $"rz-paginator rz-unselectable-text rz-helper-clearfix {HorizontalAlignCssClasses[HorizontalAlign]}";
var additionalClasses = new List<string>();
if (Density == Density.Compact)
{
additionalClasses.Add("rz-density-compact");
}
return $"rz-paginator rz-unselectable-text rz-helper-clearfix {HorizontalAlignCssClasses[HorizontalAlign]} {String.Join(" ", additionalClasses)}";
}
/// <summary>
@@ -37,6 +44,12 @@ namespace Radzen.Blazor
[Parameter]
public HorizontalAlign HorizontalAlign { get; set; } = HorizontalAlign.Justify;
/// <summary>
/// Gets or sets a value indicating Pager density.
/// </summary>
[Parameter]
public Density Density { get; set; }
/// <summary>
/// Gets or sets the page size.
/// </summary>
@@ -114,11 +127,11 @@ namespace Radzen.Blazor
return Visible && (AlwaysVisible || Count > PageSize || (PageSizeOptions != null && PageSizeOptions.Any()));
}
/// <summary>
/// Gets or sets a value indicating whether pager is visible even when not enough data for paging.
/// </summary>
/// <value><c>true</c> if pager is visible even when not enough data for paging otherwise, <c>false</c>.</value>
[Parameter]
/// <summary>
/// Gets or sets a value indicating whether pager is visible even when not enough data for paging.
/// </summary>
/// <value><c>true</c> if pager is visible even when not enough data for paging otherwise, <c>false</c>.</value>
[Parameter]
public bool AlwaysVisible { get; set; }
/// <summary>
@@ -157,7 +170,7 @@ namespace Radzen.Blazor
protected async Task OnPageSizeChanged(object value)
{
bool isFirstPage = CurrentPage == 0;
bool isLastPage = CurrentPage == numberOfPages - 1;
bool isLastPage = CurrentPage == numberOfPages - 1 && numberOfPages > 1;
int prevSkip = skip;
PageSize = (int)value;
await InvokeAsync(Reload);

View File

@@ -5,5 +5,5 @@
@if (Visible)
{
<input @ref="@Element" name="@Name" disabled="@Disabled" readonly="@ReadOnly" style="@Style" type="password" @attributes="Attributes" class="@GetCssClass()"
placeholder="@Placeholder" autocomplete="@(AutoComplete ? "on" : "new-password")" value="@Value" @onchange="@OnChange" tabindex="@(Disabled ? "-1" : $"{TabIndex}")" id="@GetId()"/>
placeholder="@Placeholder" autocomplete="@AutoCompleteAttribute" value="@Value" @onchange="@OnChange" tabindex="@(Disabled ? "-1" : $"{TabIndex}")" id="@GetId()"/>
}

View File

@@ -26,6 +26,17 @@ namespace Radzen.Blazor
[Parameter]
public bool AutoComplete { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType AutoCompleteType { get; set; } = AutoCompleteType.On;
/// <summary>
/// Handles the <see cref="E:Change" /> event.
/// </summary>
@@ -44,5 +55,17 @@ namespace Radzen.Blazor
{
return GetClassList("rz-textbox").ToString();
}
/// <summary>
/// Gets the autocomplete attribute's string value.
/// </summary>
/// <value>
/// <c>new-password</c> if the AutoComplete parameter is false. When
/// the AutoComplete parameter is true, the value is <c>on</c> or, if
/// set, the value of AutoCompleteType.</value>
public string AutoCompleteAttribute
{
get => !AutoComplete ? "new-password" : AutoCompleteType.GetAutoCompleteValue();
}
}
}

View File

@@ -16,37 +16,47 @@
var y = CenterY;
var radius = CurrentRadius;
return
return
@<g class="@className">
@if (Items.Any())
{
var sum = Items.Sum(Value);
double startAngle = -90;
@foreach(var data in Items)
@if (PositiveItems.Any())
{
var value = Value(data);
var angle = sum == 0 ? 0 : (value / sum) * 360;
var endAngle = startAngle + angle;
var sum = PositiveItems.Sum(Value);
var d = Segment(x, y, radius, 0, startAngle, endAngle);
double startAngle = -90;
startAngle = endAngle;
var index = Items.IndexOf(data);
var arcClassName = $"rz-series-item-{index}";
var fill = PickColor(index, Fills);
var stroke = PickColor(index, Strokes);
@foreach (var data in PositiveItems)
{
var value = Value(data);
var angle = sum == 0 ? 0 : (value / sum) * 360;
var endAngle = startAngle + angle;
var d = Segment(x, y, radius, 0, startAngle, endAngle);
startAngle = endAngle;
var index = Items.IndexOf(data);
var arcClassName = $"rz-series-item-{index}";
var fill = PickColor(index, Fills);
var stroke = PickColor(index, Strokes);
<g class="@arcClassName">
@if (angle > 0)
{
<Path D="@d" Fill="@fill" StrokeWidth="@StrokeWidth" Stroke="@stroke" />
}
</g>
}
}
else
{
var arcClassName = $"rz-series-item-0";
var d = Segment(x, y, radius, radius - 1, -90, 270);
var fill = PickColor(0, Fills);
var stroke = PickColor(0, Strokes);
<g class="@arcClassName">
@if (angle > 0)
{
<Path D="@d" Fill="@fill" StrokeWidth="@StrokeWidth" Stroke="@stroke" />
}
<Path D="@d" Fill="@fill" StrokeWidth="@StrokeWidth" Stroke="@stroke" />
</g>
}
}
</g>;
}
}

View File

@@ -93,6 +93,27 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Stores <see cref="Data" /> filtered to items greater than zero as an IList of <typeparamref name="TItem"/>.
/// </summary>
/// <value>The items.</value>
protected IList<TItem> PositiveItems { get; set; }
/// <inheritdoc />
public override async Task SetParametersAsync(ParameterView parameters)
{
await base.SetParametersAsync(parameters);
if (Items != null)
{
PositiveItems = Items.Where(e => Value(e) > 0).ToList();
}
else
{
PositiveItems = new List<TItem>();
}
}
/// <inheritdoc />
public override double MeasureLegend()
{
@@ -208,11 +229,11 @@ namespace Radzen.Blazor
/// <inheritdoc />
internal override double TooltipX(TItem item)
{
var sum = Items.Sum(Value);
var sum = PositiveItems.Sum(Value);
double startAngle = 0;
double endAngle = 0;
foreach (var data in Items)
foreach (var data in PositiveItems)
{
var value = Value(data);
endAngle = startAngle + (value / sum) * 360;
@@ -233,7 +254,7 @@ namespace Radzen.Blazor
/// <inheritdoc />
internal override double TooltipY(TItem item)
{
var sum = Items.Sum(Value);
var sum = PositiveItems.Sum(Value);
double startAngle = 0;
double endAngle = 0;
@@ -310,7 +331,7 @@ namespace Radzen.Blazor
if (Math.Abs(end.X - start.X) < 0.01 && Math.Abs(end.Y - start.Y) < 0.01)
{
// Full circle - SVG can't render a full circle arc
// Full circle - SVG can't render a full circle arc
endX = (end.X - 0.01).ToInvariantString();
innerEndX = (innerEnd.X - 0.01).ToInvariantString();
@@ -324,31 +345,36 @@ namespace Radzen.Blazor
{
var list = new List<ChartDataLabel>();
foreach (var d in Data)
if(Data != null)
{
var x = TooltipX(d) - CenterX;
var y = TooltipY(d) - CenterY;
//var DataGreaterZero = Data.Where(e => Value(e) > 0).ToList();
// find angle and add offset
var phi = Math.Atan2(y, x);
foreach (var d in PositiveItems)
{
var x = TooltipX(d) - CenterX;
var y = TooltipY(d) - CenterY;
phi += Polar.ToRadian(offsetY % 360);
// find angle and add offset
var phi = Math.Atan2(y, x);
var textAnchor = phi >= -1.5 && phi <= 1.5 ? "start" : "end";
phi += Polar.ToRadian(offsetY % 360);
// find radius
var hyp = Math.Sqrt(x * x + y * y) + offsetX + 16;
var textAnchor = phi >= -1.5 && phi <= 1.5 ? "start" : "end";
// move along the radius and rotate
x = CenterX + hyp * Math.Cos(phi);
y = CenterY + hyp * Math.Sin(phi);
// find radius
var hyp = Math.Sqrt(x * x + y * y) + offsetX + 16;
list.Add(new ChartDataLabel
{
TextAnchor = textAnchor,
Position = new Point { X = x, Y = y },
Text = Chart.ValueAxis.Format(Chart.ValueScale, Value(d))
});
// move along the radius and rotate
x = CenterX + hyp * Math.Cos(phi);
y = CenterY + hyp * Math.Sin(phi);
list.Add(new ChartDataLabel
{
TextAnchor = textAnchor,
Position = new Point { X = x, Y = y },
Text = Chart.ValueAxis.Format(Chart.ValueScale, Value(d))
});
}
}
return list;

View File

@@ -274,6 +274,27 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Selects the specified <see cref="ISchedulerView"/>. The view must already be present in this scheduler.
/// If the specified view is already selected, no action will be performed.
/// </summary>
/// <param name="view">The <see cref="ISchedulerView"/> to select</param>
public async Task SelectView(ISchedulerView view)
{
var viewIndex = Views.IndexOf(view);
if (viewIndex == -1)
return;
if (SelectedView == view)
return;
selectedIndex = viewIndex;
await InvokeLoadData();
StateHasChanged();
}
/// <summary>
/// Causes the current scheduler view to render. Enumerates the items of <see cref="Data" /> and creates instances of <see cref="AppointmentData" /> to
/// display in the current view. Use it when <see cref="Data" /> has changed.

View File

@@ -29,12 +29,15 @@
builder.OpenRegion(0);
foreach (var label in series.GetDataLabels(OffsetX, OffsetY))
{
builder.AddContent(1,
@<g>
<Text @key="@($"{label.Position}-{Chart.Series.IndexOf(series)}")"
Value="@label.Text" Position="@label.Position" TextAnchor="@label.TextAnchor" Class="rz-series-data-label" />
</g>
if (!(double.IsNaN(label.Position.X) || double.IsNaN(label.Position.Y)))
{
builder.AddContent(1,
@<g>
<Text @key="@($"{label.Position}-{Chart.Series.IndexOf(series)}")"
Value="@label.Text" Position="@label.Position" TextAnchor="@label.TextAnchor" Class="rz-series-data-label" />
</g>
);
}
}
builder.CloseRegion();
};

View File

@@ -4,24 +4,35 @@
@if (Visible)
{
<div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<button disabled="@Disabled" class="@getButtonCss()" type="button" @onclick="@OnClick">
@if (!string.IsNullOrEmpty(@Icon))
<button disabled="@IsDisabled" class="@getButtonCss()" type="button" @onclick="@OnClick">
@if (IsBusy)
{
<i class="rz-button-icon-left rzi">@((MarkupString)Icon)</i>
}
@if (!string.IsNullOrEmpty(Image))
{
<img class="rz-button-icon-left rzi" src="@Image" />
}
@if (!string.IsNullOrEmpty(Text))
{
<span class="rz-button-text">@Text</span>
<RadzenIcon Icon="refresh" Style="animation: rotation 700ms linear infinite" />
@if (!string.IsNullOrEmpty(BusyText))
{
<span class="rz-button-text">@BusyText</span>
}
}
else
{
<span class="rz-button-text">&nbsp;</span>
@if (!string.IsNullOrEmpty(@Icon))
{
<i class="rz-button-icon-left rzi">@((MarkupString)Icon)</i>
}
@if (!string.IsNullOrEmpty(Image))
{
<img class="rz-button-icon-left rzi" src="@Image" />
}
@if (!string.IsNullOrEmpty(Text))
{
<span class="rz-button-text">@Text</span>
}
else
{
<span class="rz-button-text">&nbsp;</span>
}
}
</button><button onclick="@OpenPopupScript()" class="@getPopupButtonCss()" type="button">
</button><button disabled="@IsDisabled" onclick="@OpenPopupScript()" class="@getPopupButtonCss()" type="button">
<span aria-hidden="true" class="rz-button-icon-left rzi rzi-chevron-down"></span><span class="rz-button-text"></span>
</button>
<div id="@PopupID" class="rz-splitbutton-menu">

View File

@@ -75,6 +75,26 @@ namespace Radzen.Blazor
[Parameter]
public ButtonSize Size { get; set; } = ButtonSize.Medium;
/// <summary>
/// Gets or sets a value indicating whether this instance busy text is shown.
/// </summary>
/// <value><c>true</c> if this instance busy text is shown; otherwise, <c>false</c>.</value>
[Parameter]
public bool IsBusy { get; set; }
/// <summary>
/// Gets or sets the busy text.
/// </summary>
/// <value>The busy text.</value>
[Parameter]
public string BusyText { get; set; } = "";
/// <summary>
/// Gets a value indicating whether this instance is disabled.
/// </summary>
/// <value><c>true</c> if this instance is disabled; otherwise, <c>false</c>.</value>
public bool IsDisabled { get => Disabled || IsBusy; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenSplitButton"/> is disabled.
/// </summary>
@@ -138,12 +158,12 @@ namespace Radzen.Blazor
private string getButtonCss()
{
return $"rz-button rz-button-{getButtonSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()} {(Disabled ? " rz-state-disabled" : "")}{(string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Icon) ? " rz-button-icon-only" : "")}";
return $"rz-button rz-button-{getButtonSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()} {(IsDisabled ? " rz-state-disabled" : "")}{(string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Icon) ? " rz-button-icon-only" : "")}";
}
private string getPopupButtonCss()
{
return $"rz-splitbutton-menubutton rz-button rz-button-icon-only rz-button-{getButtonSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()}{(Disabled ? " rz-state-disabled" : "")}";
return $"rz-splitbutton-menubutton rz-button rz-button-icon-only rz-button-{getButtonSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()}{(IsDisabled ? " rz-state-disabled" : "")}";
}
private string OpenPopupScript()

View File

@@ -100,7 +100,7 @@ namespace Radzen.Blazor
if (!pane.Resizable)
return Task.CompletedTask;
var paneNextResizable = Panes.Skip(paneIndex + 1).FirstOrDefault(o => o.Resizable && !o.Collapsed);
var paneNextResizable = Panes.Skip(paneIndex + 1).FirstOrDefault(o => o.Resizable && !o.GetCollapsed());
return JSRuntime.InvokeVoidAsync("Radzen.startSplitterResize",
@@ -164,7 +164,7 @@ namespace Radzen.Blazor
var pane = Panes[paneIndex];
var paneNext = pane.Next();
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && paneNext.Collapsed)
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && paneNext.GetCollapsed())
{
if (Expand.HasDelegate)
{
@@ -197,7 +197,7 @@ namespace Radzen.Blazor
var pane = Panes[paneIndex];
var paneNext = pane.Next();
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && !pane.Collapsed)
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && !pane.GetCollapsed())
{
if (Collapse.HasDelegate)
{

View File

@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components;
using System.Linq;
using System.Threading.Tasks;
namespace Radzen.Blazor
{
@@ -19,7 +20,7 @@ namespace Radzen.Blazor
internal bool IsLastResizable
{
get { return Splitter.Panes.Last(o => o.Resizable && !o.Collapsed) == this; }
get { return Splitter.Panes.Last(o => o.Resizable && !o.GetCollapsed()) == this; }
}
internal bool IsLast => Splitter.Panes.Count - 1 == Index;
@@ -37,9 +38,9 @@ namespace Radzen.Blazor
{
var paneNext = Next();
if (Collapsed
if (GetCollapsed()
|| (Index == Splitter.Panes.Count - 2 && !paneNext.IsResizable)
|| (IsLastResizable && paneNext != null && paneNext.Collapsed)
|| (IsLastResizable && paneNext != null && paneNext.GetCollapsed())
)
return false;
@@ -52,14 +53,14 @@ namespace Radzen.Blazor
{
get
{
if (Collapsible && !Collapsed)
if (Collapsible && !GetCollapsed())
return true;
var paneNext = Next();
if (paneNext == null)
return false;
return paneNext.IsLast && paneNext.Collapsible && paneNext.Collapsed;
return paneNext.IsLast && paneNext.Collapsible && paneNext.GetCollapsed();
}
}
@@ -67,14 +68,14 @@ namespace Radzen.Blazor
{
get
{
if (Collapsed)
if (GetCollapsed())
return true;
var paneNext = Next();
if (paneNext == null)
return false;
return paneNext.IsLast && paneNext.Collapsible && !paneNext.Collapsed;
return paneNext.IsLast && paneNext.Collapsible && !paneNext.GetCollapsed();
}
}
@@ -82,7 +83,7 @@ namespace Radzen.Blazor
{
get
{
if (Collapsed)
if (GetCollapsed())
return "collapsed";
if (IsLastResizable)
@@ -109,6 +110,7 @@ namespace Radzen.Blazor
[Parameter]
public bool Collapsible { get; set; } = true;
private bool? collapsed;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenSplitterPane"/> is collapsed.
/// </summary>
@@ -168,9 +170,13 @@ namespace Radzen.Blazor
internal void SetCollapsed(bool value)
{
Collapsed = value;
collapsed = value;
}
internal bool GetCollapsed()
{
return collapsed ?? Collapsed;
}
/// <inheritdoc />
public override void Dispose()
@@ -179,6 +185,17 @@ namespace Radzen.Blazor
Splitter?.RemovePane(this);
}
/// <inheritdoc />
public override async Task SetParametersAsync(ParameterView parameters)
{
if (parameters.DidParameterChange(nameof(Collapsed), Collapsed))
{
collapsed = parameters.GetValueOrDefault<bool>(nameof(Collapsed));
}
await base.SetParametersAsync(parameters);
}
/// <inheritdoc />
protected override string GetComponentCssClass()
{

View File

@@ -0,0 +1,56 @@
@using Radzen
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@typeparam TItem
@inherits Radzen.Blazor.CartesianSeries<TItem>
@implements IChartStackedBarSeries
<CascadingValue Value="@this">
@ChildContent
</CascadingValue>
@code {
public override RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale)
{
var value = ComposeValue(categoryScale);
var category = ComposeCategory(valueScale);
var ticks = Chart.CategoryScale.Ticks(Chart.ValueAxis.TickDistance);
var style = $"clip-path: url(#{Chart.ClipPath}); -webkit-clip-path: url(#{Chart.ClipPath});";
var barSeries = StackedBarSeries;
var barIndex = BarIndex;
var height = BarHeight;
var className = $"rz-bar-series rz-series-{Chart.Series.IndexOf(this)}";
return
@<g class="@className">
@for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var y = GetBarTop(data, category);
var x = GetBarRight(data, barIndex, index, barSeries);
var radius = Chart.BarOptions.Radius;
if (radius > height / 2 || barIndex < barSeries.Count - 1)
{
radius = 0;
}
var x0 = GetBarLeft(barIndex, index, barSeries);
var r = radius.ToInvariantString();
var path = $"M {x0.ToInvariantString()} {y.ToInvariantString()} L {(x-radius).ToInvariantString()} {y.ToInvariantString()} A {r} {r} 0 0 1 {x.ToInvariantString()} {(y+radius).ToInvariantString()} L {x.ToInvariantString()} {(y+height-radius).ToInvariantString()} A {r} {r} 0 0 1 {(x-radius).ToInvariantString()} {(y + height).ToInvariantString()} L {x0.ToInvariantString()} {(y+height).ToInvariantString()} Z";
if (x < x0)
{
path = $"M {x0.ToInvariantString()} {y.ToInvariantString()} L {(x+radius).ToInvariantString()} {y.ToInvariantString()} A {r} {r} 0 0 0 {x.ToInvariantString()} {(y+radius).ToInvariantString()} L {x.ToInvariantString()} {(y+height-radius).ToInvariantString()} A {r} {r} 0 0 0 {(x+radius).ToInvariantString()} {(y + height).ToInvariantString()} L {x0.ToInvariantString()} {(y+height).ToInvariantString()} Z";
}
var fill = PickColor(Items.IndexOf(data), Fills, Fill);
var stroke = PickColor(Items.IndexOf(data), Strokes, Stroke);
<Path @key="@path" D="@path" Stroke="@stroke" StrokeWidth="@StrokeWidth" Fill="@fill" LineType="@LineType" Style="@style" />
}
</g>;
}
}

View File

@@ -0,0 +1,265 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Radzen.Blazor
{
/// <summary>
/// Renders bar series in <see cref="RadzenChart" />.
/// </summary>
/// <typeparam name="TItem">The type of the series data item.</typeparam>
public partial class RadzenStackedBarSeries<TItem> : CartesianSeries<TItem>, IChartStackedBarSeries
{
/// <summary>
/// Specifies the fill (background color) of the bar series.
/// </summary>
/// <value>The fill.</value>
[Parameter]
public string Fill { get; set; }
/// <summary>
/// Specifies a list of colors that will be used to set the individual bar backgrounds.
/// </summary>
/// <value>The fills.</value>
[Parameter]
public IEnumerable<string> Fills { get; set; }
/// <summary>
/// Specifies the stroke (border color) of the bar series.
/// </summary>
/// <value>The stroke.</value>
[Parameter]
public string Stroke { get; set; }
/// <summary>
/// Specifies a list of colors that will be used to set the individual bar borders.
/// </summary>
/// <value>The strokes.</value>
[Parameter]
public IEnumerable<string> Strokes { get; set; }
/// <summary>
/// Gets or sets the width of the stroke (border).
/// </summary>
/// <value>The width of the stroke.</value>
[Parameter]
public double StrokeWidth { get; set; }
/// <summary>
/// Gets or sets the type of the line used to render the bar border.
/// </summary>
/// <value>The type of the line.</value>
[Parameter]
public LineType LineType { get; set; }
/// <inheritdoc />
public override string Color
{
get
{
return Fill;
}
}
/// <inheritdoc />
public override ScaleBase TransformCategoryScale(ScaleBase scale)
{
var stackedBarSeries = BarSeries.Cast<IChartStackedBarSeries>();
var count = stackedBarSeries.Max(series => series.Count);
var sums = Enumerable.Range(0, count).Select(i => stackedBarSeries.Sum(series => series.ValueAt(i)));
var max = sums.Max();
var min = Items.Min(Value);
scale.Input.MergeWidth(new ScaleRange { Start = min, End = max });
return scale;
}
/// <inheritdoc />
public override ScaleBase TransformValueScale(ScaleBase scale)
{
return base.TransformCategoryScale(scale);
}
/// <inheritdoc />
protected override IList<object> GetCategories()
{
return base.GetCategories().Reverse().ToList();
}
private IList<IChartSeries> BarSeries => Chart.Series.Where(series => series is IChartStackedBarSeries).Cast<IChartSeries>().ToList();
private IList<IChartSeries> VisibleBarSeries => BarSeries.Where(series => series.Visible).ToList();
private IList<IChartStackedBarSeries> StackedBarSeries => VisibleBarSeries.Cast<IChartStackedBarSeries>().ToList();
/// <inheritdoc />
protected override string TooltipStyle(TItem item)
{
var style = base.TooltipStyle(item);
var index = Items.IndexOf(item);
if (index >= 0)
{
var color = PickColor(index, Fills, Fill);
if (color != null)
{
style = $"{style}; border-color: {color};";
}
}
return style;
}
private double BandHeight
{
get
{
var barSeries = VisibleBarSeries;
if (Chart.BarOptions.Height.HasValue)
{
return Chart.BarOptions.Height.Value * barSeries.Count;
}
else
{
var availableHeight = Chart.ValueScale.OutputSize; // - (Chart.ValueAxis.Padding * 2);
var bands = barSeries.Cast<IChartStackedBarSeries>().Max(series => series.Count) + 2;
return availableHeight / bands;
}
}
}
double BarHeight => Chart.BarOptions.Height ?? BandHeight - Chart.BarOptions.Margin;
int BarIndex => VisibleBarSeries.IndexOf(this);
private double GetBarTop(TItem item, Func<TItem, double> category = null)
{
category = category ?? ComposeCategory(Chart.ValueScale);
return category(item) - BarHeight / 2;
}
private double GetBarRight(TItem item, int barIndex, int index, IEnumerable<IChartStackedBarSeries> stackedBarSeries)
{
var count = stackedBarSeries.Max(series => series.Count);
var sum = stackedBarSeries.Take(barIndex).Sum(series => series.ValueAt(index));
var y = Chart.CategoryScale.Scale(Value(item) + sum);
return y;
}
private double GetBarLeft(int barIndex, int index, IEnumerable<IChartStackedBarSeries> stackedBarSeries)
{
var ticks = Chart.CategoryScale.Ticks(Chart.ValueAxis.TickDistance);
var sum = stackedBarSeries.Take(barIndex).Sum(series => series.ValueAt(index));
return Chart.CategoryScale.Scale(Math.Max(0, Math.Max(ticks.Start, sum)));
}
int IChartBarSeries.Count
{
get
{
return Items.Count;
}
}
double IChartStackedBarSeries.ValueAt(int index)
{
if (Items == null || index < 0 || index >= Items.Count)
{
return 0;
}
return Value(Items[index]);
}
/// <inheritdoc />
public override bool Contains(double x, double y, double tolerance)
{
return DataAt(x, y) != null;
}
/// <inheritdoc />
internal override double TooltipX(TItem item)
{
return GetBarRight(item, BarIndex, Items.IndexOf(item), StackedBarSeries);
}
/// <inheritdoc />
protected override string TooltipValue(TItem item)
{
return Chart.ValueAxis.Format(Chart.CategoryScale, Chart.CategoryScale.Value(Value(item)));
}
/// <inheritdoc />
protected override string TooltipTitle(TItem item)
{
var category = Category(Chart.ValueScale);
return Chart.CategoryAxis.Format(Chart.ValueScale, Chart.ValueScale.Value(category(item)));
}
/// <inheritdoc />
public override object DataAt(double x, double y)
{
var category = ComposeCategory(Chart.ValueScale);
var barSeries = VisibleBarSeries;
var barIndex = BarIndex;
for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var startY = GetBarTop(data, category);
var endY = startY + BandHeight;
var dataX = GetBarRight(data, barIndex, index, StackedBarSeries);
var x0 = GetBarLeft(barIndex, index, StackedBarSeries);
var startX = Math.Min(dataX, x0);
var endX = Math.Max(dataX, x0);
if (startX <= x && x <= endX && startY <= y && y <= endY)
{
return data;
}
}
return null;
}
/// <inheritdoc />
internal override double TooltipY(TItem item)
{
return GetBarTop(item) + BarHeight / 2;
}
/// <inheritdoc />
public override IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
var list = new List<ChartDataLabel>();
var barIndex = BarIndex;
var stackedBarSeries = StackedBarSeries;
for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var left = GetBarLeft(barIndex, index, stackedBarSeries);
var right = GetBarRight(data, barIndex, index, stackedBarSeries);
var x = left + (right - left) / 2;
list.Add(new ChartDataLabel
{
Position = new Point() { X = x + offsetX, Y = TooltipY(data) + offsetY },
TextAnchor = "middle",
Text = Chart.ValueAxis.Format(Chart.CategoryScale, Value(data))
});
}
return list;
}
}
}

View File

@@ -0,0 +1,51 @@
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@typeparam TItem
@inherits Radzen.Blazor.CartesianSeries<TItem>
@implements IChartStackedColumnSeries
<CascadingValue Value="@this">
@ChildContent
</CascadingValue>
@code {
public override RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale)
{
var category = ComposeCategory(categoryScale);
var style = $"clip-path: url(#{Chart.ClipPath}); -webkit-clip-path: url(#{Chart.ClipPath});";
var columnIndex = ColumnIndex;
var stackedColumnSeries = StackedColumnSeries;
var width = ColumnWidth;
var className = $"rz-column-series rz-series-{Chart.Series.IndexOf(this)}";
return
@<g class="@className">
@for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var x = GetColumnLeft(data, category);
var y = GetColumnTop(data, columnIndex, index, stackedColumnSeries);
var radius = Chart.ColumnOptions.Radius;
if (radius > width / 2 || columnIndex < stackedColumnSeries.Count - 1)
{
radius = 0;
}
var y0 = GetColumnBottom(columnIndex, index, stackedColumnSeries);
var path = $"M {x.ToInvariantString()} {(y+radius).ToInvariantString()} A {radius.ToInvariantString()} {radius.ToInvariantString()} 0 0 1 {(x + radius).ToInvariantString()} {y.ToInvariantString()} L {(x + width - radius).ToInvariantString()} {y.ToInvariantString()} A {radius.ToInvariantString()} {radius.ToInvariantString()} 0 0 1 {(x + width).ToInvariantString()} {(y+radius).ToInvariantString()} L {(x+width).ToInvariantString()} {y0.ToInvariantString()} L {x.ToInvariantString()} {y0.ToInvariantString()} Z";
if (y > y0)
{
path = $"M {x.ToInvariantString()} {y0.ToInvariantString()} L {(x+width).ToInvariantString()} {y0.ToInvariantString()} L {(x+width).ToInvariantString()} {(y-radius).ToInvariantString()} A {radius.ToInvariantString()} {radius.ToInvariantString()} 0 0 1 {(x + width - radius).ToInvariantString()} {y.ToInvariantString()} L {(x + radius).ToInvariantString()} {y.ToInvariantString()} A {radius.ToInvariantString()} {radius.ToInvariantString()} 0 0 1 {x.ToInvariantString()} {(y-radius).ToInvariantString()} L {x.ToInvariantString()} {y0.ToInvariantString()} Z";
}
var fill = PickColor(Items.IndexOf(data), Fills, Fill);
var stroke = PickColor(Items.IndexOf(data), Strokes, Stroke);
<Path @key="@path" D="@path" Stroke="@stroke" StrokeWidth="@StrokeWidth" Fill="@fill" LineType="@LineType" Style="@style" />
}
</g>;
}
}

View File

@@ -0,0 +1,248 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Radzen.Blazor
{
/// <summary>
/// Renders column series in <see cref="RadzenChart" />
/// </summary>
/// <typeparam name="TItem">The type of the series data item.</typeparam>
public partial class RadzenStackedColumnSeries<TItem> : CartesianSeries<TItem>, IChartStackedColumnSeries
{
/// <summary>
/// Specifies the fill (background color) of the column series.
/// </summary>
/// <value>The fill.</value>
[Parameter]
public string Fill { get; set; }
/// <summary>
/// Specifies a list of colors that will be used to set the individual column backgrounds.
/// </summary>
/// <value>The fills.</value>
[Parameter]
public IEnumerable<string> Fills { get; set; }
/// <summary>
/// Specifies the stroke (border color) of the column series.
/// </summary>
/// <value>The stroke.</value>
[Parameter]
public string Stroke { get; set; }
/// <summary>
/// Specifies a list of colors that will be used to set the individual column borders.
/// </summary>
/// <value>The strokes.</value>
[Parameter]
public IEnumerable<string> Strokes { get; set; }
/// <summary>
/// Gets or sets the width of the stroke (border).
/// </summary>
/// <value>The width of the stroke.</value>
[Parameter]
public double StrokeWidth { get; set; }
/// <summary>
/// Gets or sets the type of the line used to render the column border.
/// </summary>
/// <value>The type of the line.</value>
[Parameter]
public LineType LineType { get; set; }
/// <inheritdoc />
public override string Color
{
get
{
return Fill;
}
}
int IChartStackedColumnSeries.Count
{
get
{
if (Items == null)
{
return 0;
}
return Items.Count();
}
}
double IChartStackedColumnSeries.ValueAt(int index)
{
if (Items == null || index < 0 || index >= Items.Count)
{
return 0;
}
return Value(Items[index]);
}
private IList<IChartSeries> ColumnSeries => Chart.Series.Where(series => series is IChartStackedColumnSeries).Cast<IChartSeries>().ToList();
private IList<IChartSeries> VisibleColumnSeries => ColumnSeries.Where(series => series.Visible).ToList();
private IList<IChartStackedColumnSeries> StackedColumnSeries => VisibleColumnSeries.Cast<IChartStackedColumnSeries>().ToList();
/// <inheritdoc />
protected override string TooltipStyle(TItem item)
{
var style = base.TooltipStyle(item);
var index = Items.IndexOf(item);
if (index >= 0)
{
var color = PickColor(index, Fills, Fill);
if (color != null)
{
style = $"{style}; border-color: {color};";
}
}
return style;
}
private double BandWidth
{
get
{
var columnSeries = VisibleColumnSeries;
if (Chart.ColumnOptions.Width.HasValue)
{
return Chart.ColumnOptions.Width.Value * columnSeries.Count + Chart.ColumnOptions.Margin * (columnSeries.Count - 1);
}
else
{
var availableWidth = Chart.CategoryScale.OutputSize - (Chart.CategoryAxis.Padding * 2);
var bands = columnSeries.Cast<IChartStackedColumnSeries>().Max(series => series.Count) + 2;
return availableWidth / bands;
}
}
}
/// <inheritdoc />
public override bool Contains(double x, double y, double tolerance)
{
return DataAt(x, y) != null;
}
double ColumnWidth => Chart.ColumnOptions.Width ?? BandWidth - Chart.ColumnOptions.Margin;
private double GetColumnLeft(TItem item, Func<TItem, double> category = null)
{
category = category ?? ComposeCategory(Chart.CategoryScale);
return category(item) - ColumnWidth / 2;
}
private double GetColumnTop(TItem item, int columnIndex, int index, IEnumerable<IChartStackedColumnSeries> stackedColumnSeries)
{
var count = stackedColumnSeries.Max(series => series.Count);
var sum = stackedColumnSeries.Take(columnIndex).Sum(series => series.ValueAt(index));
var y = Chart.ValueScale.Scale(Value(item) + sum);
return y;
}
private double GetColumnBottom(int columnIndex, int index, IEnumerable<IChartStackedColumnSeries> stackedColumnSeries)
{
var ticks = Chart.ValueScale.Ticks(Chart.ValueAxis.TickDistance);
var sum = stackedColumnSeries.Take(columnIndex).Sum(series => series.ValueAt(index));
return Chart.ValueScale.Scale(Math.Max(0, Math.Max(ticks.Start, sum)));
}
int ColumnIndex => VisibleColumnSeries.IndexOf(this);
/// <inheritdoc />
internal override double TooltipX(TItem item)
{
return GetColumnLeft(item) + ColumnWidth / 2;
}
/// <inheritdoc />
internal override double TooltipY(TItem item)
{
return GetColumnTop(item, ColumnIndex, Items.IndexOf(item), StackedColumnSeries);
}
/// <inheritdoc />
public override object DataAt(double x, double y)
{
var category = ComposeCategory(Chart.CategoryScale);
var columnIndex = ColumnIndex;
var width = ColumnWidth;
var stackedColumnSeries = StackedColumnSeries;
for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var startX = GetColumnLeft(data, category);
var endX = startX + width;
var dataY = GetColumnTop(data, columnIndex, index, stackedColumnSeries);
var y0 = GetColumnBottom(columnIndex, index, stackedColumnSeries);
var startY = Math.Min(dataY, y0);
var endY = Math.Max(dataY, y0);
if (startX <= x && x <= endX && startY <= y && y <= endY)
{
return data;
}
}
return null;
}
/// <inheritdoc />
public override IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
var list = new List<ChartDataLabel>();
var stackedColumnSeries = StackedColumnSeries;
var columnIndex = ColumnIndex;
for (var index = 0; index < Items.Count; index++)
{
var data = Items[index];
var top = GetColumnTop(data, columnIndex, index, stackedColumnSeries);
var bottom = GetColumnBottom(columnIndex, index, stackedColumnSeries);
var y = top + (bottom - top) / 2;
list.Add(new ChartDataLabel
{
Position = new Point { X = TooltipX(data) + offsetX, Y = y + offsetY },
TextAnchor = "middle",
Text = Chart.ValueAxis.Format(Chart.ValueScale, Value(data))
});
}
return list;
}
/// <inheritdoc />
public override ScaleBase TransformValueScale(ScaleBase scale)
{
var stackedColumnSeries = ColumnSeries.Cast<IChartStackedColumnSeries>();
var count = stackedColumnSeries.Max(series => series.Count);
var sums = Enumerable.Range(0, count).Select(i => stackedColumnSeries.Sum(series => series.ValueAt(i)));
var max = sums.Max();
var min = Items.Min(Value);
scale.Input.MergeWidth(new ScaleRange { Start = min, End = max });
return scale;
}
}
}

View File

@@ -2,5 +2,5 @@
@if (Visible)
{
<input @ref="@Element" disabled="@Disabled" readonly="@ReadOnly" name="@Name" style="@Style" @attributes="Attributes" class="@GetCssClass()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")"
placeholder="@Placeholder" maxlength="@MaxLength" autocomplete="@(AutoComplete ? "on" : "off")" value="@Value" @onchange="@OnChange" id="@GetId()" />
placeholder="@Placeholder" maxlength="@MaxLength" autocomplete="@AutoCompleteAttribute" value="@Value" @onchange="@OnChange" id="@GetId()" />
}

View File

@@ -27,6 +27,17 @@ namespace Radzen.Blazor
[Parameter]
public bool AutoComplete { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
/// <see cref="Blazor.AutoCompleteType" />
/// </summary>
/// <value>
/// The type of built-in autocomplete.
/// </value>
[Parameter]
public AutoCompleteType AutoCompleteType { get; set; } = AutoCompleteType.On;
/// <summary>
/// Gets or sets the maximum allowed text length.
/// </summary>
@@ -68,5 +79,16 @@ namespace Radzen.Blazor
{
return GetClassList("rz-textbox").ToString();
}
/// <summary>
/// Gets the autocomplete attribute's string value.
/// </summary>
/// <value>
/// <c>off</c> if the AutoComplete parameter is false or the
/// AutoCompleteType parameter is "off". When the AutoComplete
/// parameter is true, the value is <c>on</c> or, if set, the value of
/// AutoCompleteType.</value>
public string AutoCompleteAttribute { get => !AutoComplete ? "off" :
AutoCompleteType.GetAutoCompleteValue(); }
}
}

View File

@@ -274,7 +274,14 @@ namespace Radzen.Blazor
});
}
}
/// <summary>
/// Clear the current selection to allow re-selection by mouse click
/// </summary>
public void ClearSelection()
{
SelectedItem?.Unselect();
SelectedItem = null;
}
internal async Task ExpandItem(RadzenTreeItem item)
{
var args = new TreeExpandEventArgs()

View File

@@ -1,7 +1,7 @@
@using Radzen
@using Radzen.Blazor.Rendering
@implements IDisposable
<li class="rz-treenode">
<li class="rz-treenode" @attributes="Attributes">
<div class=@ContentClassList @onclick="@Select">
@if (ChildContent != null || HasChildren)
{

View File

@@ -13,6 +13,9 @@ namespace Radzen.Blazor
/// </summary>
public partial class RadzenTreeItem : IDisposable
{
[Parameter(CaptureUnmatchedValues = true)]
public IReadOnlyDictionary<string, object> Attributes { get; set; }
ClassList ContentClassList => ClassList.Create("rz-treenode-content")
.Add("rz-treenode-content-selected", selected);
ClassList IconClassList => ClassList.Create("rz-tree-toggler rzi")

View File

@@ -0,0 +1,31 @@
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inherits SchedulerViewBase
@code {
public override RenderFragment Render()
{
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate);
var maxAppointmentsInSlot = 0;
if (MaxAppointmentsInSlot != null)
{
maxAppointmentsInSlot = MaxAppointmentsInSlot.Value;
}
else
{
var slotHeight = (Scheduler.Height - 60) / 12;
maxAppointmentsInSlot = Convert.ToInt32(Math.Floor(slotHeight / 16)) - 1;
}
return @<CascadingValue Value=@Scheduler>
<YearPlannerView StartDate=@StartDate
EndDate=@EndDate
MaxAppointmentsInSlot=@maxAppointmentsInSlot
MoreText=@MoreText
Appointments=@appointments />
</CascadingValue>;
}
}

View File

@@ -0,0 +1,83 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Drawing;
using System.Globalization;
namespace Radzen.Blazor
{
/// <summary>
/// Displays the appointments in a month day in <see cref="RadzenScheduler{TItem}" />
/// </summary>
/// <example>
/// <code>
/// &lt;RadzenScheduler Data="@appointments"&gt;
/// &lt;RadzenMonthView /&gt;
/// &lt;/RadzenScheduler&gt;
/// </code>
/// </example>
public partial class RadzenYearPlannerView : SchedulerViewBase
{
/// <inheritdoc />
public override string Icon => "view_list";
/// <inheritdoc />
public override string Title
{
get => Scheduler.CurrentDate.ToString("yyyy", Scheduler.Culture);
}
/// <inheritdoc />
[Parameter]
public override string Text { get; set; } = "Planner";
/// <summary>
/// Specifies the maximum appointnments to render in a slot.
/// </summary>
/// <value>The maximum appointments in slot.</value>
[Parameter]
public int? MaxAppointmentsInSlot { get; set; }
/// <summary>
/// Specifies the text displayed when there are more appointments in a slot than <see cref="MaxAppointmentsInSlot" />.
/// </summary>
/// <value>The more text. Set to <c>"+ {0} more"</c> by default.</value>
[Parameter]
public string MoreText { get; set; } = "+{0}";
/// <inheritdoc />
public override DateTime StartDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).StartOfWeek();
if (d.DayOfWeek == DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) d.AddDays(-7);
return d;
}
}
/// <inheritdoc />
public override DateTime EndDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).AddDays(DateTime.IsLeapYear(Scheduler.CurrentDate.Date.Year) ? 366 : 365).EndOfWeek();
return d;
}
}
/// <inheritdoc />
public override DateTime Next()
{
return Scheduler.CurrentDate.Date.AddYears(1);
}
/// <inheritdoc />
public override DateTime Prev()
{
return Scheduler.CurrentDate.Date.AddYears(-1);
}
}
}

View File

@@ -0,0 +1,31 @@
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inherits SchedulerViewBase
@code {
public override RenderFragment Render()
{
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate);
var maxAppointmentsInSlot = 0;
if (MaxAppointmentsInSlot != null)
{
maxAppointmentsInSlot = MaxAppointmentsInSlot.Value;
}
else
{
var slotHeight = 100.0;
maxAppointmentsInSlot = Convert.ToInt32(Math.Floor(slotHeight / 24)) - 1;
}
return @<CascadingValue Value=@Scheduler>
<YearTimelineView StartDate=@StartDate
EndDate=@EndDate
MaxAppointmentsInSlot=@maxAppointmentsInSlot
MoreText=@MoreText
Appointments=@appointments />
</CascadingValue>;
}
}

View File

@@ -0,0 +1,83 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Drawing;
using System.Globalization;
namespace Radzen.Blazor
{
/// <summary>
/// Displays the appointments in a month day in <see cref="RadzenScheduler{TItem}" />
/// </summary>
/// <example>
/// <code>
/// &lt;RadzenScheduler Data="@appointments"&gt;
/// &lt;RadzenMonthView /&gt;
/// &lt;/RadzenScheduler&gt;
/// </code>
/// </example>
public partial class RadzenYearTimelineView : SchedulerViewBase
{
/// <inheritdoc />
public override string Icon => "view_timeline";
/// <inheritdoc />
public override string Title
{
get => Scheduler.CurrentDate.ToString("yyyy", Scheduler.Culture);
}
/// <inheritdoc />
[Parameter]
public override string Text { get; set; } = "Timeline";
/// <summary>
/// Specifies the maximum appointnments to render in a slot.
/// </summary>
/// <value>The maximum appointments in slot.</value>
[Parameter]
public int? MaxAppointmentsInSlot { get; set; }
/// <summary>
/// Specifies the text displayed when there are more appointments in a slot than <see cref="MaxAppointmentsInSlot" />.
/// </summary>
/// <value>The more text. Set to <c>"+ {0} more"</c> by default.</value>
[Parameter]
public string MoreText { get; set; } = "+ {0} more";
/// <inheritdoc />
public override DateTime StartDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).StartOfWeek();
if (d.DayOfWeek == DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) d.AddDays(-7);
return d;
}
}
/// <inheritdoc />
public override DateTime EndDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).AddDays(DateTime.IsLeapYear(Scheduler.CurrentDate.Date.Year) ? 366 : 365).EndOfWeek();
return d;
}
}
/// <inheritdoc />
public override DateTime Next()
{
return Scheduler.CurrentDate.Date.AddYears(1);
}
/// <inheritdoc />
public override DateTime Prev()
{
return Scheduler.CurrentDate.Date.AddYears(-1);
}
}
}

View File

@@ -0,0 +1,17 @@
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inherits SchedulerViewBase
@code {
public override RenderFragment Render()
{
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate);
var maxAppointmentsInSlot = 0;
return @<CascadingValue Value=@Scheduler>
<YearView StartDate=@StartDate EndDate=@EndDate MaxAppointmentsInSlot=@maxAppointmentsInSlot MoreText=@MoreText Appointments=@appointments />
</CascadingValue>;
}
}

View File

@@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Globalization;
namespace Radzen.Blazor
{
/// <summary>
/// Displays the appointments in a month day in <see cref="RadzenScheduler{TItem}" />
/// </summary>
/// <example>
/// <code>
/// &lt;RadzenScheduler Data="@appointments"&gt;
/// &lt;RadzenMonthView /&gt;
/// &lt;/RadzenScheduler&gt;
/// </code>
/// </example>
public partial class RadzenYearView : SchedulerViewBase
{
/// <inheritdoc />
public override string Icon => "calendar_month";
/// <inheritdoc />
public override string Title
{
get => Scheduler.CurrentDate.ToString("yyyy", Scheduler.Culture);
}
/// <inheritdoc />
[Parameter]
public override string Text { get; set; } = "Year";
/// <summary>
/// Specifies the text displayed when there are more appointments in a slot than <see cref="MaxAppointmentsInSlot" />.
/// </summary>
/// <value>The more text. Set to <c>"+ {0} more"</c> by default.</value>
[Parameter]
public string MoreText { get; set; } = "+ {0} more";
/// <inheritdoc />
public override DateTime StartDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).StartOfWeek();
if (d.DayOfWeek == DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) d.AddDays(-7);
return d;
}
}
/// <inheritdoc />
public override DateTime EndDate
{
get
{
var d = new DateTime(Scheduler.CurrentDate.Date.Year, 1, 1).AddDays(DateTime.IsLeapYear(Scheduler.CurrentDate.Date.Year) ? 366 : 365).EndOfWeek();
return d;
}
}
/// <inheritdoc />
public override DateTime Next()
{
return Scheduler.CurrentDate.Date.AddYears(1);
}
/// <inheritdoc />
public override DateTime Prev()
{
return Scheduler.CurrentDate.Date.AddYears(-1);
}
}
}

View File

@@ -3,7 +3,10 @@
<div class="rz-event" style=@Style @onclick=@OnClick>
<div class="rz-event-content" title=@Data?.Text @attributes=@Attributes>
@Scheduler.RenderAppointment(Data)
@if (ShowAppointmentContent)
{
@Scheduler.RenderAppointment(Data)
}
</div>
</div>
@code {
@@ -27,6 +30,9 @@
[Parameter]
public AppointmentData Data { get; set; }
[Parameter]
public bool ShowAppointmentContent { get; set; } = true;
[CascadingParameter]
public IScheduler Scheduler { get; set; }

View File

@@ -1,6 +1,15 @@
<button tabindex="-1" @onclick=@OnClick class=@Class disabled=@(Editor.Disabled || Disabled) @onmousedown=@Empty @onmousedown:preventDefault @onclick:preventDefault title=@Title>
@if (PreventBlur)
{
<button tabindex="-1" @onclick=@OnClick class=@Class disabled=@(Editor.Disabled || Disabled || !EnabledModes.HasFlag(Editor.GetMode())) @onmousedown=@Empty @onmousedown:preventDefault @onclick:preventDefault title=@Title>
<i class="rzi">@Icon</i>
</button>
}
else
{
<button tabindex="-1" @onclick=@OnClick class=@Class disabled=@(Editor.Disabled || Disabled || !EnabledModes.HasFlag(Editor.GetMode())) title=@Title>
<i class="rzi">@Icon</i>
</button>
}
@code {
[CascadingParameter]
public RadzenHtmlEditor Editor { get; set; }
@@ -11,12 +20,18 @@
[Parameter]
public bool Disabled { get; set; }
[Parameter]
public bool PreventBlur { get; set; } = true;
[Parameter]
public bool Selected { get; set; }
[Parameter]
public string Icon { get; set; }
[Parameter]
public HtmlEditorMode EnabledModes { get; set; } = HtmlEditorMode.Design;
[Parameter]
public EventCallback Click { get; set; }
@@ -31,7 +46,7 @@
{
var classList = new List<string>() { "rz-html-editor-button" };
if (Selected && !Editor.Disabled)
if (Selected && !Editor.Disabled && EnabledModes.HasFlag(Editor.GetMode()))
{
classList.Add("rz-selected");
}

View File

@@ -1,11 +1,11 @@
<div title=@Title class="rz-html-editor-colorpicker" @onmousedown:preventDefault>
<button tabindex="-1" class="rz-html-editor-color" @onclick=@OnClick disabled=@Editor.Disabled @onclick:preventDefault>
<button tabindex="-1" class="rz-html-editor-color" @onclick=@OnClick disabled=@(Editor.Disabled || !EnabledModes.HasFlag(Editor.GetMode())) @onclick:preventDefault>
<i class="rzi">@Icon</i>
<div class="rz-html-editor-color-value" style="background-color:@Value"></div>
</button>
<RadzenColorPicker
@bind-Value=@Value Change=@OnChange @onclick:stopPropagation
Open=@OnOpen Disabled=@Editor.Disabled ShowHSV=@ShowHSV
<RadzenColorPicker
@bind-Value=@Value Change=@OnChange @onclick:stopPropagation
Open=@OnOpen Disabled=@(Editor.Disabled || !EnabledModes.HasFlag(Editor.GetMode())) ShowHSV=@ShowHSV
ShowRGBA=@ShowRGBA ShowColors=@ShowColors ShowButton=@ShowButton
HexText=@HexText RedText=@RedText GreenText=@GreenText BlueText=@BlueText AlphaText=@AlphaText
ButtonText=@ButtonText
@@ -30,6 +30,9 @@
[Parameter]
public string Value { get; set; }
[Parameter]
public HtmlEditorMode EnabledModes { get; set; } = HtmlEditorMode.Design;
[Parameter]
public bool ShowHSV { get; set; } = true;

View File

@@ -1,6 +1,6 @@
@inherits RadzenComponent
@using Microsoft.JSInterop
<div title=@Title @ref=@Element class=@Class @onclick=@Toggle @onmousedown:preventDefault @attributes=@Attributes>
<div title=@Title @ref=@Element class=@Class @onclick=@Toggle @onmousedown:preventDefault @attributes=@Attributes disabled=@(Editor.Disabled || !EnabledModes.HasFlag(Editor.GetMode()))>
<div class="rz-html-editor-dropdown-value">
@if (SelectedItem != null)
{
@@ -11,7 +11,7 @@
@Placeholder
}
</div>
<button @onclick:preventDefault tabindex="-1" class="rz-html-editor-dropdown-trigger" disabled=@Editor.Disabled><i class="rzi" /></button>
<button @onclick:preventDefault tabindex="-1" class="rz-html-editor-dropdown-trigger" disabled=@(Editor.Disabled || !EnabledModes.HasFlag(Editor.GetMode()))><i class="rzi" /></button>
<Popup @ref=Popup class="rz-html-editor-dropdown-items" Style=@PopupStyle>
<CascadingValue Value=@this>
@ChildContent
@@ -22,7 +22,7 @@
[CascadingParameter]
public RadzenHtmlEditor Editor { get; set; }
Popup Popup { get; set; }
Popup Popup { get; set; }
[Parameter]
public string Title { get; set; }
@@ -36,9 +36,12 @@
[Parameter]
public string Placeholder { get; set; }
[Parameter]
public HtmlEditorMode EnabledModes { get; set; } = HtmlEditorMode.Design;
async Task Toggle()
{
if (!Editor.Disabled)
if (!Editor.Disabled && EnabledModes.HasFlag(Editor.GetMode()))
{
await Popup.ToggleAsync(Element);
}
@@ -57,7 +60,7 @@
internal async Task Select(EditorDropDownItem item, bool change)
{
if (SelectedItem != item && !Editor.Disabled)
if (SelectedItem != item && !Editor.Disabled && EnabledModes.HasFlag(Editor.GetMode()))
{
SelectedItem = item;
@@ -78,7 +81,7 @@
{
var classList = new List<string>() { "rz-html-editor-dropdown" };
if (Editor.Disabled)
if (Editor.Disabled || !EnabledModes.HasFlag(Editor.GetMode()))
{
classList.Add("rz-disabled");
}

View File

@@ -7,7 +7,7 @@
@if (InPlotArea(x, y))
{
<Marker X="@x" Y="@y" Type="@MarkerType" Fill="@Fill" Stroke="@Stroke" StrokeWidth="@StrokeWidth" Size="@Size" />
<Marker Click="@(() => OnClick(data))" X="@x" Y="@y" Type="@MarkerType" Fill="@Fill" Stroke="@Stroke" StrokeWidth="@StrokeWidth" Size="@Size" />
}
}
@@ -15,12 +15,20 @@
[CascadingParameter]
public RadzenChart Chart { get; set;}
[Parameter]
public IChartSeries Series { get; set; }
private async Task OnClick(TItem data)
{
await Series.InvokeClick(Chart.SeriesClick, data);
}
[Parameter]
public IEnumerable<TItem> Data { get; set; }
[Parameter]
public Func<TItem, double> Category { get; set; }
[Parameter]
public Func<TItem, double> Value { get; set; }

View File

@@ -18,17 +18,18 @@
style.Append($"fill: {Fill};");
}
if (StrokeWidth != null)
if (StrokeWidth >= 0)
{
style.Append($"stroke-width: {StrokeWidth.ToInvariantString()};");
}
if (Style != null)
if (!string.IsNullOrEmpty(Style))
{
foreach (var value in Style.Split(';'))
if (style.Length > 0)
{
style.Append(value);
style.Append(";");
}
style.Append(Style);
}
return style.ToString();

View File

@@ -1,6 +1,6 @@
@inherits RadzenComponent
@using Microsoft.JSInterop
<div @ref=@Element @onmousedown:preventDefault @attributes=@Attributes style=@Style id=@GetId()>
<div @ref=@Element @attributes=@Attributes style=@Style id=@GetId()>
@if (open || !Lazy)
{
@ChildContent

View File

@@ -0,0 +1,233 @@
@using Radzen
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inject DialogService DialogService
@{
var points = new Dictionary<AppointmentData, double>();
var startyear = StartDate.AddDays(7).Year;
DateTime date = StartDate;
DateTime realstart = StartDate;
int daysinmonth;
const double NUMBER_DAYS_COLUMNS = 38.0;
}
<div class="rz-view rz-planner-view">
<div class="rz-view-header">
<div class="rz-slot-header">
</div>
@for (var dateheader = StartDate; dateheader <= StartDate.AddDays(NUMBER_DAYS_COLUMNS - 1); dateheader = dateheader.AddDays(1))
{
<div class="rz-slot-header">
@dateheader.ToString("dddd", Scheduler.Culture).Substring(0,3)
</div>
}
<div class="rz-slot-header">
</div>
</div>
@for (int month = 1; month < 13; month++)
{
realstart = new DateTime(startyear, month, 1);
daysinmonth = DateTime.DaysInMonth(startyear, month);
date = realstart.StartOfMonth().StartOfWeek();
<div class="rz-month">
<div class="rz-events">
@for (var start = date; start < date.AddDays(NUMBER_DAYS_COLUMNS); start = start.AddDays(1))
{
var end = start.AddDays(1);
var appointments = AppointmentsInSlot(start, end);
var excessCount = appointments.Count() - MaxAppointmentsInSlot;
var existingTops = ExistingTops(points, appointments.Take(MaxAppointmentsInSlot));
if (start.Month == month)
{
@foreach (var item in appointments.Take(MaxAppointmentsInSlot))
{
var startSlotIndex = realstart.Subtract(date).Days + 1;
var slotIndex = startSlotIndex + item.Start.Date.Subtract(realstart).Days;
var slotWidth = 100 / 40.0;
var left = slotIndex * slotWidth;
var length = Math.Max(1, Math.Ceiling(item.End.Subtract(realstart).TotalDays) - (slotIndex - startSlotIndex));
var width = item.End <= realstart.AddDays(daysinmonth - 1) ? (length) * slotWidth : (daysinmonth + startSlotIndex - slotIndex) * slotWidth;
if (!points.TryGetValue(item, out var top))
{
top = DetermineTop(existingTops);
points.Add(item, top);
existingTops.Add(top);
}
var height = 0.6;
var data = item;
@if (item.Start >= realstart && item.Start <= end)
{
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false />
}
else if (realstart == start)
{
left = startSlotIndex * slotWidth;
length = Math.Max(1, Math.Min(daysinmonth, Math.Ceiling(item.End.Subtract(date).TotalDays - (startSlotIndex - 1))));
width = length * slotWidth;
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false />
}
}
@if (excessCount > 0)
{
var slotIndex = start.Subtract(date).Days;
var slotWidth = 100 / 40.0;
var left = (slotIndex + 1) * slotWidth;
var top = ((MaxAppointmentsInSlot + 1) * 0.6) + 1.3;
var listDate = start;
<a class="rz-event-list-btn" style="top: @(top.ToInvariantString())em; left: @(left.ToInvariantString())%" @onclick=@(args => OnListClick(listDate, appointments))>@String.Format(MoreText, excessCount)</a>
}
}
}
</div>
<div class="rz-slots">
<div @attributes=@Attributes(realstart, "rz-slot")>
<div class="rz-slot-header">
@realstart.ToString("MMM", Scheduler.Culture)
</div>
</div>
@for (var day = 0; day < NUMBER_DAYS_COLUMNS; day++)
{
string dayType = "";
var dayOfWeek = date.AddDays(day);
bool slotInMonth = dayOfWeek.Month == month;
dayType = dayOfWeek.DayOfWeek == DayOfWeek.Saturday || dayOfWeek.DayOfWeek == DayOfWeek.Sunday ? "rz-weekend" : "";
dayType = dayOfWeek.Month != month ? "rz-other-month" : dayType;
@if (slotInMonth)
{
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"))>
<div class="rz-slot-title">
@if (dayOfWeek.Month == month)
{
@dayOfWeek.Day
}
</div>
</div>
}
else
{
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"))>
<div class="rz-slot-title">
@if (dayOfWeek.Month == month)
{
@dayOfWeek.Day
}
</div>
</div>
}
}
<div @attributes=@Attributes(realstart, "rz-slot")>
<div class="rz-slot-header">
@realstart.ToString("MMM", Scheduler.Culture)
</div>
</div>
</div>
</div>
}
</div>
@code {
[Parameter]
public DateTime StartDate { get; set; }
[Parameter]
public DateTime EndDate { get; set; }
[Parameter]
public int MaxAppointmentsInSlot { get; set; }
[Parameter]
public string MoreText { get; set; }
[CascadingParameter]
public IScheduler Scheduler { get; set; }
[Parameter]
public IEnumerable<AppointmentData> Appointments { get; set; }
IDictionary<string, object> Attributes(DateTime start, string className)
{
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
return attributes;
}
async Task OnSlotClick(DateTime date)
{
await Scheduler.SelectSlot(date, date.AddDays(1));
}
double DetermineTop(HashSet<double> existingTops)
{
var top = 1.2;
while (existingTops.Contains(top))
{
top += 0.6;
}
return top;
}
HashSet<double> ExistingTops(IDictionary<AppointmentData, double> tops, IEnumerable<AppointmentData> appointments)
{
var existingTops = new HashSet<double>();
foreach (var appointment in appointments)
{
if (tops.TryGetValue(appointment, out var existingTop))
{
existingTops.Add(existingTop);
}
}
return existingTops;
}
async Task OnAppointmentClick(AppointmentData data)
{
await Scheduler.SelectAppointment(data);
}
private AppointmentData[] AppointmentsInSlot(DateTime start, DateTime end)
{
if (Appointments == null)
{
return Array.Empty<AppointmentData>();
}
return Appointments.Where(item => Scheduler.IsAppointmentInRange(item, start, end)).OrderBy(item => item.Start).ThenByDescending(item => item.End).ToArray();
}
async Task OnListClick(DateTime date, IEnumerable<AppointmentData> appointments)
{
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
@<div class="rz-event-list">
<CascadingValue Value=@Scheduler>
@foreach (var item in appointments)
{
<Appointment Data=@item Click="OnListEventClick" />
}
</CascadingValue>
</div>);
}
async Task OnListEventClick(AppointmentData data)
{
DialogService.Close();
await OnAppointmentClick(data);
}
}

View File

@@ -0,0 +1,226 @@
@using Radzen
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inject DialogService DialogService
@{
var points = new Dictionary<AppointmentData, double>();
var startyear = StartDate.AddDays(7).Year;
DateTime date = StartDate;
DateTime realstart = StartDate;
int daysinmonth;
const double NUMBER_DAYS_COLUMNS = 37.0;
const double SLOT_WIDTH = 100.0;
const double CALENDAR_WIDTH = 3800.0;
}
<div class="rz-view rz-timeline-view">
<div class="rz-view-header">
<div class="rz-slot-header">
</div>
@for (var dateheader = StartDate; dateheader <= StartDate.AddDays(NUMBER_DAYS_COLUMNS - 1); dateheader = dateheader.AddDays(1))
{
<div class="rz-slot-header">
@dateheader.ToString("dddd", Scheduler.Culture)
</div>
}
</div>
@for (int month = 1; month < 13; month++)
{
realstart = new DateTime(startyear, month, 1);
daysinmonth = DateTime.DaysInMonth(startyear, month);
date = realstart.StartOfMonth().StartOfWeek();
<div class="rz-month">
<div class="rz-events">
@for (var start = date; start < date.AddDays(NUMBER_DAYS_COLUMNS); start = start.AddDays(1))
{
var end = start.AddDays(1);
var appointments = AppointmentsInSlot(start, end);
var excessCount = appointments.Count() - MaxAppointmentsInSlot;
var existingTops = ExistingTops(points, appointments.Take(MaxAppointmentsInSlot));
if (start.Month == month)
{
@foreach (var item in appointments.Take(MaxAppointmentsInSlot))
{
var startSlotIndex = realstart.Subtract(date).Days + 1;
var slotIndex = startSlotIndex + item.Start.Date.Subtract(realstart).Days;
var slotWidth = (SLOT_WIDTH / CALENDAR_WIDTH) * 100;
var left = slotIndex * slotWidth;
var length = Math.Max(1, Math.Ceiling(item.End.Subtract(realstart).TotalDays) - (slotIndex - startSlotIndex));
var width = item.End <= realstart.AddDays(daysinmonth - 1) ? (length) * slotWidth : (daysinmonth + startSlotIndex - slotIndex) * slotWidth;
if (!points.TryGetValue(item, out var top))
{
top = DetermineTop(existingTops);
points.Add(item, top);
existingTops.Add(top);
}
var height = 1.5;
var data = item;
@if (item.Start >= realstart && item.Start <= end)
{
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick />
}
else if (realstart == start)
{
left = startSlotIndex * slotWidth;
length = Math.Max(1, Math.Min(daysinmonth, Math.Ceiling(item.End.Subtract(date).TotalDays - (startSlotIndex - 1))));
width = length * slotWidth;
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick />
}
}
}
@if (excessCount > 0)
{
var slotIndex = start.Subtract(date).Days;
var slotWidth = (SLOT_WIDTH / CALENDAR_WIDTH) * 100;
var left = ((slotIndex + 1) * slotWidth) + (100.0 / 85.0);
var top = ((MaxAppointmentsInSlot + 1) * 1.5) + 1.7;
var listDate = start;
<a class="rz-event-list-btn" style="top: @(top.ToInvariantString())em; left: @(left.ToInvariantString())%" @onclick=@(args => OnListClick(listDate, appointments))>@String.Format(MoreText, excessCount)</a>
}
}
</div>
<div class="rz-slots">
<div @attributes=@Attributes(realstart, "rz-slot")>
<div class="rz-slot-header">
@realstart.ToString("MMMM", Scheduler.Culture)
</div>
</div>
@for (var day = 0; day < NUMBER_DAYS_COLUMNS; day++)
{
string dayType = "";
var dayOfWeek = date.AddDays(day);
bool slotInMonth = dayOfWeek.Month == month;
dayType = dayOfWeek.DayOfWeek == DayOfWeek.Saturday || dayOfWeek.DayOfWeek == DayOfWeek.Sunday ? "rz-weekend" : "";
dayType = dayOfWeek.Month != month ? "rz-other-month" : dayType;
@if (slotInMonth)
{
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"))>
<div class="rz-slot-title">
@if (dayOfWeek.Month == month)
{
@dayOfWeek.Day
}
</div>
</div>
}
else
{
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"))>
<div class="rz-slot-title">
@if (dayOfWeek.Month == month)
{
@dayOfWeek.Day
}
</div>
</div>
}
}
</div>
</div>
}
</div>
@code {
[Parameter]
public DateTime StartDate { get; set; }
[Parameter]
public DateTime EndDate { get; set; }
[Parameter]
public int MaxAppointmentsInSlot { get; set; }
[Parameter]
public string MoreText { get; set; }
[CascadingParameter]
public IScheduler Scheduler { get; set; }
[Parameter]
public IEnumerable<AppointmentData> Appointments { get; set; }
IDictionary<string, object> Attributes(DateTime start, string className)
{
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
return attributes;
}
async Task OnSlotClick(DateTime date)
{
await Scheduler.SelectSlot(date, date.AddDays(1));
}
double DetermineTop(HashSet<double> existingTops)
{
var top = 1.5;
while (existingTops.Contains(top))
{
top += 1.5;
}
return top;
}
HashSet<double> ExistingTops(IDictionary<AppointmentData, double> tops, IEnumerable<AppointmentData> appointments)
{
var existingTops = new HashSet<double>();
foreach (var appointment in appointments)
{
if (tops.TryGetValue(appointment, out var existingTop))
{
existingTops.Add(existingTop);
}
}
return existingTops;
}
async Task OnAppointmentClick(AppointmentData data)
{
await Scheduler.SelectAppointment(data);
}
private AppointmentData[] AppointmentsInSlot(DateTime start, DateTime end)
{
if (Appointments == null)
{
return Array.Empty<AppointmentData>();
}
return Appointments.Where(item => Scheduler.IsAppointmentInRange(item, start, end)).OrderBy(item => item.Start).ThenByDescending(item => item.End).ToArray();
}
async Task OnListClick(DateTime date, IEnumerable<AppointmentData> appointments)
{
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
@<div class="rz-event-list">
<CascadingValue Value=@Scheduler>
@foreach (var item in appointments)
{
<Appointment Data=@item Click="OnListEventClick" />
}
</CascadingValue>
</div>);
}
async Task OnListEventClick(AppointmentData data)
{
DialogService.Close();
await OnAppointmentClick(data);
}
}

View File

@@ -0,0 +1,193 @@
@using Radzen
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inject DialogService DialogService
@{
var points = new Dictionary<AppointmentData, double>();
// delaci check usage
var year = StartDate.AddDays(7).Year;
DateTime date = StartDate.AddDays(7);
DateTime realstart = StartDate;
int daysinmonth;
}
<div class="rz-view rz-year-view">
<div class="rz-display-flex rz-row rz-align-items-normal rz-justify-content-space-between">
@for (int month = 1; month < 13; month++)
{
realstart = new DateTime(year, month, 1);
daysinmonth = DateTime.DaysInMonth(year, month);
date = realstart.StartOfMonth().StartOfWeek();
<div class="rz-display-flex rz-flex-column rz-col-12 rz-col-sm-6 rz-col-md-4 rz-col-lg-3">
<div class="rz-slot-header rz-pb-2">
<span class="rz-text-subtitle1">
@realstart.ToString("MMMM yyyy")
</span>
</div>
<div class="rz-view-header">
@for (var dateheader = StartDate; dateheader <= StartDate.EndOfWeek(); dateheader = dateheader.AddDays(1))
{
<div class="rz-slot-header">
@dateheader.ToString("ddd", Scheduler.Culture).Substring(0,1)
</div>
}
</div>
@for (var row = 0; row < 6; row++)
{
<div class="rz-week">
<div class="rz-events">
<div class="rz-slots">
@for (var col = 0; col < 7; col++)
{
var day = date.AddDays((row * 7) + col);
var appointments = AppointmentsInSlot(day, day.AddDays(1));
var excessCount = appointments.Count();
string classname;
@if (day.Month != month)
{
if (excessCount > 0)
{
classname = "rz-slot-title rz-other-month rz-has-appointments";
<div @onclick=@(args => OnListClick(day, appointments)) @attributes=@Attributes(day, "rz-slot")>
<div class="@classname">
@day.Day
</div>
</div>
}
else
{
classname = "rz-slot-title rz-other-month";
<div @onclick=@(args => OnListClick(day, appointments)) @attributes=@Attributes(day, "rz-slot")>
<div class="@classname">
@day.Day
</div>
</div>
}
}
else
{
if (excessCount > 0)
{
classname = "rz-slot-title rz-has-appointments";
<div @onclick=@(args => OnListClick(day, appointments)) @attributes=@Attributes(day, "rz-slot")>
<div class="@classname">
@day.Day
</div>
</div>
}
else
{
classname = "rz-slot-title";
<div @onclick=@(args => OnListClick(day, appointments)) @attributes=@Attributes(day, "rz-slot")>
<div class="@classname">
@day.Day
</div>
</div>
}
}
}
</div>
</div>
</div>
}
</div>
}
</div>
</div>
<style>
</style>
@code {
[Parameter]
public DateTime StartDate { get; set; }
[Parameter]
public DateTime EndDate { get; set; }
[Parameter]
public int MaxAppointmentsInSlot { get; set; }
[Parameter]
public string MoreText { get; set; }
[CascadingParameter]
public IScheduler Scheduler { get; set; }
[Parameter]
public IEnumerable<AppointmentData> Appointments { get; set; }
IDictionary<string, object> Attributes(DateTime start, string className)
{
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
return attributes;
}
async Task OnSlotClick(DateTime date)
{
await Scheduler.SelectSlot(date, date.AddDays(1));
}
async Task OnAppointmentClick(AppointmentData data)
{
await Scheduler.SelectAppointment(data);
}
private AppointmentData[] AppointmentsInSlot(DateTime start, DateTime end)
{
if (Appointments == null)
{
return Array.Empty<AppointmentData>();
}
return Appointments.Where(item => Scheduler.IsAppointmentInRange(item, start, end)).OrderBy(item => item.Start).ThenByDescending(item => item.End).ToArray();
}
async Task OnListClick(DateTime date, IEnumerable<AppointmentData> appointments)
{
if (appointments.Count() > 0)
{
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
@<div class="rz-event-list">
<CascadingValue Value=@Scheduler>
@foreach (var item in appointments)
{
<Appointment Data=@item Click="OnListEventClick" />
}
</CascadingValue>
</div>
);
}
else
{
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
@<div class="rz-event-list">
There are no scheduled events taking place on this day
</div>
);
}
}
async Task OnListEventClick(AppointmentData data)
{
DialogService.Close();
await OnAppointmentClick(data);
}
}

View File

@@ -96,10 +96,12 @@ namespace Radzen.Blazor
private void ValidateField(object sender, FieldChangedEventArgs args)
{
var component = Form.FindComponent(Component);
if (args.FieldIdentifier.FieldName == component?.FieldIdentifier.FieldName)
if (component != null)
{
ValidateModel(sender, ValidationRequestedEventArgs.Empty);
if (args.FieldIdentifier.Equals(component.FieldIdentifier))
{
ValidateModel(sender, ValidationRequestedEventArgs.Empty);
}
}
}
@@ -169,4 +171,4 @@ namespace Radzen.Blazor
}
}
}
}
}

View File

@@ -24,6 +24,18 @@
}
}
@mixin rz-utility-list-breakpoints-css($property, $list, $breakpoints) {
@each $breakpoint, $breakpoint-value in $breakpoints {
@media (min-width: #{$breakpoint-value}) {
@each $value in $list {
.rz-#{$property}-#{$breakpoint}-#{$value} {
#{$property}: #{$value} !important;
}
}
}
}
}
@mixin rz-ripple($ripple-background: rgba(0,0,0,.12), $pseudo: false) {
@if $pseudo == true {

View File

@@ -11,12 +11,15 @@ $button-hover-shadow: inset 0 -3px 0 0 rgba(255, 255, 255, 0.2) !default;
$button-hover-gradient: linear-gradient(rgba(#fff, 0.1), rgba(#fff, 0.1)) !default;
$button-hover-background-size: $button-background-size !default;
$button-focus-shadow: inset 0 -3px 0 0 rgba(255, 255, 255, 0.2) !default;
$button-focus-gradient: linear-gradient(rgba(#fff, 0.1), rgba(#fff, 0.1)) !default;
$button-focus-background-size: $button-background-size !default;
$button-focus-outline: none !default;
$button-active-shadow: inset 0 3px 0 0 rgba(0, 0, 0, 0.1) !default;
$button-active-gradient: linear-gradient(rgba(#000, 0.1), rgba(#000, 0.1)) !default;
$button-active-background-size: $button-background-size !default;
$button-focus-outline: none !default;
$button-disabled-opacity: 0.2 !default;
$button-sizes: () !default;
@@ -157,20 +160,23 @@ $button-styles: map-merge(
:root {
--rz-button-base-background-color: #{$button-base-background-color};
--rz-button-base-color: #{$button-base-color};
--rz-button-hover-shadow: #{$button-hover-shadow};
--rz-button-hover-gradient: #{$button-hover-gradient};
--rz-button-active-shadow: #{$button-active-shadow};
--rz-button-active-gradient: #{$button-active-gradient};
--rz-button-focus-outline: #{$button-focus-outline};
--rz-button-background-size: #{$button-background-size};
--rz-button-border-radius: #{$button-border-radius};
--rz-button-shadow: #{$button-shadow};
--rz-button-transition: #{$button-transition};
--rz-button-disabled-opacity: #{$button-disabled-opacity};
--rz-button-line-height: #{$button-line-height};
--rz-button-vertical-align: #{$button-vertical-align};
--rz-button-background-size: #{$button-background-size};
--rz-button-hover-shadow: #{$button-hover-shadow};
--rz-button-hover-gradient: #{$button-hover-gradient};
--rz-button-hover-background-size: #{$button-hover-background-size};
--rz-button-focus-shadow: #{$button-focus-shadow};
--rz-button-focus-gradient: #{$button-focus-gradient};
--rz-button-focus-background-size: #{$button-focus-background-size};
--rz-button-focus-outline: #{$button-focus-outline};
--rz-button-active-shadow: #{$button-active-shadow};
--rz-button-active-gradient: #{$button-active-gradient};
--rz-button-active-background-size: #{$button-active-background-size};
--rz-button-disabled-opacity: #{$button-disabled-opacity};
}
.rz-button {
@@ -205,6 +211,15 @@ $button-styles: map-merge(
}
}
&:focus {
&:not(:active) {
text-decoration: none;
background-image: var(--rz-button-focus-gradient);
background-size: var(--rz-button-focus-background-size);
box-shadow: var(--rz-button-focus-shadow);
}
}
&:active {
text-decoration: none;
background-image: var(--rz-button-active-gradient);
@@ -315,6 +330,7 @@ $button-styles: map-merge(
background-color: transparent;
&:not(.rz-state-disabled):hover:not(:active),
&:not(.rz-state-disabled):focus:not(:active),
&:not(.rz-state-disabled):active {
&.rz-shade-lighter {
color: var(--rz-#{$style})
@@ -366,6 +382,7 @@ $button-styles: map-merge(
box-shadow: none;
&:not(.rz-state-disabled):hover:not(:active),
&:not(.rz-state-disabled):focus:not(:active),
&:not(.rz-state-disabled):active {
&.rz-shade-lighter {
color: var(--rz-#{$style})

View File

@@ -76,36 +76,6 @@ $chart-color-schemes: (
--rz-chart-tooltip-color: #{$chart-tooltip-color};
}
.chart,
.pie {
height: 200px;
.ngx-charts {
overflow: visible !important;
.gridline-path {
stroke: var(--rz-chart-axis-color);
}
}
.chart-legend {
.legend-labels {
background-color: transparent;
}
}
.legend-title {
display: none;
}
.tick {
text {
fill: var(--rz-chart-axis-label-color);
font-size: var(--rz-chart-axis-font-size) !important;
}
}
}
.rz-chart {
position: relative;
height: 300px;

View File

@@ -58,8 +58,8 @@ $colorpicker-input-labels-color: var(--rz-text-tertiary-color) !default;
@extend %input;
&.rz-disabled {
color: var(--rz-text-color);
&.rz-state-disabled {
@extend %input-disabled;
cursor: default;
}
}
@@ -80,6 +80,11 @@ button.rz-colorpicker-trigger {
content: 'arrow_drop_down';
}
}
.rz-state-disabled & {
color: var(--rz-input-disabled-color);
}
}
.rz-colorpicker-popup {

View File

@@ -79,6 +79,7 @@ $multiselect-checkbox-margin: 0 0.5rem 0 0 !default;
flex-direction: column;
position: relative;
overflow: hidden;
text-align: start;
@extend %input;

View File

@@ -43,6 +43,19 @@ $editor-content-background-color: var(--rz-base-background-color) !default;
background-color: var(--rz-editor-content-background-color);
}
.rz-html-editor-source.rz-textarea {
--rz-input-hover-shadow: none;
--rz-input-border: none;
--rz-input-hover-border: none;
--rz-input-focus-shadow: none;
--rz-input-focus-border: none;
flex: 1;
padding: 0.5rem;
overflow: auto;
outline: none;
background-color: var(--rz-editor-content-background-color);
}
.rz-html-editor-toolbar {
border-bottom: var(--rz-editor-border);
display: flex;
@@ -206,19 +219,15 @@ $editor-content-background-color: var(--rz-base-background-color) !default;
background-color: var(--rz-editor-separator-background-color);
}
.rz-html-editor-toolbar {
.rz-html-editor-colorpicker {
.rz-colorpicker {
&:not(:disabled):not(.rz-state-disabled):hover {
border: none;
}
}
.rz-colorpicker-trigger {
.rzi {
font-size: 1.25rem;

View File

@@ -776,11 +776,36 @@ $column-draggable-shadow: 0 8px 10px 0 rgba(0, 0, 0, 0.1) !default;
td,
.rz-cell-data {
transition: background-color var(--rz-transition), color var(--rz-transition);
&.rz-frozen-cell {
&:before,
&:after {
content: "";
position: absolute;
inset: 0;
transition: background-color var(--rz-transition), color var(--rz-transition);
}
&:before {
z-index: -1;
}
&:after {
z-index: -2;
background-color: var(--rz-grid-frozen-cell-background-color);
}
}
}
&.rz-state-highlight {
> td {
background-color: var(--rz-grid-selected-background-color);
&.rz-frozen-cell {
&:before {
background-color: var(--rz-grid-selected-background-color);
}
}
}
.rz-cell-data {
@@ -799,8 +824,14 @@ $column-draggable-shadow: 0 8px 10px 0 rgba(0, 0, 0, 0.1) !default;
&:hover {
&:not(.rz-state-highlight) {
> td:not(.rz-frozen-cell) {
> td {
background-color: var(--rz-grid-hover-background-color);
&.rz-frozen-cell {
&:before {
background-color: var(--rz-grid-hover-background-color);
}
}
}
.rz-cell-data {

View File

@@ -4,7 +4,6 @@
cursor: pointer;
.rz-link-text {
vertical-align: middle;
text-decoration: var(--rz-link-text-decoration)
}

View File

@@ -41,6 +41,7 @@ $listbox-header-icon-margin: 0 !default;
background-color: var(--rz-listbox-background-color);
border: var(--rz-listbox-border);
border-radius: var(--rz-listbox-border-radius);
text-align: start;
.rz-chkbox {
margin: var(--rz-listbox-checkbox-margin);

View File

@@ -80,8 +80,6 @@ $paginator-button-size: ".rz-button-md" !default;
--rz-paginator-summary-padding: #{$paginator-summary-padding};
--rz-paginator-summary-font-size: #{$paginator-summary-font-size};
--rz-paginator-summary-color: #{$paginator-summary-color};
--rz-paginator-button-size: #{$paginator-button-size};
}
.rz-paginator {
@@ -318,3 +316,19 @@ $paginator-button-size: ".rz-button-md" !default;
margin: 0 !important;
}
}
// Density
.rz-paginator {
&.rz-density-compact {
--rz-paginator-padding: 0.25rem;
--rz-paginator-numeric-button-margin: 0 0.125rem;
--rz-paginator-first-button-margin: 0 0.25rem 0 0;
--rz-paginator-last-button-margin: 0 0 0 0.25rem;
--rz-paginator-dropdown-margin: 0 0 0 0.25rem;
--rz-paginator-summary-padding: 0 0.5rem 0 0;
.rz-paginator-element {
@extend .rz-button-sm;
}
}
}

View File

@@ -39,6 +39,7 @@ $scheduler-view-selected-border-color: $scheduler-view-selected-background-color
$scheduler-header-background-color: var(--rz-base-200) !default;
$scheduler-header-font-size: 0.75rem !default;
$scheduler-header-font-size-small: 0.5rem !default;
$scheduler-header-text-transform: uppercase !default;
$scheduler-header-color: inherit !default;
$scheduler-header-border: var(--rz-border-normal) !default;
@@ -55,10 +56,26 @@ $scheduler-event-list-button-color: var(--rz-secondary);
$scheduler-event-list-button-font-size: 0.75rem;
$scheduler-slot-title-font-size: 0.875rem !default;
$scheduler-slot-title-font-size-small: 0.6rem !default;
$scheduler-slot-title-padding: 0 0.25rem !default;
$scheduler-day-number-padding: 0 0.5rem !default;
$scheduler-weekend-color: var(--rz-text-disabled-color) !default;
$scheduler-weekend-background-color: var(--rz-base-50) !default;
$scheduler-other-month-background-color: var(--rz-base-100) !default;
$scheduler-timeline-slot-width: 7rem !default;
$scheduler-timeline-slot-height: 7rem !default;
$scheduler-year-padding: 1.5rem !default;
$scheduler-year-slot-padding: 1px !default;
$scheduler-year-slot-title-width: 100% !default;
$scheduler-year-slot-title-border-radius: 0.25rem !default;
$scheduler-planner-slot-width: 3rem !default;
$scheduler-planner-slot-height: 4.5rem !default;
// Scheduler CSS variables
:root {
@@ -98,6 +115,7 @@ $scheduler-day-number-padding: 0 0.5rem !default;
--rz-scheduler-header-background-color: #{$scheduler-header-background-color};
--rz-scheduler-header-font-size: #{$scheduler-header-font-size};
--rz-scheduler-header-font-size-small: #{$scheduler-header-font-size-small};
--rz-scheduler-header-text-transform: #{$scheduler-header-text-transform};
--rz-scheduler-header-color: #{$scheduler-header-color};
--rz-scheduler-header-border: #{$scheduler-header-border};
@@ -114,9 +132,25 @@ $scheduler-day-number-padding: 0 0.5rem !default;
--rz-scheduler-event-list-button-font-size: #{$scheduler-event-list-button-font-size};
--rz-scheduler-slot-title-font-size: #{$scheduler-slot-title-font-size};
--rz-scheduler-slot-title-font-size-small: #{$scheduler-slot-title-font-size-small};
--rz-scheduler-slot-title-padding: #{$scheduler-slot-title-padding};
--rz-scheduler-day-number-padding: #{$scheduler-day-number-padding};
--rz-scheduler-weekend-color: #{$scheduler-weekend-color};
--rz-scheduler-weekend-background-color: #{$scheduler-weekend-background-color};
--rz-scheduler-other-month-background-color: #{$scheduler-other-month-background-color};
--rz-scheduler-timeline-slot-width: #{$scheduler-timeline-slot-width};
--rz-scheduler-timeline-slot-height: #{$scheduler-timeline-slot-height};
--rz-scheduler-year-padding: #{$scheduler-year-padding};
--rz-scheduler-year-slot-padding: #{$scheduler-year-slot-padding};
--rz-scheduler-year-slot-title-width: #{$scheduler-year-slot-title-width};
--rz-scheduler-year-slot-title-border-radius: #{$scheduler-year-slot-title-border-radius};
--rz-scheduler-planner-slot-width: #{$scheduler-planner-slot-width};
--rz-scheduler-planner-slot-height: #{$scheduler-planner-slot-height};
}
.rz-scheduler {
@@ -152,6 +186,12 @@ $scheduler-day-number-padding: 0 0.5rem !default;
border-left: 1px solid var(--rz-scheduler-border-color);
}
.rz-slot-title {
text-align: right;
font-size: var(--rz-scheduler-slot-title-font-size);
padding: var(--rz-scheduler-slot-title-padding);
}
.rz-slot-hours {
.rz-slot-header {
height: 1.5rem;
@@ -178,6 +218,7 @@ $scheduler-day-number-padding: 0 0.5rem !default;
.rz-event {
position: absolute;
padding: var(--rz-scheduler-event-padding);
cursor: pointer;
}
.rz-event-content {
@@ -195,20 +236,6 @@ $scheduler-day-number-padding: 0 0.5rem !default;
position: relative;
}
.rz-month-view {
.rz-view-content {
flex: 1;
display: flex;
flex-direction: column;
}
}
.rz-slot-title {
text-align: right;
font-size: var(--rz-scheduler-slot-title-font-size);
padding: var(--rz-scheduler-slot-title-padding);
}
.rz-scheduler-nav {
display: flex;
flex-wrap: wrap;
@@ -259,55 +286,11 @@ $scheduler-day-number-padding: 0 0.5rem !default;
height: 0;
}
.rz-week-view-content {
flex: 1;
display: flex;
}
.rz-slots {
flex: 1;
font-size: 1rem;
}
.rz-week {
flex: 1;
font-size: 1rem;
.rz-slots {
display: flex;
height: 100%;
}
&:first-child .rz-slot {
border-top: none;
}
}
.rz-month-view {
.rz-slot {
flex: 1;
height: 100%;
&:first-child {
border-left: none;
}
}
}
.rz-day-view,
.rz-week-view {
.rz-slot:nth-of-type(2) {
border-top: none;
}
}
.rz-week-view,
.rz-day-view {
.rz-view-header {
padding-right: 15px;
}
}
.rz-scheduler-nav-views {
display: flex;
@@ -371,6 +354,260 @@ $scheduler-day-number-padding: 0 0.5rem !default;
}
}
// Week range slots
.rz-week {
flex: 1;
font-size: 1rem;
.rz-slots {
display: flex;
height: 100%;
}
&:first-child .rz-slot {
border-top: none;
}
}
// Month range slots
.rz-month {
flex: 1;
font-size: 1rem;
.rz-slots {
display: flex;
height: 100%;
}
&:nth-child(2) .rz-slot {
border-top: none;
}
.rz-slot {
flex: 1;
height: 100%;
display: flex;
border-top: 1px solid var(--rz-scheduler-border-color);
border-left: 1px solid var(--rz-scheduler-border-color);
&:first-child {
position: sticky;
z-index: 9998;
left: 0;
justify-content: center;
align-items: center;
background-color: var(--rz-scheduler-header-background-color);
border-left: none;
border-right: 1px solid var(--rz-scheduler-border-color);
.rz-slot-header {
text-align: center;
font-size: var(--rz-scheduler-header-font-size);
padding: var(--rz-scheduler-header-padding);
text-transform: var(--rz-scheduler-header-text-transform);
color: var(--rz-scheduler-header-color);
}
}
&:nth-child(2) {
border-left: none;
}
}
}
// Day View
.rz-day-view{
.rz-slot:nth-of-type(2) {
border-top: none;
}
.rz-view-header {
padding-right: 15px;
}
}
// Week View
.rz-week-view-content {
flex: 1;
display: flex;
}
.rz-week-view {
.rz-slot:nth-of-type(2) {
border-top: none;
}
.rz-view-header {
padding-right: 15px;
}
}
// Month View
.rz-month-view {
.rz-view-content {
flex: 1;
flex-direction: column;
}
.rz-slot {
flex: 1;
height: 100%;
&:first-child {
border-left: none;
}
}
}
// Planner View
.rz-planner-view {
overflow: auto;
.rz-view-header {
position: sticky;
top: 0px;
min-height: 2.25rem;
z-index: 9999;
}
.rz-month {
.rz-slot {
&:first-child {
.rz-slot-header {
writing-mode: vertical-lr;
transform: rotate(-180deg);
}
}
&:last-child {
justify-content: center;
align-items: center;
background-color: var(--rz-scheduler-header-background-color);
.rz-slot-header {
writing-mode: vertical-rl;
text-align: center;
font-size: var(--rz-scheduler-header-font-size);
padding: var(--rz-scheduler-header-padding);
text-transform: var(--rz-scheduler-header-text-transform);
color: var(--rz-scheduler-header-color);
}
}
&.rz-other-month {
background-color: var(--rz-scheduler-other-month-background-color);
}
&.rz-weekend {
color: var(--rz-scheduler-weekend-color);
background-color: var(--rz-scheduler-weekend-background-color);
}
}
}
}
// Timeline View
.rz-timeline-view {
flex: auto;
overflow: auto;
flex-wrap: wrap;
flex-direction: unset;
.rz-view-header {
position: sticky;
top: 0px;
min-height: 36px;
z-index: 9999;
.rz-slot-header {
min-width: var(--rz-scheduler-timeline-slot-width);
flex: 0 0 auto;
}
}
.rz-month {
flex: 0 0 auto;
.rz-slots {
flex: 0 0 auto;
}
.rz-slot {
width: var(--rz-scheduler-timeline-slot-width);
height: var(--rz-scheduler-timeline-slot-height);
&.rz-other-month {
background-color: var(--rz-scheduler-other-month-background-color);
}
&.rz-weekend {
color: var(--rz-scheduler-weekend-color);
background-color: var(--rz-scheduler-weekend-background-color);
}
}
}
}
// Year View
.rz-year-view {
overflow: auto;
padding: var(--rz-scheduler-year-padding);
--rz-gap: var(--rz-scheduler-year-padding);
.rz-flex-column,
.rz-week {
min-width: fit-content;
}
.rz-slot {
flex: 1;
border-top: none;
justify-content: center;
height: initial;
padding: var(--rz-scheduler-year-slot-padding);
cursor: pointer;
.rz-slot-title {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
text-align: center;
width: var(--rz-scheduler-year-slot-title-width);
min-width: 2rem;
min-height: 2rem;
border-radius: var(--rz-scheduler-year-slot-title-border-radius);
transition: var(--rz-datepicker-calendar-transition);
&.rz-other-month {
opacity: 0.5;
}
&.rz-has-appointments {
color: var(--rz-scheduler-event-color);
background-color: var(--rz-scheduler-event-background-color)
}
}
&:hover {
.rz-slot-title:not(.rz-has-appointments) {
color: var(--rz-datepicker-calendar-hover-color);
background: var(--rz-datepicker-calendar-hover-background-color);
}
}
}
}
// Responsive Styles
@media (max-width: 576px) {
.rz-scheduler-nav {
.rz-scheduler-nav-prev-next {
@@ -409,4 +646,31 @@ $scheduler-day-number-padding: 0 0.5rem !default;
width: auto;
}
}
}
}
@media (max-width: 1399px) {
.rz-planner-view {
flex-wrap: wrap;
flex-direction: unset;
.rz-view-header {
.rz-slot-header {
flex: 0 0 auto;
width: var(--rz-scheduler-planner-slot-width);
}
}
.rz-month {
flex: 0 0 auto;
.rz-slots {
flex: 0 0 auto;
}
.rz-slot {
width: var(--rz-scheduler-planner-slot-width);
height: var(--rz-scheduler-planner-slot-height);
}
}
}
}

View File

@@ -115,6 +115,49 @@ $text-align: (
}
}
// Text Align with responsive breakpoints
@each $breakpoint, $breakpoint-value in $rz-breakpoints-map {
@media (min-width: #{$breakpoint-value}) {
@each $name, $property in $text-align {
.rz-text-align-#{$breakpoint}-#{$name} {
@each $property, $value in $property {
#{$property}: #{$value} !important;
}
}
}
}
}
// Text Wrap, NoWrap and Truncate
.rz-text-wrap {
white-space: normal !important;
}
.rz-text-nowrap {
white-space: nowrap !important;
}
.rz-text-truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// Text Transform
$text-transform: (
capitalize: (text-transform: capitalize),
uppercase: (text-transform: uppercase),
lowercase: (text-transform: lowercase),
) !default;
@each $name, $property in $text-transform {
.rz-text-#{$name} {
@each $property, $value in $property {
#{$property}: #{$value};
}
}
}
// Body
@if $base == false {
:root {

View File

@@ -426,6 +426,7 @@ $rz-gutter-map: map-merge(
// Example .rz-display-block
$display: none, block, inline, inline-block, flex, inline-flex, grid, inline-grid;
@include rz-utility-list-css('display', $display);
@include rz-utility-list-breakpoints-css('display', $display, $rz-breakpoints-map);
// Justify-content
// Example .rz-justify-content-center

View File

@@ -294,6 +294,9 @@ $scheduler-header-background-color: var(--rz-base-700) !default;
$scheduler-header-border: none !default;
$scheduler-border-color: var(--rz-base-700) !default;
$scheduler-minor-border-color: var(--rz-base-700) !default;
$scheduler-weekend-color: var(--rz-text-tertiary-color) !default;
$scheduler-weekend-background-color: var(--rz-base-700) !default;
$scheduler-other-month-background-color: var(--rz-base-900) !default;
.rz-slot-minor {
border-top: 1px dotted var(--rz-scheduler-minor-border-color) !important;

View File

@@ -329,6 +329,9 @@ $scheduler-header-background-color: var(--rz-base-700) !default;
$scheduler-header-border: none !default;
$scheduler-border-color: var(--rz-base-700) !default;
$scheduler-minor-border-color: var(--rz-base-700) !default;
$scheduler-weekend-color: var(--rz-text-tertiary-color) !default;
$scheduler-weekend-background-color: var(--rz-base-700) !default;
$scheduler-other-month-background-color: var(--rz-base-900) !default;
.rz-slot-minor {
border-top: 1px dotted var(--rz-scheduler-minor-border-color) !important;

Some files were not shown because too many files have changed in this diff Show More