diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..ad34bcb74 --- /dev/null +++ b/404.html @@ -0,0 +1,1528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ +

404 - Not found

+ + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/about/license/index.html b/about/license/index.html new file mode 100644 index 000000000..36bb46221 --- /dev/null +++ b/about/license/index.html @@ -0,0 +1,1572 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + License - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

License

+ +

License

+

MIT License

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/about/release-notes/index.html b/about/release-notes/index.html new file mode 100644 index 000000000..95c26ed19 --- /dev/null +++ b/about/release-notes/index.html @@ -0,0 +1,7539 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Release notes - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Releases

+

3.20.0

+

Enhancements

+
    +
  • Dashboard: added new WidgetSize #1845
  • +
  • Dashboard: IWidgetLink improvements #1813
  • +
  • DynamicForm: custom sorting #1802
  • +
  • ImagePicker: new Control ImagePicker #1820
  • +
  • UserPicker: new Control UserPicker #1675
  • +
  • DynamicForm: DynamicForm storeLastActiveTab option #1879 #1879
  • +
  • FilePicker: Image picker enhancements #1805
  • +
  • DynamicForm: Adds ability to create files/folders in subfolder using DynamicForm. #1901
  • +
+

Fixes

+
    +
  • Debug Controls in any language #1882
  • +
  • AdaptiveCardHost: lock down adaptive-expression package version #1876
  • +
  • ListItemPicker: PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. #1887
  • +
  • ListItemAttachments: Fix 1858 to correct Chinese localization files #1894 #1894
  • +
  • DynamicForm: Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type #1872
  • +
  • GridLayout: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. 1851
  • +
  • DynamicForm: Always Show Required Field Validation Error In FormDisplayMode.Edit Mode #1775
  • +
  • DynamicForm: Required Field Validation won't work #1760
  • +
  • DynamicForm: Adds ability to render file/folder name field in DynamicForm and Field. #1906
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alex Terentiev, Antanina Druzhkina, Guido Zambarda, IRRDC, joaojmendes, Martin Lingstuyl, Michaël Maillot, Nishkalank Bezawada, srpmtt, wilecoyotegenius, wuxiaojun514.

+

3.19.0

+

Enhancements

+
    +
  • SharePoint Framework v1.19.0 support #1857
  • +
  • DynamicForm: enable/disable save button #1810
  • +
  • PeoplePicker: add new prop - useSubstrateSearch #1819
  • +
  • SitePicker: add button to clear single / multiple selection #1839
  • +
+

Fixes

+
    +
  • DynamicForm: more than 100 lookups and date format in lookup field #1722
  • +
  • Richtext: can not undo ordered lists #1135
  • +
  • FilePicker: fixing organization tab browsing issue #1861
  • +
  • PeoplePicker: method to clear the array #1838
  • +
  • SitePicker: documentation patch #1842
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alex Terentiev, Antanina Druzhkina, Guido Zambarda, Luccas Castro, Michaël Maillot, Niels Söth, srpmtt.

+

3.18.1

+

Fixes

+
    +
  • FilePicker: Fix issue with adding link by typing in 'From a link' tab #1814
  • +
  • Update nl-nl.ts #1823
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Antanina Druzhkina, Elio Struyf.

+

3.18.0

+

Enhancements

+
    +
  • DynamicField: Added orderBy to DynamicField props for lookup fields #1747
  • +
  • DateTimePicker: disable array of dates #516
  • +
  • DynamicForm: new customIcons property to allow custom icons for the form #1745
  • +
  • RichText: Added style property to Rich text control #1773
  • +
  • fast-serve: Fast-serve update to match the most recent changes. #1782
  • +
  • PeoplePicker: Added context optimization #1764
  • +
  • Multiple controls: Wrong fluentui imports cause webpack build errors #1763
  • +
  • FileTypeIcon: Added standard events #1789
  • +
+

Fixes

+
    +
  • FolderPicker: Update documentation on how to use the control with siteAbsoluteUrl property #1743
  • +
  • Readme documents highlight extension does not work correctly #1495
  • +
  • DynamicForm: Error on rendering DynamicForm when having a Date Field with internal name starting with underscore ('_')#1738
  • +
  • DynamicForm: Dynamic form loading error in other site #1758
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Guido Zambarda, Harminder Singh, IRRDC, Matthias Z'Brun, Michaël Maillot, Nishkalank Bezawada, Sergei Sergeev, srpmtt.

+

3.17.0

+

Enhancements

+
    +
  • DyanmicForm: Added file handling #1625
  • +
  • DynamicForm: Custom Formatting and Validation, ControlsTestWebPart updates #1672
  • +
  • PeoplePicker: Added custom filter to PeoplePicker selection #1657
  • +
  • RichText: Align RichText heading styles and font sizes with OOB SharePoint text web part #1706
  • +
+

Fixes

+
    +
  • Build fails due to missing @iconify/react dependency after upgrade to 3.16.0 #1719
  • +
  • ModernTaxonomyPicker: not displaying suggestions when typing in values - API not found error #1688
  • +
  • DynamicForm: Disable issue on fieldOverrides field control when onBeforeSubmit return true #1715
  • +
  • PeoplePicker: PeoplePicker returns no results with webAbsoluteUrl and ensureUser #1669
  • +
  • DynamicForm: [DynamicForm] Fixing multi taxonomy field (loading + saving existing item) #1739
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Guido Zambarda, Lars Fernhomberg, Mark Bice, Michaël Maillot, Nishkalank Bezawada, Tom G, wuxiaojun514.

+

3.16.2

+

Fixes

+
    +
  • DynamicForm: Fixing the previous version's issue #1736 (introduced in #1718)
  • +
+

Contributors

+

Special thanks to our contributor: IRRDC.

+

3.16.1

+

Fixes

+
    +
  • DynamicForm: Additional check to see if DefaultValue is an object. No more null comparisons, which should have been undefined comparisons
  • +
+

Contributors

+

Special thanks to our contributor: IRRDC.

+

3.16.0

+

New control(s)

+
    +
  • ViewPicker: new control ViewPicker #1439
  • +
  • HoverReactionsBar: new control HoverReactionsBar #1652
  • +
+

Enhancements

+
    +
  • FieldCollectionData: render on page instead of panel and added combobox and peoplepicker controls #1588
  • +
  • FieldCollectionData: added date field control and updated number field #1600
  • +
  • ListItemComments: Added ListItemComments component to Controls.tsx #1621
  • +
  • FolderPicker: Improve documentation of FolderPicker #1379
  • +
  • RichText: Add https:// as placeholder instead of textbox value when adding url #1651
  • +
  • Fix package.json to remove phantom dependencies issues #1660
  • +
  • PeoplePicker: new property to starting the search after n characters #374
  • +
  • SharePoint Framework v1.18.2 support
  • +
+

Fixes

+
    +
  • AccessibleAccordion: fix typo in documentation #1634
  • +
  • DynamicForm: fix issue with MultiChoice field #1510
  • +
  • Localization: Update dutch translations #1635
  • +
  • TaxonomyPicker: suggested item contains double termset name #1597
  • +
  • DynamicForm: DynamicForm does not properly handle NULL default values for Taxonomy fields #1267
  • +
  • DynamicForm: New items are always created with the default content type if the list has multiple content types #1626
  • +
  • PeoplePicker:PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620)
  • +
  • DynamicForm: Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results #1614
  • +
  • DynamicForm: Number validations are working, but the percentage values are not getting saved #1601
  • +
  • DynamicForm: Number validation is preventing form save in certain circumstances, not enabled for currency fields #1604
  • +
  • ListItemAttachments: Inconsistent file handling #1644
  • +
  • Localization: Update Japanese translations #1686
  • +
  • ListItemPicker: Fix docs for onSelectedItem #1690
  • +
  • ComboBoxListItemPicker: Fix docs for onSelectedItem #1690
  • +
  • ListItemAttachments: Fix click behavior in ListItemAttachments component #1692
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Dan Toft, Gerke van Garderen, Guido Zambarda, Joakim, Michaël Maillot, Nils Andresen, Nishkalank Bezawada, Rico van de Ven, Steve Beaugé, wuxiaojun514, Tetsuya Kawahara, Tom G, Yannik Reiter.

+

3.15.0

+

New control(s)

+
    +
  • TermSetNavigation: new control TermSetNavigation #1527
  • +
+

Enhancements

+
    +
  • FolderExplorer: show files on folder explorer control #1502
  • +
  • DynamicForm: Fixed typo in property name #1529
  • +
  • DynamicForm: validation error dialog added #1531
  • +
  • DateTimePicker: Add new property initialPickerDate #1581
  • +
  • ModernTaxonomyPicker: can't find term when UI is in language not supported by term store #1573
  • +
  • AdaptiveCardHost: Add null check for adaptive card elements #1574
  • +
  • ControlsTestWebPart: Updated the ControlsTestWebPart to show the controls filtered by control type #1547
  • +
  • fast-serve: Fast-serve updated to the latest version and serve warnings fixed #1589
  • +
  • DynamicForm: DynamicForm Number min max #1585
  • +
+

Fixes

+
    +
  • FieldPicker: Changed react import to fix cannot be used as a JSX component error #1500
  • +
  • Localization: Fixes to Italian localization #1532
  • +
  • Localization: Fixes to Netherlands localization #1537
  • +
  • ListItemAttachments: Fix the OnClick handler when clicking on the document card #1541
  • +
  • fast-serve: Fix issue with File and Directory Entries API #1555
  • +
  • FilePicker: Tile view issue on first render #1558
  • +
  • DynamicForm lookups - first time you select an option from a lookup, it doesnt select it #1535
  • +
  • DynamicForm: Fields of type Note don't get disabled #1264
  • +
  • ListItemAttachments: Fix for files containing dots in the name #1580
  • +
  • PeoplePicker: Shows wrong value in Dynamic Form when null is provided #1421
  • +
  • DynamicForm: Error on save when clearing person from Person or Group field and leaving it blank #1578
  • +
  • DynamicForm: Number validation is not working, if the field is set to minimum and maximum value #1571
  • +
  • DynamicForm: controls are shown with error messages even if the values are assigned #1133
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Andreas Omayrat, Ayoub, Desislav, Guido Zambarda, João Mendes, Nishkalank Bezawada, Patrik Hellgren, Rico van de Ven, Sergei Sergeev, Sharepointalist, Zhephyr.

+

3.14.0

+

Enhancements

+
    +
  • DateTimePicker: Fixed DateTimePicker strings in Danish Locale #1498
  • +
  • SharePoint Framework v1.17.1 support
  • +
  • FieldCollectionData: Adds panelProps property to FieldCollectionData #1525
  • +
+

Fixes

+
    +
  • DynamicForm: Fixes DynamicForm trying to load TaxonomyFields with wrong display name #1422
  • +
  • ListItemAttachments: FIX: Cannot download items when it has a ilegal character #1484
  • +
  • FilePicker: FIX: recent tab empty until re-render #1482
  • +
  • Dynamic Form: Adds onListItemLoaded handler to DynamicForm #1472
  • +
  • Dynamic Form: Fix for the DynamicForm when a defaultValue is null and the code try to call the split method on it. #1486
  • +
  • DynamicForm: DynamicForm - Fixing Required Multi Field Saving Problem #1489
  • +
  • FolderExplorer: FolderExplorer doesn't explore folders with ' in the name #1491
  • +
  • DynamicForm: cannot display lookup value when the source field is not Title #1511
  • +
  • FilePicker:Features/1478 filepicker tiles view #1521
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Chad Eiserloh, Dan Toft, Guido Zambarda, Martin Lingstuyl, Nishkalank Bezawada, Sergio Villalta, Josef Benda, Victor Romanov, wuxiaojun514, Zied FEHRI.

+

3.13.0

+

New control(s)

+
    +
  • UploadFiles: New Upload Files control #1388
  • +
+

Enhancements

+
    +
  • ListItemPicker: use list name as well as GUID to point to list #1355
  • +
  • ListItemPicker: Add Styles property to ListItemPicker and ComboBoxListItemPicker #1407
  • +
  • SitePicker: Pass styles property to Dropdown #1389
  • +
  • FilePicker: Site Tab - Many Document Libraries No Scrolling #1413
  • +
  • DynamicForm: Add respectETag option to DynamicForm #1395
  • +
  • MonacoEditor: Fixed minor typos and misleading instructions #1415
  • +
  • SharePoint Framework v1.16.1 support #1427
  • +
  • RichText: label property is missing #1375
  • +
  • PeoplePicker: PeopleSearch service should also find people by userPrincipalName when group transitive membership check is used. #1446
  • +
  • Update the SPFx source project to add an extension + form customizer #1410
  • +
  • AdaptiveCardDesignerHost: Add Sample Data to Adaptive Card Editor #1425
  • +
  • AdaptiveCardHost: Logic to prevent re-renders (flicker) #1425
  • +
  • ListItemComments: Add new parameter for ListItemComments to highlight comment #1430
  • +
  • ComboBoxListItemPicker: Update ComboBoxListItemPicker.md #1470
  • +
+

Fixes

+
    +
  • DateTimePicker: broken link for getErrorMessage property fixed #1277
  • +
  • ProgressStepsIndicator: Fix missing image reference in Progress Steps Indicator #1409
  • +
  • DynamicForm: Dynamicform is hanging on the loading screen if the list has a single value list lookup field #1393
  • +
  • ListView: Update ListView control docs to use a valid field for the icon #1398
  • +
  • Accordion: Fixing Accordion control documentation image issue #1408
  • +
  • DynamicForm: Cannot read properties of undefined (reading 'startsWith') when submitting the form with contentType={undefined] #1431
  • +
  • FilePicker: Fix site breadcrumb navigation #1368
  • +
  • DynamicForm: Initialize changedValue with defaultValue #1454
  • +
  • DynamicForm: Fix image path #1455
  • +
  • DynamicForm: Check empty array and trasform it in set as null #1456
  • +
  • FilePicker: Fix site browser resize #1457
  • +
  • ModernTaxonomyPicker Fix - Show ModernTaxonomyPicker label in correct form #1459
  • +
  • DynamicForm: Update DynamicForm.tsx #1462
  • +
  • FilePicker: Fix breadcrumb nav #1458
  • +
  • DateTimePicker: Date picker locale #1464
  • +
  • DateTimePicker: Date picker locale #1095
  • +
  • RichText: Use theme colors - fix dark mode #669
  • +
  • FilePicker: Use theme colors - fix dark mode #1132
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): araver, Brian Krainer Jacobsen, Edin Kapic, Eduard Paul, Fredrik Ekström, Guido Zambarda, Harminder Singh, Hugo Bernier, João Mendes, mgitta, Michaël Maillot, mikezimm, Nikolay Belykh, Patrik Hellgren, Rico van de Ven, Samuele Furnari, sambilfinger, wuxiaojun514.

+

3.12.0

+

Enhancements

+
    +
  • DynamicForm: support cretion of document sets #1335
  • +
  • SitePicker: add HubId to filter to only sites within a hub #1346
  • +
  • SharePoint Framework v1.16.0 support
  • +
+

Fixes

+
    +
  • FilePicker: panel causes SharePoint to Throttle due to infinite loop fetching files #1325
  • +
  • ContentTypePicker: problem importing control #1337
  • +
  • FilePicker: correctly request data from provided webAbsoluteUrl #1340
  • +
  • ModernTaxonomyPicker: Fix infinite loop #1342
  • +
  • ModernTaxonomyPicker: improve display of the term path to align with out of the box control UI #1343
  • +
  • FolderPicker: get folders of other site url instead of the current context/site #1305
  • +
  • FilePicker: browsing Site / Doclibs loops and floods SPO Service with requests and causes http 429 #1350
  • +
  • Remove invalid comma in tsconfig.json #1341
  • +
  • TaxonomyPicker: control allows select deprecated/untaggable terms when typing #1093
  • +
  • SitePicker: prevent infinite loop when fetching sites #1346
  • +
  • DynamicForm: AnchorId of TaxonomyField gets ignored and the whole tree is rendered #1310
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Carlos Marins Jr, Edin Kapic, Josef Benda, Nello D'Andrea, Nishkalank Bezawada, Nizar Grindi, Paolo Pialorsi, Patrik Hellgren, Peter Paul Kirschner, Victor Romanov.

+

3.11.0

+

New control(s)

+
    +
  • ProgressStepsIndicator: New control that shows a progress of steps. #1322
  • +
+

Enhancements

+
    +
  • DynamicForm: Add taxonomy tree to test harness #1269
  • +
  • ModernTaxonomyPicker: ability to disallow selecting children #1279
  • +
  • PeoplePicker: Use webAbsoluteUrl if provided through props to ensure user #1273
  • +
  • DynamicForm: Support for hidden fields #1307
  • +
  • Placeholder: Documentation example to only display in edit mode #1280
  • +
  • DynamicForm: Update documentation regarding onBeforeSubmit #1319
  • +
  • DynamicForm: FirstDayOfWeek in DatePickers from webs regional settings #1317
  • +
+

Fixes

+
    +
  • PeoplePicker: fixes where people picker returns no results #1292
  • +
  • FilePicker: Tile view fix #1272
  • +
  • Issues with v1.15.2 #1288
  • +
  • RichText: Fix broken arrow icons #1302
  • +
  • TaxonomyPicker: Does not show term set labels in Version 3.10.0 #1299
  • +
  • TaxonomyPicker: Dynamic form select term not working #1303
  • +
  • DynamicForm: Check if hiddenfields property is undefined #1314
  • +
  • DynamicForm: PeoplePicker preselects wrong user if PrincipalType allows groups #1315
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Chad Eiserloh, Hilton Giesenow, Jake Stanger, Jasey Waegebaert, João Mendes, Josef Benda, Mark Bice, Paolo Pialorsi, Victor Romanov.

+

3.10.0

+

Enhancements

+
    +
  • DynamicForm: possibility to override field rendering for individual fields #1257
  • +
  • ModernTaxonomyPicker: Display the full path of a term #1172
  • +
  • SharePoint Framework v1.15.2 support #1261
  • +
+

Fixes

+
    +
  • DateTimePicker: onChange not triggered when clearing date #1277
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Bart-Jan Dekker, Edin Kapic, Milan Holemans, Steve Beaugé.

+

3.9.0

+

New control(s)

+
    +
  • EnhancedThemeProvider: Added 'EnhancedThemeProvider' control #1202
  • +
  • FieldPicker: Added FieldPicker control #1219
  • +
  • ContentTypePicler: Added ContentTypePicker control #1220
  • +
  • ModernAudio: Added ModernAudio control #1224
  • +
  • AdaptiveCardDesignerHost: Added AdaptiveCardDesignerHost control #1237
  • +
+

Enhancements

+
    +
  • DateTimePicker: Added button to clear date #1217
  • +
  • Toolbar: Allow filters on a Toolbar to be controlled externally #1222
  • +
  • PeoplePicker: add new allowUnvalidated option to allow adding non-tenant users #1232
  • +
  • DynamicForm: Add support for webAbsoluteUrl #1244
  • +
+

Fixes

+
    +
  • Localization: Updates to English localizations #1207
  • +
  • Localization: Updates to Dutch localizations #1209
  • +
  • Localization: Updates to Danish localizations #1233
  • +
  • TaxonomyPicker: Check if cultureInfo is valid #1226
  • +
  • FieldCollectionData: Updated docs to fix duplicated property #1236
  • +
  • Changelog: Fix changelog script by setting CHANGELOG.JSON filename extension to lower case #1242
  • +
  • PeoplePicker: PeoplePicker validation on focus out #1221
  • +
  • DynamicForm: Cannot display lookup value when the source field is not Title #1215
  • +
  • FilePicker: the endPoint for webSearch do not work #1256
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Annie-Johnson, Daniel Watford, Dennis Kuhn, Fabio Franzini, Jake Stanger, Joseph Halvey, Markus Möller, Milan Holemans, Morten Andersen, Richard Gigan, Rico van de Ven, ryanexner, Sergio Villalta.

+

3.8.1

+

Fixes

+
    +
  • LivePersona: Fix LivePersona not showing card on hover #1241
  • +
+

3.8.0

+

Enhancements

+
    +
  • PeoplePicker: Allow the use of multiple groupId-s #1163
  • +
  • PeoplePicker: search users in nested security groups #1173
  • +
  • ModenrTaxonomyPicker: Add more complete example of TaxonomyTree usage #1190
  • +
  • AdaptiveCardHost: Add SPFx Context property #1145
  • +
  • AdaptiveCardHost: Remove the isUniqueControlInPage from the control by rebuilding the way to apply AC CSS class names #1154
  • +
  • ListView: Different background color to even and odd rows in ListView #1153
  • +
  • AccessibleAccordion: Support of section variations #1195
  • +
  • TreeView: Support of section variations #1196
  • +
+

Fixes

+
    +
  • LocationPicker: Resolve issue when in root site #1162
  • +
  • LocationPicker: Trigger onChange on picker clear action #1165
  • +
  • TreeView: TreeView Control is broken after updating to v3.7.0 #1170
  • +
  • TreeView: collapses on selection of a child node #1182
  • +
  • TreeView: expanded nodes state is getting lost after refresh #1062
  • +
  • NPM Audit Critical Issues #1187
  • +
  • Bump momentjs from 2.29.1 to 2.29.2 #1185
  • +
  • TaxonomyPicker: Sorting the terms in locale language #1160
  • +
  • ComboboxListItemPicker: options are not reloaded after the filter is changed #1180
  • +
  • FieldRendererHelper: Add missing PnPjs import to SPHelper #1140
  • +
  • RichText: Update font style and font size on property pane #1151
  • +
  • Placeholder: Support section variations for themes #1193
  • +
+

3.7.2

+

3.7.0

+

New control(s)

+
    +
  • VariantThemeProvider: new VariantThemeProvider control #1120
  • +
  • MonacoEditor: new MonacoEditor control #1134
  • +
+

Enhancements

+
    +
  • Carousel: Prev and Next Buttons are not labeled, and read as 'Unlabeled button' by screen readers #1137
  • +
  • TreeView: Ability to set keys of items that should be expanded by default #1084
  • +
  • SharePoint Framework v1.14.0 support
  • +
+

Fixes

+
    +
  • FilePicker: defaultFolderAbsolutePath doesn't work with webAbsoluteUrl #1129
  • +
  • LocationPicker: Location picker not resolving locations #1149
  • +
  • DynamicForm: RichText Field losing focus on typing #1024
  • +
  • LivePersona: Documentation fix for template type #1147
  • +
+

3.6.0

+

New control(s)

+
    +
  • AdaptiveCardHost: React control that allows you to render an Adaptive Card as a component #1096
  • +
+

Enhancements

+
    +
  • ModernTaxonomyPicker: ability to add action buttons to terms #1058
  • +
  • FilePicker: allow to select files from other sites #907
  • +
  • Localization: Update Swedish translations #1099
  • +
  • FilePicker: ability to allow external link and disable file existance chech commit
  • +
  • FilePicker: support for multi-select on additional sources #1047
  • +
  • DateTimePicker: new property for allowTextInput #1094
  • +
+

Fixes

+
    +
  • LivePersona: Cannot find module '@pnp/spfx-controls-react/lib/LivePersona'#1069
  • +
  • ListView: documentation spelling mistake 'ColumndName' #1063
  • +
  • Fixes for Norwegian localization #1083
  • +
  • DynamicForm: doesn't load or save correctly when field name starts with a special character #1077
  • +
  • DynamicForm: fields in DynamicForm do not honour regional settings #1075
  • +
  • DynamicForm: Boolean fields do not honour the default value in list settings #1073
  • +
  • TaxonomyPicker: table markdown fix in documentation #1072
  • +
  • WebPartTitle: Fix for styling of WebPartTitle to better match the styling of the oob webpart titles. #1088
  • +
  • LivePersona: fix for documentation typos #1106
  • +
  • LivePersona: remove property for SPFx context #1108
  • +
  • Documentation fix for swedish translations #1100
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alexander M, Carlos Marins Jr, Fabio Franzini, Henrik, Jasey Waegebaert, João Mendes, Milan Holemans, MonalisaBaltatescu, Patrik Hellgren, Tom G.

+

3.5.0

+

Enhancements

+
    +
  • Update mgt package to the latest version #1038
  • +
  • ListView: Add ability to provide CSS class names for list wrapper and list itself #1007
  • +
  • IconPicker: onCancel property is added #1043
  • +
  • SharePoint Framework v1.13.* support
  • +
  • DynamicForm: disabledFields property added #987
  • +
  • ListPicker: Add multi numbers support for baseTemplate option #1016
  • +
  • ComboboxListItemPicker: Add option to sort the items in the picker #985
  • +
  • PeoplePicker: Added filter for Microsoft 365 Group #985
  • +
  • Accordion: Added custom icons #1033
  • +
  • Localization: Correction for german localizations #1059
  • +
  • Localization: Corrections for norwegian localizations #1060
  • +
  • PeoplePicker: Added Styles property #1061
  • +
  • Localization: Update pt-pt and pt-br loc files #1066
  • +
+

Fixes

+
    +
  • FilePicker: defaultFolderAbsolutePath does not work Out of context #1023
  • +
  • ModernTaxonomyPicker: correctly display with RTL mode #1041
  • +
  • FilePicker: Fixed showing the selection circle on recent tabs #1048
  • +
  • FilePicker: Your organisation tab breadcrumb not working #1056
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Gautam Sheth, Jouni Pohjolainen, jumpei-yamauchi, Louis Pineau, Michalis Koutroupis, MonalisaBaltatescu, Patrik Hellgren, Xiyitifu, Russell gove, Andreas Omayrat, Abderahman Moujahid, Alexander M, João Mendes.

+

3.4.0

+

New control(s)

+
    +
  • ModernTaxonomyPicker: New control ModernTaxonomyPicker #1014
  • +
+

Enhancements

+
    +
  • Translations: Update translation keys #994
  • +
  • LocationPicker: Update docs #1009
  • +
  • FileTypeIcon: Add support of 20px icons#1013
  • +
  • Pagination: Update import from lodash #1021
  • +
+

Fixes

+
    +
  • ChartControl: Charts not updating properly when properties are changed #997
  • +
  • TaxonomyPicker: suggestions language is always English #879
  • +
  • TaxonomyPicker: errorMessage label not being removed #953
  • +
  • FilePicker: Sorting Not Working as Expected in Site Tab #1011
  • +
  • FilePicker: Site Tab - Lots of file types don't have appropriate icons #1012
  • +
  • LocationPicker: Correct documentation #1019
  • +
  • FilePicker: fileNameWithoutExtension not calculated right #1022
  • +
  • FieldUserRenderer: Add missing PnPJS imports #1025
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Dennis Kuhn, Gautam Sheth, Jean-Luc Richer, hesperanca, Kiryl Shchasny, Patrik Hellgren, Peter Paul Kirschner, Ravichandran Krishnasamy.

+

3.3.0

+

New control(s)

+
    +
  • LivePersona: New Control LivePersona #969
  • +
  • ListItemComments: New Control ListItemComments #979
  • +
+

Enhancements

+
    +
  • FilePicker: spanish translation for Stock Images labels #946
  • +
  • FilePicker: Add support for a defaultFolderAbsolutePath prop #947
  • +
  • DynamicForm: Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944
  • +
  • DateTimePicker: Add property for minutes dropdown increment #939
  • +
  • ListItemPicker: add property to show all options by default #955
  • +
  • ListItemPicker: Missing translation keys, improved FI, NL translation #957
  • +
  • TaxonomyPicker: Added onNewTerm called when enter is pressed #967
  • +
  • DynamicForm: Principal Types support #956
  • +
  • DateTimePicker: Expose allowTextInput from the underlying date picker #928
  • +
  • Dynamic Form: Show field descriptions #975
  • +
+

Fixes

+
    +
  • RichText: Image button is checked when hyperlink is added to the text #948
  • +
  • RichText: impossible to display link with the text equal to the url #949
  • +
  • ComboBoxListItemPicker: defaultSelectedItems not working #954
  • +
  • Dynamic Form: query items in a folder (managed metadata field) #973
  • +
  • PeoplePicker: Default selected items for groups #958
  • +
  • Documentation: corrected Twitter handle for M365PnP #984
  • +
  • Carousel: Carousel is missing import of ICarouselImageProps #986
  • +
  • Documentation fix - DynamicForm example has incorrect syntax #990
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alexey Morozov, Daniel Stratton, Dennis Kuhn, Gautam Sheth, João Mendes, Ketill Antoníus Ágústsson, kmrshubham0, Modern Dev Dude, Ravichandran Krishnasamy, Sergio Ortega Martín, Yannick Reekmans.

+

3.2.1

+

Enhancements

+
    +
  • ListItemAttachments: Add new label and description properties #943
  • +
+

Fixes

+
    +
  • ListPicker: ListPicker stopped working in upgrade from 3.1.0 to 3.2.0 #945
  • +
  • ListItemAttachments: Fixed multiple bugs #943
  • +
+

3.2.0

+

New control(s)

+
    +
  • DynamicForm: New Control: Dynamic form #878
  • +
  • LocationPicker: New Control - Location Picker #915
  • +
+

Enhancements

+
    +
  • fast-serve: Add fast-serve support #916
  • +
  • ComboBoxListItemPicker and ListItemPicker: Add label to control #914
  • +
  • PeoplePicker: new property groupId. #917
  • +
  • ListPicker: add contenttype id to list picker #894
  • +
  • ListPicker: Few more tests with a little better description #906
  • +
  • Translations: Improved Finnish translations #937
  • +
+

Fixes

+
    +
  • Documentation for RichText: correct event handler name #898
  • +
  • SitePicker: SitePicker does not display initial sites until you click the dropdown to select #895
  • +
  • DatePicker: Fix Spanish loc strings #923
  • +
  • FilePicker: invalid CSS: relative in quotes. #930
  • +
  • MyTeams: Update MyTeams to use new library mgt-spfx #918
  • +
  • FieldCollectionData: FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Nikolay Belykh, Eduard Paul, Patrik Hellgren, Peter Paul Kirschner, Ravichandran Krishnasamy, Russell gove, Sergei Sergeev, João Mendes, Marcin Wojciechowski, Gautam Sheth.

+

3.1.0

+

New control(s)

+
    +
  • TeamPicker: new Team Picker control #846
  • +
  • TeamChannelPicker: new Team Channel Picker control #846
  • +
  • SitePicker: new Site Picker control #868
  • +
  • DocumentLibraryBrowser, SiteFilePickerTab: jest unit tests #866
  • +
  • DragDropFiles: new DragDropFiles control #861
  • +
  • MyTeams: new MyTeams control #874
  • +
  • TeamChannelPicker: new TeamChannelPicker control #874
  • +
  • TeamPicker: new TeamPicker control #874
  • +
+

Enhancements

+
    +
  • ListView: Use new DragDropFiles control #861
  • +
  • FilePicker: Use new DragDropFiles control #861
  • +
  • SharePoint Framework v1.12.1 support
  • +
  • ListView: Ability to provide custom sorting function #880
  • +
  • FilePicker: Allow panel on FilePicker to be invoked after first load #886
  • +
  • FilePicker: Allow FilePicker button to be hidden #887
  • +
  • FilePicker: Change same function to return an array of objects
  • +
+

Fixes

+
    +
  • Documentation for ListView: typos fixes #855
  • +
  • Documentation fix: type on index page #852
  • +
  • PeoplePicker: error message isn't cleared after onGetErrorMessage returns an empty string #841
  • +
  • TreeView: Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870
  • +
  • FilePicker: React crash on large folders #826
  • +
  • ListItemAttachments: updated filename replacement logic #873
  • +
  • RichText: Adding a link does not work #875
  • +
  • FilePicker: Stock images url is getting a 404 server error #882
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Ari Gunawan, aroraans1512, cwparsons, joaojmendes, Kunj Balkrishna Sangani, Marcin Wojciechowski, Yannick Reekmans, André Lage.

+

3.0.0

+

Enhancements

+
    +
  • SharePoint Framework v1.12 support (breaking change)
  • +
  • Fluent UI v7 support
  • +
+

2.9.0

+

Enhancements

+
    +
  • FilePicker: spanish translation for Stock Images labels #946
  • +
  • FilePicker: Add support for a defaultFolderAbsolutePath prop #947
  • +
  • DynamicForm: Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944
  • +
  • DateTimePicker: Add property for minutes dropdown increment #939
  • +
  • DynamicForm: Principal Types support #956
  • +
  • Dynamic Form: Show field descriptions #975
  • +
+

Fixes

+
    +
  • RichText: Image button is checked when hyperlink is added to the text #948
  • +
  • RichText: impossible to display link with the text equal to the url #949
  • +
  • ComboBoxListItemPicker: defaultSelectedItems not working #954
  • +
  • PeoplePicker: Default selected items for groups #958
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alexey Morozov, Daniel Stratton, Ketill Antoníus Ágústsson, Ravichandran Krishnasamy, Sergio Ortega Martín.

+

2.8.0

+

New control(s)

+
    +
  • DynamicForm: New Control: Dynamic form #878
  • +
  • LocationPicker: New Control - Location Picker #915
  • +
+

Enhancements

+
    +
  • ComboBoxListItemPicker and ListItemPicker: Add label to control #910
  • +
  • PeoplePicker: new property groupId. #917
  • +
+

Fixes

+
    +
  • SitePicker: SitePicker does not display initial sites until you click the dropdown to select #895
  • +
  • FilePicker: invalid CSS: relative in quotes. #930
  • +
  • FieldCollectionData: FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Nikolay Belykh, Patrik Hellgren, Peter Paul Kirschner, Ravichandran Krishnasamy.

+

2.7.0

+

New control(s)

+
    +
  • DragDropFiles: new DragDropFiles control #856
  • +
  • SitePicker new Site Picker control #867
  • +
  • Controls Add locale strings for pt-br #865
  • +
+

Enhancements

+
    +
  • ListView: Use new DragDropFiles control #856
  • +
  • FilePicker: Use new DragDropFiles control #856
  • +
  • ListView: Ability to provide custom sorting function #880
  • +
  • FilePicker: Allow panel on FilePicker to be invoked after first load #886
  • +
  • FilePicker: Allow FilePicker button to be hidden #887
  • +
  • FilePicker: Changed save function to return an array of objects
  • +
+

Fixes

+
    +
  • PeoplePicker: error message isn't cleared after onGetErrorMessage returns an empty string #841
  • +
  • TreeView: Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870
  • +
  • FilePicker: React crash on large folders #826
  • +
  • ListItemAttachments: updated filename replacement logic #873
  • +
  • RichText: Adding a link does not work #875
  • +
  • FilePicker: Stock images url is getting a 404 server error #882
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): André Lage, cwparsons, Kunj Balkrishna Sangani, Yannick Reekmans.

+

2.6.0

+

New control(s)

+
    +
  • AnimatedDialog: new Animated Dialog control #815
  • +
  • Jest unit tests #834
  • +
+

Enhancements

+
    +
  • IconPicker: search icons using contains comparison.
  • +
  • FilePicker: default alphabet sorting #824
  • +
  • ListItemPicker: ability to provide orderBy #829
  • +
  • Dashboard: Dashboard widget wrapper for styling and error catching #836
  • +
  • FolderExplorer: Update folder explorer documentation #835
  • +
+

Fixes

+
    +
  • IconPicker: Fix case sensitive fluent icon search service #814
  • +
  • Carousel: documentation fix - broken table style #817
  • +
  • AccessibleAccordion: documentation link is broken #818
  • +
  • Documentation: Controls link in the menu is broken #821
  • +
  • TreeView: Fix two potential null reference issues #832
  • +
  • RichText: Problem with bullets and number list #795
  • +
  • FolderPicker: Correct FolderPicker link alignment
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Anoop Tatti, Ari Gunawan, Gautam Sheth, Kunj Balkrishna Sangani, Marcin Wojciechowski, Mark Bice, Nizar Grindi, Yannick Reekmans.

+

2.5.0

+

Enhancements

+
    +
  • TreeView: Adding support to clear TreeView selected items by passing an empty array. #787
  • +
  • FilePicker: new property includePageLibraries to optionally display Site Pages library on Site tab #601
  • +
  • ListItemPicker: Support of Calculated columns #805
  • +
  • Progress: Documentation update to have consistency in variables names #811
  • +
  • FolderExplorer: Add support for sorting folder explorer items #812
  • +
+

Fixes

+
    +
  • ListView: Selection is reset when putting a ListView inside a React Component that controls its items and selection props #251
  • +
  • Documentation fix for PeoplePicker: Removed unwanted new line in help content. #783
  • +
  • Documentation fix for TreeView: TreeViewSelectionMode added in the import #780
  • +
  • Documentation fix for TreeView: removed unwanted comma #779
  • +
  • IFrameDialog: height unable to resize relative to screen size, even if we provide in % it is taking default value. #636
  • +
  • DateTimePicker: Clear Date functionality #799
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Ari Gunawan, Joel Rodrigues, Mike Myers, Ravichandran Krishnasamy, San.

+

2.4.0

+

New control(s)

+
    +
  • AccessibleAccordion control #770
  • +
+

Enhancements

+
    +
  • Placeholder: support of custom rendering for iconText and description
  • +
  • PeoplePicker: ability just to display inactive users name (ideally the value fetched from 'Author/Title') #768
  • +
  • TaxonomyPicker: New onPanelSelectionChange property added. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. #761
  • +
  • TaxonomyPicker: selectChildrenIfParentSelected property added. Specifies if the children should be selected when parent item is selected (defaults to false). #765
  • +
  • ListPicker: ability to pick lists from specified site using webAbsoluteUrl property.
  • +
  • FilePicker: buttonIconProps to define properties of the button's icon #770
  • +
+

Fixes

+
    +
  • DateTimePicker: documentation fix #767
  • +
  • PeoplePicker: documentation fix - Changed isRequired property to new required #769
  • +
  • Documentation fix - missing IFramePanel link on home page #775
  • +
  • Documentation fix for FilePicker: updated onChaged to onChange #776
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): André Lage, Christian Metz, Gaurav Goyal, Leif Frederiksen, Ravichandran Krishnasamy, San, João Mendes.

+

2.3.0

+

New control(s)

+
    +
  • Dashboard control for Microsoft Teams #758
  • +
  • Toobar control for Microsoft Teams #758
  • +
+

Enhancements

+
    +
  • TaxonomyPicker: Added useSessionStorage property #759
  • +
+

Fixes

+
    +
  • FilePicker: documentation fix: '|' not escaped #756
  • +
  • TaxonomyPicker: Return TermSetId for suggestions #762
  • +
  • WebPartTitle: Fluent UI Updates to SharePoint - WebPartTitle control too thin now #605
  • +
  • ListView: Sticky Header scrolling issue #734
  • +
  • DateTimePicker: hours dropdown not re-rendered when state changed programmatically #757
  • +
  • RichText: controlled mode doesn't work #666
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Gautam Sheth, Marcin Wojciechowski, Nikolay Belykh, André Lage.

+

2.2.0

+

Enhancements

+
    +
  • RichText: Add image support #705
  • +
  • FilePicker: Add file size to the Upload tab and IFilePickerResult #706
  • +
  • FieldCollectionData: SearchBox instead of TextBox #719
  • +
  • TaxonomyPicker: control does not show an error message for an invalid/unresolved input #728
  • +
  • Canadian French localization #671
  • +
  • FilePicker: reduce bundle size #732
  • +
  • FilePicker: Custom render callbacks for the 'Upload' and 'Link' tabs #746
  • +
+

Fixes

+
    +
  • Localization: Fixing some wrong localizations for the DatePicker short day in Spanish.#702
  • +
  • ListItemPicker: When use defaultSelectedItems, ListItemPicker allows you to select dublicate entries #722
  • +
  • Deprecated stuff is removed #733
  • +
  • DateTimePicker: time portion not re-rendered when state changed programmatically - when time is displayed as dropdown only #713
  • +
  • PeoplePicker: errorMessage not being removed #730
  • +
  • ListItemAttachment: the control is not fully disabled #736
  • +
  • TaxonomyPicker: icons are not being rendered on Classic SharePoint pages #735
  • +
  • FilePicker: Site Tab does not load document if we access SharePoint site in different language than default language of the site #724
  • +
  • Documentation fix for 'attention' block on index page #740
  • +
  • TaxonomyPicker: sessionStorage exceeds max-size when browsing large termsets #739
  • +
  • FolderExplorer and FolderPicker do not seem to work for document libraries #741
  • +
  • FilePicker: onChange event does not exist despite being documented #747
  • +
  • ListItemPicker: Selected values are not getting cleared or reset #659
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Abderahman Moujahid, avadhootdindorkar, Devang Bhavsar, Gautam Sheth, Konrad K., Nikolay Belykh, Vertamin.

+

2.1.0

+

Enhancements

+
    +
  • Carousel: Ability to display indicators in a dedicated block #681
  • +
  • FilePicker: Org Assets are not displayed for non-admin users #687
  • +
  • ListView: Drag and Drop option #679
  • +
  • FolderExplorerService: support special characters if folder name #691
  • +
  • ListView: Sticky Header #634
  • +
  • IconPicker: get icons from @uifabric/icons/lib/data/AllIconNames.json
  • +
  • ListView: Sticky header with className instead of additional components #696
  • +
  • ListView: StickyHeader code consistency #697
  • +
  • TreeView: Added (optional) property 'defaultExpandedChildren' that controls the behavior of the expansion of child elements.#698
  • +
+

Fixes

+
    +
  • RichText: Cannot add link in first line #672
  • +
  • TaxonomyPicker: Ability to reset the TaxonomyPicker (Remove all selected Terms) #367
  • +
  • Documentation fix for TaxonomyPicker: the disabled property is a boolean and not a string as currently specified #695
  • +
  • ComboBoxListItemPicker: update options when listId has been changed #683
  • +
  • FilePicker: styles are updated to match OOB control #700
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Abderahman88, André Lage, Gautam Sheth.

+

2.0.0

+

Enhancements

+
    +
  • FilePicker: added additional properties - isPanelOpen and onCancel #668
  • +
+

Fixes

+
    +
  • PeoplePicker: Disabled doesn't work #484
  • +
  • Pagination: control not re-rendering when currentPage is updated in state #663
  • +
+

Contributors

+

Special thanks to our contributor: Gautam Sheth.

+

1.20.0

+

New control(s)

+
    +
  • Accordion control #638
  • +
  • FieldCollectionData control #591
  • +
+

Enhancements

+
    +
  • FilePicker: Stock images option added #593
  • +
  • TaxonomyPicker: Add the 'required' property #216
  • +
  • TaxonomyPicker: Add errorMessage and onGetErrorMessage props #600
  • +
  • ListItemPicker: ability to use substring search instead of startswith #583
  • +
  • Map: return display name and address details for the location #585
  • +
  • Map: support for draggable and static Bing maps #586
  • +
  • TaxonomyPicker: onLoad validation #602
  • +
  • FieldCollectionData: Add pagining and filtering #617
  • +
  • TaxonomyPicker: Finding terms with labels #288
  • +
  • FileTypeIcon: Added support for additional file type in Image mode #640
  • +
+

Fixes

+
    +
  • ComboBoxListItemPicker: fetching only 100 items #569
  • +
  • TaxonomyPicker: browse (tree view) doesn't work with SP 2016 On-Premises #183
  • +
  • FilePicker: default tab when opened shows hidden RecentTab #477
  • +
  • PeoplePicker: The required error message not showing #590
  • +
  • ListItemAttachments: fails in Microsoft Teams Tab SPFx applications #582
  • +
  • Carousel: Changing pages doesn't work #609
  • +
  • TaxonomyPicker: no suggestions are displayed if anchorId is not set
  • +
  • TaxonomyPicker: Suggestion/match does not work as expected #604
  • +
  • TaxonomyPicker: Include check for separator while filtering path of terms when anchorId is configured #625
  • +
  • FilePicker: Bing API search issue #633
  • +
  • ListView: Sort fires selection #621
  • +
  • Map: A minor issue in componentWillUpdate method to get the next props rather than the current props.#641
  • +
  • IFrameDialog: dialog size is incorrect when opening the dialog second time #615
  • +
  • FolderPicker: imports don't work #614
  • +
  • FilePicker: Yor Organization tab is not shown #596
  • +
  • FolderPicker, FolderExplorer: Controls don't let you explore sub folders if parent folder has apostrophe (') in its name.#644
  • +
  • PeoplePicker: image for a user picked in PeoplePicker didn't get resolved #646
  • +
  • Documentation fix for IconPicker: renderOption dialog should be lowercased. #649
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Alexey Sadomov, Anoop Tatti, Devang Bhavsar, Gautam Sheth, geltapatio, Joel Jeffery, juhaalhojoki, Piotr Siatka, Rabia Williams, Ravichandran Krishnasamy, Victor Pollet.

+

1.19.0

+

Enhancements

+
    +
  • ListView: Add clear button to filter text box #549
  • +
  • FolderExplorer: Add clear button to filter text box #553
  • +
  • TreeView: there should be possibility to collapse the first level nodes by default #561
  • +
  • TreeView: Expand to selected #559
  • +
  • DateTimePicker: When using the datetimePicker I would like to have an opportunity to set maximum/minimum date like in Office UI Fabric #497
  • +
  • TaxonomyPicker: Added the selectTerm, hideTerm, and disableTerm actions #578
  • +
  • TaxonomyPicker: Added the functionality to enable/disable term actions on the fly #578
  • +
  • Carousel: indicators, slide animation, auto cycling, easier basic usage #587
  • +
+

Fixes

+
    +
  • TaxonomyPicker: Correct the AnchorID getting all TermSet search options #150
  • +
  • Documentation fix for TreeView: Some tables in TreeView documentation are displayed as plain text. #562
  • +
  • ComboBoxListItemPicker, ListItemPicker: Show error span if error is present #557
  • +
  • TreeView: defaultExpanded: true doesn't work #560
  • +
  • IListPicker: typo fix #574
  • +
  • DateTimePicker: DateTime Picker noon/midnight issue with 12 hour format #576
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Chad Eiserloh, Gautam Sheth, Koen Zomers, Markus Langer, Nanddeep Nachan, Prasad Kasireddy, David Ramalho, Siddharth Vaghasia.

+

1.18.0

+

New control(s)

+
    +
  • Pagination Control #535
  • +
  • TreeView Control #536
  • +
  • FolderPicker Control #525
  • +
+

Enhancements

+
    +
  • FolderExplorer updates: allow selection of libraries if site url is used as the root, allow passing items to be passed as a property and added to the breadcrumb, add support for loading folders from a different site, fix breadcrumb names for document libraries #534
  • +
  • IconPicker: renderOption property to render icons list as a panel or dialog #537
  • +
+

Fixes

+
    +
  • ComboBoxListItemPicker documentation fix: Updated import statement in docs for ComboBoxListItemPicker #510
  • +
  • Documentation fix: add the new control ComboBoxListItemPicker component to landing page #511
  • +
  • FilePicker: While using the control, if hideOrganisationalAssetTab is set to true, even then an additional HTTP request is made.
  • +
  • IconPicker: search fix and updated list of icons #533
  • +
  • ListItemAttachment: when I upload a file that contains an hyphen, the "-" char is replaced by an empty string #526
  • +
  • IconPicker shows selected icon only during the first opening #513
  • +
  • ComboBoxListItemPicker: onSelectedItem passing data to callback method but with attributes value as undefined #519
  • +
  • FilePicker: filename is not visible on Upload tab #518
  • +
  • IconPicker: Search doesn't work at all #512
  • +
  • ComboBoxListItemPicker documentation fix: correct onSelectedItem notation #547
  • +
  • Documentation: Fix mistranslation in Japanese #545
  • +
  • FieldUserRenderer: displayName in FieldUserHoverCard is not updated if props of the FIeldUserRenderer have been changed #542
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): David Ramalho, Gautam Sheth, Gregghis, João Mendes, Joel Rodrigues, Nanddeep Nachan, Prasad Kasireddy, Siddharth Vaghasia, Takashi Shinohara.

+

1.17.0

+

New control(s)

+
    +
  • ComboBoxListItemPicker component #292
  • +
  • Localization: Project now supports localization of all SharePoint Online languages (auto translation via Cognitive Services) #456
  • +
  • IconPicker: component #485
  • +
  • FolderExplorer component #499
  • +
+

Enhancements

+
    +
  • SecurityTrimmedControl: Added the option to show a control when the user doesn't have permissions 307
  • +
  • PnP Telemetry service opt-out support #475
  • +
  • TaxonomyPicker: Possibility to hide deprecated and "Available for Tagging"= false terms #421
  • +
  • FilePicker - French translation #449
  • +
  • Slovak localization #457
  • +
  • TaxonomyPicker: Placeholder for Taxonomy Picker #464
  • +
  • ListItemPicker, PeoplePicker: Placeholder for ListItemPicker and PeoplePicker #486
  • +
  • FilePicker: Do not store active tab in url's hash #488
  • +
  • DateTimePicker: Placeholder property option added #503
  • +
+

Fixes

+
    +
  • RichText: problem with edit mode #445
  • +
  • ListView documentation: Typo - the first occurrence of maxWidth should be minWidth #400
  • +
  • RichText: Text indent buttons were copy-paste of subscript and superscript buttons. Clicking on the text-indent buttons would call subscript or superscript instead. #454
  • +
  • RichText: Fix of removing text and inserting link instead #455
  • +
  • FilePicker: Read file content in IE11 #444
  • +
  • ListPicker: listPicker always return "test" when multiple allowed #458
  • +
  • FilePicker: Button text overflow fix + global classnames and properties
  • +
  • FieldUserRenderer: implementation of api/SP.UserProfiles.PeopleManager/GetPropertiesFor is not working on on-prem #468
  • +
  • Placeholder: Placeholder component is not rendering after a string change in it's properties #469
  • +
  • ListView documentation update: minWidth instead of maxWidth #480
  • +
  • DateTimePicker: Minutes and Seconds validation #495
  • +
  • FilePicker: bingAPIKey not working #489
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Richard Gigan, Reginald Johnson, JonasBjerke89, Prasad Kasireddy, Alexander Kleshcheov, Konradox, Léo Maradan, Matej, mgwojciech, Joel Rodrigues, Jason S, Piotr Siatka, Rabia Williams.

+

1.16.0

+

Enhancements

+
    +
  • FilePicker: Fixes for OneDrive CORS issues #407
  • +
  • ListItemPicker: added new control property filter #392
  • +
  • allowing to use context from any type of SPFx extensions: #419
  • +
  • Placeholder: remove unused and vendor specific CSS #426
  • +
+

Fixes

+
    +
  • Documentation fix for FilePicker: updated accepts value in props #404
  • +
  • The FilePicker control doesn't work in many languages due to missing localization keys #412
  • +
  • Documentation fix for broken links of Property Controls landing page #388
  • +
  • Documentation fix to include new components from v 1.15.0 #394
  • +
  • DateTimePicker: dropdown for time not handling AM/PM correctly #405
  • +
  • Documentation fix for index page: updated link to Chart controls #417
  • +
  • Documentation update for SPFx On Premises notice: #418
  • +
  • Documentation update for ListItemPicker: valueColumnInternalName should be keyColumnInternalName
  • +
  • RichText: Fix "Align Left" button #429
  • +
  • Documentation update for FilePicker: misspelling #432
  • +
  • IFramePanel: Fix doubled scroll issue when iframe content is higher than frame height #431
  • +
  • PeoplePicker: errorMessage not showing #420
  • +
  • IFrameDialog: commitPopUp typo causes popups with classic forms to not close after hitting save #433
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Piotr Siatka, Dani Domínguez, Siddharth Vaghasia, João Mendes, PrasadKasireddy, Chad Eiserloh, Koen Zomers, Dmitry Rogozhny, Alexander Kleshcheov, Hugo Bernier, Beniamin, Giovani Martini.

+

1.15.0

+

New control(s)

+
    +
  • FilePicker: New control added to the library #366
  • +
  • GridLayout: New control added to the library #350
  • +
  • Carousel: New control added to the library #227
  • +
+

Enhancements

+
    +
  • TaxonomyPicker: Localization keys added to the buttons #361
  • +
  • Swedish localization support added #359
  • +
  • Improved German translations #338
  • +
  • DateTimePicker: added options to render time part as mask or dropdown #330
  • +
  • ListItemPicker: option to select a key column #350, #381
  • +
  • Improved Russian translations #384
  • +
  • RichText: Added the ability to add a third Color Swatch Group called custom. This will allow you to add custom colors to the font color selector. #385
  • +
+

Fixes

+
    +
  • TaxonomyPicker: Tags icon styling issue on IE11 #356
  • +
  • DateTimePicker: Does not respect dateLabel and timeLabel #346
  • +
  • PeoplePicker: Get loginName with ensureUser #342
  • +
  • PeoplePicker: Fix missing required field label #371
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): amortsell, Hugo Bernier, Robert Lindström, pfc2k8, Piotr Siatka, Alex Terentiev, Luis Robertto Mello, eweintraub.

+

1.14.0

+

Enhancements

+
    +
  • German translations added for attachment and RichText controls #333
  • +
  • SecurityTrimmedControl: Added a wrapper className property for the parent element #325
  • +
  • ListPicker: Add ability to filter the control via OData #319
  • +
  • IFrameDialog: closing dialog on commit #313
  • +
  • WebPartTitle add support for section background color #258
  • +
+

Fixes

+
    +
  • Fix in return type of onClick and onDoubleClick events #321
  • +
  • ListPicker: Fix for available dropdown selection after selection was done #315
  • +
  • Fixes to French translations #312
  • +
  • RichText: Issue on rendering the control in view mode #287
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Amr Fouad, Joel Jeffery, Mark Powney, Dominik Schmieder, Alex Terentiev, Zhephyr.

+

1.13.2

+

Enhancements

+
    +
  • Improvements to the Lithuanian localization #285
  • +
+

Fixes

+
    +
  • IFrameDialog: dimensions issue #303
  • +
  • DateTimePicker: IE11 layout issue #301
  • +
  • FileTypeIcon: Only displays PDF's in SPFx 1.8.2 #300
  • +
  • FieldNameRenderer: Fails to encode URI when hasPreview #296
  • +
  • TaxonomyPicker: Cannot find name `TermLabelAction #293
  • +
  • ListItemAttachments: Move deleted attachments to the recycle bin #291
  • +
  • DateTimePicker: Does not respect isMonthPickerVisible prop #283
  • +
  • ListItemAttachments: Render issue fixed + improvements to the attachment API calls #282
  • +
  • RichText: Fixes an issue when hitting enter in the control #277
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Tautvydas Duda, Thomas Granheim, Robert Lindström, Alex Terentiev.

+

1.13.1

+

Fixes

+
    +
  • WebPartTitle: Fix for className property which is not defined #281
  • +
  • RichText: Fix issue where control turns drop-downs black #279
  • +
+

Contributors

+

Special thanks to our contributor: Hugo Bernier.

+

1.13.0

+

New control(s)

+
    +
  • Progress: New control added #230
  • +
  • DateTimePicker: New control added #21
  • +
  • RichText: New control added #20
  • +
+

Enhancements

+
    +
  • SecurityTrimmedControl: Support for item and folder permission checks added #271
  • +
  • Retrieve the user its profile picture from SharePoint instead of Office 365 / Outlook #248
  • +
  • Added Lithuanian localization #247
  • +
  • FileTypeIcon: Added support for PDF icon file types #260
  • +
  • WebPartTitle: Added the ability to render a see all link or custom component #228
  • +
+

Fixes

+
    +
  • PeoplePicker: Fix for single quotes around the ms-peoplepicker class #275
  • +
  • RichText: Fix for toolbar that appears at top of the page #265
  • +
  • ListItemAttachments: Updated import statement reference in the documentation #254
  • +
  • ListView: Updated documentation for the iconFieldName property #245
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Francis, Fredrik Andreasson, Hugo Bernier, Tautvydas Duda, Özgür Ersoy, Robert Lindström, Alex Terentiev.

+

1.12.0

+

New control(s)

+
    +
  • ListItemAttachments: New control added #177
  • +
  • IFramePanel: New control added #226
  • +
+

Enhancements

+
    +
  • Added Russian localization #214
  • +
  • TaxonomyPicker: Ability to specify term actions #237
  • +
+

Fixes

+
    +
  • TaxonomyPicker: Terms are sorted incorrectly under the wrong parent #199 #229
  • +
  • TaxonomyPicker: Issue with custom sort order of items underneath root terms #231
  • +
  • PeoplePicker: Fix for issue where values couldn't be cleared #234
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Patrik Hellgren, João Mendes, David Opdendries, Piotr Siatka, Alex Terentiev, Tse Kit Yam.

+

1.11.0

+

New control(s)

+
    +
  • Map: Newly introduced map control is available #14
  • +
  • ChartControl: Newly introduced control to render charts #15
  • +
+

Enhancements

+
    +
  • PeoplePicker: Allow the people picker to search on site level and on tenant level #97
  • +
  • ListView: Added support for filtering #99
  • +
  • PeoplePicker: Make the titleText property not required #184
  • +
  • Placeholder: Added the ability to specify if the button can be hidden #206
  • +
  • Updated the office-ui-fabric-react to the same version as in SPFx 1.7.0
  • +
+

Fixes

+
    +
  • IFrameDialog: fix for spinner which keeps appearing on the iframe #154
  • +
  • PeoplePicker: fix SharePoint groups which could not be retrieved #161
  • +
  • TaxonomyPicker: fix sort order with lowercased terms #205
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Hugo Bernier, joaojmendes, Asish Padhy, Piotr Siatka, Anoop Tatti, Alex Terentiev, Tse Kit Yam.

+

1.10.0

+

New control(s)

+
    +
  • ListItemPicker: New field control #165
  • +
+

Enhancements

+
    +
  • Dutch localization added #100
  • +
  • German localization added #101
  • +
  • French localization added #102
  • +
  • PeoplePicker: Move defaultSelectedUsers from ComponentWillMount to ComponentDidUpdate Lifecycle #135
  • +
  • PeoplePicker: Initialize with users from a list item #138
  • +
  • PeoplePicker: Remove Messagebar error handling to match Office UI Fabric field error styling #140
  • +
  • PeoplePicker: REST API filter and nometadata header added to reduce payload #139
  • +
  • PeoplePicker: Allow to set the maximum number of suggestions suggestionsLimit #143 #148
  • +
  • TaxonomyPicker: retreiving the terms in the correct custom sort order #146
  • +
  • PeoplePicker: Documentation format updated to make it easier to check the default values #159
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Marc D Anderson, Ole Bergtun, João Mendes, Markus Möller, Asish Padhy, PooLP, Gautam Sheth, Tse Kit Yam.

+

1.9.0

+

Enhancements

+
    +
  • Optimize bundle size for latest SPFx version due to Office UI Fabric specific versioning #136
  • +
+

Fixes

+
    +
  • FieldLookupRenderer: Lookup dialog is empty #131
  • +
  • IFrameDialog: Unnecessary horizontal scroll in IFrame dialog #132
  • +
  • PeoplePicker: Suggested People not loading after first selection #134
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Gautam Sheth, Alex Terentiev.

+

1.8.0

+

Enhancements

+
    +
  • PeoplePicker: Specify to hide or show the users/groups which are hidden in the UI #122
  • +
  • WebPartTitle: changing font-sizes on different resolutions #114
  • +
  • WebPartTitle: Added accessibility tags for web part title #121
  • +
  • ListView: Resizable columns - introduced a isResizable property #119
  • +
  • FieldNameRenderer double click support added #116
  • +
  • TaxonomyPicker: table markup changed to DIV #113
  • +
  • PeoplePicker: ability to specify the source site to load users from #110
  • +
  • TaxonomyPicker: Disable the terms which are set as deprecated or unavailable for tagging #109
  • +
  • PeoplePicker: Specify principle type to retrieve (users, groups, ...) #94
  • +
+

Fixes

+
    +
  • FieldLookupRenderer: Fixed URL querystring params #126
  • +
  • IFrameDialog: dialog width is not correct in IE11 #118
  • +
  • PeoplePicker: fix freezes when typing in search values #117
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Thomas Lamb, Joel Rodrigues, Mikael Svenson, Alex Terentiev.

+

1.7.0

+

Enhancements

+
    +
  • PeoplePicker: added functionality to initialize the control with person(s) or group(s) #98
  • +
  • PeoplePicker: support for searching on contains #93
  • +
  • PeoplePicker: find user based on email address #95
  • +
  • Bundle size: statically reference Office UI Fabric components in the FieldRenderer controls #107
  • +
+

Fixes

+
    +
  • FieldNameRenderer onClick does not suppress default link behavior #103
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Octavie van Haaften, Asish Padhy, Mikael Svenson, Alex Terentiev.

+

1.6.0

+

Enhancements

+
    +
  • Disabled property for PeoplePicker #88
  • +
+

Fixes

+
    +
  • New telemetry approach which allows you to use Application Insights #81
  • +
  • PeoplePicker property selectedItems not implemented? #90
  • +
+

Contributors

+

Special thanks to our contributor: Octavie van Haaften.

+

1.5.0

+

New control(s)

+
    +
  • New PeoplePicker control added #19
  • +
+

Enhancements

+
    +
  • Added properties to the TaxonomyPicker to specify which terms are disabled/not-selectable #82
  • +
+

Fixes

+
    +
  • Bug in TaxonomyPicker where values are not updated by an async change #83
  • +
  • FieldUserRenderer uses email prop for GetPropertiesFor #84
  • +
  • Fixed issue in single selection mode when all group items were selected in the ListView when user clicked on the group header #86
  • +
+

Contributors

+

Special thanks to our contributors (in alphabetical order): Asish Padhy, Alex Terentiev.

+

1.4.0

+

New control(s)

+
    +
  • SecurityTrimmedControl control got added #74
  • +
+

Enhancements

+
    +
  • Allow the TaxonomyPicker to also be used in Application Customizer #77
  • +
  • Add npm postinstall script to automatically add the locale config #78
  • +
+

Fixes

+
    +
  • Icon not showing up in the Placeholder control #76
  • +
+

1.3.0

+

Enhancements

+
    +
  • TaxonomyPicker control got added #22 #63 #64
  • +
  • ListPicker control got added #34
  • +
+

Fixes

+
    +
  • Issue fixed when the optional selection property was not provided to the ListView #65
  • +
+

1.2.5

+

Fixes

+
    +
  • Undo ListView item selection after items array updates #55
  • +
+

1.2.4

+

Enhancements

+
    +
  • Hiding placeholder title on small zones
  • +
+

Fixes

+
    +
  • iFrame dialog reference fix #52
  • +
+

1.2.3

+

Enhancements

+
    +
  • Optimized telemetry so that it only pushes control data
  • +
  • WebPartTitle hide control completely when empty
  • +
+

1.2.2

+

Fixes

+
    +
  • Fixes an issue sorting in the ListView control while items were selected. Indexes were not updated.
  • +
+

1.2.1

+

Fixes

+
    +
  • FieldTaxonomyRenderer got fixed to support single and multiple values
  • +
+

1.2.0

+

New control(s)

+
    +
  • Field controls are added to the project
  • +
  • IFrameDialog was added to the project
  • +
+

Fixes

+
    +
  • Fixed theming in the WebPartTitle control
  • +
+

1.1.3

+

Fixes

+
    +
  • FileTypeIcon icon fixed where it did not render an icon. This control should now works in SPFx extensions.
  • +
+

1.1.2

+

Enhancements

+
    +
  • Improved telemetry with some object checks
  • +
+

Fixes

+
    +
  • Fix for WebPartTitle control to inherit color
  • +
+

1.1.1

+

Enhancements

+
    +
  • Removed operation name from telemetry
  • +
+

1.1.0

+

Enhancements

+
    +
  • Telemetry added
  • +
+

1.0.0

+

New control(s)

+
    +
  • WebPartTitle control got added
  • +
+

Enhancements

+
    +
  • ListView control got extended with the ability to specify a set of preselected items.
  • +
+

Beta 1.0.0-beta.8

+

Fixes

+
    +
  • Fix for the ListView control when selection is used in combination with setState.
  • +
+

Beta 1.0.0-beta.7

+

New control(s)

+
    +
  • Grouping functionality added to the ListView control
  • +
+

Beta 1.0.0-beta.6

+

New control(s)

+
    +
  • Initial release
  • +
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/assets/AccessibleAccordion.gif b/assets/AccessibleAccordion.gif new file mode 100644 index 000000000..db54ae957 Binary files /dev/null and b/assets/AccessibleAccordion.gif differ diff --git a/assets/AdaptiveCardDesignerHost.gif b/assets/AdaptiveCardDesignerHost.gif new file mode 100644 index 000000000..4715c3cda Binary files /dev/null and b/assets/AdaptiveCardDesignerHost.gif differ diff --git a/assets/AdaptiveCardHost.gif b/assets/AdaptiveCardHost.gif new file mode 100644 index 000000000..490709ae6 Binary files /dev/null and b/assets/AdaptiveCardHost.gif differ diff --git a/assets/AdaptiveCardHostTeams.gif b/assets/AdaptiveCardHostTeams.gif new file mode 100644 index 000000000..5c9a39775 Binary files /dev/null and b/assets/AdaptiveCardHostTeams.gif differ diff --git a/assets/AnimatedDialog.gif b/assets/AnimatedDialog.gif new file mode 100644 index 000000000..46138544a Binary files /dev/null and b/assets/AnimatedDialog.gif differ diff --git a/assets/AnimatedDialogCustomFooter.gif b/assets/AnimatedDialogCustomFooter.gif new file mode 100644 index 000000000..e314f23fe Binary files /dev/null and b/assets/AnimatedDialogCustomFooter.gif differ diff --git a/assets/AnimatedDialogWithIcon.gif b/assets/AnimatedDialogWithIcon.gif new file mode 100644 index 000000000..a45794818 Binary files /dev/null and b/assets/AnimatedDialogWithIcon.gif differ diff --git a/assets/AreaChart.png b/assets/AreaChart.png new file mode 100644 index 000000000..4078215c2 Binary files /dev/null and b/assets/AreaChart.png differ diff --git a/assets/AreaChartCurved.png b/assets/AreaChartCurved.png new file mode 100644 index 000000000..3acefd878 Binary files /dev/null and b/assets/AreaChartCurved.png differ diff --git a/assets/AreaChartDefault.png b/assets/AreaChartDefault.png new file mode 100644 index 000000000..9d8430db4 Binary files /dev/null and b/assets/AreaChartDefault.png differ diff --git a/assets/AreaChartFillEnd.png b/assets/AreaChartFillEnd.png new file mode 100644 index 000000000..ab7d058d0 Binary files /dev/null and b/assets/AreaChartFillEnd.png differ diff --git a/assets/AreaChartFillStart.png b/assets/AreaChartFillStart.png new file mode 100644 index 000000000..eb23918a7 Binary files /dev/null and b/assets/AreaChartFillStart.png differ diff --git a/assets/BarChart.png b/assets/BarChart.png new file mode 100644 index 000000000..2b68b45fd Binary files /dev/null and b/assets/BarChart.png differ diff --git a/assets/BarChartDefaultColors.png b/assets/BarChartDefaultColors.png new file mode 100644 index 000000000..fcc64471b Binary files /dev/null and b/assets/BarChartDefaultColors.png differ diff --git a/assets/BarTimeScale.png b/assets/BarTimeScale.png new file mode 100644 index 000000000..c4e72de94 Binary files /dev/null and b/assets/BarTimeScale.png differ diff --git a/assets/BubbleChart.png b/assets/BubbleChart.png new file mode 100644 index 000000000..e8b3f19bd Binary files /dev/null and b/assets/BubbleChart.png differ diff --git a/assets/Carousel.png b/assets/Carousel.png new file mode 100644 index 000000000..a5f819a5b Binary files /dev/null and b/assets/Carousel.png differ diff --git a/assets/ChartControl.gif b/assets/ChartControl.gif new file mode 100644 index 000000000..313d06d25 Binary files /dev/null and b/assets/ChartControl.gif differ diff --git a/assets/ChartControlDataPromise.gif b/assets/ChartControlDataPromise.gif new file mode 100644 index 000000000..d4e0f39bf Binary files /dev/null and b/assets/ChartControlDataPromise.gif differ diff --git a/assets/ChartControlDataPromiseError.gif b/assets/ChartControlDataPromiseError.gif new file mode 100644 index 000000000..28148593b Binary files /dev/null and b/assets/ChartControlDataPromiseError.gif differ diff --git a/assets/ChartControlDataPromiseSpinner.gif b/assets/ChartControlDataPromiseSpinner.gif new file mode 100644 index 000000000..7703e857f Binary files /dev/null and b/assets/ChartControlDataPromiseSpinner.gif differ diff --git a/assets/ChartControlSample1.png b/assets/ChartControlSample1.png new file mode 100644 index 000000000..82e7ee71e Binary files /dev/null and b/assets/ChartControlSample1.png differ diff --git a/assets/ChartControlSample2.png b/assets/ChartControlSample2.png new file mode 100644 index 000000000..76467d4b9 Binary files /dev/null and b/assets/ChartControlSample2.png differ diff --git a/assets/ChartControlSample3.png b/assets/ChartControlSample3.png new file mode 100644 index 000000000..25f70d944 Binary files /dev/null and b/assets/ChartControlSample3.png differ diff --git a/assets/ComboBoxListItemPicker_1.png b/assets/ComboBoxListItemPicker_1.png new file mode 100644 index 000000000..2589b32dc Binary files /dev/null and b/assets/ComboBoxListItemPicker_1.png differ diff --git a/assets/ComboBoxListItemPicker_Multi.png b/assets/ComboBoxListItemPicker_Multi.png new file mode 100644 index 000000000..925eff2eb Binary files /dev/null and b/assets/ComboBoxListItemPicker_Multi.png differ diff --git a/assets/ComboBoxListItemPicker_Options_Multi.png b/assets/ComboBoxListItemPicker_Options_Multi.png new file mode 100644 index 000000000..8a3a74da2 Binary files /dev/null and b/assets/ComboBoxListItemPicker_Options_Multi.png differ diff --git a/assets/ComboBoxListItemPicker_Options_Single.png b/assets/ComboBoxListItemPicker_Options_Single.png new file mode 100644 index 000000000..c9e94a6fc Binary files /dev/null and b/assets/ComboBoxListItemPicker_Options_Single.png differ diff --git a/assets/ContentTypePicker-initial.png b/assets/ContentTypePicker-initial.png new file mode 100644 index 000000000..cbc2286ea Binary files /dev/null and b/assets/ContentTypePicker-initial.png differ diff --git a/assets/ContentTypePicker-multi.png b/assets/ContentTypePicker-multi.png new file mode 100644 index 000000000..a861e6ead Binary files /dev/null and b/assets/ContentTypePicker-multi.png differ diff --git a/assets/ContentTypePicker-single.png b/assets/ContentTypePicker-single.png new file mode 100644 index 000000000..8038cc50f Binary files /dev/null and b/assets/ContentTypePicker-single.png differ diff --git a/assets/CustomisedAnimatedDialog.gif b/assets/CustomisedAnimatedDialog.gif new file mode 100644 index 000000000..77b9e6ff5 Binary files /dev/null and b/assets/CustomisedAnimatedDialog.gif differ diff --git a/assets/DateTimePicker-12h.png b/assets/DateTimePicker-12h.png new file mode 100644 index 000000000..9c5ccc25f Binary files /dev/null and b/assets/DateTimePicker-12h.png differ diff --git a/assets/DateTimePicker-24h.png b/assets/DateTimePicker-24h.png new file mode 100644 index 000000000..db0187dc7 Binary files /dev/null and b/assets/DateTimePicker-24h.png differ diff --git a/assets/DateTimePicker-dateOnly.png b/assets/DateTimePicker-dateOnly.png new file mode 100644 index 000000000..51bdff553 Binary files /dev/null and b/assets/DateTimePicker-dateOnly.png differ diff --git a/assets/DateTimePicker-dropdown.png b/assets/DateTimePicker-dropdown.png new file mode 100644 index 000000000..b75fdc259 Binary files /dev/null and b/assets/DateTimePicker-dropdown.png differ diff --git a/assets/DateTimePicker-noseconds.png b/assets/DateTimePicker-noseconds.png new file mode 100644 index 000000000..55c474f61 Binary files /dev/null and b/assets/DateTimePicker-noseconds.png differ diff --git a/assets/DefaultAnimatedDialog.gif b/assets/DefaultAnimatedDialog.gif new file mode 100644 index 000000000..a06bf11ac Binary files /dev/null and b/assets/DefaultAnimatedDialog.gif differ diff --git a/assets/DoughnutChart.png b/assets/DoughnutChart.png new file mode 100644 index 000000000..e60152084 Binary files /dev/null and b/assets/DoughnutChart.png differ diff --git a/assets/DragDropFilesSample1.png b/assets/DragDropFilesSample1.png new file mode 100644 index 000000000..53973a497 Binary files /dev/null and b/assets/DragDropFilesSample1.png differ diff --git a/assets/DragDropFilesSample2.png b/assets/DragDropFilesSample2.png new file mode 100644 index 000000000..80b23ef02 Binary files /dev/null and b/assets/DragDropFilesSample2.png differ diff --git a/assets/DynamicForm.png b/assets/DynamicForm.png new file mode 100644 index 000000000..73e489a5d Binary files /dev/null and b/assets/DynamicForm.png differ diff --git a/assets/DynamicFormWithFileSelection.png b/assets/DynamicFormWithFileSelection.png new file mode 100644 index 000000000..548b28573 Binary files /dev/null and b/assets/DynamicFormWithFileSelection.png differ diff --git a/assets/EnhancedThemeProviderSharePoint.gif b/assets/EnhancedThemeProviderSharePoint.gif new file mode 100644 index 000000000..ba7dd8fce Binary files /dev/null and b/assets/EnhancedThemeProviderSharePoint.gif differ diff --git a/assets/EnhancedThemeProviderTeams.gif b/assets/EnhancedThemeProviderTeams.gif new file mode 100644 index 000000000..db8cc15fd Binary files /dev/null and b/assets/EnhancedThemeProviderTeams.gif differ diff --git a/assets/FieldAttachmentsRenderer.png b/assets/FieldAttachmentsRenderer.png new file mode 100644 index 000000000..a05346277 Binary files /dev/null and b/assets/FieldAttachmentsRenderer.png differ diff --git a/assets/FieldCollectionData.gif b/assets/FieldCollectionData.gif new file mode 100644 index 000000000..fde743ec8 Binary files /dev/null and b/assets/FieldCollectionData.gif differ diff --git a/assets/FieldDateRenderer.png b/assets/FieldDateRenderer.png new file mode 100644 index 000000000..15e7116a8 Binary files /dev/null and b/assets/FieldDateRenderer.png differ diff --git a/assets/FieldFileTypeRenderer.png b/assets/FieldFileTypeRenderer.png new file mode 100644 index 000000000..c17c8a35e Binary files /dev/null and b/assets/FieldFileTypeRenderer.png differ diff --git a/assets/FieldLookupRenderer.png b/assets/FieldLookupRenderer.png new file mode 100644 index 000000000..fb1f92969 Binary files /dev/null and b/assets/FieldLookupRenderer.png differ diff --git a/assets/FieldLookupRendererDialog.png b/assets/FieldLookupRendererDialog.png new file mode 100644 index 000000000..494300fed Binary files /dev/null and b/assets/FieldLookupRendererDialog.png differ diff --git a/assets/FieldNameRenderer.png b/assets/FieldNameRenderer.png new file mode 100644 index 000000000..da7ec45e2 Binary files /dev/null and b/assets/FieldNameRenderer.png differ diff --git a/assets/FieldPicker-initial.png b/assets/FieldPicker-initial.png new file mode 100644 index 000000000..0c1e98b83 Binary files /dev/null and b/assets/FieldPicker-initial.png differ diff --git a/assets/FieldPicker-multi.png b/assets/FieldPicker-multi.png new file mode 100644 index 000000000..6e27ef892 Binary files /dev/null and b/assets/FieldPicker-multi.png differ diff --git a/assets/FieldPicker-single.png b/assets/FieldPicker-single.png new file mode 100644 index 000000000..bf1ed359d Binary files /dev/null and b/assets/FieldPicker-single.png differ diff --git a/assets/FieldTaxonomyRenderer.png b/assets/FieldTaxonomyRenderer.png new file mode 100644 index 000000000..68d6f2e14 Binary files /dev/null and b/assets/FieldTaxonomyRenderer.png differ diff --git a/assets/FieldTextRenderer.png b/assets/FieldTextRenderer.png new file mode 100644 index 000000000..c7c99a373 Binary files /dev/null and b/assets/FieldTextRenderer.png differ diff --git a/assets/FieldTitleRenderer.png b/assets/FieldTitleRenderer.png new file mode 100644 index 000000000..5e44501f6 Binary files /dev/null and b/assets/FieldTitleRenderer.png differ diff --git a/assets/FieldUrlRendererImage.png b/assets/FieldUrlRendererImage.png new file mode 100644 index 000000000..cc609af10 Binary files /dev/null and b/assets/FieldUrlRendererImage.png differ diff --git a/assets/FieldUrlRendererUrl.png b/assets/FieldUrlRendererUrl.png new file mode 100644 index 000000000..9b0d98e3b Binary files /dev/null and b/assets/FieldUrlRendererUrl.png differ diff --git a/assets/FieldUserRenderer.png b/assets/FieldUserRenderer.png new file mode 100644 index 000000000..a4186e6a9 Binary files /dev/null and b/assets/FieldUserRenderer.png differ diff --git a/assets/FieldUserRendererPersona.png b/assets/FieldUserRendererPersona.png new file mode 100644 index 000000000..d1a797d87 Binary files /dev/null and b/assets/FieldUserRendererPersona.png differ diff --git a/assets/FilePickerBreadcrumb.gif b/assets/FilePickerBreadcrumb.gif new file mode 100644 index 000000000..0e58e9f0e Binary files /dev/null and b/assets/FilePickerBreadcrumb.gif differ diff --git a/assets/FilePickerOverview.png b/assets/FilePickerOverview.png new file mode 100644 index 000000000..d08b16a3e Binary files /dev/null and b/assets/FilePickerOverview.png differ diff --git a/assets/FilePickerPaging.gif b/assets/FilePickerPaging.gif new file mode 100644 index 000000000..03fc81498 Binary files /dev/null and b/assets/FilePickerPaging.gif differ diff --git a/assets/FilePickerViews.gif b/assets/FilePickerViews.gif new file mode 100644 index 000000000..d3b47e8aa Binary files /dev/null and b/assets/FilePickerViews.gif differ diff --git a/assets/FileTypeIcon.png b/assets/FileTypeIcon.png new file mode 100644 index 000000000..0305e0b7f Binary files /dev/null and b/assets/FileTypeIcon.png differ diff --git a/assets/FolderExplorer-new.png b/assets/FolderExplorer-new.png new file mode 100644 index 000000000..c0d7d2e15 Binary files /dev/null and b/assets/FolderExplorer-new.png differ diff --git a/assets/FolderExplorer.png b/assets/FolderExplorer.png new file mode 100644 index 000000000..807476375 Binary files /dev/null and b/assets/FolderExplorer.png differ diff --git a/assets/FolderPicker-no-selection.png b/assets/FolderPicker-no-selection.png new file mode 100644 index 000000000..847d187a5 Binary files /dev/null and b/assets/FolderPicker-no-selection.png differ diff --git a/assets/FolderPicker-selected.png b/assets/FolderPicker-selected.png new file mode 100644 index 000000000..8ecfd60fd Binary files /dev/null and b/assets/FolderPicker-selected.png differ diff --git a/assets/FolderPicker-selection.png b/assets/FolderPicker-selection.png new file mode 100644 index 000000000..1362eee60 Binary files /dev/null and b/assets/FolderPicker-selection.png differ diff --git a/assets/FolderPicker.png b/assets/FolderPicker.png new file mode 100644 index 000000000..5ce0a6d72 Binary files /dev/null and b/assets/FolderPicker.png differ diff --git a/assets/GridLayout.png b/assets/GridLayout.png new file mode 100644 index 000000000..e3b2472d6 Binary files /dev/null and b/assets/GridLayout.png differ diff --git a/assets/GridLayoutReflow.gif b/assets/GridLayoutReflow.gif new file mode 100644 index 000000000..47513d6c7 Binary files /dev/null and b/assets/GridLayoutReflow.gif differ diff --git a/assets/HorizontalBarChart.png b/assets/HorizontalBarChart.png new file mode 100644 index 000000000..caf0e6cd6 Binary files /dev/null and b/assets/HorizontalBarChart.png differ diff --git a/assets/IFramePanel.png b/assets/IFramePanel.png new file mode 100644 index 000000000..ae38f9a09 Binary files /dev/null and b/assets/IFramePanel.png differ diff --git a/assets/IconPickerOverview.png b/assets/IconPickerOverview.png new file mode 100644 index 000000000..ee6478841 Binary files /dev/null and b/assets/IconPickerOverview.png differ diff --git a/assets/IconPickerPanel.gif b/assets/IconPickerPanel.gif new file mode 100644 index 000000000..f1c5ef14c Binary files /dev/null and b/assets/IconPickerPanel.gif differ diff --git a/assets/IconPicker_dialog.gif b/assets/IconPicker_dialog.gif new file mode 100644 index 000000000..d8c1d42aa Binary files /dev/null and b/assets/IconPicker_dialog.gif differ diff --git a/assets/ImagePicker00.png b/assets/ImagePicker00.png new file mode 100644 index 000000000..4caf09a70 Binary files /dev/null and b/assets/ImagePicker00.png differ diff --git a/assets/ImagePicker01.png b/assets/ImagePicker01.png new file mode 100644 index 000000000..c84aec14b Binary files /dev/null and b/assets/ImagePicker01.png differ diff --git a/assets/ImagePicker02.png b/assets/ImagePicker02.png new file mode 100644 index 000000000..da5e144f6 Binary files /dev/null and b/assets/ImagePicker02.png differ diff --git a/assets/ImagePicker03.png b/assets/ImagePicker03.png new file mode 100644 index 000000000..53b29a107 Binary files /dev/null and b/assets/ImagePicker03.png differ diff --git a/assets/ImagePicker04.png b/assets/ImagePicker04.png new file mode 100644 index 000000000..d67420f57 Binary files /dev/null and b/assets/ImagePicker04.png differ diff --git a/assets/ImagePicker05.png b/assets/ImagePicker05.png new file mode 100644 index 000000000..f65b8d53c Binary files /dev/null and b/assets/ImagePicker05.png differ diff --git a/assets/LineChart.png b/assets/LineChart.png new file mode 100644 index 000000000..4e129afa1 Binary files /dev/null and b/assets/LineChart.png differ diff --git a/assets/LineChartCurved.png b/assets/LineChartCurved.png new file mode 100644 index 000000000..f9b28dae9 Binary files /dev/null and b/assets/LineChartCurved.png differ diff --git a/assets/ListItemAttachementDeletedMsg.png b/assets/ListItemAttachementDeletedMsg.png new file mode 100644 index 000000000..7d5c37a07 Binary files /dev/null and b/assets/ListItemAttachementDeletedMsg.png differ diff --git a/assets/ListItemAttachmentDeleteConfirm.png b/assets/ListItemAttachmentDeleteConfirm.png new file mode 100644 index 000000000..c0cc7f241 Binary files /dev/null and b/assets/ListItemAttachmentDeleteConfirm.png differ diff --git a/assets/ListItemAttachmentsTitles.png b/assets/ListItemAttachmentsTitles.png new file mode 100644 index 000000000..aa8927857 Binary files /dev/null and b/assets/ListItemAttachmentsTitles.png differ diff --git a/assets/ListItemAttachmentsTitles2.png b/assets/ListItemAttachmentsTitles2.png new file mode 100644 index 000000000..e67fe6e5a Binary files /dev/null and b/assets/ListItemAttachmentsTitles2.png differ diff --git a/assets/ListItemAttachmentsUpload.png b/assets/ListItemAttachmentsUpload.png new file mode 100644 index 000000000..20c60aa68 Binary files /dev/null and b/assets/ListItemAttachmentsUpload.png differ diff --git a/assets/ListItemComments.gif b/assets/ListItemComments.gif new file mode 100644 index 000000000..b1347d9db Binary files /dev/null and b/assets/ListItemComments.gif differ diff --git a/assets/ListItemComments01.png b/assets/ListItemComments01.png new file mode 100644 index 000000000..a61343a71 Binary files /dev/null and b/assets/ListItemComments01.png differ diff --git a/assets/ListItemComments02.png b/assets/ListItemComments02.png new file mode 100644 index 000000000..30595097e Binary files /dev/null and b/assets/ListItemComments02.png differ diff --git a/assets/ListItemComments03.png b/assets/ListItemComments03.png new file mode 100644 index 000000000..fa4ca653e Binary files /dev/null and b/assets/ListItemComments03.png differ diff --git a/assets/ListItemComments04.png b/assets/ListItemComments04.png new file mode 100644 index 000000000..351fde302 Binary files /dev/null and b/assets/ListItemComments04.png differ diff --git a/assets/ListItemComments05.png b/assets/ListItemComments05.png new file mode 100644 index 000000000..2ec5510c6 Binary files /dev/null and b/assets/ListItemComments05.png differ diff --git a/assets/ListItemComments06.png b/assets/ListItemComments06.png new file mode 100644 index 000000000..db246a5ed Binary files /dev/null and b/assets/ListItemComments06.png differ diff --git a/assets/ListItemPicker-selectedItems.png b/assets/ListItemPicker-selectedItems.png new file mode 100644 index 000000000..bca220555 Binary files /dev/null and b/assets/ListItemPicker-selectedItems.png differ diff --git a/assets/ListItemPicker-selectlist.png b/assets/ListItemPicker-selectlist.png new file mode 100644 index 000000000..aff7eb624 Binary files /dev/null and b/assets/ListItemPicker-selectlist.png differ diff --git a/assets/ListItemPicker-selectlist2.png b/assets/ListItemPicker-selectlist2.png new file mode 100644 index 000000000..c900bbe7b Binary files /dev/null and b/assets/ListItemPicker-selectlist2.png differ diff --git a/assets/ListPicker-initial.png b/assets/ListPicker-initial.png new file mode 100644 index 000000000..dc54fda35 Binary files /dev/null and b/assets/ListPicker-initial.png differ diff --git a/assets/ListPicker-multi.png b/assets/ListPicker-multi.png new file mode 100644 index 000000000..f0b06ac7d Binary files /dev/null and b/assets/ListPicker-multi.png differ diff --git a/assets/ListPicker-single.png b/assets/ListPicker-single.png new file mode 100644 index 000000000..06d8afddb Binary files /dev/null and b/assets/ListPicker-single.png differ diff --git a/assets/ListView-DragDrop.png b/assets/ListView-DragDrop.png new file mode 100644 index 000000000..e711b037e Binary files /dev/null and b/assets/ListView-DragDrop.png differ diff --git a/assets/ListView-grouping.png b/assets/ListView-grouping.png new file mode 100644 index 000000000..2ae25c131 Binary files /dev/null and b/assets/ListView-grouping.png differ diff --git a/assets/ListView.ContextualMenu.png b/assets/ListView.ContextualMenu.png new file mode 100644 index 000000000..618d1ab5c Binary files /dev/null and b/assets/ListView.ContextualMenu.png differ diff --git a/assets/ListView.ContextualMenu_clicked.png b/assets/ListView.ContextualMenu_clicked.png new file mode 100644 index 000000000..8979db3f2 Binary files /dev/null and b/assets/ListView.ContextualMenu_clicked.png differ diff --git a/assets/ListView.png b/assets/ListView.png new file mode 100644 index 000000000..68fd76674 Binary files /dev/null and b/assets/ListView.png differ diff --git a/assets/LivePersona.png b/assets/LivePersona.png new file mode 100644 index 000000000..057d3efa7 Binary files /dev/null and b/assets/LivePersona.png differ diff --git a/assets/ModernAudioDarkLime.png b/assets/ModernAudioDarkLime.png new file mode 100644 index 000000000..714a11160 Binary files /dev/null and b/assets/ModernAudioDarkLime.png differ diff --git a/assets/ModernAudioDefault.png b/assets/ModernAudioDefault.png new file mode 100644 index 000000000..38d2b642e Binary files /dev/null and b/assets/ModernAudioDefault.png differ diff --git a/assets/ModernAudioInAction.gif b/assets/ModernAudioInAction.gif new file mode 100644 index 000000000..0fa3eb208 Binary files /dev/null and b/assets/ModernAudioInAction.gif differ diff --git a/assets/MonacoEditor1.png b/assets/MonacoEditor1.png new file mode 100644 index 000000000..17aa902f4 Binary files /dev/null and b/assets/MonacoEditor1.png differ diff --git a/assets/MonacoEditor2.png b/assets/MonacoEditor2.png new file mode 100644 index 000000000..1e9e3ff90 Binary files /dev/null and b/assets/MonacoEditor2.png differ diff --git a/assets/OfficeColorful1.png b/assets/OfficeColorful1.png new file mode 100644 index 000000000..9de238a1d Binary files /dev/null and b/assets/OfficeColorful1.png differ diff --git a/assets/OfficeColorful2.png b/assets/OfficeColorful2.png new file mode 100644 index 000000000..985a773b4 Binary files /dev/null and b/assets/OfficeColorful2.png differ diff --git a/assets/OfficeColorful3.png b/assets/OfficeColorful3.png new file mode 100644 index 000000000..75802c37e Binary files /dev/null and b/assets/OfficeColorful3.png differ diff --git a/assets/OfficeColorful4.png b/assets/OfficeColorful4.png new file mode 100644 index 000000000..0f379c6ab Binary files /dev/null and b/assets/OfficeColorful4.png differ diff --git a/assets/OfficeMono1.png b/assets/OfficeMono1.png new file mode 100644 index 000000000..1f6f2cecf Binary files /dev/null and b/assets/OfficeMono1.png differ diff --git a/assets/OfficeMono10.png b/assets/OfficeMono10.png new file mode 100644 index 000000000..6fd49280c Binary files /dev/null and b/assets/OfficeMono10.png differ diff --git a/assets/OfficeMono11.png b/assets/OfficeMono11.png new file mode 100644 index 000000000..68ca0e006 Binary files /dev/null and b/assets/OfficeMono11.png differ diff --git a/assets/OfficeMono12.png b/assets/OfficeMono12.png new file mode 100644 index 000000000..c4a6fb3da Binary files /dev/null and b/assets/OfficeMono12.png differ diff --git a/assets/OfficeMono13.png b/assets/OfficeMono13.png new file mode 100644 index 000000000..85e76af14 Binary files /dev/null and b/assets/OfficeMono13.png differ diff --git a/assets/OfficeMono2.png b/assets/OfficeMono2.png new file mode 100644 index 000000000..5c3579a0c Binary files /dev/null and b/assets/OfficeMono2.png differ diff --git a/assets/OfficeMono3.png b/assets/OfficeMono3.png new file mode 100644 index 000000000..f852a2904 Binary files /dev/null and b/assets/OfficeMono3.png differ diff --git a/assets/OfficeMono4.png b/assets/OfficeMono4.png new file mode 100644 index 000000000..9ef79af4c Binary files /dev/null and b/assets/OfficeMono4.png differ diff --git a/assets/OfficeMono5.png b/assets/OfficeMono5.png new file mode 100644 index 000000000..801c3b296 Binary files /dev/null and b/assets/OfficeMono5.png differ diff --git a/assets/OfficeMono6.png b/assets/OfficeMono6.png new file mode 100644 index 000000000..0d8c19029 Binary files /dev/null and b/assets/OfficeMono6.png differ diff --git a/assets/OfficeMono7.png b/assets/OfficeMono7.png new file mode 100644 index 000000000..66561bd13 Binary files /dev/null and b/assets/OfficeMono7.png differ diff --git a/assets/OfficeMono8.png b/assets/OfficeMono8.png new file mode 100644 index 000000000..f60e54e6e Binary files /dev/null and b/assets/OfficeMono8.png differ diff --git a/assets/OfficeMono9.png b/assets/OfficeMono9.png new file mode 100644 index 000000000..8ace6f741 Binary files /dev/null and b/assets/OfficeMono9.png differ diff --git a/assets/Pagination.gif b/assets/Pagination.gif new file mode 100644 index 000000000..3ea1bc8f9 Binary files /dev/null and b/assets/Pagination.gif differ diff --git a/assets/Peoplepicker-multiplechoices.png b/assets/Peoplepicker-multiplechoices.png new file mode 100644 index 000000000..f2c4ff4f1 Binary files /dev/null and b/assets/Peoplepicker-multiplechoices.png differ diff --git a/assets/Peoplepicker-selectingchoices.png b/assets/Peoplepicker-selectingchoices.png new file mode 100644 index 000000000..732a50715 Binary files /dev/null and b/assets/Peoplepicker-selectingchoices.png differ diff --git a/assets/Peoplepicker-witherrorandtooltip.png b/assets/Peoplepicker-witherrorandtooltip.png new file mode 100644 index 000000000..5bbc24715 Binary files /dev/null and b/assets/Peoplepicker-witherrorandtooltip.png differ diff --git a/assets/PieChart.png b/assets/PieChart.png new file mode 100644 index 000000000..c1c038104 Binary files /dev/null and b/assets/PieChart.png differ diff --git a/assets/PieChartFuelGage.png b/assets/PieChartFuelGage.png new file mode 100644 index 000000000..49f071748 Binary files /dev/null and b/assets/PieChartFuelGage.png differ diff --git a/assets/PieChartHalfMoon.png b/assets/PieChartHalfMoon.png new file mode 100644 index 000000000..28e22f124 Binary files /dev/null and b/assets/PieChartHalfMoon.png differ diff --git a/assets/PieChartHalfMoonSideway.png b/assets/PieChartHalfMoonSideway.png new file mode 100644 index 000000000..edb353454 Binary files /dev/null and b/assets/PieChartHalfMoonSideway.png differ diff --git a/assets/Placeholder.png b/assets/Placeholder.png new file mode 100644 index 000000000..ec158d316 Binary files /dev/null and b/assets/Placeholder.png differ diff --git a/assets/PolarAreaChart.png b/assets/PolarAreaChart.png new file mode 100644 index 000000000..ea9f3da12 Binary files /dev/null and b/assets/PolarAreaChart.png differ diff --git a/assets/Progress.png b/assets/Progress.png new file mode 100644 index 000000000..cbac3a4bc Binary files /dev/null and b/assets/Progress.png differ diff --git a/assets/ProgressStepsIndicator.png b/assets/ProgressStepsIndicator.png new file mode 100644 index 000000000..db1fbe35f Binary files /dev/null and b/assets/ProgressStepsIndicator.png differ diff --git a/assets/RadarChart.png b/assets/RadarChart.png new file mode 100644 index 000000000..e0312ec0b Binary files /dev/null and b/assets/RadarChart.png differ diff --git a/assets/RichTextOutput.gif b/assets/RichTextOutput.gif new file mode 100644 index 000000000..04b3f4376 Binary files /dev/null and b/assets/RichTextOutput.gif differ diff --git a/assets/ScatterChart.png b/assets/ScatterChart.png new file mode 100644 index 000000000..a0e17b347 Binary files /dev/null and b/assets/ScatterChart.png differ diff --git a/assets/ScatterDatasetStyle.png b/assets/ScatterDatasetStyle.png new file mode 100644 index 000000000..b99de1dc2 Binary files /dev/null and b/assets/ScatterDatasetStyle.png differ diff --git a/assets/ScatterPointStyle.png b/assets/ScatterPointStyle.png new file mode 100644 index 000000000..54a68349a Binary files /dev/null and b/assets/ScatterPointStyle.png differ diff --git a/assets/SelectTeamChannelPicker.png b/assets/SelectTeamChannelPicker.png new file mode 100644 index 000000000..e049a8830 Binary files /dev/null and b/assets/SelectTeamChannelPicker.png differ diff --git a/assets/SelectTeamPicker.gif b/assets/SelectTeamPicker.gif new file mode 100644 index 000000000..78918f3fb Binary files /dev/null and b/assets/SelectTeamPicker.gif differ diff --git a/assets/SelectTeamPicker.png b/assets/SelectTeamPicker.png new file mode 100644 index 000000000..ab52a2e30 Binary files /dev/null and b/assets/SelectTeamPicker.png differ diff --git a/assets/SelectTeamPicker_select.png b/assets/SelectTeamPicker_select.png new file mode 100644 index 000000000..64a4b1fc8 Binary files /dev/null and b/assets/SelectTeamPicker_select.png differ diff --git a/assets/SiteBreadcrumb-selected.png b/assets/SiteBreadcrumb-selected.png new file mode 100644 index 000000000..1416399a3 Binary files /dev/null and b/assets/SiteBreadcrumb-selected.png differ diff --git a/assets/SiteBreadcrumb.png b/assets/SiteBreadcrumb.png new file mode 100644 index 000000000..f11470bc5 Binary files /dev/null and b/assets/SiteBreadcrumb.png differ diff --git a/assets/StackedAreaChart.png b/assets/StackedAreaChart.png new file mode 100644 index 000000000..2490bc9fe Binary files /dev/null and b/assets/StackedAreaChart.png differ diff --git a/assets/StackedAreaChartFillStartMinus1.png b/assets/StackedAreaChartFillStartMinus1.png new file mode 100644 index 000000000..ee7f28d4a Binary files /dev/null and b/assets/StackedAreaChartFillStartMinus1.png differ diff --git a/assets/StackedBarChart.png b/assets/StackedBarChart.png new file mode 100644 index 000000000..8ffdcbfb4 Binary files /dev/null and b/assets/StackedBarChart.png differ diff --git a/assets/TermSetNavigation.gif b/assets/TermSetNavigation.gif new file mode 100644 index 000000000..1cc3d8e04 Binary files /dev/null and b/assets/TermSetNavigation.gif differ diff --git a/assets/TermSetNavigation.png b/assets/TermSetNavigation.png new file mode 100644 index 000000000..23c528eff Binary files /dev/null and b/assets/TermSetNavigation.png differ diff --git a/assets/TreeView-all-possible-options.png b/assets/TreeView-all-possible-options.png new file mode 100644 index 000000000..50e11dd94 Binary files /dev/null and b/assets/TreeView-all-possible-options.png differ diff --git a/assets/TreeView-control.gif b/assets/TreeView-control.gif new file mode 100644 index 000000000..c6b306040 Binary files /dev/null and b/assets/TreeView-control.gif differ diff --git a/assets/TreeView-without-checkbox-selection-mode.png b/assets/TreeView-without-checkbox-selection-mode.png new file mode 100644 index 000000000..84d353499 Binary files /dev/null and b/assets/TreeView-without-checkbox-selection-mode.png differ diff --git a/assets/TreeView-without-checkbox.png b/assets/TreeView-without-checkbox.png new file mode 100644 index 000000000..a8baf680b Binary files /dev/null and b/assets/TreeView-without-checkbox.png differ diff --git a/assets/UploadFiles.gif b/assets/UploadFiles.gif new file mode 100644 index 000000000..09bfbc116 Binary files /dev/null and b/assets/UploadFiles.gif differ diff --git a/assets/UploadFiles01.png b/assets/UploadFiles01.png new file mode 100644 index 000000000..9f3454447 Binary files /dev/null and b/assets/UploadFiles01.png differ diff --git a/assets/UploadFiles02.png b/assets/UploadFiles02.png new file mode 100644 index 000000000..6cedf3b54 Binary files /dev/null and b/assets/UploadFiles02.png differ diff --git a/assets/VariantThemeProvider.gif b/assets/VariantThemeProvider.gif new file mode 100644 index 000000000..c371f5de2 Binary files /dev/null and b/assets/VariantThemeProvider.gif differ diff --git a/assets/ViewPicker-multi.png b/assets/ViewPicker-multi.png new file mode 100644 index 000000000..840bb80bb Binary files /dev/null and b/assets/ViewPicker-multi.png differ diff --git a/assets/ViewPicker1.PNG b/assets/ViewPicker1.PNG new file mode 100644 index 000000000..76fc3495e Binary files /dev/null and b/assets/ViewPicker1.PNG differ diff --git a/assets/ViewPicker2.png b/assets/ViewPicker2.png new file mode 100644 index 000000000..550e79da7 Binary files /dev/null and b/assets/ViewPicker2.png differ diff --git a/assets/accordion.png b/assets/accordion.png new file mode 100644 index 000000000..5939115f6 Binary files /dev/null and b/assets/accordion.png differ diff --git a/assets/accordionCustomIcons.png b/assets/accordionCustomIcons.png new file mode 100644 index 000000000..a013050b3 Binary files /dev/null and b/assets/accordionCustomIcons.png differ diff --git a/assets/dashboard.png b/assets/dashboard.png new file mode 100644 index 000000000..29e372d64 Binary files /dev/null and b/assets/dashboard.png differ diff --git a/assets/fonts/font-awesome.css b/assets/fonts/font-awesome.css new file mode 100644 index 000000000..b476b53e3 --- /dev/null +++ b/assets/fonts/font-awesome.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url("specimen/FontAwesome.woff2") format("woff2"),url("specimen/FontAwesome.woff") format("woff"),url("specimen/FontAwesome.ttf") format("truetype")}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} \ No newline at end of file diff --git a/assets/fonts/material-icons.css b/assets/fonts/material-icons.css new file mode 100644 index 000000000..d23d365ed --- /dev/null +++ b/assets/fonts/material-icons.css @@ -0,0 +1,13 @@ +/*! + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE + * DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + * SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND + * LIMITATIONS UNDER THE LICENSE. + */@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url("specimen/MaterialIcons-Regular.woff2") format("woff2"),url("specimen/MaterialIcons-Regular.woff") format("woff"),url("specimen/MaterialIcons-Regular.ttf") format("truetype")} \ No newline at end of file diff --git a/assets/fonts/specimen/FontAwesome.ttf b/assets/fonts/specimen/FontAwesome.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/assets/fonts/specimen/FontAwesome.ttf differ diff --git a/assets/fonts/specimen/FontAwesome.woff b/assets/fonts/specimen/FontAwesome.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/assets/fonts/specimen/FontAwesome.woff differ diff --git a/assets/fonts/specimen/FontAwesome.woff2 b/assets/fonts/specimen/FontAwesome.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/assets/fonts/specimen/FontAwesome.woff2 differ diff --git a/assets/fonts/specimen/MaterialIcons-Regular.ttf b/assets/fonts/specimen/MaterialIcons-Regular.ttf new file mode 100644 index 000000000..7015564ad Binary files /dev/null and b/assets/fonts/specimen/MaterialIcons-Regular.ttf differ diff --git a/assets/fonts/specimen/MaterialIcons-Regular.woff b/assets/fonts/specimen/MaterialIcons-Regular.woff new file mode 100644 index 000000000..b648a3eea Binary files /dev/null and b/assets/fonts/specimen/MaterialIcons-Regular.woff differ diff --git a/assets/fonts/specimen/MaterialIcons-Regular.woff2 b/assets/fonts/specimen/MaterialIcons-Regular.woff2 new file mode 100644 index 000000000..9fa211252 Binary files /dev/null and b/assets/fonts/specimen/MaterialIcons-Regular.woff2 differ diff --git a/assets/hoverReactions3Bar.png b/assets/hoverReactions3Bar.png new file mode 100644 index 000000000..36b8638e9 Binary files /dev/null and b/assets/hoverReactions3Bar.png differ diff --git a/assets/hoverReactionsBar1.png b/assets/hoverReactionsBar1.png new file mode 100644 index 000000000..fd293d8ce Binary files /dev/null and b/assets/hoverReactionsBar1.png differ diff --git a/assets/hoverReactionsBar2.png b/assets/hoverReactionsBar2.png new file mode 100644 index 000000000..3dccebcda Binary files /dev/null and b/assets/hoverReactionsBar2.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 000000000..76d17f57a Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/images/icons/bitbucket.1b09e088.svg b/assets/images/icons/bitbucket.1b09e088.svg new file mode 100644 index 000000000..a25435af3 --- /dev/null +++ b/assets/images/icons/bitbucket.1b09e088.svg @@ -0,0 +1,20 @@ + + + diff --git a/assets/images/icons/github.f0b8504a.svg b/assets/images/icons/github.f0b8504a.svg new file mode 100644 index 000000000..c009420a7 --- /dev/null +++ b/assets/images/icons/github.f0b8504a.svg @@ -0,0 +1,18 @@ + + + diff --git a/assets/images/icons/gitlab.6dd19c00.svg b/assets/images/icons/gitlab.6dd19c00.svg new file mode 100644 index 000000000..9e3d6f05b --- /dev/null +++ b/assets/images/icons/gitlab.6dd19c00.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/javascripts/application.9e1f3b71.js b/assets/javascripts/application.9e1f3b71.js new file mode 100644 index 000000000..423539028 --- /dev/null +++ b/assets/javascripts/application.9e1f3b71.js @@ -0,0 +1 @@ +!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=6)}([function(e,t,n){"use strict";t.__esModule=!0,t.default={createElement:function(e,t){var n=document.createElement(e);t&&Array.prototype.forEach.call(Object.keys(t),function(e){n.setAttribute(e,t[e])});for(var r=arguments.length,i=Array(r>2?r-2:0),o=2;o pre, pre > code");Array.prototype.forEach.call(n,function(t,n){var r="__code_"+n,i=e.createElement("button",{class:"md-clipboard",title:h("clipboard.copy"),"data-clipboard-target":"#"+r+" pre, #"+r+" code"},e.createElement("span",{class:"md-clipboard__message"})),o=t.parentNode;o.id=r,o.insertBefore(i,t)});new c.default(".md-clipboard").on("success",function(e){var t=e.trigger.querySelector(".md-clipboard__message");if(!(t instanceof HTMLElement))throw new ReferenceError;e.clearSelection(),t.dataset.mdTimer&&clearTimeout(parseInt(t.dataset.mdTimer,10)),t.classList.add("md-clipboard__message--active"),t.innerHTML=h("clipboard.copied"),t.dataset.mdTimer=setTimeout(function(){t.classList.remove("md-clipboard__message--active"),t.dataset.mdTimer=""},2e3).toString()})}if(!Modernizr.details){var r=document.querySelectorAll("details > summary");Array.prototype.forEach.call(r,function(e){e.addEventListener("click",function(e){var t=e.target.parentNode;t.hasAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","")})})}var i=function(){if(document.location.hash){var e=document.getElementById(document.location.hash.substring(1));if(!e)return;for(var t=e.parentNode;t&&!(t instanceof HTMLDetailsElement);)t=t.parentNode;if(t&&!t.open){t.open=!0;var n=location.hash;location.hash=" ",location.hash=n}}};if(window.addEventListener("hashchange",i),i(),Modernizr.ios){var o=document.querySelectorAll("[data-md-scrollfix]");Array.prototype.forEach.call(o,function(e){e.addEventListener("touchstart",function(){var t=e.scrollTop;0===t?e.scrollTop=1:t+e.offsetHeight===e.scrollHeight&&(e.scrollTop=t-1)})})}}).listen(),new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Header.Shadow("[data-md-component=container]","[data-md-component=header]")).listen(),new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Header.Title("[data-md-component=title]",".md-typeset h1")).listen(),document.querySelector("[data-md-component=hero]")&&new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Tabs.Toggle("[data-md-component=hero]")).listen(),document.querySelector("[data-md-component=tabs]")&&new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Tabs.Toggle("[data-md-component=tabs]")).listen(),new d.default.Event.MatchMedia("(min-width: 1220px)",new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Sidebar.Position("[data-md-component=navigation]","[data-md-component=header]"))),document.querySelector("[data-md-component=toc]")&&new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Sidebar.Position("[data-md-component=toc]","[data-md-component=header]"))),new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener(window,"scroll",new d.default.Nav.Blur("[data-md-component=toc] [href]")));var n=document.querySelectorAll("[data-md-component=collapsible]");Array.prototype.forEach.call(n,function(e){new d.default.Event.MatchMedia("(min-width: 1220px)",new d.default.Event.Listener(e.previousElementSibling,"click",new d.default.Nav.Collapse(e)))}),new d.default.Event.MatchMedia("(max-width: 1219px)",new d.default.Event.Listener("[data-md-component=navigation] [data-md-toggle]","change",new d.default.Nav.Scrolling("[data-md-component=navigation] nav"))),document.querySelector("[data-md-component=search]")&&(new d.default.Event.MatchMedia("(max-width: 959px)",new d.default.Event.Listener("[data-md-toggle=search]","change",new d.default.Search.Lock("[data-md-toggle=search]"))),new d.default.Event.Listener("[data-md-component=query]",["focus","keyup","change"],new d.default.Search.Result("[data-md-component=result]",function(){return fetch(t.url.base+"/"+(t.version<"0.17"?"mkdocs":"search")+"/search_index.json",{credentials:"same-origin"}).then(function(e){return e.json()}).then(function(e){return e.docs.map(function(e){return e.location=t.url.base+"/"+e.location,e})})})).listen(),new d.default.Event.Listener("[data-md-component=reset]","click",function(){setTimeout(function(){var e=document.querySelector("[data-md-component=query]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.focus()},10)}).listen(),new d.default.Event.Listener("[data-md-toggle=search]","change",function(e){setTimeout(function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t.focus()}},400,e.target)}).listen(),new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener("[data-md-component=query]","focus",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked||(e.checked=!0,e.dispatchEvent(new CustomEvent("change")))})),new d.default.Event.Listener(window,"keydown",function(e){var t=document.querySelector("[data-md-toggle=search]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;var n=document.querySelector("[data-md-component=query]");if(!(n instanceof HTMLInputElement))throw new ReferenceError;if(!e.metaKey&&!e.ctrlKey)if(t.checked){if(13===e.keyCode){if(n===document.activeElement){e.preventDefault();var r=document.querySelector("[data-md-component=search] [href][data-md-state=active]");r instanceof HTMLLinkElement&&(window.location=r.getAttribute("href"),t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur())}}else if(9===e.keyCode||27===e.keyCode)t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur();else if(-1!==[8,37,39].indexOf(e.keyCode))n!==document.activeElement&&n.focus();else if(-1!==[38,40].indexOf(e.keyCode)){var i=e.keyCode,o=Array.prototype.slice.call(document.querySelectorAll("[data-md-component=query], [data-md-component=search] [href]")),a=o.find(function(e){if(!(e instanceof HTMLElement))throw new ReferenceError;return"active"===e.dataset.mdState});a&&(a.dataset.mdState="");var s=Math.max(0,(o.indexOf(a)+o.length+(38===i?-1:1))%o.length);return o[s]&&(o[s].dataset.mdState="active",o[s].focus()),e.preventDefault(),e.stopPropagation(),!1}}else document.activeElement&&!document.activeElement.form&&(70!==e.keyCode&&83!==e.keyCode||(n.focus(),e.preventDefault()))}).listen(),new d.default.Event.Listener(window,"keypress",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t!==document.activeElement&&t.focus()}}).listen()),new d.default.Event.Listener(document.body,"keydown",function(e){if(9===e.keyCode){var t=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[for]:not([tabindex])");Array.prototype.forEach.call(t,function(e){e.offsetHeight&&(e.tabIndex=0)})}}).listen(),new d.default.Event.Listener(document.body,"mousedown",function(){var e=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[tabindex]");Array.prototype.forEach.call(e,function(e){e.removeAttribute("tabIndex")})}).listen(),document.body.addEventListener("click",function(){"tabbing"===document.body.dataset.mdState&&(document.body.dataset.mdState="")}),new d.default.Event.MatchMedia("(max-width: 959px)",new d.default.Event.Listener("[data-md-component=navigation] [href^='#']","click",function(){var e=document.querySelector("[data-md-toggle=drawer]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked&&(e.checked=!1,e.dispatchEvent(new CustomEvent("change")))})),function(){var e=document.querySelector("[data-md-source]");if(!e)return a.default.resolve([]);if(!(e instanceof HTMLAnchorElement))throw new ReferenceError;switch(e.dataset.mdSource){case"github":return new d.default.Source.Adapter.GitHub(e).fetch();default:return a.default.resolve([])}}().then(function(e){var t=document.querySelectorAll("[data-md-source]");Array.prototype.forEach.call(t,function(t){new d.default.Source.Repository(t).initialize(e)})})}t.__esModule=!0,t.app=void 0,n(7),n(8),n(9),n(10),n(11),n(12),n(13);var o=n(14),a=r(o),s=n(19),c=r(s),u=n(20),l=r(u),f=n(21),d=r(f);window.Promise=window.Promise||a.default;var h=function(e){var t=document.getElementsByName("lang:"+e)[0];if(!(t instanceof HTMLMetaElement))throw new ReferenceError;return t.content},p={initialize:i};t.app=p}).call(t,n(0))},function(e,t,n){e.exports=n.p+"assets/images/icons/bitbucket.1b09e088.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/github.f0b8504a.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/gitlab.6dd19c00.svg"},function(e,t){},function(e,t){},function(e,t){!function(){if("undefined"!=typeof window)try{var e=new window.CustomEvent("test",{cancelable:!0});if(e.preventDefault(),!0!==e.defaultPrevented)throw new Error("Could not prevent default")}catch(e){var t=function(e,t){var n,r;return t=t||{bubbles:!1,cancelable:!1,detail:void 0},n=document.createEvent("CustomEvent"),n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r=n.preventDefault,n.preventDefault=function(){r.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(e){this.defaultPrevented=!0}},n};t.prototype=window.Event.prototype,window.CustomEvent=t}}()},function(e,t,n){window.fetch||(window.fetch=n(2).default||n(2))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){function r(){}function i(e,t){return function(){e.apply(t,arguments)}}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function a(e,t){for(;3===e._state;)e=e._value;if(0===e._state)return void e._deferreds.push(t);e._handled=!0,o._immediateFn(function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null===n)return void(1===e._state?s:c)(t.promise,e._value);var r;try{r=n(e._value)}catch(e){return void c(t.promise,e)}s(t.promise,r)})}function s(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void u(e);if("function"==typeof n)return void f(i(n,t),e)}e._state=1,e._value=t,u(e)}catch(t){c(e,t)}}function c(e,t){e._state=2,e._value=t,u(e)}function u(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var t=0,n=e._deferreds.length;t=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(16),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n(1))},function(e,t,n){(function(e,t){!function(e,n){"use strict";function r(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n1)for(var n=1;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===c(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=(0,m.default)(e,"click",function(e){return t.onClick(e)})}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new f.default({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return s("action",e)}},{key:"defaultTarget",value:function(e){var t=s("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return s("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach(function(e){n=n&&!!document.queryCommandSupported(e)}),n}}]),t}(h.default);e.exports=y},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,s.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,s.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":i(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}();e.exports=c},function(e,t){function n(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),i=document.createRange();i.selectNodeContents(e),r.removeAllRanges(),r.addRange(i),t=r.toString()}return t}e.exports=n},function(e,t){function n(){}n.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){function r(){i.off(e,r),t.apply(n,arguments)}var i=this;return r._=t,this.on(e,r,n)},emit:function(e){var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,i=n.length;for(r;r=0,a=navigator.userAgent.indexOf("Android")>0&&!o,s=/iP(ad|hone|od)/.test(navigator.userAgent)&&!o,c=s&&/OS 4_\d(_\d)?/.test(navigator.userAgent),u=s&&/OS [6-7]_\d/.test(navigator.userAgent),l=navigator.userAgent.indexOf("BB10")>0;i.prototype.needsClick=function(e){switch(e.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(e.disabled)return!0;break;case"input":if(s&&"file"===e.type||e.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(e.className)},i.prototype.needsFocus=function(e){switch(e.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!a;case"input":switch(e.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!e.disabled&&!e.readOnly;default:return/\bneedsfocus\b/.test(e.className)}},i.prototype.sendClick=function(e,t){var n,r;document.activeElement&&document.activeElement!==e&&document.activeElement.blur(),r=t.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(e),!0,!0,window,1,r.screenX,r.screenY,r.clientX,r.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,e.dispatchEvent(n)},i.prototype.determineEventType=function(e){return a&&"select"===e.tagName.toLowerCase()?"mousedown":"click"},i.prototype.focus=function(e){var t;s&&e.setSelectionRange&&0!==e.type.indexOf("date")&&"time"!==e.type&&"month"!==e.type?(t=e.value.length,e.setSelectionRange(t,t)):e.focus()},i.prototype.updateScrollParent=function(e){var t,n;if(!(t=e.fastClickScrollParent)||!t.contains(e)){n=e;do{if(n.scrollHeight>n.offsetHeight){t=n,e.fastClickScrollParent=n;break}n=n.parentElement}while(n)}t&&(t.fastClickLastScrollTop=t.scrollTop)},i.prototype.getTargetElementFromEventTarget=function(e){return e.nodeType===Node.TEXT_NODE?e.parentNode:e},i.prototype.onTouchStart=function(e){var t,n,r;if(e.targetTouches.length>1)return!0;if(t=this.getTargetElementFromEventTarget(e.target),n=e.targetTouches[0],s){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!c){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return e.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(t)}}return this.trackingClick=!0,this.trackingClickStart=e.timeStamp,this.targetElement=t,this.touchStartX=n.pageX,this.touchStartY=n.pageY,e.timeStamp-this.lastClickTimen||Math.abs(t.pageY-this.touchStartY)>n},i.prototype.onTouchMove=function(e){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(e.target)||this.touchHasMoved(e))&&(this.trackingClick=!1,this.targetElement=null),!0)},i.prototype.findControl=function(e){return void 0!==e.control?e.control:e.htmlFor?document.getElementById(e.htmlFor):e.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},i.prototype.onTouchEnd=function(e){var t,n,r,i,o,l=this.targetElement;if(!this.trackingClick)return!0;if(e.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=e.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,u&&(o=e.changedTouches[0],l=document.elementFromPoint(o.pageX-window.pageXOffset,o.pageY-window.pageYOffset)||l,l.fastClickScrollParent=this.targetElement.fastClickScrollParent),"label"===(r=l.tagName.toLowerCase())){if(t=this.findControl(l)){if(this.focus(l),a)return!1;l=t}}else if(this.needsFocus(l))return e.timeStamp-n>100||s&&window.top!==window&&"input"===r?(this.targetElement=null,!1):(this.focus(l),this.sendClick(l,e),s&&"select"===r||(this.targetElement=null,e.preventDefault()),!1);return!(!s||c||!(i=l.fastClickScrollParent)||i.fastClickLastScrollTop===i.scrollTop)||(this.needsClick(l)||(e.preventDefault(),this.sendClick(l,e)),!1)},i.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},i.prototype.onMouse=function(e){return!this.targetElement||(!!e.forwardedTouchEvent||(!e.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(e.stopImmediatePropagation?e.stopImmediatePropagation():e.propagationStopped=!0,e.stopPropagation(),e.preventDefault(),!1))))},i.prototype.onClick=function(e){var t;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===e.target.type&&0===e.detail||(t=this.onMouse(e),t||(this.targetElement=null),t)},i.prototype.destroy=function(){var e=this.layer;a&&(e.removeEventListener("mouseover",this.onMouse,!0),e.removeEventListener("mousedown",this.onMouse,!0),e.removeEventListener("mouseup",this.onMouse,!0)),e.removeEventListener("click",this.onClick,!0),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1),e.removeEventListener("touchcancel",this.onTouchCancel,!1)},i.notNeeded=function(e){var t,n,r;if(void 0===window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!a)return!0;if(t=document.querySelector("meta[name=viewport]")){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(l&&(r=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),r[1]>=10&&r[2]>=3&&(t=document.querySelector("meta[name=viewport]")))){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===e.style.msTouchAction||"manipulation"===e.style.touchAction||(!!(+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]>=27&&(t=document.querySelector("meta[name=viewport]"))&&(-1!==t.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))||("none"===e.style.touchAction||"manipulation"===e.style.touchAction))},i.attach=function(e,t){return new i(e,t)},void 0!==(r=function(){return i}.call(t,n,t,e))&&(e.exports=r)}()},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(22),o=r(i),a=n(24),s=r(a),c=n(27),u=r(c),l=n(31),f=r(l),d=n(37),h=r(d),p=n(39),m=r(p),y=n(45),v=r(y);t.default={Event:o.default,Header:s.default,Nav:u.default,Search:f.default,Sidebar:h.default,Source:m.default,Tabs:v.default}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(3),o=r(i),a=n(23),s=r(a);t.default={Listener:o.default,MatchMedia:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=n(3),o=(function(e){e&&e.__esModule}(i),function e(t,n){r(this,e),this.handler_=function(e){e.matches?n.listen():n.unlisten()};var i=window.matchMedia(t);i.addListener(this.handler_),this.handler_(i)});t.default=o},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(25),o=r(i),a=n(26),s=r(a);t.default={Shadow:o.default,Title:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement&&i.parentNode instanceof HTMLElement))throw new ReferenceError;if(this.el_=i.parentNode,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLElement))throw new ReferenceError;this.header_=i,this.height_=0,this.active_=!1}return e.prototype.setup=function(){for(var e=this.el_;e=e.previousElementSibling;){if(!(e instanceof HTMLElement))throw new ReferenceError;this.height_+=e.offsetHeight}this.update()},e.prototype.update=function(e){if(!e||"resize"!==e.type&&"orientationchange"!==e.type){var t=window.pageYOffset>=this.height_;t!==this.active_&&(this.header_.dataset.mdState=(this.active_=t)?"shadow":"")}else this.height_=0,this.setup()},e.prototype.reset=function(){this.header_.dataset.mdState="",this.height_=0,this.active_=!1},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement))throw new ReferenceError;if(this.el_=i,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLHeadingElement))throw new ReferenceError;this.header_=i,this.active_=!1}return e.prototype.setup=function(){var e=this;Array.prototype.forEach.call(this.el_.children,function(t){t.style.width=e.el_.offsetWidth-20+"px"})},e.prototype.update=function(e){var t=this,n=window.pageYOffset>=this.header_.offsetTop;n!==this.active_&&(this.el_.dataset.mdState=(this.active_=n)?"active":""),"resize"!==e.type&&"orientationchange"!==e.type||Array.prototype.forEach.call(this.el_.children,function(e){e.style.width=t.el_.offsetWidth-20+"px"})},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.width="",this.active_=!1},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(28),o=r(i),a=n(29),s=r(a),c=n(30),u=r(c);t.default={Blur:o.default,Collapse:s.default,Scrolling:u.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e),this.els_="string"==typeof t?document.querySelectorAll(t):t,this.index_=0,this.offset_=window.pageYOffset,this.dir_=!1,this.anchors_=[].reduce.call(this.els_,function(e,t){return e.concat(document.getElementById(t.hash.substring(1))||[])},[])}return e.prototype.setup=function(){this.update()},e.prototype.update=function(){var e=window.pageYOffset,t=this.offset_-e<0;if(this.dir_!==t&&(this.index_=this.index_=t?0:this.els_.length-1),0!==this.anchors_.length){if(this.offset_<=e)for(var n=this.index_+1;n0&&(this.els_[n-1].dataset.mdState="blur"),this.index_=n;else for(var r=this.index_;r>=0;r--){if(!(this.anchors_[r].offsetTop-80>e)){this.index_=r;break}r>0&&(this.els_[r-1].dataset.mdState="")}this.offset_=e,this.dir_=t}},e.prototype.reset=function(){Array.prototype.forEach.call(this.els_,function(e){e.dataset.mdState=""}),this.index_=0,this.offset_=window.pageYOffset},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLElement))throw new ReferenceError;this.el_=n}return e.prototype.setup=function(){var e=this.el_.getBoundingClientRect().height;this.el_.style.display=e?"block":"none",this.el_.style.overflow=e?"visible":"hidden"},e.prototype.update=function(){var e=this,t=this.el_.getBoundingClientRect().height;if(this.el_.style.display="block",this.el_.style.overflow="",t)this.el_.style.maxHeight=t+"px",requestAnimationFrame(function(){e.el_.setAttribute("data-md-state","animate"),e.el_.style.maxHeight="0px"});else{this.el_.setAttribute("data-md-state","expand"),this.el_.style.maxHeight="";var n=this.el_.getBoundingClientRect().height;this.el_.removeAttribute("data-md-state"),this.el_.style.maxHeight="0px",requestAnimationFrame(function(){e.el_.setAttribute("data-md-state","animate"),e.el_.style.maxHeight=n+"px"})}var r=function e(n){var r=n.target;if(!(r instanceof HTMLElement))throw new ReferenceError;r.removeAttribute("data-md-state"),r.style.maxHeight="",r.style.display=t?"none":"block",r.style.overflow=t?"hidden":"visible",r.removeEventListener("transitionend",e)};this.el_.addEventListener("transitionend",r,!1)},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.maxHeight="",this.el_.style.display="",this.el_.style.overflow=""},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLElement))throw new ReferenceError;this.el_=n}return e.prototype.setup=function(){this.el_.children[this.el_.children.length-1].style.webkitOverflowScrolling="touch";var e=this.el_.querySelectorAll("[data-md-toggle]");Array.prototype.forEach.call(e,function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=e.nextElementSibling;if(!(t instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==t.tagName&&t.nextElementSibling;)t=t.nextElementSibling;if(!(e.parentNode instanceof HTMLElement&&e.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var n=e.parentNode.parentNode,r=t.children[t.children.length-1];n.style.webkitOverflowScrolling="",r.style.webkitOverflowScrolling="touch"}})},e.prototype.update=function(e){var t=e.target;if(!(t instanceof HTMLElement))throw new ReferenceError;var n=t.nextElementSibling;if(!(n instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==n.tagName&&n.nextElementSibling;)n=n.nextElementSibling;if(!(t.parentNode instanceof HTMLElement&&t.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var r=t.parentNode.parentNode,i=n.children[n.children.length-1];if(r.style.webkitOverflowScrolling="",i.style.webkitOverflowScrolling="",!t.checked){var o=function e(){n instanceof HTMLElement&&(r.style.webkitOverflowScrolling="touch",n.removeEventListener("transitionend",e))};n.addEventListener("transitionend",o,!1)}if(t.checked){var a=function e(){n instanceof HTMLElement&&(i.style.webkitOverflowScrolling="touch",n.removeEventListener("transitionend",e))};n.addEventListener("transitionend",a,!1)}},e.prototype.reset=function(){this.el_.children[1].style.webkitOverflowScrolling="";var e=this.el_.querySelectorAll("[data-md-toggle]");Array.prototype.forEach.call(e,function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=e.nextElementSibling;if(!(t instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==t.tagName&&t.nextElementSibling;)t=t.nextElementSibling;if(!(e.parentNode instanceof HTMLElement&&e.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var n=e.parentNode.parentNode,r=t.children[t.children.length-1];n.style.webkitOverflowScrolling="",r.style.webkitOverflowScrolling=""}})},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(32),o=r(i),a=n(33),s=r(a);t.default={Lock:o.default,Result:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLInputElement))throw new ReferenceError;if(this.el_=n,!document.body)throw new ReferenceError;this.lock_=document.body}return e.prototype.setup=function(){this.update()},e.prototype.update=function(){var e=this;this.el_.checked?(this.offset_=window.pageYOffset,setTimeout(function(){window.scrollTo(0,0),e.el_.checked&&(e.lock_.dataset.mdState="lock")},400)):(this.lock_.dataset.mdState="",setTimeout(function(){void 0!==e.offset_&&window.scrollTo(0,e.offset_)},100))},e.prototype.reset=function(){"lock"===this.lock_.dataset.mdState&&window.scrollTo(0,this.offset_),this.lock_.dataset.mdState=""},e}();t.default=i},function(e,t,n){"use strict";(function(e){function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var o=n(34),a=r(o),s=n(35),c=r(s),u=function(e){var t=document.createTextNode(e),n=document.createElement("p");return n.appendChild(t),n.innerHTML},l=function(e,t){var n=t;if(e.length>n){for(;" "!==e[n]&&--n>0;);return e.substring(0,n)+"..."}return e},f=function(e){var t=document.getElementsByName("lang:"+e)[0];if(!(t instanceof HTMLMetaElement))throw new ReferenceError;return t.content},d=function(){function t(e,n){i(this,t);var r="string"==typeof e?document.querySelector(e):e;if(!(r instanceof HTMLElement))throw new ReferenceError;this.el_=r;var o=Array.prototype.slice.call(this.el_.children),a=o[0],s=o[1];this.data_=n,this.meta_=a,this.list_=s,this.message_={placeholder:this.meta_.textContent,none:f("search.result.none"),one:f("search.result.one"),other:f("search.result.other")};var u=f("search.tokenizer");u.length&&(c.default.tokenizer.separator=u),this.lang_=f("search.language").split(",").filter(Boolean).map(function(e){return e.trim()})}return t.prototype.update=function(t){var n=this;if("focus"!==t.type||this.index_){if("focus"===t.type||"keyup"===t.type){var r=t.target;if(!(r instanceof HTMLInputElement))throw new ReferenceError;if(!this.index_||r.value===this.value_)return;for(;this.list_.firstChild;)this.list_.removeChild(this.list_.firstChild);if(this.value_=r.value,0===this.value_.length)return void(this.meta_.textContent=this.message_.placeholder);var i=this.index_.query(function(e){n.value_.toLowerCase().split(" ").filter(Boolean).forEach(function(t){e.term(t,{wildcard:c.default.Query.wildcard.TRAILING})})}).reduce(function(e,t){var r=n.docs_.get(t.ref);if(r.parent){var i=r.parent.location;e.set(i,(e.get(i)||[]).concat(t))}else{var o=r.location;e.set(o,e.get(o)||[])}return e},new Map),o=(0,a.default)(this.value_.trim()).replace(new RegExp(c.default.tokenizer.separator,"img"),"|"),s=new RegExp("(^|"+c.default.tokenizer.separator+")("+o+")","img"),d=function(e,t,n){return t+""+n+""};this.stack_=[],i.forEach(function(t,r){var i,o=n.docs_.get(r),a=e.createElement("li",{class:"md-search-result__item"},e.createElement("a",{href:o.location,title:o.title,class:"md-search-result__link",tabindex:"-1"},e.createElement("article",{class:"md-search-result__article md-search-result__article--document"},e.createElement("h1",{class:"md-search-result__title"},{__html:o.title.replace(s,d)}),o.text.length?e.createElement("p",{class:"md-search-result__teaser"},{__html:o.text.replace(s,d)}):{}))),c=t.map(function(t){return function(){var r=n.docs_.get(t.ref);a.appendChild(e.createElement("a",{href:r.location,title:r.title,class:"md-search-result__link","data-md-rel":"anchor",tabindex:"-1"},e.createElement("article",{class:"md-search-result__article"},e.createElement("h1",{class:"md-search-result__title"},{__html:r.title.replace(s,d)}),r.text.length?e.createElement("p",{class:"md-search-result__teaser"},{__html:l(r.text.replace(s,d),400)}):{})))}});(i=n.stack_).push.apply(i,[function(){return n.list_.appendChild(a)}].concat(c))});var h=this.el_.parentNode;if(!(h instanceof HTMLElement))throw new ReferenceError;for(;this.stack_.length&&h.offsetHeight>=h.scrollHeight-16;)this.stack_.shift()();var p=this.list_.querySelectorAll("[data-md-rel=anchor]");switch(Array.prototype.forEach.call(p,function(e){["click","keydown"].forEach(function(t){e.addEventListener(t,function(n){if("keydown"!==t||13===n.keyCode){var r=document.querySelector("[data-md-toggle=search]");if(!(r instanceof HTMLInputElement))throw new ReferenceError;r.checked&&(r.checked=!1,r.dispatchEvent(new CustomEvent("change"))),n.preventDefault(),setTimeout(function(){document.location.href=e.href},100)}})})}),i.size){case 0:this.meta_.textContent=this.message_.none;break;case 1:this.meta_.textContent=this.message_.one;break;default:this.meta_.textContent=this.message_.other.replace("#",i.size)}}}else{var m=function(e){n.docs_=e.reduce(function(e,t){var n=t.location.split("#"),r=n[0],i=n[1];return t.title=u(t.title),t.text=u(t.text),i&&(t.parent=e.get(r),t.parent&&!t.parent.done&&(t.parent.title=t.title,t.parent.text=t.text,t.parent.done=!0)),t.text=t.text.replace(/\n/g," ").replace(/\s+/g," ").replace(/\s+([,.:;!?])/g,function(e,t){return t}),t.parent&&t.parent.title===t.title||e.set(t.location,t),e},new Map);var t=n.docs_,r=n.lang_;n.stack_=[],n.index_=(0,c.default)(function(){var e,n=this,i={"search.pipeline.trimmer":c.default.trimmer,"search.pipeline.stopwords":c.default.stopWordFilter},o=Object.keys(i).reduce(function(e,t){return f(t).match(/^false$/i)||e.push(i[t]),e},[]);this.pipeline.reset(),o&&(e=this.pipeline).add.apply(e,o),1===r.length&&"en"!==r[0]&&c.default[r[0]]?this.use(c.default[r[0]]):r.length>1&&this.use(c.default.multiLanguage.apply(c.default,r)),this.field("title",{boost:10}),this.field("text"),this.ref("location"),t.forEach(function(e){return n.add(e)})});var i=n.el_.parentNode;if(!(i instanceof HTMLElement))throw new ReferenceError;i.addEventListener("scroll",function(){for(;n.stack_.length&&i.scrollTop+i.offsetHeight>=i.scrollHeight-16;)n.stack_.splice(0,10).forEach(function(e){return e()})})};setTimeout(function(){return"function"==typeof n.data_?n.data_().then(m):m(n.data_)},250)}},t}();t.default=d}).call(t,n(0))},function(e,t,n){"use strict";var r=/[|\\{}()[\]^$+*?.]/g;e.exports=function(e){if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(r,"\\$&")}},function(e,t,n){(function(t){e.exports=t.lunr=n(36)}).call(t,n(1))},function(e,t,n){var r,i;!function(){var o=function(e){var t=new o.Builder;return t.pipeline.add(o.trimmer,o.stopWordFilter,o.stemmer),t.searchPipeline.add(o.stemmer),e.call(t,t),t.build()};o.version="2.3.5",o.utils={},o.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),o.utils.asString=function(e){return void 0===e||null===e?"":e.toString()},o.utils.clone=function(e){if(null===e||void 0===e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=o.utils.clone(t)||{};l.position=[s,u],l.index=i.length,i.push(new o.Token(n.slice(s,a),l))}s=a+1}}return i},o.tokenizer.separator=/[\s\-]+/,o.Pipeline=function(){this._stack=[]},o.Pipeline.registeredFunctions=Object.create(null),o.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&o.utils.warn("Overwriting existing registered function: "+t),e.label=t,o.Pipeline.registeredFunctions[e.label]=e},o.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||o.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},o.Pipeline.load=function(e){var t=new o.Pipeline;return e.forEach(function(e){var n=o.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)}),t},o.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(e){o.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},o.Pipeline.prototype.after=function(e,t){o.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},o.Pipeline.prototype.before=function(e,t){o.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},o.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},o.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(oe&&(n=i),o!=e);)r=n-t,i=t+Math.floor(r/2),o=this.elements[2*i];return o==e?2*i:o>e?2*i:os?u+=2:a==s&&(t+=n[c+1]*r[u+1],c+=2,u+=2);return t},o.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},o.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var a,s=i.str.charAt(0);s in i.node.edges?a=i.node.edges[s]:(a=new o.TokenSet,i.node.edges[s]=a),1==i.str.length&&(a.final=!0),r.push({node:a,editsRemaining:i.editsRemaining,str:i.str.slice(1)})}if(i.editsRemaining>0&&i.str.length>1){var c,s=i.str.charAt(1);s in i.node.edges?c=i.node.edges[s]:(c=new o.TokenSet,i.node.edges[s]=c),i.str.length<=2?c.final=!0:r.push({node:c,editsRemaining:i.editsRemaining-1,str:i.str.slice(2)})}if(i.editsRemaining>0&&1==i.str.length&&(i.node.final=!0),i.editsRemaining>0&&i.str.length>=1){if("*"in i.node.edges)var u=i.node.edges["*"];else{var u=new o.TokenSet;i.node.edges["*"]=u}1==i.str.length?u.final=!0:r.push({node:u,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)})}if(i.editsRemaining>0){if("*"in i.node.edges)var l=i.node.edges["*"];else{var l=new o.TokenSet;i.node.edges["*"]=l}0==i.str.length?l.final=!0:r.push({node:l,editsRemaining:i.editsRemaining-1,str:i.str})}if(i.editsRemaining>0&&i.str.length>1){var f,d=i.str.charAt(0),h=i.str.charAt(1);h in i.node.edges?f=i.node.edges[h]:(f=new o.TokenSet,i.node.edges[h]=f),1==i.str.length?f.final=!0:r.push({node:f,editsRemaining:i.editsRemaining-1,str:d+i.str.slice(2)})}}return n},o.TokenSet.fromString=function(e){for(var t=new o.TokenSet,n=t,r=0,i=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},o.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},o.Index.prototype.search=function(e){return this.query(function(t){new o.QueryParser(e,t).parse()})},o.Index.prototype.query=function(e){for(var t=new o.Query(this.fields),n=Object.create(null),r=Object.create(null),i=Object.create(null),a=Object.create(null),s=Object.create(null),c=0;c1?1:e},o.Builder.prototype.k1=function(e){this._k1=e},o.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var i=0;i=this.length)return o.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},o.QueryLexer.prototype.width=function(){return this.pos-this.start},o.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},o.QueryLexer.prototype.backup=function(){this.pos-=1},o.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{e=this.next(),t=e.charCodeAt(0)}while(t>47&&t<58);e!=o.QueryLexer.EOS&&this.backup()},o.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(o.QueryLexer.TERM)),e.ignore(),e.more())return o.QueryLexer.lexText},o.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(o.QueryLexer.EDIT_DISTANCE),o.QueryLexer.lexText},o.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(o.QueryLexer.BOOST),o.QueryLexer.lexText},o.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(o.QueryLexer.TERM)},o.QueryLexer.termSeparator=o.tokenizer.separator,o.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==o.QueryLexer.EOS)return o.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return o.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(o.QueryLexer.TERM),o.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(o.QueryLexer.TERM),o.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(o.QueryLexer.PRESENCE),o.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(o.QueryLexer.PRESENCE),o.QueryLexer.lexText;if(t.match(o.QueryLexer.termSeparator))return o.QueryLexer.lexTerm}else e.escapeCharacter()}},o.QueryParser=function(e,t){this.lexer=new o.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},o.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=o.QueryParser.parseClause;e;)e=e(this);return this.query},o.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},o.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},o.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},o.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(void 0!=t)switch(t.type){case o.QueryLexer.PRESENCE:return o.QueryParser.parsePresence;case o.QueryLexer.FIELD:return o.QueryParser.parseField;case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new o.QueryParseError(n,t.start,t.end)}},o.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(void 0!=t){switch(t.str){case"-":e.currentClause.presence=o.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=o.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new o.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(void 0==r){var n="expecting term or field, found nothing";throw new o.QueryParseError(n,t.start,t.end)}switch(r.type){case o.QueryLexer.FIELD:return o.QueryParser.parseField;case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var n="expecting term or field, found '"+r.type+"'";throw new o.QueryParseError(n,r.start,r.end)}}},o.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(void 0!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var i=e.peekLexeme();if(void 0==i){var r="expecting term, found nothing";throw new o.QueryParseError(r,t.start,t.end)}switch(i.type){case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var r="expecting term, found '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},o.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(void 0!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(void 0==n)return void e.nextClause();switch(n.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new o.QueryParseError(r,n.start,n.end)}}},o.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(void 0!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var i=e.peekLexeme();if(void 0==i)return void e.nextClause();switch(i.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},o.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(void 0!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var i=e.peekLexeme();if(void 0==i)return void e.nextClause();switch(i.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},function(o,a){r=a,void 0!==(i="function"==typeof r?r.call(t,n,t,e):r)&&(e.exports=i)}(0,function(){return o})}()},function(e,t,n){"use strict";t.__esModule=!0;var r=n(38),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default={Position:i.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement&&i.parentNode instanceof HTMLElement))throw new ReferenceError;if(this.el_=i,this.parent_=i.parentNode,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLElement))throw new ReferenceError;this.header_=i,this.height_=0,this.pad_="fixed"===window.getComputedStyle(this.header_).position}return e.prototype.setup=function(){var e=Array.prototype.reduce.call(this.parent_.children,function(e,t){return Math.max(e,t.offsetTop)},0);this.offset_=e-(this.pad_?this.header_.offsetHeight:0),this.update()},e.prototype.update=function(e){var t=window.pageYOffset,n=window.innerHeight;e&&"resize"===e.type&&this.setup();var r={top:this.pad_?this.header_.offsetHeight:0,bottom:this.parent_.offsetTop+this.parent_.offsetHeight},i=n-r.top-Math.max(0,this.offset_-t)-Math.max(0,t+n-r.bottom);i!==this.height_&&(this.el_.style.height=(this.height_=i)+"px"),t>=this.offset_?"lock"!==this.el_.dataset.mdState&&(this.el_.dataset.mdState="lock"):"lock"===this.el_.dataset.mdState&&(this.el_.dataset.mdState="")},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.height="",this.height_=0},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(40),o=r(i),a=n(44),s=r(a);t.default={Adapter:o.default,Repository:s.default}},function(e,t,n){"use strict";t.__esModule=!0;var r=n(41),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default={GitHub:i.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var a=n(42),s=function(e){return e&&e.__esModule?e:{default:e}}(a),c=function(e){function t(n){r(this,t);var o=i(this,e.call(this,n)),a=/^.+github\.com\/([^\/]+)\/?([^\/]+)?.*$/.exec(o.base_);if(a&&3===a.length){var s=a[1],c=a[2];o.base_="https://api.github.com/users/"+s+"/repos",o.name_=c}return o}return o(t,e),t.prototype.fetch_=function(){var e=this;return function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return fetch(e.base_+"?per_page=30&page="+n).then(function(e){return e.json()}).then(function(r){if(!(r instanceof Array))throw new TypeError;if(e.name_){var i=r.find(function(t){return t.name===e.name_});return i||30!==r.length?i?[e.format_(i.stargazers_count)+" Stars",e.format_(i.forks_count)+" Forks"]:[]:t(n+1)}return[r.length+" Repositories"]})}()},t}(s.default);t.default=c},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=n(43),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLAnchorElement))throw new ReferenceError;this.el_=n,this.base_=this.el_.href,this.salt_=this.hash_(this.base_)}return e.prototype.fetch=function(){var e=this;return new Promise(function(t){var n=o.default.getJSON(e.salt_+".cache-source");void 0!==n?t(n):e.fetch_().then(function(n){o.default.set(e.salt_+".cache-source",n,{expires:1/96}),t(n)})})},e.prototype.fetch_=function(){throw new Error("fetch_(): Not implemented")},e.prototype.format_=function(e){return e>1e4?(e/1e3).toFixed(0)+"k":e>1e3?(e/1e3).toFixed(1)+"k":""+e},e.prototype.hash_=function(e){var t=0;if(0===e.length)return t;for(var n=0,r=e.length;n1){if(o=e({path:"/"},r.defaults,o),"number"==typeof o.expires){var s=new Date;s.setMilliseconds(s.getMilliseconds()+864e5*o.expires),o.expires=s}o.expires=o.expires?o.expires.toUTCString():"";try{a=JSON.stringify(i),/^[\{\[]/.test(a)&&(i=a)}catch(e){}i=n.write?n.write(i,t):encodeURIComponent(String(i)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),t=encodeURIComponent(String(t)),t=t.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),t=t.replace(/[\(\)]/g,escape);var c="";for(var u in o)o[u]&&(c+="; "+u,!0!==o[u]&&(c+="="+o[u]));return document.cookie=t+"="+i+c}t||(a={});for(var l=document.cookie?document.cookie.split("; "):[],f=/(%[0-9A-Z]{2})+/g,d=0;d=this.el_.children[0].offsetTop+-43;e!==this.active_&&(this.el_.dataset.mdState=(this.active_=e)?"hidden":"")},e.prototype.reset=function(){this.el_.dataset.mdState="",this.active_=!1},e}();t.default=i}])); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.da.js b/assets/javascripts/lunr/lunr.da.js new file mode 100644 index 000000000..34910dfe5 --- /dev/null +++ b/assets/javascripts/lunr/lunr.da.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,m,i;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,m=e.stemmerSupport.SnowballProgram,i=new function(){var i,t,n,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new m;function l(){var e,r=c.limit-c.cursor;c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r=c.cursor;return function(){var e,r=c.cursor+3;if(t=c.limit,0<=r&&r<=c.limit){for(i=r;;){if(e=c.cursor,c.in_grouping(d,97,248)){c.cursor=e;break}if((c.cursor=e)>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(t=c.cursor)=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,n=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-n,c.cursor>=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,n=c.slice_to(n),c.limit_backward=e,c.eq_v_b(n)&&c.slice_del()):c.limit_backward=e),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.de.js b/assets/javascripts/lunr/lunr.de.js new file mode 100644 index 000000000..1529892c8 --- /dev/null +++ b/assets/javascripts/lunr/lunr.de.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var _,p,r;e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=(_=e.stemmerSupport.Among,p=e.stemmerSupport.SnowballProgram,r=new function(){var r,n,i,s=[new _("",-1,6),new _("U",0,2),new _("Y",0,1),new _("ä",0,3),new _("ö",0,4),new _("ü",0,5)],o=[new _("e",-1,2),new _("em",-1,1),new _("en",-1,2),new _("ern",-1,1),new _("er",-1,1),new _("s",-1,3),new _("es",5,2)],c=[new _("en",-1,1),new _("er",-1,1),new _("st",-1,2),new _("est",2,1)],u=[new _("ig",-1,1),new _("lich",-1,1)],a=[new _("end",-1,1),new _("ig",-1,2),new _("ung",-1,1),new _("lich",-1,3),new _("isch",-1,2),new _("ik",-1,2),new _("heit",-1,3),new _("keit",-1,4)],t=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],d=[117,30,5],l=[117,30,4],m=new p;function h(e,r,n){return!(!m.eq_s(1,e)||(m.ket=m.cursor,!m.in_grouping(t,97,252)))&&(m.slice_from(r),m.cursor=n,!0)}function w(){for(;!m.in_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}for(;!m.out_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}return!1}function f(){return i<=m.cursor}function b(){return n<=m.cursor}this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e=m.cursor;return function(){for(var e,r,n,i,s=m.cursor;;)if(e=m.cursor,m.bra=e,m.eq_s(1,"ß"))m.ket=m.cursor,m.slice_from("ss");else{if(e>=m.limit)break;m.cursor=e+1}for(m.cursor=s;;)for(r=m.cursor;;){if(n=m.cursor,m.in_grouping(t,97,252)){if(i=m.cursor,m.bra=i,h("u","U",n))break;if(m.cursor=i,h("y","Y",n))break}if(n>=m.limit)return m.cursor=r;m.cursor=n+1}}(),m.cursor=e,function(){i=m.limit,n=i;var e=m.cursor+3;0<=e&&e<=m.limit&&(r=e,w()||((i=m.cursor)=m.limit)return;m.cursor++}}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.du.js b/assets/javascripts/lunr/lunr.du.js new file mode 100644 index 000000000..588548a65 --- /dev/null +++ b/assets/javascripts/lunr/lunr.du.js @@ -0,0 +1 @@ +!function(r,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,q,e;r.du=function(){this.pipeline.reset(),this.pipeline.add(r.du.trimmer,r.du.stopWordFilter,r.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.du.stemmer))},r.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.du.trimmer=r.trimmerSupport.generateTrimmer(r.du.wordCharacters),r.Pipeline.registerFunction(r.du.trimmer,"trimmer-du"),r.du.stemmer=(v=r.stemmerSupport.Among,q=r.stemmerSupport.SnowballProgram,e=new function(){var e,i,u,o=[new v("",-1,6),new v("á",0,1),new v("ä",0,1),new v("é",0,2),new v("ë",0,2),new v("í",0,3),new v("ï",0,3),new v("ó",0,4),new v("ö",0,4),new v("ú",0,5),new v("ü",0,5)],n=[new v("",-1,3),new v("I",0,2),new v("Y",0,1)],t=[new v("dd",-1,-1),new v("kk",-1,-1),new v("tt",-1,-1)],c=[new v("ene",-1,2),new v("se",-1,3),new v("en",-1,2),new v("heden",2,1),new v("s",-1,3)],a=[new v("end",-1,1),new v("ig",-1,2),new v("ing",-1,1),new v("lijk",-1,3),new v("baar",-1,4),new v("bar",-1,5)],l=[new v("aa",-1,-1),new v("ee",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1)],m=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],d=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],f=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],_=new q;function s(r){return(_.cursor=r)>=_.limit||(_.cursor++,!1)}function w(){for(;!_.in_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}for(;!_.out_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}return!1}function b(){return i<=_.cursor}function p(){return e<=_.cursor}function g(){var r=_.limit-_.cursor;_.find_among_b(t,3)&&(_.cursor=_.limit-r,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del()))}function h(){var r;u=!1,_.ket=_.cursor,_.eq_s_b(1,"e")&&(_.bra=_.cursor,b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.slice_del(),u=!0,g())))}function k(){var r;b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.eq_s_b(3,"gem")||(_.cursor=_.limit-r,_.slice_del(),g())))}this.setCurrent=function(r){_.setCurrent(r)},this.getCurrent=function(){return _.getCurrent()},this.stem=function(){var r=_.cursor;return function(){for(var r,e,i,n=_.cursor;;){if(_.bra=_.cursor,r=_.find_among(o,11))switch(_.ket=_.cursor,r){case 1:_.slice_from("a");continue;case 2:_.slice_from("e");continue;case 3:_.slice_from("i");continue;case 4:_.slice_from("o");continue;case 5:_.slice_from("u");continue;case 6:if(_.cursor>=_.limit)break;_.cursor++;continue}break}for(_.cursor=n,_.bra=n,_.eq_s(1,"y")?(_.ket=_.cursor,_.slice_from("Y")):_.cursor=n;;)if(e=_.cursor,_.in_grouping(m,97,232)){if(i=_.cursor,_.bra=i,_.eq_s(1,"i"))_.ket=_.cursor,_.in_grouping(m,97,232)&&(_.slice_from("I"),_.cursor=e);else if(_.cursor=i,_.eq_s(1,"y"))_.ket=_.cursor,_.slice_from("Y"),_.cursor=e;else if(s(e))break}else if(s(e))break}(),_.cursor=r,i=_.limit,e=i,w()||((i=_.cursor)<3&&(i=3),w()||(e=_.cursor)),_.limit_backward=r,_.cursor=_.limit,function(){var r,e,i,n,o,t,s=_.limit-_.cursor;if(_.ket=_.cursor,r=_.find_among_b(c,5))switch(_.bra=_.cursor,r){case 1:b()&&_.slice_from("heid");break;case 2:k();break;case 3:b()&&_.out_grouping_b(f,97,232)&&_.slice_del()}if(_.cursor=_.limit-s,h(),_.cursor=_.limit-s,_.ket=_.cursor,_.eq_s_b(4,"heid")&&(_.bra=_.cursor,p()&&(e=_.limit-_.cursor,_.eq_s_b(1,"c")||(_.cursor=_.limit-e,_.slice_del(),_.ket=_.cursor,_.eq_s_b(2,"en")&&(_.bra=_.cursor,k())))),_.cursor=_.limit-s,_.ket=_.cursor,r=_.find_among_b(a,6))switch(_.bra=_.cursor,r){case 1:if(p()){if(_.slice_del(),i=_.limit-_.cursor,_.ket=_.cursor,_.eq_s_b(2,"ig")&&(_.bra=_.cursor,p()&&(n=_.limit-_.cursor,!_.eq_s_b(1,"e")))){_.cursor=_.limit-n,_.slice_del();break}_.cursor=_.limit-i,g()}break;case 2:p()&&(o=_.limit-_.cursor,_.eq_s_b(1,"e")||(_.cursor=_.limit-o,_.slice_del()));break;case 3:p()&&(_.slice_del(),h());break;case 4:p()&&_.slice_del();break;case 5:p()&&u&&_.slice_del()}_.cursor=_.limit-s,_.out_grouping_b(d,73,232)&&(t=_.limit-_.cursor,_.find_among_b(l,4)&&_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-t,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del())))}(),_.cursor=_.limit_backward,function(){for(var r;;)if(_.bra=_.cursor,r=_.find_among(n,3))switch(_.ket=_.cursor,r){case 1:_.slice_from("y");break;case 2:_.slice_from("i");break;case 3:if(_.cursor>=_.limit)return;_.cursor++}}(),!0}},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}),r.Pipeline.registerFunction(r.du.stemmer,"stemmer-du"),r.du.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.es.js b/assets/javascripts/lunr/lunr.es.js new file mode 100644 index 000000000..9de6c09cb --- /dev/null +++ b/assets/javascripts/lunr/lunr.es.js @@ -0,0 +1 @@ +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var C,P,s;e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=(C=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,s=new function(){var r,n,i,a=[new C("",-1,6),new C("á",0,1),new C("é",0,2),new C("í",0,3),new C("ó",0,4),new C("ú",0,5)],t=[new C("la",-1,-1),new C("sela",0,-1),new C("le",-1,-1),new C("me",-1,-1),new C("se",-1,-1),new C("lo",-1,-1),new C("selo",5,-1),new C("las",-1,-1),new C("selas",7,-1),new C("les",-1,-1),new C("los",-1,-1),new C("selos",10,-1),new C("nos",-1,-1)],o=[new C("ando",-1,6),new C("iendo",-1,6),new C("yendo",-1,7),new C("ándo",-1,2),new C("iéndo",-1,1),new C("ar",-1,6),new C("er",-1,6),new C("ir",-1,6),new C("ár",-1,3),new C("ér",-1,4),new C("ír",-1,5)],s=[new C("ic",-1,-1),new C("ad",-1,-1),new C("os",-1,-1),new C("iv",-1,1)],u=[new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,1)],w=[new C("ic",-1,1),new C("abil",-1,1),new C("iv",-1,1)],c=[new C("ica",-1,1),new C("ancia",-1,2),new C("encia",-1,5),new C("adora",-1,2),new C("osa",-1,1),new C("ista",-1,1),new C("iva",-1,9),new C("anza",-1,1),new C("logía",-1,3),new C("idad",-1,8),new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,2),new C("mente",-1,7),new C("amente",13,6),new C("ación",-1,2),new C("ución",-1,4),new C("ico",-1,1),new C("ismo",-1,1),new C("oso",-1,1),new C("amiento",-1,1),new C("imiento",-1,1),new C("ivo",-1,9),new C("ador",-1,2),new C("icas",-1,1),new C("ancias",-1,2),new C("encias",-1,5),new C("adoras",-1,2),new C("osas",-1,1),new C("istas",-1,1),new C("ivas",-1,9),new C("anzas",-1,1),new C("logías",-1,3),new C("idades",-1,8),new C("ables",-1,1),new C("ibles",-1,1),new C("aciones",-1,2),new C("uciones",-1,4),new C("adores",-1,2),new C("antes",-1,2),new C("icos",-1,1),new C("ismos",-1,1),new C("osos",-1,1),new C("amientos",-1,1),new C("imientos",-1,1),new C("ivos",-1,9)],m=[new C("ya",-1,1),new C("ye",-1,1),new C("yan",-1,1),new C("yen",-1,1),new C("yeron",-1,1),new C("yendo",-1,1),new C("yo",-1,1),new C("yas",-1,1),new C("yes",-1,1),new C("yais",-1,1),new C("yamos",-1,1),new C("yó",-1,1)],l=[new C("aba",-1,2),new C("ada",-1,2),new C("ida",-1,2),new C("ara",-1,2),new C("iera",-1,2),new C("ía",-1,2),new C("aría",5,2),new C("ería",5,2),new C("iría",5,2),new C("ad",-1,2),new C("ed",-1,2),new C("id",-1,2),new C("ase",-1,2),new C("iese",-1,2),new C("aste",-1,2),new C("iste",-1,2),new C("an",-1,2),new C("aban",16,2),new C("aran",16,2),new C("ieran",16,2),new C("ían",16,2),new C("arían",20,2),new C("erían",20,2),new C("irían",20,2),new C("en",-1,1),new C("asen",24,2),new C("iesen",24,2),new C("aron",-1,2),new C("ieron",-1,2),new C("arán",-1,2),new C("erán",-1,2),new C("irán",-1,2),new C("ado",-1,2),new C("ido",-1,2),new C("ando",-1,2),new C("iendo",-1,2),new C("ar",-1,2),new C("er",-1,2),new C("ir",-1,2),new C("as",-1,2),new C("abas",39,2),new C("adas",39,2),new C("idas",39,2),new C("aras",39,2),new C("ieras",39,2),new C("ías",39,2),new C("arías",45,2),new C("erías",45,2),new C("irías",45,2),new C("es",-1,1),new C("ases",49,2),new C("ieses",49,2),new C("abais",-1,2),new C("arais",-1,2),new C("ierais",-1,2),new C("íais",-1,2),new C("aríais",55,2),new C("eríais",55,2),new C("iríais",55,2),new C("aseis",-1,2),new C("ieseis",-1,2),new C("asteis",-1,2),new C("isteis",-1,2),new C("áis",-1,2),new C("éis",-1,1),new C("aréis",64,2),new C("eréis",64,2),new C("iréis",64,2),new C("ados",-1,2),new C("idos",-1,2),new C("amos",-1,2),new C("ábamos",70,2),new C("áramos",70,2),new C("iéramos",70,2),new C("íamos",70,2),new C("aríamos",74,2),new C("eríamos",74,2),new C("iríamos",74,2),new C("emos",-1,1),new C("aremos",78,2),new C("eremos",78,2),new C("iremos",78,2),new C("ásemos",78,2),new C("iésemos",78,2),new C("imos",-1,2),new C("arás",-1,2),new C("erás",-1,2),new C("irás",-1,2),new C("ís",-1,2),new C("ará",-1,2),new C("erá",-1,2),new C("irá",-1,2),new C("aré",-1,2),new C("eré",-1,2),new C("iré",-1,2),new C("ió",-1,2)],d=[new C("a",-1,1),new C("e",-1,2),new C("o",-1,1),new C("os",-1,1),new C("á",-1,1),new C("é",-1,2),new C("í",-1,1),new C("ó",-1,1)],b=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],f=new P;function _(){if(f.out_grouping(b,97,252)){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}return!1}return!0}function h(){var e,s=f.cursor;if(function(){if(f.in_grouping(b,97,252)){var e=f.cursor;if(_()){if(f.cursor=e,!f.in_grouping(b,97,252))return!0;for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}}return!1}return!0}()){if(f.cursor=s,!f.out_grouping(b,97,252))return;if(e=f.cursor,_()){if(f.cursor=e,!f.in_grouping(b,97,252)||f.cursor>=f.limit)return;f.cursor++}}i=f.cursor}function v(){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}return!0}function p(){return i<=f.cursor}function g(){return r<=f.cursor}function k(e,s){if(!g())return!0;f.slice_del(),f.ket=f.cursor;var r=f.find_among_b(e,s);return r&&(f.bra=f.cursor,1==r&&g()&&f.slice_del()),!1}function y(e){return!g()||(f.slice_del(),f.ket=f.cursor,f.eq_s_b(2,e)&&(f.bra=f.cursor,g()&&f.slice_del()),!1)}function q(){var e;if(f.ket=f.cursor,e=f.find_among_b(c,46)){switch(f.bra=f.cursor,e){case 1:if(!g())return!1;f.slice_del();break;case 2:if(y("ic"))return!1;break;case 3:if(!g())return!1;f.slice_from("log");break;case 4:if(!g())return!1;f.slice_from("u");break;case 5:if(!g())return!1;f.slice_from("ente");break;case 6:if(!(n<=f.cursor))return!1;f.slice_del(),f.ket=f.cursor,(e=f.find_among_b(s,4))&&(f.bra=f.cursor,g()&&(f.slice_del(),1==e&&(f.ket=f.cursor,f.eq_s_b(2,"at")&&(f.bra=f.cursor,g()&&f.slice_del()))));break;case 7:if(k(u,3))return!1;break;case 8:if(k(w,3))return!1;break;case 9:if(y("at"))return!1}return!0}return!1}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e,s=f.cursor;return e=f.cursor,i=f.limit,r=n=i,h(),f.cursor=e,v()&&(n=f.cursor,v()&&(r=f.cursor)),f.limit_backward=s,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,f.find_among_b(t,13)&&(f.bra=f.cursor,(e=f.find_among_b(o,11))&&p()))switch(e){case 1:f.bra=f.cursor,f.slice_from("iendo");break;case 2:f.bra=f.cursor,f.slice_from("ando");break;case 3:f.bra=f.cursor,f.slice_from("ar");break;case 4:f.bra=f.cursor,f.slice_from("er");break;case 5:f.bra=f.cursor,f.slice_from("ir");break;case 6:f.slice_del();break;case 7:f.eq_s_b(1,"u")&&f.slice_del()}}(),f.cursor=f.limit,q()||(f.cursor=f.limit,function(){var e,s;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(m,12),f.limit_backward=s,e)){if(f.bra=f.cursor,1==e){if(!f.eq_s_b(1,"u"))return!1;f.slice_del()}return!0}return!1}()||(f.cursor=f.limit,function(){var e,s,r,n;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(l,96),f.limit_backward=s,e))switch(f.bra=f.cursor,e){case 1:r=f.limit-f.cursor,f.eq_s_b(1,"u")?(n=f.limit-f.cursor,f.eq_s_b(1,"g")?f.cursor=f.limit-n:f.cursor=f.limit-r):f.cursor=f.limit-r,f.bra=f.cursor;case 2:f.slice_del()}}())),f.cursor=f.limit,function(){var e,s;if(f.ket=f.cursor,e=f.find_among_b(d,8))switch(f.bra=f.cursor,e){case 1:p()&&f.slice_del();break;case 2:p()&&(f.slice_del(),f.ket=f.cursor,f.eq_s_b(1,"u")&&(f.bra=f.cursor,s=f.limit-f.cursor,f.eq_s_b(1,"g")&&(f.cursor=f.limit-s,p()&&f.slice_del())))}}(),f.cursor=f.limit_backward,function(){for(var e;;){if(f.bra=f.cursor,e=f.find_among(a,6))switch(f.ket=f.cursor,e){case 1:f.slice_from("a");continue;case 2:f.slice_from("e");continue;case 3:f.slice_from("i");continue;case 4:f.slice_from("o");continue;case 5:f.slice_from("u");continue;case 6:if(f.cursor>=f.limit)break;f.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.fi.js b/assets/javascripts/lunr/lunr.fi.js new file mode 100644 index 000000000..2f9bf5aeb --- /dev/null +++ b/assets/javascripts/lunr/lunr.fi.js @@ -0,0 +1 @@ +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,C,e;i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=(v=i.stemmerSupport.Among,C=i.stemmerSupport.SnowballProgram,e=new function(){var n,t,l,o,r=[new v("pa",-1,1),new v("sti",-1,2),new v("kaan",-1,1),new v("han",-1,1),new v("kin",-1,1),new v("hän",-1,1),new v("kään",-1,1),new v("ko",-1,1),new v("pä",-1,1),new v("kö",-1,1)],s=[new v("lla",-1,-1),new v("na",-1,-1),new v("ssa",-1,-1),new v("ta",-1,-1),new v("lta",3,-1),new v("sta",3,-1)],a=[new v("llä",-1,-1),new v("nä",-1,-1),new v("ssä",-1,-1),new v("tä",-1,-1),new v("ltä",3,-1),new v("stä",3,-1)],u=[new v("lle",-1,-1),new v("ine",-1,-1)],c=[new v("nsa",-1,3),new v("mme",-1,3),new v("nne",-1,3),new v("ni",-1,2),new v("si",-1,1),new v("an",-1,4),new v("en",-1,6),new v("än",-1,5),new v("nsä",-1,3)],i=[new v("aa",-1,-1),new v("ee",-1,-1),new v("ii",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1),new v("ää",-1,-1),new v("öö",-1,-1)],m=[new v("a",-1,8),new v("lla",0,-1),new v("na",0,-1),new v("ssa",0,-1),new v("ta",0,-1),new v("lta",4,-1),new v("sta",4,-1),new v("tta",4,9),new v("lle",-1,-1),new v("ine",-1,-1),new v("ksi",-1,-1),new v("n",-1,7),new v("han",11,1),new v("den",11,-1,q),new v("seen",11,-1,j),new v("hen",11,2),new v("tten",11,-1,q),new v("hin",11,3),new v("siin",11,-1,q),new v("hon",11,4),new v("hän",11,5),new v("hön",11,6),new v("ä",-1,8),new v("llä",22,-1),new v("nä",22,-1),new v("ssä",22,-1),new v("tä",22,-1),new v("ltä",26,-1),new v("stä",26,-1),new v("ttä",26,9)],w=[new v("eja",-1,-1),new v("mma",-1,1),new v("imma",1,-1),new v("mpa",-1,1),new v("impa",3,-1),new v("mmi",-1,1),new v("immi",5,-1),new v("mpi",-1,1),new v("impi",7,-1),new v("ejä",-1,-1),new v("mmä",-1,1),new v("immä",10,-1),new v("mpä",-1,1),new v("impä",12,-1)],_=[new v("i",-1,-1),new v("j",-1,-1)],k=[new v("mma",-1,1),new v("imma",0,-1)],b=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],e=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],f=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],h=new C;function p(){for(var i;i=h.cursor,!h.in_grouping(d,97,246);){if((h.cursor=i)>=h.limit)return!0;h.cursor++}for(h.cursor=i;!h.out_grouping(d,97,246);){if(h.cursor>=h.limit)return!0;h.cursor++}return!1}function g(){var i,e;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(r,10)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.in_grouping_b(f,97,246))return;break;case 2:if(!(l<=h.cursor))return}h.slice_del()}else h.limit_backward=e}function j(){return h.find_among_b(i,7)}function q(){return h.eq_s_b(1,"i")&&h.in_grouping_b(e,97,246)}this.setCurrent=function(i){h.setCurrent(i)},this.getCurrent=function(){return h.getCurrent()},this.stem=function(){var i,e=h.cursor;return o=h.limit,l=o,p()||(o=h.cursor,p()||(l=h.cursor)),n=!1,h.limit_backward=e,h.cursor=h.limit,g(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(c,9))switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:r=h.limit-h.cursor,h.eq_s_b(1,"k")||(h.cursor=h.limit-r,h.slice_del());break;case 2:h.slice_del(),h.ket=h.cursor,h.eq_s_b(3,"kse")&&(h.bra=h.cursor,h.slice_from("ksi"));break;case 3:h.slice_del();break;case 4:h.find_among_b(s,6)&&h.slice_del();break;case 5:h.find_among_b(a,6)&&h.slice_del();break;case 6:h.find_among_b(u,2)&&h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(m,30)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.eq_s_b(1,"a"))return;break;case 2:case 9:if(!h.eq_s_b(1,"e"))return;break;case 3:if(!h.eq_s_b(1,"i"))return;break;case 4:if(!h.eq_s_b(1,"o"))return;break;case 5:if(!h.eq_s_b(1,"ä"))return;break;case 6:if(!h.eq_s_b(1,"ö"))return;break;case 7:if(r=h.limit-h.cursor,!j()&&(h.cursor=h.limit-r,!h.eq_s_b(2,"ie"))){h.cursor=h.limit-r;break}if(h.cursor=h.limit-r,h.cursor<=h.limit_backward){h.cursor=h.limit-r;break}h.cursor--,h.bra=h.cursor;break;case 8:if(!h.in_grouping_b(d,97,246)||!h.out_grouping_b(d,97,246))return}h.slice_del(),n=!0}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=l)if(e=h.limit_backward,h.limit_backward=l,h.ket=h.cursor,i=h.find_among_b(w,14)){if(h.bra=h.cursor,h.limit_backward=e,1==i){if(r=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-r}h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,h.cursor=(n?h.cursor>=o&&(i=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.find_among_b(_,2)?(h.bra=h.cursor,h.limit_backward=i,h.slice_del()):h.limit_backward=i):(h.cursor=h.limit,function(){var i,e,r,n,t,s;if(h.cursor>=o){if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.eq_s_b(1,"t")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.in_grouping_b(d,97,246)&&(h.cursor=h.limit-r,h.slice_del(),h.limit_backward=e,n=h.limit-h.cursor,h.cursor>=l&&(h.cursor=l,t=h.limit_backward,h.limit_backward=h.cursor,h.cursor=h.limit-n,h.ket=h.cursor,i=h.find_among_b(k,2))))){if(h.bra=h.cursor,h.limit_backward=t,1==i){if(s=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-s}return h.slice_del()}h.limit_backward=e}}()),h.limit),function(){var i,e,r,n;if(h.cursor>=o){for(i=h.limit_backward,h.limit_backward=o,e=h.limit-h.cursor,j()&&(h.cursor=h.limit-e,h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.in_grouping_b(b,97,228)&&(h.bra=h.cursor,h.out_grouping_b(d,97,246)&&h.slice_del()),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"j")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.eq_s_b(1,"o")?h.slice_del():(h.cursor=h.limit-r,h.eq_s_b(1,"u")&&h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"o")&&(h.bra=h.cursor,h.eq_s_b(1,"j")&&h.slice_del()),h.cursor=h.limit-e,h.limit_backward=i;;){if(n=h.limit-h.cursor,h.out_grouping_b(d,97,246)){h.cursor=h.limit-n;break}if(h.cursor=h.limit-n,h.cursor<=h.limit_backward)return;h.cursor--}h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,t=h.slice_to(),h.eq_v_b(t)&&h.slice_del())}}(),!0}},function(i){return"function"==typeof i.update?i.update(function(i){return e.setCurrent(i),e.stem(),e.getCurrent()}):(e.setCurrent(i),e.stem(),e.getCurrent())}),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.fr.js b/assets/javascripts/lunr/lunr.fr.js new file mode 100644 index 000000000..078d0cab7 --- /dev/null +++ b/assets/javascripts/lunr/lunr.fr.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,y,s;e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=(r=e.stemmerSupport.Among,y=e.stemmerSupport.SnowballProgram,s=new function(){var s,i,t,n=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],u=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],o=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],c=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],a=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],l=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],w=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],f=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],m=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],_=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],b=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],d=new y;function k(e,r,s){return!(!d.eq_s(1,e)||(d.ket=d.cursor,!d.in_grouping(_,97,251)))&&(d.slice_from(r),d.cursor=s,!0)}function p(e,r,s){return!!d.eq_s(1,e)&&(d.ket=d.cursor,d.slice_from(r),d.cursor=s,!0)}function g(){for(;!d.in_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}for(;!d.out_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}function q(){return t<=d.cursor}function v(){return i<=d.cursor}function h(){return s<=d.cursor}function z(){if(!function(){var e,r;if(d.ket=d.cursor,e=d.find_among_b(a,43)){switch(d.bra=d.cursor,e){case 1:if(!h())return!1;d.slice_del();break;case 2:if(!h())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")&&(d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU"));break;case 3:if(!h())return!1;d.slice_from("log");break;case 4:if(!h())return!1;d.slice_from("u");break;case 5:if(!h())return!1;d.slice_from("ent");break;case 6:if(!q())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(o,6))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&d.slice_del()));break;case 2:h()?d.slice_del():v()&&d.slice_from("eux");break;case 3:h()&&d.slice_del();break;case 4:q()&&d.slice_from("i")}break;case 7:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(c,3))switch(d.bra=d.cursor,e){case 1:h()?d.slice_del():d.slice_from("abl");break;case 2:h()?d.slice_del():d.slice_from("iqU");break;case 3:h()&&d.slice_del()}break;case 8:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")))){d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU");break}break;case 9:d.slice_from("eau");break;case 10:if(!v())return!1;d.slice_from("al");break;case 11:if(h())d.slice_del();else{if(!v())return!1;d.slice_from("eux")}break;case 12:if(!v()||!d.out_grouping_b(_,97,251))return!1;d.slice_del();break;case 13:return q()&&d.slice_from("ant"),!1;case 14:return q()&&d.slice_from("ent"),!1;case 15:return r=d.limit-d.cursor,d.in_grouping_b(_,97,251)&&q()&&(d.cursor=d.limit-r,d.slice_del()),!1}return!0}return!1}()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor=t){if(s=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,e=d.find_among_b(f,7))switch(d.bra=d.cursor,e){case 1:if(h()){if(i=d.limit-d.cursor,!d.eq_s_b(1,"s")&&(d.cursor=d.limit-i,!d.eq_s_b(1,"t")))break;d.slice_del()}break;case 2:d.slice_from("i");break;case 3:d.slice_del();break;case 4:d.eq_s_b(2,"gu")&&d.slice_del()}d.limit_backward=s}}();d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"Y")?(d.bra=d.cursor,d.slice_from("i")):(d.cursor=d.limit,d.eq_s_b(1,"ç")&&(d.bra=d.cursor,d.slice_from("c")))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e,r;;){if(e=d.cursor,d.in_grouping(_,97,251)){if(d.bra=d.cursor,r=d.cursor,k("u","U",e))continue;if(d.cursor=r,k("i","I",e))continue;if(d.cursor=r,p("y","Y",e))continue}if(d.cursor=e,!k("y","Y",d.bra=e)){if(d.cursor=e,d.eq_s(1,"q")&&(d.bra=d.cursor,p("u","U",e)))continue;if((d.cursor=e)>=d.limit)return;d.cursor++}}}(),d.cursor=r,function(){var e=d.cursor;if(t=d.limit,s=i=t,d.in_grouping(_,97,251)&&d.in_grouping(_,97,251)&&d.cursor=d.limit){d.cursor=t;break}d.cursor++}while(!d.in_grouping(_,97,251))}t=d.cursor,d.cursor=e,g()||(i=d.cursor,g()||(s=d.cursor))}(),d.limit_backward=r,d.cursor=d.limit,z(),d.cursor=d.limit,e=d.limit-d.cursor,d.find_among_b(m,5)&&(d.cursor=d.limit-e,d.ket=d.cursor,d.cursor>d.limit_backward&&(d.cursor--,d.bra=d.cursor,d.slice_del())),d.cursor=d.limit,function(){for(var e,r=1;d.out_grouping_b(_,97,251);)r--;if(r<=0){if(d.ket=d.cursor,e=d.limit-d.cursor,!d.eq_s_b(1,"é")&&(d.cursor=d.limit-e,!d.eq_s_b(1,"è")))return;d.bra=d.cursor,d.slice_from("e")}}(),d.cursor=d.limit_backward,function(){for(var e,r;r=d.cursor,d.bra=r,e=d.find_among(u,4);)switch(d.ket=d.cursor,e){case 1:d.slice_from("i");break;case 2:d.slice_from("u");break;case 3:d.slice_from("y");break;case 4:if(d.cursor>=d.limit)return;d.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.hu.js b/assets/javascripts/lunr/lunr.hu.js new file mode 100644 index 000000000..56a4b0dc1 --- /dev/null +++ b/assets/javascripts/lunr/lunr.hu.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var p,_,n;e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=(p=e.stemmerSupport.Among,_=e.stemmerSupport.SnowballProgram,n=new function(){var r,i=[new p("cs",-1,-1),new p("dzs",-1,-1),new p("gy",-1,-1),new p("ly",-1,-1),new p("ny",-1,-1),new p("sz",-1,-1),new p("ty",-1,-1),new p("zs",-1,-1)],n=[new p("á",-1,1),new p("é",-1,2)],a=[new p("bb",-1,-1),new p("cc",-1,-1),new p("dd",-1,-1),new p("ff",-1,-1),new p("gg",-1,-1),new p("jj",-1,-1),new p("kk",-1,-1),new p("ll",-1,-1),new p("mm",-1,-1),new p("nn",-1,-1),new p("pp",-1,-1),new p("rr",-1,-1),new p("ccs",-1,-1),new p("ss",-1,-1),new p("zzs",-1,-1),new p("tt",-1,-1),new p("vv",-1,-1),new p("ggy",-1,-1),new p("lly",-1,-1),new p("nny",-1,-1),new p("tty",-1,-1),new p("ssz",-1,-1),new p("zz",-1,-1)],t=[new p("al",-1,1),new p("el",-1,2)],e=[new p("ba",-1,-1),new p("ra",-1,-1),new p("be",-1,-1),new p("re",-1,-1),new p("ig",-1,-1),new p("nak",-1,-1),new p("nek",-1,-1),new p("val",-1,-1),new p("vel",-1,-1),new p("ul",-1,-1),new p("nál",-1,-1),new p("nél",-1,-1),new p("ból",-1,-1),new p("ról",-1,-1),new p("tól",-1,-1),new p("bõl",-1,-1),new p("rõl",-1,-1),new p("tõl",-1,-1),new p("ül",-1,-1),new p("n",-1,-1),new p("an",19,-1),new p("ban",20,-1),new p("en",19,-1),new p("ben",22,-1),new p("képpen",22,-1),new p("on",19,-1),new p("ön",19,-1),new p("képp",-1,-1),new p("kor",-1,-1),new p("t",-1,-1),new p("at",29,-1),new p("et",29,-1),new p("ként",29,-1),new p("anként",32,-1),new p("enként",32,-1),new p("onként",32,-1),new p("ot",29,-1),new p("ért",29,-1),new p("öt",29,-1),new p("hez",-1,-1),new p("hoz",-1,-1),new p("höz",-1,-1),new p("vá",-1,-1),new p("vé",-1,-1)],s=[new p("án",-1,2),new p("én",-1,1),new p("ánként",-1,3)],c=[new p("stul",-1,2),new p("astul",0,1),new p("ástul",0,3),new p("stül",-1,2),new p("estül",3,1),new p("éstül",3,4)],w=[new p("á",-1,1),new p("é",-1,2)],o=[new p("k",-1,7),new p("ak",0,4),new p("ek",0,6),new p("ok",0,5),new p("ák",0,1),new p("ék",0,2),new p("ök",0,3)],l=[new p("éi",-1,7),new p("áéi",0,6),new p("ééi",0,5),new p("é",-1,9),new p("ké",3,4),new p("aké",4,1),new p("eké",4,1),new p("oké",4,1),new p("áké",4,3),new p("éké",4,2),new p("öké",4,1),new p("éé",3,8)],u=[new p("a",-1,18),new p("ja",0,17),new p("d",-1,16),new p("ad",2,13),new p("ed",2,13),new p("od",2,13),new p("ád",2,14),new p("éd",2,15),new p("öd",2,13),new p("e",-1,18),new p("je",9,17),new p("nk",-1,4),new p("unk",11,1),new p("ánk",11,2),new p("énk",11,3),new p("ünk",11,1),new p("uk",-1,8),new p("juk",16,7),new p("ájuk",17,5),new p("ük",-1,8),new p("jük",19,7),new p("éjük",20,6),new p("m",-1,12),new p("am",22,9),new p("em",22,9),new p("om",22,9),new p("ám",22,10),new p("ém",22,11),new p("o",-1,18),new p("á",-1,19),new p("é",-1,20)],m=[new p("id",-1,10),new p("aid",0,9),new p("jaid",1,6),new p("eid",0,9),new p("jeid",3,6),new p("áid",0,7),new p("éid",0,8),new p("i",-1,15),new p("ai",7,14),new p("jai",8,11),new p("ei",7,14),new p("jei",10,11),new p("ái",7,12),new p("éi",7,13),new p("itek",-1,24),new p("eitek",14,21),new p("jeitek",15,20),new p("éitek",14,23),new p("ik",-1,29),new p("aik",18,26),new p("jaik",19,25),new p("eik",18,26),new p("jeik",21,25),new p("áik",18,27),new p("éik",18,28),new p("ink",-1,20),new p("aink",25,17),new p("jaink",26,16),new p("eink",25,17),new p("jeink",28,16),new p("áink",25,18),new p("éink",25,19),new p("aitok",-1,21),new p("jaitok",32,20),new p("áitok",-1,22),new p("im",-1,5),new p("aim",35,4),new p("jaim",36,1),new p("eim",35,4),new p("jeim",38,1),new p("áim",35,2),new p("éim",35,3)],k=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],f=new _;function b(){return r<=f.cursor}function d(){var e=f.limit-f.cursor;return!!f.find_among_b(a,23)&&(f.cursor=f.limit-e,!0)}function g(){if(f.cursor>f.limit_backward){f.cursor--,f.ket=f.cursor;var e=f.cursor-1;f.limit_backward<=e&&e<=f.limit&&(f.cursor=e,f.bra=e,f.slice_del())}}function h(){f.ket=f.cursor,f.find_among_b(e,44)&&(f.bra=f.cursor,b()&&(f.slice_del(),function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(n,2))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e")}}()))}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e=f.cursor;return function(){var e,n=f.cursor;if(r=f.limit,f.in_grouping(k,97,252))for(;;){if(e=f.cursor,f.out_grouping(k,97,252))return f.cursor=e,f.find_among(i,8)||(f.cursor=e)=f.limit)return r=e;f.cursor++}if(f.cursor=n,f.out_grouping(k,97,252)){for(;!f.in_grouping(k,97,252);){if(f.cursor>=f.limit)return;f.cursor++}r=f.cursor}}(),f.limit_backward=e,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(t,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,h(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(s,3))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("e");break;case 2:case 3:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(c,6))&&(f.bra=f.cursor,b()))switch(e){case 1:case 2:f.slice_del();break;case 3:f.slice_from("a");break;case 4:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(w,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(l,12))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 9:f.slice_del();break;case 2:case 5:case 8:f.slice_from("e");break;case 3:case 6:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(u,31))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:f.slice_del();break;case 2:case 5:case 10:case 14:case 19:f.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(m,42))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:f.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:f.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(o,7))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:f.slice_del()}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.it.js b/assets/javascripts/lunr/lunr.it.js new file mode 100644 index 000000000..50dddaa04 --- /dev/null +++ b/assets/javascripts/lunr/lunr.it.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var z,P,r;e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=(z=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,r=new function(){var o,t,s,a=[new z("",-1,7),new z("qu",0,6),new z("á",0,1),new z("é",0,2),new z("í",0,3),new z("ó",0,4),new z("ú",0,5)],u=[new z("",-1,3),new z("I",0,1),new z("U",0,2)],c=[new z("la",-1,-1),new z("cela",0,-1),new z("gliela",0,-1),new z("mela",0,-1),new z("tela",0,-1),new z("vela",0,-1),new z("le",-1,-1),new z("cele",6,-1),new z("gliele",6,-1),new z("mele",6,-1),new z("tele",6,-1),new z("vele",6,-1),new z("ne",-1,-1),new z("cene",12,-1),new z("gliene",12,-1),new z("mene",12,-1),new z("sene",12,-1),new z("tene",12,-1),new z("vene",12,-1),new z("ci",-1,-1),new z("li",-1,-1),new z("celi",20,-1),new z("glieli",20,-1),new z("meli",20,-1),new z("teli",20,-1),new z("veli",20,-1),new z("gli",20,-1),new z("mi",-1,-1),new z("si",-1,-1),new z("ti",-1,-1),new z("vi",-1,-1),new z("lo",-1,-1),new z("celo",31,-1),new z("glielo",31,-1),new z("melo",31,-1),new z("telo",31,-1),new z("velo",31,-1)],w=[new z("ando",-1,1),new z("endo",-1,1),new z("ar",-1,2),new z("er",-1,2),new z("ir",-1,2)],r=[new z("ic",-1,-1),new z("abil",-1,-1),new z("os",-1,-1),new z("iv",-1,1)],n=[new z("ic",-1,1),new z("abil",-1,1),new z("iv",-1,1)],i=[new z("ica",-1,1),new z("logia",-1,3),new z("osa",-1,1),new z("ista",-1,1),new z("iva",-1,9),new z("anza",-1,1),new z("enza",-1,5),new z("ice",-1,1),new z("atrice",7,1),new z("iche",-1,1),new z("logie",-1,3),new z("abile",-1,1),new z("ibile",-1,1),new z("usione",-1,4),new z("azione",-1,2),new z("uzione",-1,4),new z("atore",-1,2),new z("ose",-1,1),new z("ante",-1,1),new z("mente",-1,1),new z("amente",19,7),new z("iste",-1,1),new z("ive",-1,9),new z("anze",-1,1),new z("enze",-1,5),new z("ici",-1,1),new z("atrici",25,1),new z("ichi",-1,1),new z("abili",-1,1),new z("ibili",-1,1),new z("ismi",-1,1),new z("usioni",-1,4),new z("azioni",-1,2),new z("uzioni",-1,4),new z("atori",-1,2),new z("osi",-1,1),new z("anti",-1,1),new z("amenti",-1,6),new z("imenti",-1,6),new z("isti",-1,1),new z("ivi",-1,9),new z("ico",-1,1),new z("ismo",-1,1),new z("oso",-1,1),new z("amento",-1,6),new z("imento",-1,6),new z("ivo",-1,9),new z("ità",-1,8),new z("istà",-1,1),new z("istè",-1,1),new z("istì",-1,1)],l=[new z("isca",-1,1),new z("enda",-1,1),new z("ata",-1,1),new z("ita",-1,1),new z("uta",-1,1),new z("ava",-1,1),new z("eva",-1,1),new z("iva",-1,1),new z("erebbe",-1,1),new z("irebbe",-1,1),new z("isce",-1,1),new z("ende",-1,1),new z("are",-1,1),new z("ere",-1,1),new z("ire",-1,1),new z("asse",-1,1),new z("ate",-1,1),new z("avate",16,1),new z("evate",16,1),new z("ivate",16,1),new z("ete",-1,1),new z("erete",20,1),new z("irete",20,1),new z("ite",-1,1),new z("ereste",-1,1),new z("ireste",-1,1),new z("ute",-1,1),new z("erai",-1,1),new z("irai",-1,1),new z("isci",-1,1),new z("endi",-1,1),new z("erei",-1,1),new z("irei",-1,1),new z("assi",-1,1),new z("ati",-1,1),new z("iti",-1,1),new z("eresti",-1,1),new z("iresti",-1,1),new z("uti",-1,1),new z("avi",-1,1),new z("evi",-1,1),new z("ivi",-1,1),new z("isco",-1,1),new z("ando",-1,1),new z("endo",-1,1),new z("Yamo",-1,1),new z("iamo",-1,1),new z("avamo",-1,1),new z("evamo",-1,1),new z("ivamo",-1,1),new z("eremo",-1,1),new z("iremo",-1,1),new z("assimo",-1,1),new z("ammo",-1,1),new z("emmo",-1,1),new z("eremmo",54,1),new z("iremmo",54,1),new z("immo",-1,1),new z("ano",-1,1),new z("iscano",58,1),new z("avano",58,1),new z("evano",58,1),new z("ivano",58,1),new z("eranno",-1,1),new z("iranno",-1,1),new z("ono",-1,1),new z("iscono",65,1),new z("arono",65,1),new z("erono",65,1),new z("irono",65,1),new z("erebbero",-1,1),new z("irebbero",-1,1),new z("assero",-1,1),new z("essero",-1,1),new z("issero",-1,1),new z("ato",-1,1),new z("ito",-1,1),new z("uto",-1,1),new z("avo",-1,1),new z("evo",-1,1),new z("ivo",-1,1),new z("ar",-1,1),new z("ir",-1,1),new z("erà",-1,1),new z("irà",-1,1),new z("erò",-1,1),new z("irò",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],f=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],v=[17],b=new P;function d(e,r,n){return!(!b.eq_s(1,e)||(b.ket=b.cursor,!b.in_grouping(m,97,249)))&&(b.slice_from(r),b.cursor=n,!0)}function _(e){if(b.cursor=e,!b.in_grouping(m,97,249))return!1;for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function g(){var e,r=b.cursor;if(!function(){if(b.in_grouping(m,97,249)){var e=b.cursor;if(b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return _(e);b.cursor++}return!0}return _(e)}return!1}()){if(b.cursor=r,!b.out_grouping(m,97,249))return;if(e=b.cursor,b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return b.cursor=e,void(b.in_grouping(m,97,249)&&b.cursor=b.limit)return;b.cursor++}s=b.cursor}function p(){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function k(){return s<=b.cursor}function h(){return o<=b.cursor}function q(){var e;if(b.ket=b.cursor,!(e=b.find_among_b(i,51)))return!1;switch(b.bra=b.cursor,e){case 1:if(!h())return!1;b.slice_del();break;case 2:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del());break;case 3:if(!h())return!1;b.slice_from("log");break;case 4:if(!h())return!1;b.slice_from("u");break;case 5:if(!h())return!1;b.slice_from("ente");break;case 6:if(!k())return!1;b.slice_del();break;case 7:if(!(t<=b.cursor))return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(r,4))&&(b.bra=b.cursor,h()&&(b.slice_del(),1==e&&(b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&b.slice_del()))));break;case 8:if(!h())return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(n,3))&&(b.bra=b.cursor,1==e&&h()&&b.slice_del());break;case 9:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del())))}return!0}function C(){var e;e=b.limit-b.cursor,b.ket=b.cursor,b.in_grouping_b(f,97,242)&&(b.bra=b.cursor,k()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(1,"i")&&(b.bra=b.cursor,k())))?b.slice_del():b.cursor=b.limit-e,b.ket=b.cursor,b.eq_s_b(1,"h")&&(b.bra=b.cursor,b.in_grouping_b(v,99,103)&&k()&&b.slice_del())}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e,r,n,i=b.cursor;return function(){for(var e,r,n,i,o=b.cursor;;){if(b.bra=b.cursor,e=b.find_among(a,7))switch(b.ket=b.cursor,e){case 1:b.slice_from("à");continue;case 2:b.slice_from("è");continue;case 3:b.slice_from("ì");continue;case 4:b.slice_from("ò");continue;case 5:b.slice_from("ù");continue;case 6:b.slice_from("qU");continue;case 7:if(b.cursor>=b.limit)break;b.cursor++;continue}break}for(b.cursor=o;;)for(r=b.cursor;;){if(n=b.cursor,b.in_grouping(m,97,249)){if(b.bra=b.cursor,i=b.cursor,d("u","U",n))break;if(b.cursor=i,d("i","I",n))break}if(b.cursor=n,b.cursor>=b.limit)return b.cursor=r;b.cursor++}}(),b.cursor=i,e=b.cursor,s=b.limit,o=t=s,g(),b.cursor=e,p()&&(t=b.cursor,p()&&(o=b.cursor)),b.limit_backward=i,b.cursor=b.limit,function(){var e;if(b.ket=b.cursor,b.find_among_b(c,37)&&(b.bra=b.cursor,(e=b.find_among_b(w,5))&&k()))switch(e){case 1:b.slice_del();break;case 2:b.slice_from("e")}}(),b.cursor=b.limit,q()||(b.cursor=b.limit,b.cursor>=s&&(n=b.limit_backward,b.limit_backward=s,b.ket=b.cursor,(r=b.find_among_b(l,87))&&(b.bra=b.cursor,1==r&&b.slice_del()),b.limit_backward=n)),b.cursor=b.limit,C(),b.cursor=b.limit_backward,function(){for(var e;b.bra=b.cursor,e=b.find_among(u,3);)switch(b.ket=b.cursor,e){case 1:b.slice_from("i");break;case 2:b.slice_from("u");break;case 3:if(b.cursor>=b.limit)return;b.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.jp.js b/assets/javascripts/lunr/lunr.jp.js new file mode 100644 index 000000000..ed2b3d258 --- /dev/null +++ b/assets/javascripts/lunr/lunr.jp.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(n){if(void 0===n)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===n.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==n.version[0];n.jp=function(){this.pipeline.reset(),this.pipeline.add(n.jp.stopWordFilter,n.jp.stemmer),i?this.tokenizer=n.jp.tokenizer:(n.tokenizer&&(n.tokenizer=n.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=n.jp.tokenizer))};var o=new n.TinySegmenter;n.jp.tokenizer=function(e){if(!arguments.length||null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return i?new n.Token(e.toLowerCase()):e.toLowerCase()});for(var r=e.toString().toLowerCase().replace(/^\s+/,""),t=r.length-1;0<=t;t--)if(/\S/.test(r.charAt(t))){r=r.substring(0,t+1);break}return o.segment(r).filter(function(e){return!!e}).map(function(e){return i?new n.Token(e):e})},n.jp.stemmer=function(e){return e},n.Pipeline.registerFunction(n.jp.stemmer,"stemmer-jp"),n.jp.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",n.jp.stopWordFilter=function(e){if(-1===n.jp.stopWordFilter.stopWords.indexOf(i?e.toString():e))return e},n.jp.stopWordFilter=n.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),n.Pipeline.registerFunction(n.jp.stopWordFilter,"stopWordFilter-jp")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.multi.js b/assets/javascripts/lunr/lunr.multi.js new file mode 100644 index 000000000..8a145c911 --- /dev/null +++ b/assets/javascripts/lunr/lunr.multi.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(o){o.multiLanguage=function(){for(var e=Array.prototype.slice.call(arguments),i=e.join("-"),t="",r=[],n=[],s=0;s=c.limit)return;c.cursor=e+1}for(;!c.out_grouping(u,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(s=c.cursor)=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,e=c.find_among_b(a,29),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:n=c.limit-c.cursor,c.in_grouping_b(d,98,122)?c.slice_del():(c.cursor=c.limit-n,c.eq_s_b(1,"k")&&c.out_grouping_b(u,97,248)&&c.slice_del());break;case 3:c.slice_from("er")}}(),c.cursor=c.limit,r=c.limit-c.cursor,c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.find_among_b(m,2)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e),c.cursor=c.limit,c.cursor>=s&&(i=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,(n=c.find_among_b(l,11))?(c.bra=c.cursor,c.limit_backward=i,1==n&&c.slice_del()):c.limit_backward=i),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.pt.js b/assets/javascripts/lunr/lunr.pt.js new file mode 100644 index 000000000..f50fc9fa6 --- /dev/null +++ b/assets/javascripts/lunr/lunr.pt.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var j,C,r;e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=(j=e.stemmerSupport.Among,C=e.stemmerSupport.SnowballProgram,r=new function(){var s,n,i,o=[new j("",-1,3),new j("ã",0,1),new j("õ",0,2)],a=[new j("",-1,3),new j("a~",0,1),new j("o~",0,2)],r=[new j("ic",-1,-1),new j("ad",-1,-1),new j("os",-1,-1),new j("iv",-1,1)],t=[new j("ante",-1,1),new j("avel",-1,1),new j("ível",-1,1)],u=[new j("ic",-1,1),new j("abil",-1,1),new j("iv",-1,1)],w=[new j("ica",-1,1),new j("ância",-1,1),new j("ência",-1,4),new j("ira",-1,9),new j("adora",-1,1),new j("osa",-1,1),new j("ista",-1,1),new j("iva",-1,8),new j("eza",-1,1),new j("logía",-1,2),new j("idade",-1,7),new j("ante",-1,1),new j("mente",-1,6),new j("amente",12,5),new j("ável",-1,1),new j("ível",-1,1),new j("ución",-1,3),new j("ico",-1,1),new j("ismo",-1,1),new j("oso",-1,1),new j("amento",-1,1),new j("imento",-1,1),new j("ivo",-1,8),new j("aça~o",-1,1),new j("ador",-1,1),new j("icas",-1,1),new j("ências",-1,4),new j("iras",-1,9),new j("adoras",-1,1),new j("osas",-1,1),new j("istas",-1,1),new j("ivas",-1,8),new j("ezas",-1,1),new j("logías",-1,2),new j("idades",-1,7),new j("uciones",-1,3),new j("adores",-1,1),new j("antes",-1,1),new j("aço~es",-1,1),new j("icos",-1,1),new j("ismos",-1,1),new j("osos",-1,1),new j("amentos",-1,1),new j("imentos",-1,1),new j("ivos",-1,8)],m=[new j("ada",-1,1),new j("ida",-1,1),new j("ia",-1,1),new j("aria",2,1),new j("eria",2,1),new j("iria",2,1),new j("ara",-1,1),new j("era",-1,1),new j("ira",-1,1),new j("ava",-1,1),new j("asse",-1,1),new j("esse",-1,1),new j("isse",-1,1),new j("aste",-1,1),new j("este",-1,1),new j("iste",-1,1),new j("ei",-1,1),new j("arei",16,1),new j("erei",16,1),new j("irei",16,1),new j("am",-1,1),new j("iam",20,1),new j("ariam",21,1),new j("eriam",21,1),new j("iriam",21,1),new j("aram",20,1),new j("eram",20,1),new j("iram",20,1),new j("avam",20,1),new j("em",-1,1),new j("arem",29,1),new j("erem",29,1),new j("irem",29,1),new j("assem",29,1),new j("essem",29,1),new j("issem",29,1),new j("ado",-1,1),new j("ido",-1,1),new j("ando",-1,1),new j("endo",-1,1),new j("indo",-1,1),new j("ara~o",-1,1),new j("era~o",-1,1),new j("ira~o",-1,1),new j("ar",-1,1),new j("er",-1,1),new j("ir",-1,1),new j("as",-1,1),new j("adas",47,1),new j("idas",47,1),new j("ias",47,1),new j("arias",50,1),new j("erias",50,1),new j("irias",50,1),new j("aras",47,1),new j("eras",47,1),new j("iras",47,1),new j("avas",47,1),new j("es",-1,1),new j("ardes",58,1),new j("erdes",58,1),new j("irdes",58,1),new j("ares",58,1),new j("eres",58,1),new j("ires",58,1),new j("asses",58,1),new j("esses",58,1),new j("isses",58,1),new j("astes",58,1),new j("estes",58,1),new j("istes",58,1),new j("is",-1,1),new j("ais",71,1),new j("eis",71,1),new j("areis",73,1),new j("ereis",73,1),new j("ireis",73,1),new j("áreis",73,1),new j("éreis",73,1),new j("íreis",73,1),new j("ásseis",73,1),new j("ésseis",73,1),new j("ísseis",73,1),new j("áveis",73,1),new j("íeis",73,1),new j("aríeis",84,1),new j("eríeis",84,1),new j("iríeis",84,1),new j("ados",-1,1),new j("idos",-1,1),new j("amos",-1,1),new j("áramos",90,1),new j("éramos",90,1),new j("íramos",90,1),new j("ávamos",90,1),new j("íamos",90,1),new j("aríamos",95,1),new j("eríamos",95,1),new j("iríamos",95,1),new j("emos",-1,1),new j("aremos",99,1),new j("eremos",99,1),new j("iremos",99,1),new j("ássemos",99,1),new j("êssemos",99,1),new j("íssemos",99,1),new j("imos",-1,1),new j("armos",-1,1),new j("ermos",-1,1),new j("irmos",-1,1),new j("ámos",-1,1),new j("arás",-1,1),new j("erás",-1,1),new j("irás",-1,1),new j("eu",-1,1),new j("iu",-1,1),new j("ou",-1,1),new j("ará",-1,1),new j("erá",-1,1),new j("irá",-1,1)],c=[new j("a",-1,1),new j("i",-1,1),new j("o",-1,1),new j("os",-1,1),new j("á",-1,1),new j("í",-1,1),new j("ó",-1,1)],l=[new j("e",-1,1),new j("ç",-1,2),new j("é",-1,1),new j("ê",-1,1)],f=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],d=new C;function v(){if(d.out_grouping(f,97,250)){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}return!0}function p(){var e,r,s=d.cursor;if(d.in_grouping(f,97,250))if(e=d.cursor,v()){if(d.cursor=e,function(){if(d.in_grouping(f,97,250))for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return i=d.cursor,!0}())return}else i=d.cursor;if(d.cursor=s,d.out_grouping(f,97,250)){if(r=d.cursor,v()){if(d.cursor=r,!d.in_grouping(f,97,250)||d.cursor>=d.limit)return;d.cursor++}i=d.cursor}}function _(){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return!0}function h(){return i<=d.cursor}function b(){return s<=d.cursor}function g(){var e;if(d.ket=d.cursor,!(e=d.find_among_b(w,45)))return!1;switch(d.bra=d.cursor,e){case 1:if(!b())return!1;d.slice_del();break;case 2:if(!b())return!1;d.slice_from("log");break;case 3:if(!b())return!1;d.slice_from("u");break;case 4:if(!b())return!1;d.slice_from("ente");break;case 5:if(!(n<=d.cursor))return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(r,4))&&(d.bra=d.cursor,b()&&(d.slice_del(),1==e&&(d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del()))));break;case 6:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(t,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 7:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(u,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 8:if(!b())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del());break;case 9:if(!h()||!d.eq_s_b(1,"e"))return!1;d.slice_from("ir")}return!0}function k(e,r){if(d.eq_s_b(1,e)){d.bra=d.cursor;var s=d.limit-d.cursor;if(d.eq_s_b(1,r))return d.cursor=d.limit-s,h()&&d.slice_del(),!1}return!0}function q(){if(!g()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor>=i){if(r=d.limit_backward,d.limit_backward=i,d.ket=d.cursor,e=d.find_among_b(m,120))return d.bra=d.cursor,1==e&&d.slice_del(),d.limit_backward=r,!0;d.limit_backward=r}return!1}()))return d.cursor=d.limit,d.ket=d.cursor,void((e=d.find_among_b(c,7))&&(d.bra=d.cursor,1==e&&h()&&d.slice_del()));var e;d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"i")&&(d.bra=d.cursor,d.eq_s_b(1,"c")&&(d.cursor=d.limit,h()&&d.slice_del()))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(o,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("a~");continue;case 2:d.slice_from("o~");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),d.cursor=r,e=d.cursor,i=d.limit,s=n=i,p(),d.cursor=e,_()&&(n=d.cursor,_()&&(s=d.cursor)),d.limit_backward=r,d.cursor=d.limit,q(),d.cursor=d.limit,function(){var e;if(d.ket=d.cursor,e=d.find_among_b(l,4))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.limit,d.cursor,k("u","g")&&k("i","c"));break;case 2:d.slice_from("c")}}(),d.cursor=d.limit_backward,function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(a,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("ã");continue;case 2:d.slice_from("õ");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.ro.js b/assets/javascripts/lunr/lunr.ro.js new file mode 100644 index 000000000..b19627e1b --- /dev/null +++ b/assets/javascripts/lunr/lunr.ro.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,z,i;e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=(h=e.stemmerSupport.Among,z=e.stemmerSupport.SnowballProgram,i=new function(){var r,n,t,a,o=[new h("",-1,3),new h("I",0,1),new h("U",0,2)],s=[new h("ea",-1,3),new h("aţia",-1,7),new h("aua",-1,2),new h("iua",-1,4),new h("aţie",-1,7),new h("ele",-1,3),new h("ile",-1,5),new h("iile",6,4),new h("iei",-1,4),new h("atei",-1,6),new h("ii",-1,4),new h("ului",-1,1),new h("ul",-1,1),new h("elor",-1,3),new h("ilor",-1,4),new h("iilor",14,4)],c=[new h("icala",-1,4),new h("iciva",-1,4),new h("ativa",-1,5),new h("itiva",-1,6),new h("icale",-1,4),new h("aţiune",-1,5),new h("iţiune",-1,6),new h("atoare",-1,5),new h("itoare",-1,6),new h("ătoare",-1,5),new h("icitate",-1,4),new h("abilitate",-1,1),new h("ibilitate",-1,2),new h("ivitate",-1,3),new h("icive",-1,4),new h("ative",-1,5),new h("itive",-1,6),new h("icali",-1,4),new h("atori",-1,5),new h("icatori",18,4),new h("itori",-1,6),new h("ători",-1,5),new h("icitati",-1,4),new h("abilitati",-1,1),new h("ivitati",-1,3),new h("icivi",-1,4),new h("ativi",-1,5),new h("itivi",-1,6),new h("icităi",-1,4),new h("abilităi",-1,1),new h("ivităi",-1,3),new h("icităţi",-1,4),new h("abilităţi",-1,1),new h("ivităţi",-1,3),new h("ical",-1,4),new h("ator",-1,5),new h("icator",35,4),new h("itor",-1,6),new h("ător",-1,5),new h("iciv",-1,4),new h("ativ",-1,5),new h("itiv",-1,6),new h("icală",-1,4),new h("icivă",-1,4),new h("ativă",-1,5),new h("itivă",-1,6)],u=[new h("ica",-1,1),new h("abila",-1,1),new h("ibila",-1,1),new h("oasa",-1,1),new h("ata",-1,1),new h("ita",-1,1),new h("anta",-1,1),new h("ista",-1,3),new h("uta",-1,1),new h("iva",-1,1),new h("ic",-1,1),new h("ice",-1,1),new h("abile",-1,1),new h("ibile",-1,1),new h("isme",-1,3),new h("iune",-1,2),new h("oase",-1,1),new h("ate",-1,1),new h("itate",17,1),new h("ite",-1,1),new h("ante",-1,1),new h("iste",-1,3),new h("ute",-1,1),new h("ive",-1,1),new h("ici",-1,1),new h("abili",-1,1),new h("ibili",-1,1),new h("iuni",-1,2),new h("atori",-1,1),new h("osi",-1,1),new h("ati",-1,1),new h("itati",30,1),new h("iti",-1,1),new h("anti",-1,1),new h("isti",-1,3),new h("uti",-1,1),new h("işti",-1,3),new h("ivi",-1,1),new h("ităi",-1,1),new h("oşi",-1,1),new h("ităţi",-1,1),new h("abil",-1,1),new h("ibil",-1,1),new h("ism",-1,3),new h("ator",-1,1),new h("os",-1,1),new h("at",-1,1),new h("it",-1,1),new h("ant",-1,1),new h("ist",-1,3),new h("ut",-1,1),new h("iv",-1,1),new h("ică",-1,1),new h("abilă",-1,1),new h("ibilă",-1,1),new h("oasă",-1,1),new h("ată",-1,1),new h("ită",-1,1),new h("antă",-1,1),new h("istă",-1,3),new h("ută",-1,1),new h("ivă",-1,1)],w=[new h("ea",-1,1),new h("ia",-1,1),new h("esc",-1,1),new h("ăsc",-1,1),new h("ind",-1,1),new h("ând",-1,1),new h("are",-1,1),new h("ere",-1,1),new h("ire",-1,1),new h("âre",-1,1),new h("se",-1,2),new h("ase",10,1),new h("sese",10,2),new h("ise",10,1),new h("use",10,1),new h("âse",10,1),new h("eşte",-1,1),new h("ăşte",-1,1),new h("eze",-1,1),new h("ai",-1,1),new h("eai",19,1),new h("iai",19,1),new h("sei",-1,2),new h("eşti",-1,1),new h("ăşti",-1,1),new h("ui",-1,1),new h("ezi",-1,1),new h("âi",-1,1),new h("aşi",-1,1),new h("seşi",-1,2),new h("aseşi",29,1),new h("seseşi",29,2),new h("iseşi",29,1),new h("useşi",29,1),new h("âseşi",29,1),new h("işi",-1,1),new h("uşi",-1,1),new h("âşi",-1,1),new h("aţi",-1,2),new h("eaţi",38,1),new h("iaţi",38,1),new h("eţi",-1,2),new h("iţi",-1,2),new h("âţi",-1,2),new h("arăţi",-1,1),new h("serăţi",-1,2),new h("aserăţi",45,1),new h("seserăţi",45,2),new h("iserăţi",45,1),new h("userăţi",45,1),new h("âserăţi",45,1),new h("irăţi",-1,1),new h("urăţi",-1,1),new h("ârăţi",-1,1),new h("am",-1,1),new h("eam",54,1),new h("iam",54,1),new h("em",-1,2),new h("asem",57,1),new h("sesem",57,2),new h("isem",57,1),new h("usem",57,1),new h("âsem",57,1),new h("im",-1,2),new h("âm",-1,2),new h("ăm",-1,2),new h("arăm",65,1),new h("serăm",65,2),new h("aserăm",67,1),new h("seserăm",67,2),new h("iserăm",67,1),new h("userăm",67,1),new h("âserăm",67,1),new h("irăm",65,1),new h("urăm",65,1),new h("ârăm",65,1),new h("au",-1,1),new h("eau",76,1),new h("iau",76,1),new h("indu",-1,1),new h("ându",-1,1),new h("ez",-1,1),new h("ească",-1,1),new h("ară",-1,1),new h("seră",-1,2),new h("aseră",84,1),new h("seseră",84,2),new h("iseră",84,1),new h("useră",84,1),new h("âseră",84,1),new h("iră",-1,1),new h("ură",-1,1),new h("âră",-1,1),new h("ează",-1,1)],i=[new h("a",-1,1),new h("e",-1,1),new h("ie",1,1),new h("i",-1,1),new h("ă",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],l=new z;function f(e,i){l.eq_s(1,e)&&(l.ket=l.cursor,l.in_grouping(m,97,259)&&l.slice_from(i))}function p(){if(l.out_grouping(m,97,259)){for(;!l.in_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}return!0}function d(){var e,i,r=l.cursor;if(l.in_grouping(m,97,259)){if(e=l.cursor,!p())return void(a=l.cursor);if(l.cursor=e,!function(){if(l.in_grouping(m,97,259))for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}())return void(a=l.cursor)}l.cursor=r,l.out_grouping(m,97,259)&&(i=l.cursor,p()&&(l.cursor=i,l.in_grouping(m,97,259)&&l.cursor=l.limit)return!1;l.cursor++}for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function v(){return t<=l.cursor}function _(){var e,i=l.limit-l.cursor;if(l.ket=l.cursor,(e=l.find_among_b(c,46))&&(l.bra=l.cursor,v())){switch(e){case 1:l.slice_from("abil");break;case 2:l.slice_from("ibil");break;case 3:l.slice_from("iv");break;case 4:l.slice_from("ic");break;case 5:l.slice_from("at");break;case 6:l.slice_from("it")}return r=!0,l.cursor=l.limit-i,!0}return!1}function g(){var e,i;for(r=!1;;)if(i=l.limit-l.cursor,!_()){l.cursor=l.limit-i;break}if(l.ket=l.cursor,(e=l.find_among_b(u,62))&&(l.bra=l.cursor,n<=l.cursor)){switch(e){case 1:l.slice_del();break;case 2:l.eq_s_b(1,"ţ")&&(l.bra=l.cursor,l.slice_from("t"));break;case 3:l.slice_from("ist")}r=!0}}function k(){var e;l.ket=l.cursor,(e=l.find_among_b(i,5))&&(l.bra=l.cursor,a<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var e,i=l.cursor;return function(){for(var e,i;e=l.cursor,l.in_grouping(m,97,259)&&(i=l.cursor,l.bra=i,f("u","U"),l.cursor=i,f("i","I")),l.cursor=e,!(l.cursor>=l.limit);)l.cursor++}(),l.cursor=i,e=l.cursor,a=l.limit,n=t=a,d(),l.cursor=e,b()&&(t=l.cursor,b()&&(n=l.cursor)),l.limit_backward=i,l.cursor=l.limit,function(){var e,i;if(l.ket=l.cursor,(e=l.find_among_b(s,16))&&(l.bra=l.cursor,v()))switch(e){case 1:l.slice_del();break;case 2:l.slice_from("a");break;case 3:l.slice_from("e");break;case 4:l.slice_from("i");break;case 5:i=l.limit-l.cursor,l.eq_s_b(2,"ab")||(l.cursor=l.limit-i,l.slice_from("i"));break;case 6:l.slice_from("at");break;case 7:l.slice_from("aţi")}}(),l.cursor=l.limit,g(),l.cursor=l.limit,r||(l.cursor=l.limit,function(){var e,i,r;if(l.cursor>=a){if(i=l.limit_backward,l.limit_backward=a,l.ket=l.cursor,e=l.find_among_b(w,94))switch(l.bra=l.cursor,e){case 1:if(r=l.limit-l.cursor,!l.out_grouping_b(m,97,259)&&(l.cursor=l.limit-r,!l.eq_s_b(1,"u")))break;case 2:l.slice_del()}l.limit_backward=i}}(),l.cursor=l.limit),k(),l.cursor=l.limit_backward,function(){for(var e;;){if(l.bra=l.cursor,e=l.find_among(o,3))switch(l.ket=l.cursor,e){case 1:l.slice_from("i");continue;case 2:l.slice_from("u");continue;case 3:if(l.cursor>=l.limit)break;l.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.ru.js b/assets/javascripts/lunr/lunr.ru.js new file mode 100644 index 000000000..ac9924804 --- /dev/null +++ b/assets/javascripts/lunr/lunr.ru.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,g,n;e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=(h=e.stemmerSupport.Among,g=e.stemmerSupport.SnowballProgram,n=new function(){var n,e,r=[new h("в",-1,1),new h("ив",0,2),new h("ыв",0,2),new h("вши",-1,1),new h("ивши",3,2),new h("ывши",3,2),new h("вшись",-1,1),new h("ившись",6,2),new h("ывшись",6,2)],t=[new h("ее",-1,1),new h("ие",-1,1),new h("ое",-1,1),new h("ые",-1,1),new h("ими",-1,1),new h("ыми",-1,1),new h("ей",-1,1),new h("ий",-1,1),new h("ой",-1,1),new h("ый",-1,1),new h("ем",-1,1),new h("им",-1,1),new h("ом",-1,1),new h("ым",-1,1),new h("его",-1,1),new h("ого",-1,1),new h("ему",-1,1),new h("ому",-1,1),new h("их",-1,1),new h("ых",-1,1),new h("ею",-1,1),new h("ою",-1,1),new h("ую",-1,1),new h("юю",-1,1),new h("ая",-1,1),new h("яя",-1,1)],w=[new h("ем",-1,1),new h("нн",-1,1),new h("вш",-1,1),new h("ивш",2,2),new h("ывш",2,2),new h("щ",-1,1),new h("ющ",5,1),new h("ующ",6,2)],i=[new h("сь",-1,1),new h("ся",-1,1)],u=[new h("ла",-1,1),new h("ила",0,2),new h("ыла",0,2),new h("на",-1,1),new h("ена",3,2),new h("ете",-1,1),new h("ите",-1,2),new h("йте",-1,1),new h("ейте",7,2),new h("уйте",7,2),new h("ли",-1,1),new h("или",10,2),new h("ыли",10,2),new h("й",-1,1),new h("ей",13,2),new h("уй",13,2),new h("л",-1,1),new h("ил",16,2),new h("ыл",16,2),new h("ем",-1,1),new h("им",-1,2),new h("ым",-1,2),new h("н",-1,1),new h("ен",22,2),new h("ло",-1,1),new h("ило",24,2),new h("ыло",24,2),new h("но",-1,1),new h("ено",27,2),new h("нно",27,1),new h("ет",-1,1),new h("ует",30,2),new h("ит",-1,2),new h("ыт",-1,2),new h("ют",-1,1),new h("уют",34,2),new h("ят",-1,2),new h("ны",-1,1),new h("ены",37,2),new h("ть",-1,1),new h("ить",39,2),new h("ыть",39,2),new h("ешь",-1,1),new h("ишь",-1,2),new h("ю",-1,2),new h("ую",44,2)],s=[new h("а",-1,1),new h("ев",-1,1),new h("ов",-1,1),new h("е",-1,1),new h("ие",3,1),new h("ье",3,1),new h("и",-1,1),new h("еи",6,1),new h("ии",6,1),new h("ами",6,1),new h("ями",6,1),new h("иями",10,1),new h("й",-1,1),new h("ей",12,1),new h("ией",13,1),new h("ий",12,1),new h("ой",12,1),new h("ам",-1,1),new h("ем",-1,1),new h("ием",18,1),new h("ом",-1,1),new h("ям",-1,1),new h("иям",21,1),new h("о",-1,1),new h("у",-1,1),new h("ах",-1,1),new h("ях",-1,1),new h("иях",26,1),new h("ы",-1,1),new h("ь",-1,1),new h("ю",-1,1),new h("ию",30,1),new h("ью",30,1),new h("я",-1,1),new h("ия",33,1),new h("ья",33,1)],o=[new h("ост",-1,1),new h("ость",-1,1)],c=[new h("ейше",-1,1),new h("н",-1,2),new h("ейш",-1,1),new h("ь",-1,3)],m=[33,65,8,232],l=new g;function f(){for(;!l.in_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function a(){for(;!l.out_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function p(e,n){var r,t;if(l.ket=l.cursor,r=l.find_among_b(e,n)){switch(l.bra=l.cursor,r){case 1:if(t=l.limit-l.cursor,!l.eq_s_b(1,"а")&&(l.cursor=l.limit-t,!l.eq_s_b(1,"я")))return!1;case 2:l.slice_del()}return!0}return!1}function d(e,n){var r;return l.ket=l.cursor,!!(r=l.find_among_b(e,n))&&(l.bra=l.cursor,1==r&&l.slice_del(),!0)}function _(){return!!d(t,26)&&(p(w,8),!0)}function b(){var e;l.ket=l.cursor,(e=l.find_among_b(o,2))&&(l.bra=l.cursor,n<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){return e=l.limit,n=e,f()&&(e=l.cursor,a()&&f()&&a()&&(n=l.cursor)),l.cursor=l.limit,!(l.cursor>3]&1<<(7&s))return this.cursor++,!0}return!1},in_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor--,!0}return!1},out_grouping:function(r,t,i){if(this.cursor>3]&1<<(7&s)))return this.cursor++,!0}return!1},out_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(i>3]&1<<(7&s)))return this.cursor--,!0}return!1},eq_s:function(r,t){if(this.limit-this.cursor>1),a=0,f=u=(l=r[i]).s_size){if(this.cursor=e+l.s_size,!l.method)return l.result;var m=l.method();if(this.cursor=e+l.s_size,m)return l.result}if((i=l.substring_i)<0)return 0}},find_among_b:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit_backward,u=0,o=0,h=!1;;){for(var c=i+(s-i>>1),a=0,f=u=(_=r[i]).s_size){if(this.cursor=e-_.s_size,!_.method)return _.result;var m=_.method();if(this.cursor=e-_.s_size,m)return _.result}if((i=_.substring_i)<0)return 0}},replace_s:function(r,t,i){var s=i.length-(t-r);return b=b.substring(0,r)+i+b.substring(t),this.limit+=s,this.cursor>=t?this.cursor+=s:this.cursor>r&&(this.cursor=r),s},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>b.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),b.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.sv.js b/assets/javascripts/lunr/lunr.sv.js new file mode 100644 index 000000000..6daf5f9d8 --- /dev/null +++ b/assets/javascripts/lunr/lunr.sv.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,l,n;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,l=e.stemmerSupport.SnowballProgram,n=new function(){var n,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new l;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e,r=m.cursor;return function(){var e,r=m.cursor+3;if(t=m.limit,0<=r||r<=m.limit){for(n=r;;){if(e=m.cursor,m.in_grouping(o,97,246)){m.cursor=e;break}if(m.cursor=e,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,e=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=e),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/lunr.tr.js b/assets/javascripts/lunr/lunr.tr.js new file mode 100644 index 000000000..e8fb5a7df --- /dev/null +++ b/assets/javascripts/lunr/lunr.tr.js @@ -0,0 +1 @@ +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var mr,dr,i;r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=(mr=r.stemmerSupport.Among,dr=r.stemmerSupport.SnowballProgram,i=new function(){var t,r=[new mr("m",-1,-1),new mr("n",-1,-1),new mr("miz",-1,-1),new mr("niz",-1,-1),new mr("muz",-1,-1),new mr("nuz",-1,-1),new mr("müz",-1,-1),new mr("nüz",-1,-1),new mr("mız",-1,-1),new mr("nız",-1,-1)],i=[new mr("leri",-1,-1),new mr("ları",-1,-1)],e=[new mr("ni",-1,-1),new mr("nu",-1,-1),new mr("nü",-1,-1),new mr("nı",-1,-1)],n=[new mr("in",-1,-1),new mr("un",-1,-1),new mr("ün",-1,-1),new mr("ın",-1,-1)],u=[new mr("a",-1,-1),new mr("e",-1,-1)],o=[new mr("na",-1,-1),new mr("ne",-1,-1)],s=[new mr("da",-1,-1),new mr("ta",-1,-1),new mr("de",-1,-1),new mr("te",-1,-1)],c=[new mr("nda",-1,-1),new mr("nde",-1,-1)],l=[new mr("dan",-1,-1),new mr("tan",-1,-1),new mr("den",-1,-1),new mr("ten",-1,-1)],a=[new mr("ndan",-1,-1),new mr("nden",-1,-1)],m=[new mr("la",-1,-1),new mr("le",-1,-1)],d=[new mr("ca",-1,-1),new mr("ce",-1,-1)],f=[new mr("im",-1,-1),new mr("um",-1,-1),new mr("üm",-1,-1),new mr("ım",-1,-1)],b=[new mr("sin",-1,-1),new mr("sun",-1,-1),new mr("sün",-1,-1),new mr("sın",-1,-1)],w=[new mr("iz",-1,-1),new mr("uz",-1,-1),new mr("üz",-1,-1),new mr("ız",-1,-1)],_=[new mr("siniz",-1,-1),new mr("sunuz",-1,-1),new mr("sünüz",-1,-1),new mr("sınız",-1,-1)],k=[new mr("lar",-1,-1),new mr("ler",-1,-1)],p=[new mr("niz",-1,-1),new mr("nuz",-1,-1),new mr("nüz",-1,-1),new mr("nız",-1,-1)],g=[new mr("dir",-1,-1),new mr("tir",-1,-1),new mr("dur",-1,-1),new mr("tur",-1,-1),new mr("dür",-1,-1),new mr("tür",-1,-1),new mr("dır",-1,-1),new mr("tır",-1,-1)],y=[new mr("casına",-1,-1),new mr("cesine",-1,-1)],z=[new mr("di",-1,-1),new mr("ti",-1,-1),new mr("dik",-1,-1),new mr("tik",-1,-1),new mr("duk",-1,-1),new mr("tuk",-1,-1),new mr("dük",-1,-1),new mr("tük",-1,-1),new mr("dık",-1,-1),new mr("tık",-1,-1),new mr("dim",-1,-1),new mr("tim",-1,-1),new mr("dum",-1,-1),new mr("tum",-1,-1),new mr("düm",-1,-1),new mr("tüm",-1,-1),new mr("dım",-1,-1),new mr("tım",-1,-1),new mr("din",-1,-1),new mr("tin",-1,-1),new mr("dun",-1,-1),new mr("tun",-1,-1),new mr("dün",-1,-1),new mr("tün",-1,-1),new mr("dın",-1,-1),new mr("tın",-1,-1),new mr("du",-1,-1),new mr("tu",-1,-1),new mr("dü",-1,-1),new mr("tü",-1,-1),new mr("dı",-1,-1),new mr("tı",-1,-1)],h=[new mr("sa",-1,-1),new mr("se",-1,-1),new mr("sak",-1,-1),new mr("sek",-1,-1),new mr("sam",-1,-1),new mr("sem",-1,-1),new mr("san",-1,-1),new mr("sen",-1,-1)],v=[new mr("miş",-1,-1),new mr("muş",-1,-1),new mr("müş",-1,-1),new mr("mış",-1,-1)],q=[new mr("b",-1,1),new mr("c",-1,2),new mr("d",-1,3),new mr("ğ",-1,4)],C=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],P=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],F=[65],S=[65],W=[["a",[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["e",[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],101,252],["ı",[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["i",[17],101,105],["o",F,111,117],["ö",S,246,252],["u",F,111,117]],L=new dr;function x(r,i,e){for(;;){var n=L.limit-L.cursor;if(L.in_grouping_b(r,i,e)){L.cursor=L.limit-n;break}if(L.cursor=L.limit-n,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}function A(){var r,i;r=L.limit-L.cursor,x(C,97,305);for(var e=0;eL.limit_backward&&(L.cursor--,e=L.limit-L.cursor,i()))?(L.cursor=L.limit-e,!0):(L.cursor=L.limit-n,r()?(L.cursor=L.limit-n,!1):(L.cursor=L.limit-n,!(L.cursor<=L.limit_backward)&&(L.cursor--,!!i()&&(L.cursor=L.limit-n,!0))))}function j(r){return E(r,function(){return L.in_grouping_b(C,97,305)})}function T(){return j(function(){return L.eq_s_b(1,"n")})}function Z(){return j(function(){return L.eq_s_b(1,"y")})}function B(){return L.find_among_b(r,10)&&E(function(){return L.in_grouping_b(P,105,305)},function(){return L.out_grouping_b(C,97,305)})}function D(){return A()&&L.in_grouping_b(P,105,305)&&j(function(){return L.eq_s_b(1,"s")})}function G(){return L.find_among_b(i,2)}function H(){return A()&&L.find_among_b(n,4)&&T()}function I(){return A()&&L.find_among_b(s,4)}function J(){return A()&&L.find_among_b(c,2)}function K(){return A()&&L.find_among_b(f,4)&&Z()}function M(){return A()&&L.find_among_b(b,4)}function N(){return A()&&L.find_among_b(w,4)&&Z()}function O(){return L.find_among_b(_,4)}function Q(){return A()&&L.find_among_b(k,2)}function R(){return A()&&L.find_among_b(g,8)}function U(){return A()&&L.find_among_b(z,32)&&Z()}function V(){return L.find_among_b(h,8)&&Z()}function X(){return A()&&L.find_among_b(v,4)&&Z()}function Y(){var r=L.limit-L.cursor;return!(X()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,L.eq_s_b(3,"ken")&&Z()))))}function $(){if(L.find_among_b(y,2)){var r=L.limit-L.cursor;if(O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X())return!1}return!0}function rr(){if(!A()||!L.find_among_b(p,4))return!0;var r=L.limit-L.cursor;return!U()&&(L.cursor=L.limit-r,!V())}function ir(){var r,i,e,n=L.limit-L.cursor;if(L.ket=L.cursor,t=!0,Y()&&(L.cursor=L.limit-n,$()&&(L.cursor=L.limit-n,function(){if(Q()){L.bra=L.cursor,L.slice_del();var r=L.limit-L.cursor;return L.ket=L.cursor,R()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,X()||(L.cursor=L.limit-r)))),t=!1}return!0}()&&(L.cursor=L.limit-n,rr()&&(L.cursor=L.limit-n,e=L.limit-L.cursor,!(O()||(L.cursor=L.limit-e,N()||(L.cursor=L.limit-e,M()||(L.cursor=L.limit-e,K()))))||(L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,X()||(L.cursor=L.limit-i),0)))))){if(L.cursor=L.limit-n,!R())return;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X()||(L.cursor=L.limit-r)}L.bra=L.cursor,L.slice_del()}function er(){var r,i,e,n;if(L.ket=L.cursor,L.eq_s_b(2,"ki")){if(r=L.limit-L.cursor,I())return L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()?(L.bra=L.cursor,L.slice_del(),er()):(L.cursor=L.limit-i,B()&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))),!0;if(L.cursor=L.limit-r,H()){if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,e=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-e,L.ket=L.cursor,!B()&&(L.cursor=L.limit-e,!D()&&(L.cursor=L.limit-e,!er())))return!0;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}return!0}if(L.cursor=L.limit-r,J()){if(n=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-n,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-n,!er())return!1;return!0}}return!1}function nr(r){if(L.ket=L.cursor,!J()&&(L.cursor=L.limit-r,!A()||!L.find_among_b(o,2)))return!1;var i=L.limit-L.cursor;if(G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-i,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-i,!er())return!1;return!0}function tr(r){if(L.ket=L.cursor,!(A()&&L.find_among_b(a,2)||(L.cursor=L.limit-r,A()&&L.find_among_b(e,4))))return!1;var i=L.limit-L.cursor;return!(!D()&&(L.cursor=L.limit-i,!G()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()),!0)}function ur(){var r,i=L.limit-L.cursor;return L.ket=L.cursor,!!(H()||(L.cursor=L.limit-i,A()&&L.find_among_b(m,2)&&Z()))&&(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,!(!Q()||(L.bra=L.cursor,L.slice_del(),!er()))||(L.cursor=L.limit-r,L.ket=L.cursor,(B()||(L.cursor=L.limit-r,D()||(L.cursor=L.limit-r,er())))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())),!0))}function or(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,!(I()||(L.cursor=L.limit-e,A()&&L.in_grouping_b(P,105,305)&&Z()||(L.cursor=L.limit-e,A()&&L.find_among_b(u,2)&&Z()))))return!1;if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,B())L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()||(L.cursor=L.limit-i);else if(L.cursor=L.limit-r,!Q())return!0;return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,er(),!0}function sr(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,Q())return L.bra=L.cursor,L.slice_del(),void er();if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(d,2)&&T())if(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-r,L.ket=L.cursor,!B()&&(L.cursor=L.limit-r,!D())){if(L.cursor=L.limit-r,L.ket=L.cursor,!Q())return;if(L.bra=L.cursor,L.slice_del(),!er())return}L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}else if(L.cursor=L.limit-e,!nr(e)&&(L.cursor=L.limit-e,!tr(e))){if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(l,4))return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,i=L.limit-L.cursor,void(B()?(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())):(L.cursor=L.limit-i,Q()?(L.bra=L.cursor,L.slice_del()):L.cursor=L.limit-i,er()));if(L.cursor=L.limit-e,!ur()){if(L.cursor=L.limit-e,G())return L.bra=L.cursor,void L.slice_del();L.cursor=L.limit-e,er()||(L.cursor=L.limit-e,or()||(L.cursor=L.limit-e,L.ket=L.cursor,(B()||(L.cursor=L.limit-e,D()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))))}}}function cr(r,i,e){if(L.cursor=L.limit-r,function(){for(;;){var r=L.limit-L.cursor;if(L.in_grouping_b(C,97,305)){L.cursor=L.limit-r;break}if(L.cursor=L.limit-r,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}()){var n=L.limit-L.cursor;if(!L.eq_s_b(1,i)&&(L.cursor=L.limit-n,!L.eq_s_b(1,e)))return!0;L.cursor=L.limit-r;var t=L.cursor;return L.insert(L.cursor,L.cursor,e),L.cursor=t,!1}return!0}function lr(r,i,e){for(;!L.eq_s(i,e);){if(L.cursor>=L.limit)return!0;L.cursor++}return i!=L.limit||(L.cursor=r,!1)}function ar(){var r,i,e=L.cursor;return!(!lr(r=L.cursor,2,"ad")||!lr(L.cursor=r,5,"soyad"))&&(L.limit_backward=e,L.cursor=L.limit,i=L.limit-L.cursor,(L.eq_s_b(1,"d")||(L.cursor=L.limit-i,L.eq_s_b(1,"g")))&&cr(i,"a","ı")&&cr(i,"e","i")&&cr(i,"o","u")&&cr(i,"ö","ü"),L.cursor=L.limit,function(){var r;if(L.ket=L.cursor,r=L.find_among_b(q,4))switch(L.bra=L.cursor,r){case 1:L.slice_from("p");break;case 2:L.slice_from("ç");break;case 3:L.slice_from("t");break;case 4:L.slice_from("k")}}(),!0)}this.setCurrent=function(r){L.setCurrent(r)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){return!!(function(){for(var r,i=L.cursor,e=2;;){for(r=L.cursor;!L.in_grouping(C,97,305);){if(L.cursor>=L.limit)return L.cursor=r,!(0c;c++)if(m=e[c],v=j.style[m],u(m,"-")&&(m=p(m)),j.style[m]!==n){if(i||r(o,"undefined"))return a(),"pfx"!=t||m;try{j.style[m]=o}catch(e){}if(j.style[m]!=v)return a(),"pfx"!=t||m}return a(),!1}function m(e,t){return function(){return e.apply(t,arguments)}}function v(e,t,n){var o;for(var i in e)if(e[i]in t)return!1===n?e[i]:(o=t[e[i]],r(o,"function")?m(o,n||t):o);return!1}function y(e,t,n,o,i){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+k.join(s+" ")+s).split(" ");return r(t,"string")||r(t,"undefined")?h(a,t,o,i):(a=(e+" "+A.join(s+" ")+s).split(" "),v(a,t,n))}function g(e,t,r){return y(e,n,n,t,r)}var S=[],C={_version:"3.6.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){S.push({name:e,fn:t,options:n})},addAsyncTest:function(e){S.push({name:null,fn:e})}},w=function(){};w.prototype=C,w=new w;var b,_=[],x=t.documentElement,T="svg"===x.nodeName.toLowerCase();!function(){var e={}.hasOwnProperty;b=r(e,"undefined")||r(e.call,"undefined")?function(e,t){return t in e&&r(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),C._l={},C.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),w.hasOwnProperty(e)&&setTimeout(function(){w._trigger(e,w[e])},0)},C._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e;for(e=0;epnp-spfx-controls diff --git a/assets/sharepoint.png b/assets/sharepoint.png new file mode 100644 index 000000000..2406dddb9 Binary files /dev/null and b/assets/sharepoint.png differ diff --git a/assets/site-picker-multi-select.gif b/assets/site-picker-multi-select.gif new file mode 100644 index 000000000..72e22d95d Binary files /dev/null and b/assets/site-picker-multi-select.gif differ diff --git a/assets/site-picker-single-select.gif b/assets/site-picker-single-select.gif new file mode 100644 index 000000000..ffc5a1089 Binary files /dev/null and b/assets/site-picker-single-select.gif differ diff --git a/assets/stylesheets/application-palette.22915126.css b/assets/stylesheets/application-palette.22915126.css new file mode 100644 index 000000000..3c8766e26 --- /dev/null +++ b/assets/stylesheets/application-palette.22915126.css @@ -0,0 +1,1176 @@ +button[data-md-color-primary], +button[data-md-color-accent] { + width: 13rem; + margin-bottom: 0.4rem; + padding: 2.4rem 0.8rem 0.4rem; + transition: background-color 0.25s, opacity 0.25s; + border-radius: 0.2rem; + color: white; + font-size: 1.28rem; + text-align: left; + cursor: pointer; } + button[data-md-color-primary]:hover, + button[data-md-color-accent]:hover { + opacity: 0.75; } + +button[data-md-color-primary="red"] { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-typeset a { + color: #ef5350; } + +[data-md-color-primary="red"] .md-header { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-hero { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-nav__link:active, +[data-md-color-primary="red"] .md-nav__link--active { + color: #ef5350; } + +[data-md-color-primary="red"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="pink"] { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-typeset a { + color: #e91e63; } + +[data-md-color-primary="pink"] .md-header { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-hero { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-nav__link:active, +[data-md-color-primary="pink"] .md-nav__link--active { + color: #e91e63; } + +[data-md-color-primary="pink"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="purple"] { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-typeset a { + color: #ab47bc; } + +[data-md-color-primary="purple"] .md-header { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-hero { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-nav__link:active, +[data-md-color-primary="purple"] .md-nav__link--active { + color: #ab47bc; } + +[data-md-color-primary="purple"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="deep-purple"] { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-typeset a { + color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-header { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-hero { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-nav__link:active, +[data-md-color-primary="deep-purple"] .md-nav__link--active { + color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="indigo"] { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-typeset a { + color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-header { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-hero { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-nav__link:active, +[data-md-color-primary="indigo"] .md-nav__link--active { + color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="blue"] { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-typeset a { + color: #2196f3; } + +[data-md-color-primary="blue"] .md-header { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-hero { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-nav__link:active, +[data-md-color-primary="blue"] .md-nav__link--active { + color: #2196f3; } + +[data-md-color-primary="blue"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="light-blue"] { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-typeset a { + color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-header { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-hero { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-nav__link:active, +[data-md-color-primary="light-blue"] .md-nav__link--active { + color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="cyan"] { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-typeset a { + color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-header { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-hero { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-nav__link:active, +[data-md-color-primary="cyan"] .md-nav__link--active { + color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="teal"] { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-typeset a { + color: #009688; } + +[data-md-color-primary="teal"] .md-header { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-hero { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-nav__link:active, +[data-md-color-primary="teal"] .md-nav__link--active { + color: #009688; } + +[data-md-color-primary="teal"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="green"] { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-typeset a { + color: #4caf50; } + +[data-md-color-primary="green"] .md-header { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-hero { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-nav__link:active, +[data-md-color-primary="green"] .md-nav__link--active { + color: #4caf50; } + +[data-md-color-primary="green"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="light-green"] { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-typeset a { + color: #7cb342; } + +[data-md-color-primary="light-green"] .md-header { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-hero { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-nav__link:active, +[data-md-color-primary="light-green"] .md-nav__link--active { + color: #7cb342; } + +[data-md-color-primary="light-green"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="lime"] { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-typeset a { + color: #c0ca33; } + +[data-md-color-primary="lime"] .md-header { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-hero { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-nav__link:active, +[data-md-color-primary="lime"] .md-nav__link--active { + color: #c0ca33; } + +[data-md-color-primary="lime"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="yellow"] { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-typeset a { + color: #f9a825; } + +[data-md-color-primary="yellow"] .md-header { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-hero { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-nav__link:active, +[data-md-color-primary="yellow"] .md-nav__link--active { + color: #f9a825; } + +[data-md-color-primary="yellow"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="amber"] { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-typeset a { + color: #ffa000; } + +[data-md-color-primary="amber"] .md-header { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-hero { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-nav__link:active, +[data-md-color-primary="amber"] .md-nav__link--active { + color: #ffa000; } + +[data-md-color-primary="amber"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="orange"] { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-typeset a { + color: #fb8c00; } + +[data-md-color-primary="orange"] .md-header { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-hero { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-nav__link:active, +[data-md-color-primary="orange"] .md-nav__link--active { + color: #fb8c00; } + +[data-md-color-primary="orange"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="deep-orange"] { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-typeset a { + color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-header { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-hero { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-nav__link:active, +[data-md-color-primary="deep-orange"] .md-nav__link--active { + color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="brown"] { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-typeset a { + color: #795548; } + +[data-md-color-primary="brown"] .md-header { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-hero { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-nav__link:active, +[data-md-color-primary="brown"] .md-nav__link--active { + color: #795548; } + +[data-md-color-primary="brown"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="grey"] { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-typeset a { + color: #757575; } + +[data-md-color-primary="grey"] .md-header { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-hero { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-nav__link:active, +[data-md-color-primary="grey"] .md-nav__link--active { + color: #757575; } + +[data-md-color-primary="grey"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="blue-grey"] { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-typeset a { + color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-header { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-hero { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-nav__link:active, +[data-md-color-primary="blue-grey"] .md-nav__link--active { + color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="white"] { + background-color: white; + color: rgba(0, 0, 0, 0.87); + box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.54) inset; } + +[data-md-color-primary="white"] .md-header { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + +[data-md-color-primary="white"] .md-hero { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + [data-md-color-primary="white"] .md-hero--expand { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); } + +button[data-md-color-accent="red"] { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset a:hover, +[data-md-color-accent="red"] .md-typeset a:active { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="red"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="red"] .md-typeset .md-clipboard:active::before { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="red"] .md-typeset .footnote li:target .footnote-backref { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="red"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="red"] .md-typeset [id] .headerlink:focus { + color: #ff1744; } + +[data-md-color-accent="red"] .md-nav__link:focus, +[data-md-color-accent="red"] .md-nav__link:hover { + color: #ff1744; } + +[data-md-color-accent="red"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="red"] .md-search-result__link:hover { + background-color: rgba(255, 23, 68, 0.1); } + +[data-md-color-accent="red"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-source-file:hover::before { + background-color: #ff1744; } + +button[data-md-color-accent="pink"] { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset a:hover, +[data-md-color-accent="pink"] .md-typeset a:active { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="pink"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="pink"] .md-typeset .md-clipboard:active::before { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="pink"] .md-typeset .footnote li:target .footnote-backref { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="pink"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="pink"] .md-typeset [id] .headerlink:focus { + color: #f50057; } + +[data-md-color-accent="pink"] .md-nav__link:focus, +[data-md-color-accent="pink"] .md-nav__link:hover { + color: #f50057; } + +[data-md-color-accent="pink"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="pink"] .md-search-result__link:hover { + background-color: rgba(245, 0, 87, 0.1); } + +[data-md-color-accent="pink"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-source-file:hover::before { + background-color: #f50057; } + +button[data-md-color-accent="purple"] { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset a:hover, +[data-md-color-accent="purple"] .md-typeset a:active { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="purple"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="purple"] .md-typeset .md-clipboard:active::before { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="purple"] .md-typeset .footnote li:target .footnote-backref { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="purple"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="purple"] .md-typeset [id] .headerlink:focus { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-nav__link:focus, +[data-md-color-accent="purple"] .md-nav__link:hover { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="purple"] .md-search-result__link:hover { + background-color: rgba(224, 64, 251, 0.1); } + +[data-md-color-accent="purple"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-source-file:hover::before { + background-color: #e040fb; } + +button[data-md-color-accent="deep-purple"] { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset a:hover, +[data-md-color-accent="deep-purple"] .md-typeset a:active { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="deep-purple"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="deep-purple"] .md-typeset .md-clipboard:active::before { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="deep-purple"] .md-typeset .footnote li:target .footnote-backref { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="deep-purple"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="deep-purple"] .md-typeset [id] .headerlink:focus { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-nav__link:focus, +[data-md-color-accent="deep-purple"] .md-nav__link:hover { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="deep-purple"] .md-search-result__link:hover { + background-color: rgba(124, 77, 255, 0.1); } + +[data-md-color-accent="deep-purple"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-source-file:hover::before { + background-color: #7c4dff; } + +button[data-md-color-accent="indigo"] { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset a:hover, +[data-md-color-accent="indigo"] .md-typeset a:active { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="indigo"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="indigo"] .md-typeset .md-clipboard:active::before { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="indigo"] .md-typeset .footnote li:target .footnote-backref { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="indigo"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="indigo"] .md-typeset [id] .headerlink:focus { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-nav__link:focus, +[data-md-color-accent="indigo"] .md-nav__link:hover { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="indigo"] .md-search-result__link:hover { + background-color: rgba(83, 109, 254, 0.1); } + +[data-md-color-accent="indigo"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-source-file:hover::before { + background-color: #536dfe; } + +button[data-md-color-accent="blue"] { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset a:hover, +[data-md-color-accent="blue"] .md-typeset a:active { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="blue"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="blue"] .md-typeset .md-clipboard:active::before { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="blue"] .md-typeset .footnote li:target .footnote-backref { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="blue"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="blue"] .md-typeset [id] .headerlink:focus { + color: #448aff; } + +[data-md-color-accent="blue"] .md-nav__link:focus, +[data-md-color-accent="blue"] .md-nav__link:hover { + color: #448aff; } + +[data-md-color-accent="blue"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="blue"] .md-search-result__link:hover { + background-color: rgba(68, 138, 255, 0.1); } + +[data-md-color-accent="blue"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-source-file:hover::before { + background-color: #448aff; } + +button[data-md-color-accent="light-blue"] { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset a:hover, +[data-md-color-accent="light-blue"] .md-typeset a:active { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="light-blue"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="light-blue"] .md-typeset .md-clipboard:active::before { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="light-blue"] .md-typeset .footnote li:target .footnote-backref { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="light-blue"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="light-blue"] .md-typeset [id] .headerlink:focus { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-nav__link:focus, +[data-md-color-accent="light-blue"] .md-nav__link:hover { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="light-blue"] .md-search-result__link:hover { + background-color: rgba(0, 145, 234, 0.1); } + +[data-md-color-accent="light-blue"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-source-file:hover::before { + background-color: #0091ea; } + +button[data-md-color-accent="cyan"] { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset a:hover, +[data-md-color-accent="cyan"] .md-typeset a:active { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="cyan"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="cyan"] .md-typeset .md-clipboard:active::before { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="cyan"] .md-typeset .footnote li:target .footnote-backref { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="cyan"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="cyan"] .md-typeset [id] .headerlink:focus { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-nav__link:focus, +[data-md-color-accent="cyan"] .md-nav__link:hover { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="cyan"] .md-search-result__link:hover { + background-color: rgba(0, 184, 212, 0.1); } + +[data-md-color-accent="cyan"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-source-file:hover::before { + background-color: #00b8d4; } + +button[data-md-color-accent="teal"] { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset a:hover, +[data-md-color-accent="teal"] .md-typeset a:active { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="teal"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="teal"] .md-typeset .md-clipboard:active::before { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="teal"] .md-typeset .footnote li:target .footnote-backref { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="teal"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="teal"] .md-typeset [id] .headerlink:focus { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-nav__link:focus, +[data-md-color-accent="teal"] .md-nav__link:hover { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="teal"] .md-search-result__link:hover { + background-color: rgba(0, 191, 165, 0.1); } + +[data-md-color-accent="teal"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-source-file:hover::before { + background-color: #00bfa5; } + +button[data-md-color-accent="green"] { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-typeset a:hover, +[data-md-color-accent="green"] .md-typeset a:active { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="green"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="green"] .md-typeset .md-clipboard:active::before { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="green"] .md-typeset .footnote li:target .footnote-backref { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="green"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="green"] .md-typeset [id] .headerlink:focus { + color: #00c853; } + +[data-md-color-accent="green"] .md-nav__link:focus, +[data-md-color-accent="green"] .md-nav__link:hover { + color: #00c853; } + +[data-md-color-accent="green"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="green"] .md-search-result__link:hover { + background-color: rgba(0, 200, 83, 0.1); } + +[data-md-color-accent="green"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-source-file:hover::before { + background-color: #00c853; } + +button[data-md-color-accent="light-green"] { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset a:hover, +[data-md-color-accent="light-green"] .md-typeset a:active { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="light-green"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="light-green"] .md-typeset .md-clipboard:active::before { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="light-green"] .md-typeset .footnote li:target .footnote-backref { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="light-green"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="light-green"] .md-typeset [id] .headerlink:focus { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-nav__link:focus, +[data-md-color-accent="light-green"] .md-nav__link:hover { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="light-green"] .md-search-result__link:hover { + background-color: rgba(100, 221, 23, 0.1); } + +[data-md-color-accent="light-green"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-source-file:hover::before { + background-color: #64dd17; } + +button[data-md-color-accent="lime"] { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset a:hover, +[data-md-color-accent="lime"] .md-typeset a:active { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="lime"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="lime"] .md-typeset .md-clipboard:active::before { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="lime"] .md-typeset .footnote li:target .footnote-backref { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="lime"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="lime"] .md-typeset [id] .headerlink:focus { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-nav__link:focus, +[data-md-color-accent="lime"] .md-nav__link:hover { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="lime"] .md-search-result__link:hover { + background-color: rgba(174, 234, 0, 0.1); } + +[data-md-color-accent="lime"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-source-file:hover::before { + background-color: #aeea00; } + +button[data-md-color-accent="yellow"] { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset a:hover, +[data-md-color-accent="yellow"] .md-typeset a:active { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="yellow"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="yellow"] .md-typeset .md-clipboard:active::before { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="yellow"] .md-typeset .footnote li:target .footnote-backref { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="yellow"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="yellow"] .md-typeset [id] .headerlink:focus { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-nav__link:focus, +[data-md-color-accent="yellow"] .md-nav__link:hover { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="yellow"] .md-search-result__link:hover { + background-color: rgba(255, 214, 0, 0.1); } + +[data-md-color-accent="yellow"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-source-file:hover::before { + background-color: #ffd600; } + +button[data-md-color-accent="amber"] { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset a:hover, +[data-md-color-accent="amber"] .md-typeset a:active { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="amber"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="amber"] .md-typeset .md-clipboard:active::before { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="amber"] .md-typeset .footnote li:target .footnote-backref { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="amber"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="amber"] .md-typeset [id] .headerlink:focus { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-nav__link:focus, +[data-md-color-accent="amber"] .md-nav__link:hover { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="amber"] .md-search-result__link:hover { + background-color: rgba(255, 171, 0, 0.1); } + +[data-md-color-accent="amber"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-source-file:hover::before { + background-color: #ffab00; } + +button[data-md-color-accent="orange"] { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset a:hover, +[data-md-color-accent="orange"] .md-typeset a:active { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="orange"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="orange"] .md-typeset .md-clipboard:active::before { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="orange"] .md-typeset .footnote li:target .footnote-backref { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="orange"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="orange"] .md-typeset [id] .headerlink:focus { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-nav__link:focus, +[data-md-color-accent="orange"] .md-nav__link:hover { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="orange"] .md-search-result__link:hover { + background-color: rgba(255, 145, 0, 0.1); } + +[data-md-color-accent="orange"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-source-file:hover::before { + background-color: #ff9100; } + +button[data-md-color-accent="deep-orange"] { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset a:hover, +[data-md-color-accent="deep-orange"] .md-typeset a:active { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="deep-orange"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="deep-orange"] .md-typeset .md-clipboard:active::before { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="deep-orange"] .md-typeset .footnote li:target .footnote-backref { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="deep-orange"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="deep-orange"] .md-typeset [id] .headerlink:focus { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-nav__link:focus, +[data-md-color-accent="deep-orange"] .md-nav__link:hover { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="deep-orange"] .md-search-result__link:hover { + background-color: rgba(255, 110, 64, 0.1); } + +[data-md-color-accent="deep-orange"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-source-file:hover::before { + background-color: #ff6e40; } + +@media only screen and (max-width: 59.9375em) { + [data-md-color-primary="red"] .md-nav__source { + background-color: rgba(190, 66, 64, 0.9675); } + [data-md-color-primary="pink"] .md-nav__source { + background-color: rgba(185, 24, 79, 0.9675); } + [data-md-color-primary="purple"] .md-nav__source { + background-color: rgba(136, 57, 150, 0.9675); } + [data-md-color-primary="deep-purple"] .md-nav__source { + background-color: rgba(100, 69, 154, 0.9675); } + [data-md-color-primary="indigo"] .md-nav__source { + background-color: rgba(50, 64, 144, 0.9675); } + [data-md-color-primary="blue"] .md-nav__source { + background-color: rgba(26, 119, 193, 0.9675); } + [data-md-color-primary="light-blue"] .md-nav__source { + background-color: rgba(2, 134, 194, 0.9675); } + [data-md-color-primary="cyan"] .md-nav__source { + background-color: rgba(0, 150, 169, 0.9675); } + [data-md-color-primary="teal"] .md-nav__source { + background-color: rgba(0, 119, 108, 0.9675); } + [data-md-color-primary="green"] .md-nav__source { + background-color: rgba(60, 139, 64, 0.9675); } + [data-md-color-primary="light-green"] .md-nav__source { + background-color: rgba(99, 142, 53, 0.9675); } + [data-md-color-primary="lime"] .md-nav__source { + background-color: rgba(153, 161, 41, 0.9675); } + [data-md-color-primary="yellow"] .md-nav__source { + background-color: rgba(198, 134, 29, 0.9675); } + [data-md-color-primary="amber"] .md-nav__source { + background-color: rgba(203, 127, 0, 0.9675); } + [data-md-color-primary="orange"] .md-nav__source { + background-color: rgba(200, 111, 0, 0.9675); } + [data-md-color-primary="deep-orange"] .md-nav__source { + background-color: rgba(203, 89, 53, 0.9675); } + [data-md-color-primary="brown"] .md-nav__source { + background-color: rgba(96, 68, 57, 0.9675); } + [data-md-color-primary="grey"] .md-nav__source { + background-color: rgba(93, 93, 93, 0.9675); } + [data-md-color-primary="blue-grey"] .md-nav__source { + background-color: rgba(67, 88, 97, 0.9675); } + [data-md-color-primary="white"] .md-nav__source { + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.87); } } + +@media only screen and (max-width: 76.1875em) { + html [data-md-color-primary="red"] .md-nav--primary .md-nav__title--site { + background-color: #ef5350; } + html [data-md-color-primary="pink"] .md-nav--primary .md-nav__title--site { + background-color: #e91e63; } + html [data-md-color-primary="purple"] .md-nav--primary .md-nav__title--site { + background-color: #ab47bc; } + html [data-md-color-primary="deep-purple"] .md-nav--primary .md-nav__title--site { + background-color: #7e57c2; } + html [data-md-color-primary="indigo"] .md-nav--primary .md-nav__title--site { + background-color: #3f51b5; } + html [data-md-color-primary="blue"] .md-nav--primary .md-nav__title--site { + background-color: #2196f3; } + html [data-md-color-primary="light-blue"] .md-nav--primary .md-nav__title--site { + background-color: #03a9f4; } + html [data-md-color-primary="cyan"] .md-nav--primary .md-nav__title--site { + background-color: #00bcd4; } + html [data-md-color-primary="teal"] .md-nav--primary .md-nav__title--site { + background-color: #009688; } + html [data-md-color-primary="green"] .md-nav--primary .md-nav__title--site { + background-color: #4caf50; } + html [data-md-color-primary="light-green"] .md-nav--primary .md-nav__title--site { + background-color: #7cb342; } + html [data-md-color-primary="lime"] .md-nav--primary .md-nav__title--site { + background-color: #c0ca33; } + html [data-md-color-primary="yellow"] .md-nav--primary .md-nav__title--site { + background-color: #f9a825; } + html [data-md-color-primary="amber"] .md-nav--primary .md-nav__title--site { + background-color: #ffa000; } + html [data-md-color-primary="orange"] .md-nav--primary .md-nav__title--site { + background-color: #fb8c00; } + html [data-md-color-primary="deep-orange"] .md-nav--primary .md-nav__title--site { + background-color: #ff7043; } + html [data-md-color-primary="brown"] .md-nav--primary .md-nav__title--site { + background-color: #795548; } + html [data-md-color-primary="grey"] .md-nav--primary .md-nav__title--site { + background-color: #757575; } + html [data-md-color-primary="blue-grey"] .md-nav--primary .md-nav__title--site { + background-color: #546e7a; } + html [data-md-color-primary="white"] .md-nav--primary .md-nav__title--site { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + [data-md-color-primary="white"] .md-hero { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); } } + +@media only screen and (min-width: 76.25em) { + [data-md-color-primary="red"] .md-tabs { + background-color: #ef5350; } + [data-md-color-primary="pink"] .md-tabs { + background-color: #e91e63; } + [data-md-color-primary="purple"] .md-tabs { + background-color: #ab47bc; } + [data-md-color-primary="deep-purple"] .md-tabs { + background-color: #7e57c2; } + [data-md-color-primary="indigo"] .md-tabs { + background-color: #3f51b5; } + [data-md-color-primary="blue"] .md-tabs { + background-color: #2196f3; } + [data-md-color-primary="light-blue"] .md-tabs { + background-color: #03a9f4; } + [data-md-color-primary="cyan"] .md-tabs { + background-color: #00bcd4; } + [data-md-color-primary="teal"] .md-tabs { + background-color: #009688; } + [data-md-color-primary="green"] .md-tabs { + background-color: #4caf50; } + [data-md-color-primary="light-green"] .md-tabs { + background-color: #7cb342; } + [data-md-color-primary="lime"] .md-tabs { + background-color: #c0ca33; } + [data-md-color-primary="yellow"] .md-tabs { + background-color: #f9a825; } + [data-md-color-primary="amber"] .md-tabs { + background-color: #ffa000; } + [data-md-color-primary="orange"] .md-tabs { + background-color: #fb8c00; } + [data-md-color-primary="deep-orange"] .md-tabs { + background-color: #ff7043; } + [data-md-color-primary="brown"] .md-tabs { + background-color: #795548; } + [data-md-color-primary="grey"] .md-tabs { + background-color: #757575; } + [data-md-color-primary="blue-grey"] .md-tabs { + background-color: #546e7a; } + [data-md-color-primary="white"] .md-tabs { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); + background-color: white; + color: rgba(0, 0, 0, 0.87); } } + +@media only screen and (min-width: 60em) { + [data-md-color-primary="white"] .md-search__input { + background-color: rgba(0, 0, 0, 0.07); } + [data-md-color-primary="white"] .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } } + +/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24tcGFsZXR0ZS4yMjkxNTEyNi5jc3MiLCJzb3VyY2VSb290IjoiIn0=*/ \ No newline at end of file diff --git a/assets/stylesheets/application.11e41852.css b/assets/stylesheets/application.11e41852.css new file mode 100644 index 000000000..01456b445 --- /dev/null +++ b/assets/stylesheets/application.11e41852.css @@ -0,0 +1,2563 @@ +@charset "UTF-8"; +html { + box-sizing: border-box; } + +*, +*::before, +*::after { + box-sizing: inherit; } + +html { + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + -ms-text-size-adjust: none; + text-size-adjust: none; } + +body { + margin: 0; } + +hr { + overflow: visible; + box-sizing: content-box; } + +a { + -webkit-text-decoration-skip: objects; } + +a, +button, +label, +input { + -webkit-tap-highlight-color: transparent; } + +a { + color: inherit; + text-decoration: none; } + +small { + font-size: 80%; } + +sub, +sup { + position: relative; + font-size: 80%; + line-height: 0; + vertical-align: baseline; } + +sub { + bottom: -0.25em; } + +sup { + top: -0.5em; } + +img { + border-style: none; } + +table { + border-collapse: separate; + border-spacing: 0; } + +td, +th { + font-weight: normal; + vertical-align: top; } + +button { + margin: 0; + padding: 0; + border: 0; + outline-style: none; + background: transparent; + font-size: inherit; } + +input { + border: 0; + outline: 0; } + +.md-icon, .md-clipboard::before, .md-nav__title::before, .md-nav__button, .md-nav__link::after, .md-search-result__article--document::before, .md-source-file::before, .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before, .md-typeset .footnote-backref, .md-typeset .critic.comment::before, .md-typeset summary::after, .md-typeset .task-list-control .task-list-indicator::before { + font-family: "Material Icons"; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + text-transform: none; + white-space: nowrap; + speak: none; + word-wrap: normal; + direction: ltr; } + .md-content__icon, .md-header-nav__button, .md-footer-nav__button, .md-nav__title::before, .md-nav__button, .md-search-result__article--document::before { + display: inline-block; + margin: 0.4rem; + padding: 0.8rem; + font-size: 2.4rem; + cursor: pointer; } + +.md-icon--arrow-back::before { + content: "\E5C4"; } + +.md-icon--arrow-forward::before { + content: "\E5C8"; } + +.md-icon--menu::before { + content: "\E5D2"; } + +.md-icon--search::before { + content: "\E8B6"; } + +[dir="rtl"] .md-icon--arrow-back::before { + content: "\E5C8"; } + +[dir="rtl"] .md-icon--arrow-forward::before { + content: "\E5C4"; } + +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +body, +input { + color: rgba(0, 0, 0, 0.87); + -webkit-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } + +pre, +code, +kbd { + color: rgba(0, 0, 0, 0.87); + -webkit-font-feature-settings: "kern"; + font-feature-settings: "kern"; + font-family: "Courier New", Courier, monospace; } + +.md-typeset { + font-size: 1.6rem; + line-height: 1.6; + -webkit-print-color-adjust: exact; } + .md-typeset p, + .md-typeset ul, + .md-typeset ol, + .md-typeset blockquote { + margin: 1em 0; } + .md-typeset h1 { + margin: 0 0 4rem; + color: rgba(0, 0, 0, 0.54); + font-size: 3.125rem; + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.3; } + .md-typeset h2 { + margin: 4rem 0 1.6rem; + font-size: 2.5rem; + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.4; } + .md-typeset h3 { + margin: 3.2rem 0 1.6rem; + font-size: 2rem; + font-weight: 400; + letter-spacing: -0.01em; + line-height: 1.5; } + .md-typeset h2 + h3 { + margin-top: 1.6rem; } + .md-typeset h4 { + margin: 1.6rem 0; + font-size: 1.6rem; + font-weight: 700; + letter-spacing: -0.01em; } + .md-typeset h5, + .md-typeset h6 { + margin: 1.6rem 0; + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + font-weight: 700; + letter-spacing: -0.01em; } + .md-typeset h5 { + text-transform: uppercase; } + .md-typeset hr { + margin: 1.5em 0; + border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.26); } + .md-typeset a { + color: #3f51b5; + word-break: break-word; } + .md-typeset a, .md-typeset a::before { + transition: color 0.125s; } + .md-typeset a:hover, .md-typeset a:active { + color: #536dfe; } + .md-typeset code, + .md-typeset pre { + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + font-size: 85%; + direction: ltr; } + .md-typeset code { + margin: 0 0.29412em; + padding: 0.07353em 0; + border-radius: 0.2rem; + box-shadow: 0.29412em 0 0 rgba(236, 236, 236, 0.5), -0.29412em 0 0 rgba(236, 236, 236, 0.5); + word-break: break-word; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + .md-typeset h1 code, + .md-typeset h2 code, + .md-typeset h3 code, + .md-typeset h4 code, + .md-typeset h5 code, + .md-typeset h6 code { + margin: 0; + background-color: transparent; + box-shadow: none; } + .md-typeset a > code { + margin: inherit; + padding: inherit; + border-radius: none; + background-color: inherit; + color: inherit; + box-shadow: none; } + .md-typeset pre { + position: relative; + margin: 1em 0; + border-radius: 0.2rem; + line-height: 1.4; + -webkit-overflow-scrolling: touch; } + .md-typeset pre > code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + font-size: inherit; + box-shadow: none; + -webkit-box-decoration-break: none; + box-decoration-break: none; + overflow: auto; } + .md-typeset pre > code::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-typeset pre > code::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-typeset pre > code::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + .md-typeset kbd { + padding: 0 0.29412em; + border: 0.1rem solid #c9c9c9; + border-radius: 0.3rem; + border-bottom-color: #bcbcbc; + background-color: #FCFCFC; + color: #555555; + font-size: 85%; + box-shadow: 0 0.1rem 0 #b0b0b0; + word-break: break-word; } + .md-typeset mark { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + background-color: rgba(255, 235, 59, 0.5); + box-shadow: 0.25em 0 0 rgba(255, 235, 59, 0.5), -0.25em 0 0 rgba(255, 235, 59, 0.5); + word-break: break-word; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + .md-typeset abbr { + border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.54); + text-decoration: none; + cursor: help; } + .md-typeset small { + opacity: 0.75; } + .md-typeset sup, + .md-typeset sub { + margin-left: 0.07812em; } + [dir="rtl"] .md-typeset sup, [dir="rtl"] + .md-typeset sub { + margin-right: 0.07812em; + margin-left: initial; } + .md-typeset blockquote { + padding-left: 1.2rem; + border-left: 0.4rem solid rgba(0, 0, 0, 0.26); + color: rgba(0, 0, 0, 0.54); } + [dir="rtl"] .md-typeset blockquote { + padding-right: 1.2rem; + padding-left: initial; + border-right: 0.4rem solid rgba(0, 0, 0, 0.26); + border-left: initial; } + .md-typeset ul { + list-style-type: disc; } + .md-typeset ul, + .md-typeset ol { + margin-left: 0.625em; + padding: 0; } + [dir="rtl"] .md-typeset ul, [dir="rtl"] + .md-typeset ol { + margin-right: 0.625em; + margin-left: initial; } + .md-typeset ul ol, + .md-typeset ol ol { + list-style-type: lower-alpha; } + .md-typeset ul ol ol, + .md-typeset ol ol ol { + list-style-type: lower-roman; } + .md-typeset ul li, + .md-typeset ol li { + margin-bottom: 0.5em; + margin-left: 1.25em; } + [dir="rtl"] .md-typeset ul li, [dir="rtl"] + .md-typeset ol li { + margin-right: 1.25em; + margin-left: initial; } + .md-typeset ul li p, + .md-typeset ul li blockquote, + .md-typeset ol li p, + .md-typeset ol li blockquote { + margin: 0.5em 0; } + .md-typeset ul li:last-child, + .md-typeset ol li:last-child { + margin-bottom: 0; } + .md-typeset ul li ul, + .md-typeset ul li ol, + .md-typeset ol li ul, + .md-typeset ol li ol { + margin: 0.5em 0 0.5em 0.625em; } + [dir="rtl"] .md-typeset ul li ul, [dir="rtl"] + .md-typeset ul li ol, [dir="rtl"] + .md-typeset ol li ul, [dir="rtl"] + .md-typeset ol li ol { + margin-right: 0.625em; + margin-left: initial; } + .md-typeset dd { + margin: 1em 0 1em 1.875em; } + [dir="rtl"] .md-typeset dd { + margin-right: 1.875em; + margin-left: initial; } + .md-typeset iframe, + .md-typeset img, + .md-typeset svg { + max-width: 100%; } + .md-typeset table:not([class]) { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); + display: inline-block; + max-width: 100%; + border-radius: 0.2rem; + font-size: 1.28rem; + overflow: auto; + -webkit-overflow-scrolling: touch; } + .md-typeset table:not([class]) + * { + margin-top: 1.5em; } + .md-typeset table:not([class]) th:not([align]), + .md-typeset table:not([class]) td:not([align]) { + text-align: left; } + [dir="rtl"] .md-typeset table:not([class]) th:not([align]), [dir="rtl"] + .md-typeset table:not([class]) td:not([align]) { + text-align: right; } + .md-typeset table:not([class]) th { + min-width: 10rem; + padding: 1.2rem 1.6rem; + background-color: rgba(0, 0, 0, 0.54); + color: white; + vertical-align: top; } + .md-typeset table:not([class]) td { + padding: 1.2rem 1.6rem; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + vertical-align: top; } + .md-typeset table:not([class]) tr:first-child td { + border-top: 0; } + .md-typeset table:not([class]) a { + word-break: normal; } + .md-typeset__scrollwrap { + margin: 1em -1.6rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; } + .md-typeset .md-typeset__table { + display: inline-block; + margin-bottom: 0.5em; + padding: 0 1.6rem; } + .md-typeset .md-typeset__table table { + display: table; + width: 100%; + margin: 0; + overflow: hidden; } + +html { + height: 100%; + font-size: 62.5%; + overflow-x: hidden; } + +body { + position: relative; + height: 100%; } + +hr { + display: block; + height: 0.1rem; + padding: 0; + border: 0; } + +.md-svg { + display: none; } + +.md-grid { + max-width: 122rem; + margin-right: auto; + margin-left: auto; } + +.md-container, +.md-main { + overflow: auto; } + +.md-container { + display: table; + width: 100%; + height: 100%; + padding-top: 4.8rem; + table-layout: fixed; } + +.md-main { + display: table-row; + height: 100%; } + .md-main__inner { + height: 100%; + padding-top: 3rem; + padding-bottom: 0.1rem; } + +.md-toggle { + display: none; } + +.md-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + transition: width 0s 0.25s, height 0s 0.25s, opacity 0.25s; + background-color: rgba(0, 0, 0, 0.54); + opacity: 0; + z-index: 3; } + +.md-flex { + display: table; } + .md-flex__cell { + display: table-cell; + position: relative; + vertical-align: top; } + .md-flex__cell--shrink { + width: 0%; } + .md-flex__cell--stretch { + display: table; + width: 100%; + table-layout: fixed; } + .md-flex__ellipsis { + display: table-cell; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } + +.md-skip { + position: fixed; + width: 0.1rem; + height: 0.1rem; + margin: 1rem; + padding: 0.6rem 1rem; + clip: rect(0.1rem); + -webkit-transform: translateY(0.8rem); + transform: translateY(0.8rem); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.87); + color: white; + font-size: 1.28rem; + opacity: 0; + overflow: hidden; } + .md-skip:focus { + width: auto; + height: auto; + clip: auto; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; + z-index: 10; } + +@page { + margin: 25mm; } + +.md-clipboard { + position: absolute; + top: 0.6rem; + right: 0.6rem; + width: 2.8rem; + height: 2.8rem; + border-radius: 0.2rem; + font-size: 1.6rem; + cursor: pointer; + z-index: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .md-clipboard::before { + transition: color 0.25s, opacity 0.25s; + color: rgba(0, 0, 0, 0.07); + content: "\E14D"; } + pre:hover .md-clipboard::before, + .codehilite:hover .md-clipboard::before, + .md-typeset .highlight:hover .md-clipboard::before { + color: rgba(0, 0, 0, 0.54); } + .md-clipboard:focus::before, .md-clipboard:hover::before { + color: #536dfe; } + .md-clipboard__message { + display: block; + position: absolute; + top: 0; + right: 3.4rem; + padding: 0.6rem 1rem; + -webkit-transform: translateX(0.8rem); + transform: translateX(0.8rem); + transition: opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0); + transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s; + transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.54); + color: white; + font-size: 1.28rem; + white-space: nowrap; + opacity: 0; + pointer-events: none; } + .md-clipboard__message--active { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; + pointer-events: initial; } + .md-clipboard__message::before { + content: attr(aria-label); } + .md-clipboard__message::after { + display: block; + position: absolute; + top: 50%; + right: -0.4rem; + width: 0; + margin-top: -0.4rem; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-style: solid; + border-color: transparent rgba(0, 0, 0, 0.54); + content: ""; } + +.md-content__inner { + margin: 0 1.6rem 2.4rem; + padding-top: 1.2rem; } + .md-content__inner::before { + display: block; + height: 0.8rem; + content: ""; } + .md-content__inner > :last-child { + margin-bottom: 0; } + +.md-content__icon { + position: relative; + margin: 0.8rem 0; + padding: 0; + float: right; } + .md-typeset .md-content__icon { + color: rgba(0, 0, 0, 0.26); } + +.md-header { + position: fixed; + top: 0; + right: 0; + left: 0; + height: 4.8rem; + transition: background-color 0.25s, color 0.25s; + background-color: #3f51b5; + color: white; + box-shadow: none; + z-index: 2; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .no-js .md-header { + transition: none; + box-shadow: none; } + .md-header[data-md-state="shadow"] { + transition: background-color 0.25s, color 0.25s, box-shadow 0.25s; + box-shadow: 0 0 0.4rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2); } + +.md-header-nav { + padding: 0 0.4rem; } + .md-header-nav__button { + position: relative; + transition: opacity 0.25s; + z-index: 1; } + .md-header-nav__button:hover { + opacity: 0.7; } + .md-header-nav__button.md-logo * { + display: block; } + .no-js .md-header-nav__button.md-icon--search { + display: none; } + .md-header-nav__topic { + display: block; + position: absolute; + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } + .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(2.5rem); + transform: translateX(2.5rem); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + opacity: 0; + z-index: -1; + pointer-events: none; } + [dir="rtl"] .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(-2.5rem); + transform: translateX(-2.5rem); } + .no-js .md-header-nav__topic { + position: initial; } + .no-js .md-header-nav__topic + .md-header-nav__topic { + display: none; } + .md-header-nav__title { + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; } + .md-header-nav__title[data-md-state="active"] .md-header-nav__topic { + -webkit-transform: translateX(-2.5rem); + transform: translateX(-2.5rem); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + opacity: 0; + z-index: -1; + pointer-events: none; } + [dir="rtl"] .md-header-nav__title[data-md-state="active"] .md-header-nav__topic { + -webkit-transform: translateX(2.5rem); + transform: translateX(2.5rem); } + .md-header-nav__title[data-md-state="active"] .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 1; + z-index: 0; + pointer-events: initial; } + .md-header-nav__source { + display: none; } + +.md-hero { + transition: background 0.25s; + background-color: #3f51b5; + color: white; + font-size: 2rem; + overflow: hidden; } + .md-hero__inner { + margin-top: 2rem; + padding: 1.6rem 1.6rem 0.8rem; + transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition-delay: 0.1s; } + [data-md-state="hidden"] .md-hero__inner { + pointer-events: none; + -webkit-transform: translateY(1.25rem); + transform: translateY(1.25rem); + transition: opacity 0.1s 0s, -webkit-transform 0s 0.4s; + transition: transform 0s 0.4s, opacity 0.1s 0s; + transition: transform 0s 0.4s, opacity 0.1s 0s, -webkit-transform 0s 0.4s; + opacity: 0; } + .md-hero--expand .md-hero__inner { + margin-bottom: 2.4rem; } + +.md-footer-nav { + background-color: rgba(0, 0, 0, 0.87); + color: white; } + .md-footer-nav__inner { + padding: 0.4rem; + overflow: auto; } + .md-footer-nav__link { + padding-top: 2.8rem; + padding-bottom: 0.8rem; + transition: opacity 0.25s; } + .md-footer-nav__link:hover { + opacity: 0.7; } + .md-footer-nav__link--prev { + width: 25%; + float: left; } + [dir="rtl"] .md-footer-nav__link--prev { + float: right; } + .md-footer-nav__link--next { + width: 75%; + float: right; + text-align: right; } + [dir="rtl"] .md-footer-nav__link--next { + float: left; + text-align: left; } + .md-footer-nav__button { + transition: background 0.25s; } + .md-footer-nav__title { + position: relative; + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; } + .md-footer-nav__direction { + position: absolute; + right: 0; + left: 0; + margin-top: -2rem; + padding: 0 2rem; + color: rgba(255, 255, 255, 0.7); + font-size: 1.5rem; } + +.md-footer-meta { + background-color: rgba(0, 0, 0, 0.895); } + .md-footer-meta__inner { + padding: 0.4rem; + overflow: auto; } + html .md-footer-meta.md-typeset a { + color: rgba(255, 255, 255, 0.7); } + html .md-footer-meta.md-typeset a:focus, html .md-footer-meta.md-typeset a:hover { + color: white; } + +.md-footer-copyright { + margin: 0 1.2rem; + padding: 0.8rem 0; + color: rgba(255, 255, 255, 0.3); + font-size: 1.28rem; } + .md-footer-copyright__highlight { + color: rgba(255, 255, 255, 0.7); } + +.md-footer-social { + margin: 0 0.8rem; + padding: 0.4rem 0 1.2rem; } + .md-footer-social__link { + display: inline-block; + width: 3.2rem; + height: 3.2rem; + font-size: 1.6rem; + text-align: center; } + .md-footer-social__link::before { + line-height: 1.9; } + +.md-nav { + font-size: 1.4rem; + line-height: 1.3; } + .md-nav__title { + display: block; + padding: 0 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; } + .md-nav__title::before { + display: none; + content: "\E5C4"; } + [dir="rtl"] .md-nav__title::before { + content: "\E5C8"; } + .md-nav__title .md-nav__button { + display: none; } + .md-nav__list { + margin: 0; + padding: 0; + list-style: none; } + .md-nav__item { + padding: 0 1.2rem; } + .md-nav__item:last-child { + padding-bottom: 1.2rem; } + .md-nav__item .md-nav__item { + padding-right: 0; } + [dir="rtl"] .md-nav__item .md-nav__item { + padding-right: 1.2rem; + padding-left: 0; } + .md-nav__item .md-nav__item:last-child { + padding-bottom: 0; } + .md-nav__button img { + width: 100%; + height: auto; } + .md-nav__link { + display: block; + margin-top: 0.625em; + transition: color 0.125s; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; } + .md-nav__item--nested > .md-nav__link::after { + content: "\E313"; } + html .md-nav__link[for="__toc"] { + display: none; } + html .md-nav__link[for="__toc"] ~ .md-nav { + display: none; } + html .md-nav__link[for="__toc"] + .md-nav__link::after { + display: none; } + .md-nav__link[data-md-state="blur"] { + color: rgba(0, 0, 0, 0.54); } + .md-nav__link:active, .md-nav__link--active { + color: #3f51b5; } + .md-nav__item--nested > .md-nav__link { + color: inherit; } + .md-nav__link:focus, .md-nav__link:hover { + color: #536dfe; } + .md-nav__source { + display: none; } + +.no-js .md-search { + display: none; } + +.md-search__overlay { + opacity: 0; + z-index: 1; } + +.md-search__form { + position: relative; } + +.md-search__input { + position: relative; + padding: 0 4.4rem 0 7.2rem; + text-overflow: ellipsis; + z-index: 2; } + [dir="rtl"] .md-search__input { + padding: 0 7.2rem 0 4.4rem; } + .md-search__input::-webkit-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input:-ms-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input::-ms-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input::placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input ~ .md-search__icon, .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input::-ms-clear { + display: none; } + +.md-search__icon { + position: absolute; + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + font-size: 2.4rem; + cursor: pointer; + z-index: 2; } + .md-search__icon:hover { + opacity: 0.7; } + .md-search__icon[for="__search"] { + top: 0.6rem; + left: 1rem; } + [dir="rtl"] .md-search__icon[for="__search"] { + right: 1rem; + left: initial; } + .md-search__icon[for="__search"]::before { + content: "\E8B6"; } + .md-search__icon[type="reset"] { + top: 0.6rem; + right: 1rem; + -webkit-transform: scale(0.125); + transform: scale(0.125); + transition: opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 0; } + [dir="rtl"] .md-search__icon[type="reset"] { + right: initial; + left: 1rem; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type="reset"] { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type="reset"]:hover { + opacity: 0.7; } + +.md-search__output { + position: absolute; + width: 100%; + border-radius: 0 0 0.2rem 0.2rem; + overflow: hidden; + z-index: 1; } + +.md-search__scrollwrap { + height: 100%; + background-color: white; + box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset; + overflow-y: auto; + -webkit-overflow-scrolling: touch; } + +.md-search-result { + color: rgba(0, 0, 0, 0.87); + word-break: break-word; } + .md-search-result__meta { + padding: 0 1.6rem; + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + line-height: 3.6rem; } + .md-search-result__list { + margin: 0; + padding: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + list-style: none; } + .md-search-result__item { + box-shadow: 0 -0.1rem 0 rgba(0, 0, 0, 0.07); } + .md-search-result__link { + display: block; + transition: background 0.25s; + outline: 0; + overflow: hidden; } + .md-search-result__link[data-md-state="active"], .md-search-result__link:hover { + background-color: rgba(83, 109, 254, 0.1); } + .md-search-result__link[data-md-state="active"] .md-search-result__article::before, .md-search-result__link:hover .md-search-result__article::before { + opacity: 0.7; } + .md-search-result__link:last-child .md-search-result__teaser { + margin-bottom: 1.2rem; } + .md-search-result__article { + position: relative; + padding: 0 1.6rem; + overflow: auto; } + .md-search-result__article--document::before { + position: absolute; + left: 0; + margin: 0.2rem; + transition: opacity 0.25s; + color: rgba(0, 0, 0, 0.54); + content: "\E880"; } + [dir="rtl"] .md-search-result__article--document::before { + right: 0; + left: initial; } + .md-search-result__article--document .md-search-result__title { + margin: 1.1rem 0; + font-size: 1.6rem; + font-weight: 400; + line-height: 1.4; } + .md-search-result__title { + margin: 0.5em 0; + font-size: 1.28rem; + font-weight: 700; + line-height: 1.4; } + .md-search-result__teaser { + display: -webkit-box; + max-height: 3.3rem; + margin: 0.5em 0; + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + -webkit-line-clamp: 2; } + .md-search-result em { + font-style: normal; + font-weight: 700; + text-decoration: underline; } + +.md-sidebar { + position: absolute; + width: 24.2rem; + padding: 2.4rem 0; + overflow: hidden; } + .md-sidebar[data-md-state="lock"] { + position: fixed; + top: 4.8rem; } + .md-sidebar--secondary { + display: none; } + .md-sidebar__scrollwrap { + max-height: 100%; + margin: 0 0.4rem; + overflow-y: auto; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .md-sidebar__scrollwrap::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +@-webkit-keyframes md-source__facts--done { + 0% { + height: 0; } + 100% { + height: 1.3rem; } } + +@keyframes md-source__facts--done { + 0% { + height: 0; } + 100% { + height: 1.3rem; } } + +@-webkit-keyframes md-source__fact--done { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + opacity: 0; } + 50% { + opacity: 0; } + 100% { + -webkit-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; } } + +@keyframes md-source__fact--done { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + opacity: 0; } + 50% { + opacity: 0; } + 100% { + -webkit-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; } } + +.md-source { + display: block; + padding-right: 1.2rem; + transition: opacity 0.25s; + font-size: 1.3rem; + line-height: 1.2; + white-space: nowrap; } + [dir="rtl"] .md-source { + padding-right: initial; + padding-left: 1.2rem; } + .md-source:hover { + opacity: 0.7; } + .md-source::after { + display: inline-block; + height: 4.8rem; + content: ""; + vertical-align: middle; } + .md-source__icon { + display: inline-block; + width: 4.8rem; + height: 4.8rem; + content: ""; + vertical-align: middle; } + .md-source__icon svg { + width: 2.4rem; + height: 2.4rem; + margin-top: 1.2rem; + margin-left: 1.2rem; } + [dir="rtl"] .md-source__icon svg { + margin-right: 1.2rem; + margin-left: initial; } + .md-source__icon + .md-source__repository { + margin-left: -4.4rem; + padding-left: 4rem; } + [dir="rtl"] .md-source__icon + .md-source__repository { + margin-right: -4.4rem; + margin-left: initial; + padding-right: 4rem; + padding-left: initial; } + .md-source__repository { + display: inline-block; + max-width: 100%; + margin-left: 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: middle; } + .md-source__facts { + margin: 0; + padding: 0; + font-size: 1.1rem; + font-weight: 700; + list-style-type: none; + opacity: 0.75; + overflow: hidden; } + [data-md-state="done"] .md-source__facts { + -webkit-animation: md-source__facts--done 0.25s ease-in; + animation: md-source__facts--done 0.25s ease-in; } + .md-source__fact { + float: left; } + [dir="rtl"] .md-source__fact { + float: right; } + [data-md-state="done"] .md-source__fact { + -webkit-animation: md-source__fact--done 0.4s ease-out; + animation: md-source__fact--done 0.4s ease-out; } + .md-source__fact::before { + margin: 0 0.2rem; + content: "\B7"; } + .md-source__fact:first-child::before { + display: none; } + +.md-source-file { + display: inline-block; + margin: 1em 0.5em 1em 0; + padding-right: 0.5rem; + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.07); + font-size: 1.28rem; + list-style-type: none; + cursor: pointer; + overflow: hidden; } + .md-source-file::before { + display: inline-block; + margin-right: 0.5rem; + padding: 0.5rem; + background-color: rgba(0, 0, 0, 0.26); + color: white; + font-size: 1.6rem; + content: "\E86F"; + vertical-align: middle; } + html .md-source-file { + transition: background 0.4s, color 0.4s, box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); } + html .md-source-file::before { + transition: inherit; } + html body .md-typeset .md-source-file { + color: rgba(0, 0, 0, 0.54); } + .md-source-file:hover { + box-shadow: 0 0 8px rgba(0, 0, 0, 0.18), 0 8px 16px rgba(0, 0, 0, 0.36); } + .md-source-file:hover::before { + background-color: #536dfe; } + +.md-tabs { + width: 100%; + transition: background 0.25s; + background-color: #3f51b5; + color: white; + overflow: auto; } + .md-tabs__list { + margin: 0; + margin-left: 0.4rem; + padding: 0; + list-style: none; + white-space: nowrap; } + .md-tabs__item { + display: inline-block; + height: 4.8rem; + padding-right: 1.2rem; + padding-left: 1.2rem; } + .md-tabs__link { + display: block; + margin-top: 1.6rem; + transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + font-size: 1.4rem; + opacity: 0.7; } + .md-tabs__link--active, .md-tabs__link:hover { + color: inherit; + opacity: 1; } + .md-tabs__item:nth-child(2) .md-tabs__link { + transition-delay: 0.02s; } + .md-tabs__item:nth-child(3) .md-tabs__link { + transition-delay: 0.04s; } + .md-tabs__item:nth-child(4) .md-tabs__link { + transition-delay: 0.06s; } + .md-tabs__item:nth-child(5) .md-tabs__link { + transition-delay: 0.08s; } + .md-tabs__item:nth-child(6) .md-tabs__link { + transition-delay: 0.1s; } + .md-tabs__item:nth-child(7) .md-tabs__link { + transition-delay: 0.12s; } + .md-tabs__item:nth-child(8) .md-tabs__link { + transition-delay: 0.14s; } + .md-tabs__item:nth-child(9) .md-tabs__link { + transition-delay: 0.16s; } + .md-tabs__item:nth-child(10) .md-tabs__link { + transition-delay: 0.18s; } + .md-tabs__item:nth-child(11) .md-tabs__link { + transition-delay: 0.2s; } + .md-tabs__item:nth-child(12) .md-tabs__link { + transition-delay: 0.22s; } + .md-tabs__item:nth-child(13) .md-tabs__link { + transition-delay: 0.24s; } + .md-tabs__item:nth-child(14) .md-tabs__link { + transition-delay: 0.26s; } + .md-tabs__item:nth-child(15) .md-tabs__link { + transition-delay: 0.28s; } + .md-tabs__item:nth-child(16) .md-tabs__link { + transition-delay: 0.3s; } + .md-tabs[data-md-state="hidden"] { + pointer-events: none; } + .md-tabs[data-md-state="hidden"] .md-tabs__link { + -webkit-transform: translateY(50%); + transform: translateY(50%); + transition: color 0.25s, opacity 0.1s, -webkit-transform 0s 0.4s; + transition: color 0.25s, transform 0s 0.4s, opacity 0.1s; + transition: color 0.25s, transform 0s 0.4s, opacity 0.1s, -webkit-transform 0s 0.4s; + opacity: 0; } + +.md-typeset .admonition, .md-typeset details { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); + position: relative; + margin: 1.5625em 0; + padding: 0 1.2rem; + border-left: 0.4rem solid #448aff; + border-radius: 0.2rem; + font-size: 1.28rem; + overflow: auto; } + [dir="rtl"] .md-typeset .admonition, [dir="rtl"] .md-typeset details { + border-right: 0.4rem solid #448aff; + border-left: none; } + html .md-typeset .admonition > :last-child, html .md-typeset details > :last-child { + margin-bottom: 1.2rem; } + .md-typeset .admonition .admonition, .md-typeset details .admonition, .md-typeset .admonition details, .md-typeset details details { + margin: 1em 0; } + .md-typeset .admonition > .admonition-title, .md-typeset details > .admonition-title, .md-typeset .admonition > summary, .md-typeset details > summary { + margin: 0 -1.2rem; + padding: 0.8rem 1.2rem 0.8rem 4rem; + border-bottom: 0.1rem solid rgba(68, 138, 255, 0.1); + background-color: rgba(68, 138, 255, 0.1); + font-weight: 700; } + [dir="rtl"] .md-typeset .admonition > .admonition-title, [dir="rtl"] .md-typeset details > .admonition-title, [dir="rtl"] .md-typeset .admonition > summary, [dir="rtl"] .md-typeset details > summary { + padding: 0.8rem 4rem 0.8rem 1.2rem; } + .md-typeset .admonition > .admonition-title:last-child, .md-typeset details > .admonition-title:last-child, .md-typeset .admonition > summary:last-child, .md-typeset details > summary:last-child { + margin-bottom: 0; } + .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before { + position: absolute; + left: 1.2rem; + color: #448aff; + font-size: 2rem; + content: "\E3C9"; } + [dir="rtl"] .md-typeset .admonition > .admonition-title::before, [dir="rtl"] .md-typeset details > .admonition-title::before, [dir="rtl"] .md-typeset .admonition > summary::before, [dir="rtl"] .md-typeset details > summary::before { + right: 1.2rem; + left: initial; } + .md-typeset .admonition.summary, .md-typeset details.summary, .md-typeset .admonition.tldr, .md-typeset details.tldr, .md-typeset .admonition.abstract, .md-typeset details.abstract { + border-left-color: #00b0ff; } + [dir="rtl"] .md-typeset .admonition.summary, [dir="rtl"] .md-typeset details.summary, [dir="rtl"] .md-typeset .admonition.tldr, [dir="rtl"] .md-typeset details.tldr, [dir="rtl"] .md-typeset .admonition.abstract, [dir="rtl"] .md-typeset details.abstract { + border-right-color: #00b0ff; } + .md-typeset .admonition.summary > .admonition-title, .md-typeset details.summary > .admonition-title, .md-typeset .admonition.tldr > .admonition-title, .md-typeset details.tldr > .admonition-title, .md-typeset .admonition.summary > summary, .md-typeset details.summary > summary, .md-typeset .admonition.tldr > summary, .md-typeset details.tldr > summary, .md-typeset .admonition.abstract > .admonition-title, .md-typeset details.abstract > .admonition-title, .md-typeset .admonition.abstract > summary, .md-typeset details.abstract > summary { + border-bottom-color: 0.1rem solid rgba(0, 176, 255, 0.1); + background-color: rgba(0, 176, 255, 0.1); } + .md-typeset .admonition.summary > .admonition-title::before, .md-typeset details.summary > .admonition-title::before, .md-typeset .admonition.tldr > .admonition-title::before, .md-typeset details.tldr > .admonition-title::before, .md-typeset .admonition.summary > summary::before, .md-typeset details.summary > summary::before, .md-typeset .admonition.tldr > summary::before, .md-typeset details.tldr > summary::before, .md-typeset .admonition.abstract > .admonition-title::before, .md-typeset details.abstract > .admonition-title::before, .md-typeset .admonition.abstract > summary::before, .md-typeset details.abstract > summary::before { + color: #00b0ff; + content: "\E8D2"; } + .md-typeset .admonition.todo, .md-typeset details.todo, .md-typeset .admonition.info, .md-typeset details.info { + border-left-color: #00b8d4; } + [dir="rtl"] .md-typeset .admonition.todo, [dir="rtl"] .md-typeset details.todo, [dir="rtl"] .md-typeset .admonition.info, [dir="rtl"] .md-typeset details.info { + border-right-color: #00b8d4; } + .md-typeset .admonition.todo > .admonition-title, .md-typeset details.todo > .admonition-title, .md-typeset .admonition.todo > summary, .md-typeset details.todo > summary, .md-typeset .admonition.info > .admonition-title, .md-typeset details.info > .admonition-title, .md-typeset .admonition.info > summary, .md-typeset details.info > summary { + border-bottom-color: 0.1rem solid rgba(0, 184, 212, 0.1); + background-color: rgba(0, 184, 212, 0.1); } + .md-typeset .admonition.todo > .admonition-title::before, .md-typeset details.todo > .admonition-title::before, .md-typeset .admonition.todo > summary::before, .md-typeset details.todo > summary::before, .md-typeset .admonition.info > .admonition-title::before, .md-typeset details.info > .admonition-title::before, .md-typeset .admonition.info > summary::before, .md-typeset details.info > summary::before { + color: #00b8d4; + content: "\E88E"; } + .md-typeset .admonition.hint, .md-typeset details.hint, .md-typeset .admonition.important, .md-typeset details.important, .md-typeset .admonition.tip, .md-typeset details.tip { + border-left-color: #00bfa5; } + [dir="rtl"] .md-typeset .admonition.hint, [dir="rtl"] .md-typeset details.hint, [dir="rtl"] .md-typeset .admonition.important, [dir="rtl"] .md-typeset details.important, [dir="rtl"] .md-typeset .admonition.tip, [dir="rtl"] .md-typeset details.tip { + border-right-color: #00bfa5; } + .md-typeset .admonition.hint > .admonition-title, .md-typeset details.hint > .admonition-title, .md-typeset .admonition.important > .admonition-title, .md-typeset details.important > .admonition-title, .md-typeset .admonition.hint > summary, .md-typeset details.hint > summary, .md-typeset .admonition.important > summary, .md-typeset details.important > summary, .md-typeset .admonition.tip > .admonition-title, .md-typeset details.tip > .admonition-title, .md-typeset .admonition.tip > summary, .md-typeset details.tip > summary { + border-bottom-color: 0.1rem solid rgba(0, 191, 165, 0.1); + background-color: rgba(0, 191, 165, 0.1); } + .md-typeset .admonition.hint > .admonition-title::before, .md-typeset details.hint > .admonition-title::before, .md-typeset .admonition.important > .admonition-title::before, .md-typeset details.important > .admonition-title::before, .md-typeset .admonition.hint > summary::before, .md-typeset details.hint > summary::before, .md-typeset .admonition.important > summary::before, .md-typeset details.important > summary::before, .md-typeset .admonition.tip > .admonition-title::before, .md-typeset details.tip > .admonition-title::before, .md-typeset .admonition.tip > summary::before, .md-typeset details.tip > summary::before { + color: #00bfa5; + content: "\E80E"; } + .md-typeset .admonition.check, .md-typeset details.check, .md-typeset .admonition.done, .md-typeset details.done, .md-typeset .admonition.success, .md-typeset details.success { + border-left-color: #00c853; } + [dir="rtl"] .md-typeset .admonition.check, [dir="rtl"] .md-typeset details.check, [dir="rtl"] .md-typeset .admonition.done, [dir="rtl"] .md-typeset details.done, [dir="rtl"] .md-typeset .admonition.success, [dir="rtl"] .md-typeset details.success { + border-right-color: #00c853; } + .md-typeset .admonition.check > .admonition-title, .md-typeset details.check > .admonition-title, .md-typeset .admonition.done > .admonition-title, .md-typeset details.done > .admonition-title, .md-typeset .admonition.check > summary, .md-typeset details.check > summary, .md-typeset .admonition.done > summary, .md-typeset details.done > summary, .md-typeset .admonition.success > .admonition-title, .md-typeset details.success > .admonition-title, .md-typeset .admonition.success > summary, .md-typeset details.success > summary { + border-bottom-color: 0.1rem solid rgba(0, 200, 83, 0.1); + background-color: rgba(0, 200, 83, 0.1); } + .md-typeset .admonition.check > .admonition-title::before, .md-typeset details.check > .admonition-title::before, .md-typeset .admonition.done > .admonition-title::before, .md-typeset details.done > .admonition-title::before, .md-typeset .admonition.check > summary::before, .md-typeset details.check > summary::before, .md-typeset .admonition.done > summary::before, .md-typeset details.done > summary::before, .md-typeset .admonition.success > .admonition-title::before, .md-typeset details.success > .admonition-title::before, .md-typeset .admonition.success > summary::before, .md-typeset details.success > summary::before { + color: #00c853; + content: "\E876"; } + .md-typeset .admonition.help, .md-typeset details.help, .md-typeset .admonition.faq, .md-typeset details.faq, .md-typeset .admonition.question, .md-typeset details.question { + border-left-color: #64dd17; } + [dir="rtl"] .md-typeset .admonition.help, [dir="rtl"] .md-typeset details.help, [dir="rtl"] .md-typeset .admonition.faq, [dir="rtl"] .md-typeset details.faq, [dir="rtl"] .md-typeset .admonition.question, [dir="rtl"] .md-typeset details.question { + border-right-color: #64dd17; } + .md-typeset .admonition.help > .admonition-title, .md-typeset details.help > .admonition-title, .md-typeset .admonition.faq > .admonition-title, .md-typeset details.faq > .admonition-title, .md-typeset .admonition.help > summary, .md-typeset details.help > summary, .md-typeset .admonition.faq > summary, .md-typeset details.faq > summary, .md-typeset .admonition.question > .admonition-title, .md-typeset details.question > .admonition-title, .md-typeset .admonition.question > summary, .md-typeset details.question > summary { + border-bottom-color: 0.1rem solid rgba(100, 221, 23, 0.1); + background-color: rgba(100, 221, 23, 0.1); } + .md-typeset .admonition.help > .admonition-title::before, .md-typeset details.help > .admonition-title::before, .md-typeset .admonition.faq > .admonition-title::before, .md-typeset details.faq > .admonition-title::before, .md-typeset .admonition.help > summary::before, .md-typeset details.help > summary::before, .md-typeset .admonition.faq > summary::before, .md-typeset details.faq > summary::before, .md-typeset .admonition.question > .admonition-title::before, .md-typeset details.question > .admonition-title::before, .md-typeset .admonition.question > summary::before, .md-typeset details.question > summary::before { + color: #64dd17; + content: "\E887"; } + .md-typeset .admonition.caution, .md-typeset details.caution, .md-typeset .admonition.attention, .md-typeset details.attention, .md-typeset .admonition.warning, .md-typeset details.warning { + border-left-color: #ff9100; } + [dir="rtl"] .md-typeset .admonition.caution, [dir="rtl"] .md-typeset details.caution, [dir="rtl"] .md-typeset .admonition.attention, [dir="rtl"] .md-typeset details.attention, [dir="rtl"] .md-typeset .admonition.warning, [dir="rtl"] .md-typeset details.warning { + border-right-color: #ff9100; } + .md-typeset .admonition.caution > .admonition-title, .md-typeset details.caution > .admonition-title, .md-typeset .admonition.attention > .admonition-title, .md-typeset details.attention > .admonition-title, .md-typeset .admonition.caution > summary, .md-typeset details.caution > summary, .md-typeset .admonition.attention > summary, .md-typeset details.attention > summary, .md-typeset .admonition.warning > .admonition-title, .md-typeset details.warning > .admonition-title, .md-typeset .admonition.warning > summary, .md-typeset details.warning > summary { + border-bottom-color: 0.1rem solid rgba(255, 145, 0, 0.1); + background-color: rgba(255, 145, 0, 0.1); } + .md-typeset .admonition.caution > .admonition-title::before, .md-typeset details.caution > .admonition-title::before, .md-typeset .admonition.attention > .admonition-title::before, .md-typeset details.attention > .admonition-title::before, .md-typeset .admonition.caution > summary::before, .md-typeset details.caution > summary::before, .md-typeset .admonition.attention > summary::before, .md-typeset details.attention > summary::before, .md-typeset .admonition.warning > .admonition-title::before, .md-typeset details.warning > .admonition-title::before, .md-typeset .admonition.warning > summary::before, .md-typeset details.warning > summary::before { + color: #ff9100; + content: "\E002"; } + .md-typeset .admonition.fail, .md-typeset details.fail, .md-typeset .admonition.missing, .md-typeset details.missing, .md-typeset .admonition.failure, .md-typeset details.failure { + border-left-color: #ff5252; } + [dir="rtl"] .md-typeset .admonition.fail, [dir="rtl"] .md-typeset details.fail, [dir="rtl"] .md-typeset .admonition.missing, [dir="rtl"] .md-typeset details.missing, [dir="rtl"] .md-typeset .admonition.failure, [dir="rtl"] .md-typeset details.failure { + border-right-color: #ff5252; } + .md-typeset .admonition.fail > .admonition-title, .md-typeset details.fail > .admonition-title, .md-typeset .admonition.missing > .admonition-title, .md-typeset details.missing > .admonition-title, .md-typeset .admonition.fail > summary, .md-typeset details.fail > summary, .md-typeset .admonition.missing > summary, .md-typeset details.missing > summary, .md-typeset .admonition.failure > .admonition-title, .md-typeset details.failure > .admonition-title, .md-typeset .admonition.failure > summary, .md-typeset details.failure > summary { + border-bottom-color: 0.1rem solid rgba(255, 82, 82, 0.1); + background-color: rgba(255, 82, 82, 0.1); } + .md-typeset .admonition.fail > .admonition-title::before, .md-typeset details.fail > .admonition-title::before, .md-typeset .admonition.missing > .admonition-title::before, .md-typeset details.missing > .admonition-title::before, .md-typeset .admonition.fail > summary::before, .md-typeset details.fail > summary::before, .md-typeset .admonition.missing > summary::before, .md-typeset details.missing > summary::before, .md-typeset .admonition.failure > .admonition-title::before, .md-typeset details.failure > .admonition-title::before, .md-typeset .admonition.failure > summary::before, .md-typeset details.failure > summary::before { + color: #ff5252; + content: "\E14C"; } + .md-typeset .admonition.error, .md-typeset details.error, .md-typeset .admonition.danger, .md-typeset details.danger { + border-left-color: #ff1744; } + [dir="rtl"] .md-typeset .admonition.error, [dir="rtl"] .md-typeset details.error, [dir="rtl"] .md-typeset .admonition.danger, [dir="rtl"] .md-typeset details.danger { + border-right-color: #ff1744; } + .md-typeset .admonition.error > .admonition-title, .md-typeset details.error > .admonition-title, .md-typeset .admonition.error > summary, .md-typeset details.error > summary, .md-typeset .admonition.danger > .admonition-title, .md-typeset details.danger > .admonition-title, .md-typeset .admonition.danger > summary, .md-typeset details.danger > summary { + border-bottom-color: 0.1rem solid rgba(255, 23, 68, 0.1); + background-color: rgba(255, 23, 68, 0.1); } + .md-typeset .admonition.error > .admonition-title::before, .md-typeset details.error > .admonition-title::before, .md-typeset .admonition.error > summary::before, .md-typeset details.error > summary::before, .md-typeset .admonition.danger > .admonition-title::before, .md-typeset details.danger > .admonition-title::before, .md-typeset .admonition.danger > summary::before, .md-typeset details.danger > summary::before { + color: #ff1744; + content: "\E3E7"; } + .md-typeset .admonition.bug, .md-typeset details.bug { + border-left-color: #f50057; } + [dir="rtl"] .md-typeset .admonition.bug, [dir="rtl"] .md-typeset details.bug { + border-right-color: #f50057; } + .md-typeset .admonition.bug > .admonition-title, .md-typeset details.bug > .admonition-title, .md-typeset .admonition.bug > summary, .md-typeset details.bug > summary { + border-bottom-color: 0.1rem solid rgba(245, 0, 87, 0.1); + background-color: rgba(245, 0, 87, 0.1); } + .md-typeset .admonition.bug > .admonition-title::before, .md-typeset details.bug > .admonition-title::before, .md-typeset .admonition.bug > summary::before, .md-typeset details.bug > summary::before { + color: #f50057; + content: "\E868"; } + .md-typeset .admonition.example, .md-typeset details.example { + border-left-color: #651fff; } + [dir="rtl"] .md-typeset .admonition.example, [dir="rtl"] .md-typeset details.example { + border-right-color: #651fff; } + .md-typeset .admonition.example > .admonition-title, .md-typeset details.example > .admonition-title, .md-typeset .admonition.example > summary, .md-typeset details.example > summary { + border-bottom-color: 0.1rem solid rgba(101, 31, 255, 0.1); + background-color: rgba(101, 31, 255, 0.1); } + .md-typeset .admonition.example > .admonition-title::before, .md-typeset details.example > .admonition-title::before, .md-typeset .admonition.example > summary::before, .md-typeset details.example > summary::before { + color: #651fff; + content: "\E242"; } + .md-typeset .admonition.cite, .md-typeset details.cite, .md-typeset .admonition.quote, .md-typeset details.quote { + border-left-color: #9e9e9e; } + [dir="rtl"] .md-typeset .admonition.cite, [dir="rtl"] .md-typeset details.cite, [dir="rtl"] .md-typeset .admonition.quote, [dir="rtl"] .md-typeset details.quote { + border-right-color: #9e9e9e; } + .md-typeset .admonition.cite > .admonition-title, .md-typeset details.cite > .admonition-title, .md-typeset .admonition.cite > summary, .md-typeset details.cite > summary, .md-typeset .admonition.quote > .admonition-title, .md-typeset details.quote > .admonition-title, .md-typeset .admonition.quote > summary, .md-typeset details.quote > summary { + border-bottom-color: 0.1rem solid rgba(158, 158, 158, 0.1); + background-color: rgba(158, 158, 158, 0.1); } + .md-typeset .admonition.cite > .admonition-title::before, .md-typeset details.cite > .admonition-title::before, .md-typeset .admonition.cite > summary::before, .md-typeset details.cite > summary::before, .md-typeset .admonition.quote > .admonition-title::before, .md-typeset details.quote > .admonition-title::before, .md-typeset .admonition.quote > summary::before, .md-typeset details.quote > summary::before { + color: #9e9e9e; + content: "\E244"; } + +.codehilite .o, .md-typeset .highlight .o { + color: inherit; } + +.codehilite .ow, .md-typeset .highlight .ow { + color: inherit; } + +.codehilite .ge, .md-typeset .highlight .ge { + color: #000000; } + +.codehilite .gr, .md-typeset .highlight .gr { + color: #AA0000; } + +.codehilite .gh, .md-typeset .highlight .gh { + color: #999999; } + +.codehilite .go, .md-typeset .highlight .go { + color: #888888; } + +.codehilite .gp, .md-typeset .highlight .gp { + color: #555555; } + +.codehilite .gs, .md-typeset .highlight .gs { + color: inherit; } + +.codehilite .gu, .md-typeset .highlight .gu { + color: #AAAAAA; } + +.codehilite .gt, .md-typeset .highlight .gt { + color: #AA0000; } + +.codehilite .gd, .md-typeset .highlight .gd { + background-color: #FFDDDD; } + +.codehilite .gi, .md-typeset .highlight .gi { + background-color: #DDFFDD; } + +.codehilite .k, .md-typeset .highlight .k { + color: #3B78E7; } + +.codehilite .kc, .md-typeset .highlight .kc { + color: #A71D5D; } + +.codehilite .kd, .md-typeset .highlight .kd { + color: #3B78E7; } + +.codehilite .kn, .md-typeset .highlight .kn { + color: #3B78E7; } + +.codehilite .kp, .md-typeset .highlight .kp { + color: #A71D5D; } + +.codehilite .kr, .md-typeset .highlight .kr { + color: #3E61A2; } + +.codehilite .kt, .md-typeset .highlight .kt { + color: #3E61A2; } + +.codehilite .c, .md-typeset .highlight .c { + color: #999999; } + +.codehilite .cm, .md-typeset .highlight .cm { + color: #999999; } + +.codehilite .cp, .md-typeset .highlight .cp { + color: #666666; } + +.codehilite .c1, .md-typeset .highlight .c1 { + color: #999999; } + +.codehilite .ch, .md-typeset .highlight .ch { + color: #999999; } + +.codehilite .cs, .md-typeset .highlight .cs { + color: #999999; } + +.codehilite .na, .md-typeset .highlight .na { + color: #C2185B; } + +.codehilite .nb, .md-typeset .highlight .nb { + color: #C2185B; } + +.codehilite .bp, .md-typeset .highlight .bp { + color: #3E61A2; } + +.codehilite .nc, .md-typeset .highlight .nc { + color: #C2185B; } + +.codehilite .no, .md-typeset .highlight .no { + color: #3E61A2; } + +.codehilite .nd, .md-typeset .highlight .nd { + color: #666666; } + +.codehilite .ni, .md-typeset .highlight .ni { + color: #666666; } + +.codehilite .ne, .md-typeset .highlight .ne { + color: #C2185B; } + +.codehilite .nf, .md-typeset .highlight .nf { + color: #C2185B; } + +.codehilite .nl, .md-typeset .highlight .nl { + color: #3B5179; } + +.codehilite .nn, .md-typeset .highlight .nn { + color: #EC407A; } + +.codehilite .nt, .md-typeset .highlight .nt { + color: #3B78E7; } + +.codehilite .nv, .md-typeset .highlight .nv { + color: #3E61A2; } + +.codehilite .vc, .md-typeset .highlight .vc { + color: #3E61A2; } + +.codehilite .vg, .md-typeset .highlight .vg { + color: #3E61A2; } + +.codehilite .vi, .md-typeset .highlight .vi { + color: #3E61A2; } + +.codehilite .nx, .md-typeset .highlight .nx { + color: #EC407A; } + +.codehilite .m, .md-typeset .highlight .m { + color: #E74C3C; } + +.codehilite .mf, .md-typeset .highlight .mf { + color: #E74C3C; } + +.codehilite .mh, .md-typeset .highlight .mh { + color: #E74C3C; } + +.codehilite .mi, .md-typeset .highlight .mi { + color: #E74C3C; } + +.codehilite .il, .md-typeset .highlight .il { + color: #E74C3C; } + +.codehilite .mo, .md-typeset .highlight .mo { + color: #E74C3C; } + +.codehilite .s, .md-typeset .highlight .s { + color: #0D904F; } + +.codehilite .sb, .md-typeset .highlight .sb { + color: #0D904F; } + +.codehilite .sc, .md-typeset .highlight .sc { + color: #0D904F; } + +.codehilite .sd, .md-typeset .highlight .sd { + color: #999999; } + +.codehilite .s2, .md-typeset .highlight .s2 { + color: #0D904F; } + +.codehilite .se, .md-typeset .highlight .se { + color: #183691; } + +.codehilite .sh, .md-typeset .highlight .sh { + color: #183691; } + +.codehilite .si, .md-typeset .highlight .si { + color: #183691; } + +.codehilite .sx, .md-typeset .highlight .sx { + color: #183691; } + +.codehilite .sr, .md-typeset .highlight .sr { + color: #009926; } + +.codehilite .s1, .md-typeset .highlight .s1 { + color: #0D904F; } + +.codehilite .ss, .md-typeset .highlight .ss { + color: #0D904F; } + +.codehilite .err, .md-typeset .highlight .err { + color: #A61717; } + +.codehilite .w, .md-typeset .highlight .w { + color: transparent; } + +.codehilite .hll, .md-typeset .highlight .hll { + display: block; + margin: 0 -1.2rem; + padding: 0 1.2rem; + background-color: rgba(255, 235, 59, 0.5); } + +.md-typeset .codehilite, .md-typeset .highlight { + position: relative; + margin: 1em 0; + padding: 0; + border-radius: 0.2rem; + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + line-height: 1.4; + -webkit-overflow-scrolling: touch; } + .md-typeset .codehilite pre, .md-typeset .highlight pre, + .md-typeset .codehilite code, + .md-typeset .highlight code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + overflow: auto; + vertical-align: top; } + .md-typeset .codehilite pre::-webkit-scrollbar, .md-typeset .highlight pre::-webkit-scrollbar, + .md-typeset .codehilite code::-webkit-scrollbar, + .md-typeset .highlight code::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-typeset .codehilite pre::-webkit-scrollbar-thumb, .md-typeset .highlight pre::-webkit-scrollbar-thumb, + .md-typeset .codehilite code::-webkit-scrollbar-thumb, + .md-typeset .highlight code::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover, .md-typeset .highlight pre::-webkit-scrollbar-thumb:hover, + .md-typeset .codehilite code::-webkit-scrollbar-thumb:hover, + .md-typeset .highlight code::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +.md-typeset pre.codehilite, .md-typeset pre.highlight { + overflow: visible; } + .md-typeset pre.codehilite code, .md-typeset pre.highlight code { + display: block; + padding: 1.05rem 1.2rem; + overflow: auto; } + +.md-typeset .codehilitetable, .md-typeset .highlighttable { + display: block; + margin: 1em 0; + border-radius: 0.2em; + font-size: 1.6rem; + overflow: hidden; } + .md-typeset .codehilitetable tbody, .md-typeset .highlighttable tbody, + .md-typeset .codehilitetable td, + .md-typeset .highlighttable td { + display: block; + padding: 0; } + .md-typeset .codehilitetable tr, .md-typeset .highlighttable tr { + display: flex; } + .md-typeset .codehilitetable .codehilite, .md-typeset .highlighttable .codehilite, .md-typeset .codehilitetable .highlight, .md-typeset .highlighttable .highlight, + .md-typeset .codehilitetable .linenodiv, + .md-typeset .highlighttable .linenodiv { + margin: 0; + border-radius: 0; } + + .md-typeset .codehilitetable .linenodiv, + .md-typeset .highlighttable .linenodiv { + padding: 1.05rem 1.2rem; } + .md-typeset .codehilitetable .linenos, .md-typeset .highlighttable .linenos { + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.26); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .md-typeset .codehilitetable .linenos pre, .md-typeset .highlighttable .linenos pre { + margin: 0; + padding: 0; + background-color: transparent; + color: inherit; + text-align: right; } + .md-typeset .codehilitetable .code, .md-typeset .highlighttable .code { + flex: 1; + overflow: hidden; } + +.md-typeset > .codehilitetable, .md-typeset > .highlighttable { + box-shadow: none; } + +.md-typeset [id^="fnref:"] { + display: inline-block; } + .md-typeset [id^="fnref:"]:target { + margin-top: -7.6rem; + padding-top: 7.6rem; + pointer-events: none; } + +.md-typeset [id^="fn:"]::before { + display: none; + height: 0; + content: ""; } + +.md-typeset [id^="fn:"]:target::before { + display: block; + margin-top: -7rem; + padding-top: 7rem; + pointer-events: none; } + +.md-typeset .footnote { + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; } + .md-typeset .footnote ol { + margin-left: 0; } + .md-typeset .footnote li { + transition: color 0.25s; } + .md-typeset .footnote li:target { + color: rgba(0, 0, 0, 0.87); } + .md-typeset .footnote li :first-child { + margin-top: 0; } + .md-typeset .footnote li:hover .footnote-backref, + .md-typeset .footnote li:target .footnote-backref { + -webkit-transform: translateX(0); + transform: translateX(0); + opacity: 1; } + .md-typeset .footnote li:hover .footnote-backref:hover, + .md-typeset .footnote li:target .footnote-backref { + color: #536dfe; } + +.md-typeset .footnote-ref { + display: inline-block; + pointer-events: initial; } + .md-typeset .footnote-ref::before { + display: inline; + margin: 0 0.2em; + border-left: 0.1rem solid rgba(0, 0, 0, 0.26); + font-size: 1.25em; + content: ""; + vertical-align: -0.5rem; } + +.md-typeset .footnote-backref { + display: inline-block; + -webkit-transform: translateX(0.5rem); + transform: translateX(0.5rem); + transition: color 0.25s, opacity 0.125s 0.125s, -webkit-transform 0.25s 0.125s; + transition: transform 0.25s 0.125s, color 0.25s, opacity 0.125s 0.125s; + transition: transform 0.25s 0.125s, color 0.25s, opacity 0.125s 0.125s, -webkit-transform 0.25s 0.125s; + color: rgba(0, 0, 0, 0.26); + font-size: 0; + opacity: 0; + vertical-align: text-bottom; } + [dir="rtl"] .md-typeset .footnote-backref { + -webkit-transform: translateX(-0.5rem); + transform: translateX(-0.5rem); } + .md-typeset .footnote-backref::before { + display: inline-block; + font-size: 1.6rem; + content: "\E31B"; } + [dir="rtl"] .md-typeset .footnote-backref::before { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); } + +.md-typeset .headerlink { + display: inline-block; + margin-left: 1rem; + -webkit-transform: translate(0, 0.5rem); + transform: translate(0, 0.5rem); + transition: color 0.25s, opacity 0.125s 0.25s, -webkit-transform 0.25s 0.25s; + transition: transform 0.25s 0.25s, color 0.25s, opacity 0.125s 0.25s; + transition: transform 0.25s 0.25s, color 0.25s, opacity 0.125s 0.25s, -webkit-transform 0.25s 0.25s; + opacity: 0; } + [dir="rtl"] .md-typeset .headerlink { + margin-right: 1rem; + margin-left: initial; } + html body .md-typeset .headerlink { + color: rgba(0, 0, 0, 0.26); } + +.md-typeset h1[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h1[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h1[id]:hover .headerlink, +.md-typeset h1[id]:target .headerlink, +.md-typeset h1[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h1[id]:hover .headerlink:hover, +.md-typeset h1[id]:target .headerlink, +.md-typeset h1[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h2[id]::before { + display: block; + margin-top: -0.8rem; + padding-top: 0.8rem; + content: ""; } + +.md-typeset h2[id]:target::before { + margin-top: -6.8rem; + padding-top: 6.8rem; } + +.md-typeset h2[id]:hover .headerlink, +.md-typeset h2[id]:target .headerlink, +.md-typeset h2[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h2[id]:hover .headerlink:hover, +.md-typeset h2[id]:target .headerlink, +.md-typeset h2[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h3[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h3[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h3[id]:hover .headerlink, +.md-typeset h3[id]:target .headerlink, +.md-typeset h3[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h3[id]:hover .headerlink:hover, +.md-typeset h3[id]:target .headerlink, +.md-typeset h3[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h4[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h4[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h4[id]:hover .headerlink, +.md-typeset h4[id]:target .headerlink, +.md-typeset h4[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h4[id]:hover .headerlink:hover, +.md-typeset h4[id]:target .headerlink, +.md-typeset h4[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h5[id]::before { + display: block; + margin-top: -1.1rem; + padding-top: 1.1rem; + content: ""; } + +.md-typeset h5[id]:target::before { + margin-top: -7.1rem; + padding-top: 7.1rem; } + +.md-typeset h5[id]:hover .headerlink, +.md-typeset h5[id]:target .headerlink, +.md-typeset h5[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h5[id]:hover .headerlink:hover, +.md-typeset h5[id]:target .headerlink, +.md-typeset h5[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h6[id]::before { + display: block; + margin-top: -1.1rem; + padding-top: 1.1rem; + content: ""; } + +.md-typeset h6[id]:target::before { + margin-top: -7.1rem; + padding-top: 7.1rem; } + +.md-typeset h6[id]:hover .headerlink, +.md-typeset h6[id]:target .headerlink, +.md-typeset h6[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h6[id]:hover .headerlink:hover, +.md-typeset h6[id]:target .headerlink, +.md-typeset h6[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset .MJXc-display { + margin: 0.75em 0; + padding: 0.75em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; } + +.md-typeset .MathJax_CHTML { + outline: 0; } + +.md-typeset del.critic, +.md-typeset ins.critic, +.md-typeset .critic.comment { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + +.md-typeset del.critic { + background-color: #FFDDDD; + box-shadow: 0.25em 0 0 #FFDDDD, -0.25em 0 0 #FFDDDD; } + +.md-typeset ins.critic { + background-color: #DDFFDD; + box-shadow: 0.25em 0 0 #DDFFDD, -0.25em 0 0 #DDFFDD; } + +.md-typeset .critic.comment { + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + box-shadow: 0.25em 0 0 rgba(236, 236, 236, 0.5), -0.25em 0 0 rgba(236, 236, 236, 0.5); } + .md-typeset .critic.comment::before { + padding-right: 0.125em; + color: rgba(0, 0, 0, 0.26); + content: "\E0B7"; + vertical-align: -0.125em; } + +.md-typeset .critic.block { + display: block; + margin: 1em 0; + padding-right: 1.6rem; + padding-left: 1.6rem; + box-shadow: none; } + .md-typeset .critic.block :first-child { + margin-top: 0.5em; } + .md-typeset .critic.block :last-child { + margin-bottom: 0.5em; } + +.md-typeset details { + display: block; + padding-top: 0; } + .md-typeset details[open] > summary::after { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + .md-typeset details:not([open]) { + padding-bottom: 0; } + .md-typeset details:not([open]) > summary { + border-bottom: none; } + .md-typeset details summary { + padding-right: 4rem; } + [dir="rtl"] .md-typeset details summary { + padding-left: 4rem; } + .no-details .md-typeset details:not([open]) > * { + display: none; } + .no-details .md-typeset details:not([open]) summary { + display: block; } + +.md-typeset summary { + display: block; + outline: none; + cursor: pointer; } + .md-typeset summary::-webkit-details-marker { + display: none; } + .md-typeset summary::after { + position: absolute; + top: 0.8rem; + right: 1.2rem; + color: rgba(0, 0, 0, 0.26); + font-size: 2rem; + content: "\E313"; } + [dir="rtl"] .md-typeset summary::after { + right: initial; + left: 1.2rem; } + +.md-typeset .emojione { + width: 2rem; + vertical-align: text-top; } + +.md-typeset code.codehilite, .md-typeset code.highlight { + margin: 0 0.29412em; + padding: 0.07353em 0; } + +.md-typeset .superfences-content { + display: none; + order: 99; + width: 100%; + background-color: white; } + .md-typeset .superfences-content > * { + margin: 0; + border-radius: 0; } + +.md-typeset .superfences-tabs { + display: flex; + position: relative; + flex-wrap: wrap; + margin: 1em 0; + border: 0.1rem solid rgba(0, 0, 0, 0.07); + border-radius: 0.2em; } + .md-typeset .superfences-tabs > input { + display: none; } + .md-typeset .superfences-tabs > input:checked + label { + font-weight: 700; } + .md-typeset .superfences-tabs > input:checked + label + .superfences-content { + display: block; } + .md-typeset .superfences-tabs > label { + width: auto; + padding: 1.2rem 1.2rem; + transition: color 0.125s; + font-size: 1.28rem; + cursor: pointer; } + html .md-typeset .superfences-tabs > label:hover { + color: #536dfe; } + +.md-typeset .task-list-item { + position: relative; + list-style-type: none; } + .md-typeset .task-list-item [type="checkbox"] { + position: absolute; + top: 0.45em; + left: -2em; } + [dir="rtl"] .md-typeset .task-list-item [type="checkbox"] { + right: -2em; + left: initial; } + +.md-typeset .task-list-control .task-list-indicator::before { + position: absolute; + top: 0.15em; + left: -1.25em; + color: rgba(0, 0, 0, 0.26); + font-size: 1.25em; + content: "\E835"; + vertical-align: -0.25em; } + [dir="rtl"] .md-typeset .task-list-control .task-list-indicator::before { + right: -1.25em; + left: initial; } + +.md-typeset .task-list-control [type="checkbox"]:checked + .task-list-indicator::before { + content: "\E834"; } + +.md-typeset .task-list-control [type="checkbox"] { + opacity: 0; + z-index: -1; } + +@media print { + .md-typeset a::after { + color: rgba(0, 0, 0, 0.54); + content: " [" attr(href) "]"; } + .md-typeset code, + .md-typeset pre { + white-space: pre-wrap; } + .md-typeset code { + box-shadow: none; + -webkit-box-decoration-break: initial; + box-decoration-break: initial; } + .md-clipboard { + display: none; } + .md-content__icon { + display: none; } + .md-header { + display: none; } + .md-footer { + display: none; } + .md-sidebar { + display: none; } + .md-tabs { + display: none; } + .md-typeset .headerlink { + display: none; } } + +@media only screen and (max-width: 44.9375em) { + .md-typeset pre { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset pre > code { + padding: 1.05rem 1.6rem; } + .md-footer-nav__link--prev .md-footer-nav__title { + display: none; } + .md-search-result__teaser { + max-height: 5rem; + -webkit-line-clamp: 3; } + .codehilite .hll, .md-typeset .highlight .hll { + margin: 0 -1.6rem; + padding: 0 1.6rem; } + .md-typeset > .codehilite, .md-typeset > .highlight { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset > .codehilite pre, .md-typeset > .highlight pre, + .md-typeset > .codehilite code, + .md-typeset > .highlight code { + padding: 1.05rem 1.6rem; } + .md-typeset > .codehilitetable, .md-typeset > .highlighttable { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset > .codehilitetable .codehilite > pre, .md-typeset > .highlighttable .codehilite > pre, .md-typeset > .codehilitetable .highlight > pre, .md-typeset > .highlighttable .highlight > pre, + .md-typeset > .codehilitetable .codehilite > code, + .md-typeset > .highlighttable .codehilite > code, + .md-typeset > .codehilitetable .highlight > code, + .md-typeset > .highlighttable .highlight > code, + .md-typeset > .codehilitetable .linenodiv, + .md-typeset > .highlighttable .linenodiv { + padding: 1rem 1.6rem; } + .md-typeset > p > .MJXc-display { + margin: 0.75em -1.6rem; + padding: 0.25em 1.6rem; } + .md-typeset > .superfences-tabs { + margin: 1em -1.6rem; + border: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + border-radius: 0; } + .md-typeset > .superfences-tabs pre, + .md-typeset > .superfences-tabs code { + padding: 1.05rem 1.6rem; } } + +@media only screen and (min-width: 100em) { + html { + font-size: 68.75%; } } + +@media only screen and (min-width: 125em) { + html { + font-size: 75%; } } + +@media only screen and (max-width: 59.9375em) { + body[data-md-state="lock"] { + overflow: hidden; } + .ios body[data-md-state="lock"] .md-container { + display: none; } + html .md-nav__link[for="__toc"] { + display: block; + padding-right: 4.8rem; } + html .md-nav__link[for="__toc"]::after { + color: inherit; + content: "\E8DE"; } + html .md-nav__link[for="__toc"] + .md-nav__link { + display: none; } + html .md-nav__link[for="__toc"] ~ .md-nav { + display: flex; } + html [dir="rtl"] .md-nav__link { + padding-right: 1.6rem; + padding-left: 4.8rem; } + .md-nav__source { + display: block; + padding: 0 0.4rem; + background-color: rgba(50, 64, 144, 0.9675); + color: white; } + .md-search__overlay { + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 3.6rem; + height: 3.6rem; + -webkit-transform-origin: center; + transform-origin: center; + transition: opacity 0.2s 0.2s, -webkit-transform 0.3s 0.1s; + transition: transform 0.3s 0.1s, opacity 0.2s 0.2s; + transition: transform 0.3s 0.1s, opacity 0.2s 0.2s, -webkit-transform 0.3s 0.1s; + border-radius: 2rem; + background-color: white; + overflow: hidden; + pointer-events: none; } + [dir="rtl"] .md-search__overlay { + right: 0.4rem; + left: initial; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + transition: opacity 0.1s, -webkit-transform 0.4s; + transition: transform 0.4s, opacity 0.1s; + transition: transform 0.4s, opacity 0.1s, -webkit-transform 0.4s; + opacity: 1; } + .md-search__inner { + position: fixed; + top: 0; + left: 100%; + width: 100%; + height: 100%; + -webkit-transform: translateX(5%); + transform: translateX(5%); + transition: right 0s 0.3s, left 0s 0.3s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1); + transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s; + transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 0; + z-index: 2; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + left: 0; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: right 0s 0s, left 0s 0s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s; + transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 1; } + [dir="rtl"] [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + right: 0; + left: initial; } + html [dir="rtl"] .md-search__inner { + right: 100%; + left: initial; + -webkit-transform: translateX(-5%); + transform: translateX(-5%); } + .md-search__input { + width: 100%; + height: 4.8rem; + font-size: 1.8rem; } + .md-search__icon[for="__search"] { + top: 1.2rem; + left: 1.6rem; } + .md-search__icon[for="__search"][for="__search"]::before { + content: "\E5C4"; } + [dir="rtl"] .md-search__icon[for="__search"][for="__search"]::before { + content: "\E5C8"; } + .md-search__icon[type="reset"] { + top: 1.2rem; + right: 1.6rem; } + .md-search__output { + top: 4.8rem; + bottom: 0; } + .md-search-result__article--document::before { + display: none; } } + +@media only screen and (max-width: 76.1875em) { + [data-md-toggle="drawer"]:checked ~ .md-overlay { + width: 100%; + height: 100%; + transition: width 0s, height 0s, opacity 0.25s; + opacity: 1; } + .md-header-nav__button.md-icon--home, .md-header-nav__button.md-logo { + display: none; } + .md-hero__inner { + margin-top: 4.8rem; + margin-bottom: 2.4rem; } + .md-nav { + background-color: white; } + .md-nav--primary, + .md-nav--primary .md-nav { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + flex-direction: column; + height: 100%; + z-index: 1; } + .md-nav--primary .md-nav__title, + .md-nav--primary .md-nav__item { + font-size: 1.6rem; + line-height: 1.5; } + html .md-nav--primary .md-nav__title { + position: relative; + height: 11.2rem; + padding: 6rem 1.6rem 0.4rem; + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.54); + font-weight: 400; + line-height: 4.8rem; + white-space: nowrap; + cursor: pointer; } + html .md-nav--primary .md-nav__title::before { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + color: rgba(0, 0, 0, 0.54); } + html .md-nav--primary .md-nav__title ~ .md-nav__list { + background-color: white; + box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset; } + html .md-nav--primary .md-nav__title ~ .md-nav__list > .md-nav__item:first-child { + border-top: 0; } + html .md-nav--primary .md-nav__title--site { + position: relative; + background-color: #3f51b5; + color: white; } + html .md-nav--primary .md-nav__title--site .md-nav__button { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 6.4rem; + height: 6.4rem; + font-size: 4.8rem; } + html .md-nav--primary .md-nav__title--site::before { + display: none; } + html [dir="rtl"] .md-nav--primary .md-nav__title::before { + right: 0.4rem; + left: initial; } + html [dir="rtl"] .md-nav--primary .md-nav__title--site .md-nav__button { + right: 0.4rem; + left: initial; } + .md-nav--primary .md-nav__list { + flex: 1; + overflow-y: auto; } + .md-nav--primary .md-nav__item { + padding: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); } + [dir="rtl"] .md-nav--primary .md-nav__item { + padding: 0; } + .md-nav--primary .md-nav__item--nested > .md-nav__link { + padding-right: 4.8rem; } + [dir="rtl"] .md-nav--primary .md-nav__item--nested > .md-nav__link { + padding-right: 1.6rem; + padding-left: 4.8rem; } + .md-nav--primary .md-nav__item--nested > .md-nav__link::after { + content: "\E315"; } + [dir="rtl"] .md-nav--primary .md-nav__item--nested > .md-nav__link::after { + content: "\E314"; } + .md-nav--primary .md-nav__link { + position: relative; + margin-top: 0; + padding: 1.2rem 1.6rem; } + .md-nav--primary .md-nav__link::after { + position: absolute; + top: 50%; + right: 1.2rem; + margin-top: -1.2rem; + color: inherit; + font-size: 2.4rem; } + [dir="rtl"] .md-nav--primary .md-nav__link::after { + right: initial; + left: 1.2rem; } + .md-nav--primary .md-nav--secondary .md-nav__link { + position: static; } + .md-nav--primary .md-nav--secondary .md-nav { + position: static; + background-color: transparent; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav__link { + padding-left: 2.8rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link { + padding-right: 2.8rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link { + padding-left: 4rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link { + padding-right: 4rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 5.2rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link { + padding-right: 5.2rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 6.4rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link { + padding-right: 6.4rem; + padding-left: initial; } + .md-nav__toggle ~ .md-nav { + display: flex; + -webkit-transform: translateX(100%); + transform: translateX(100%); + transition: opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1); + transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s; + transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1); + opacity: 0; } + [dir="rtl"] .md-nav__toggle ~ .md-nav { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); } + .no-csstransforms3d .md-nav__toggle ~ .md-nav { + display: none; } + .md-nav__toggle:checked ~ .md-nav { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; } + .no-csstransforms3d .md-nav__toggle:checked ~ .md-nav { + display: flex; } + .md-sidebar--primary { + position: fixed; + top: 0; + left: -24.2rem; + width: 24.2rem; + height: 100%; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + background-color: white; + z-index: 3; } + [dir="rtl"] .md-sidebar--primary { + right: -24.2rem; + left: initial; } + .no-csstransforms3d .md-sidebar--primary { + display: none; } + [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4); + -webkit-transform: translateX(24.2rem); + transform: translateX(24.2rem); } + [dir="rtl"] [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + -webkit-transform: translateX(-24.2rem); + transform: translateX(-24.2rem); } + .no-csstransforms3d [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + display: block; } + .md-sidebar--primary .md-sidebar__scrollwrap { + overflow: hidden; } + .md-sidebar--primary .md-sidebar__scrollwrap { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: 0; } + .md-tabs { + display: none; } } + +@media only screen and (min-width: 60em) { + .md-content { + margin-right: 24.2rem; } + [dir="rtl"] .md-content { + margin-right: initial; + margin-left: 24.2rem; } + .md-header-nav__button.md-icon--search { + display: none; } + .md-header-nav__source { + display: block; + width: 23rem; + max-width: 23rem; + margin-left: 2.8rem; + padding-right: 1.2rem; } + [dir="rtl"] .md-header-nav__source { + margin-right: 2.8rem; + margin-left: initial; + padding-right: initial; + padding-left: 1.2rem; } + .md-search { + padding: 0.4rem; } + .md-search__overlay { + position: fixed; + top: 0; + left: 0; + width: 0; + height: 0; + transition: width 0s 0.25s, height 0s 0.25s, opacity 0.25s; + background-color: rgba(0, 0, 0, 0.54); + cursor: pointer; } + [dir="rtl"] .md-search__overlay { + right: 0; + left: initial; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + width: 100%; + height: 100%; + transition: width 0s, height 0s, opacity 0.25s; + opacity: 1; } + .md-search__inner { + position: relative; + width: 23rem; + padding: 0.2rem 0; + float: right; + transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + [dir="rtl"] .md-search__inner { + float: left; } + .md-search__form { + border-radius: 0.2rem; } + .md-search__input { + width: 100%; + height: 3.6rem; + padding-left: 4.4rem; + transition: background-color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.26); + color: inherit; + font-size: 1.6rem; } + [dir="rtl"] .md-search__input { + padding-right: 4.4rem; } + .md-search__input + .md-search__icon { + color: inherit; } + .md-search__input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input::-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input::placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input:hover { + background-color: rgba(255, 255, 255, 0.12); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input { + border-radius: 0.2rem 0.2rem 0 0; + background-color: white; + color: rgba(0, 0, 0, 0.87); + text-overflow: none; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__output { + top: 3.8rem; + transition: opacity 0.4s; + opacity: 0; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__output { + box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.4); + opacity: 1; } + .md-search__scrollwrap { + max-height: 0; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__scrollwrap { + max-height: 75vh; } + .md-search__scrollwrap::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-search__scrollwrap::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + .md-search-result__meta { + padding-left: 4.4rem; } + [dir="rtl"] .md-search-result__meta { + padding-right: 4.4rem; + padding-left: initial; } + .md-search-result__article { + padding-left: 4.4rem; } + [dir="rtl"] .md-search-result__article { + padding-right: 4.4rem; + padding-left: 1.6rem; } + .md-sidebar--secondary { + display: block; + margin-left: 100%; + -webkit-transform: translate(-100%, 0); + transform: translate(-100%, 0); } + [dir="rtl"] .md-sidebar--secondary { + margin-right: 100%; + margin-left: initial; + -webkit-transform: translate(100%, 0); + transform: translate(100%, 0); } } + +@media only screen and (min-width: 76.25em) { + .md-content { + margin-left: 24.2rem; } + [dir="rtl"] .md-content { + margin-right: 24.2rem; } + .md-content__inner { + margin-right: 2.4rem; + margin-left: 2.4rem; } + .md-header-nav__button.md-icon--menu { + display: none; } + .md-nav[data-md-state="animate"] { + transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); } + .md-nav__toggle ~ .md-nav { + max-height: 0; + overflow: hidden; } + .no-js .md-nav__toggle ~ .md-nav { + display: none; } + .md-nav__toggle:checked ~ .md-nav, .md-nav[data-md-state="expand"] { + max-height: 100%; } + .no-js .md-nav__toggle:checked ~ .md-nav, .no-js .md-nav[data-md-state="expand"] { + display: block; } + .md-nav__item--nested > .md-nav > .md-nav__title { + display: none; } + .md-nav__item--nested > .md-nav__link::after { + display: inline-block; + -webkit-transform-origin: 0.45em 0.45em; + transform-origin: 0.45em 0.45em; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + vertical-align: -0.125em; } + .js .md-nav__item--nested > .md-nav__link::after { + transition: -webkit-transform 0.4s; + transition: transform 0.4s; + transition: transform 0.4s, -webkit-transform 0.4s; } + .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link::after { + -webkit-transform: rotateX(180deg); + transform: rotateX(180deg); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + width: 68.8rem; } + .md-search__scrollwrap { + width: 68.8rem; } + .md-sidebar--secondary { + margin-left: 122rem; } + [dir="rtl"] .md-sidebar--secondary { + margin-right: 122rem; + margin-left: initial; } + .md-tabs ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + font-size: 0; + visibility: hidden; } + .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title { + display: block; + padding: 0; } + .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title--site { + display: none; } + .no-js .md-tabs--active ~ .md-main .md-nav--primary .md-nav { + display: block; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item { + font-size: 0; + visibility: hidden; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + display: none; + font-size: 1.4rem; + overflow: auto; + visibility: visible; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested > .md-nav__link { + display: none; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--active { + display: block; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] { + max-height: initial; + overflow: visible; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] > .md-nav__list > .md-nav__item { + padding-left: 0; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] .md-nav .md-nav__title { + display: none; } } + +@media only screen and (min-width: 45em) { + .md-footer-nav__link { + width: 50%; } + .md-footer-copyright { + max-width: 75%; + float: left; } + [dir="rtl"] .md-footer-copyright { + float: right; } + .md-footer-social { + padding: 1.2rem 0; + float: right; } + [dir="rtl"] .md-footer-social { + float: left; } } + +@media only screen and (max-width: 29.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(45); + transform: scale(45); } } + +@media only screen and (min-width: 30em) and (max-width: 44.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(60); + transform: scale(60); } } + +@media only screen and (min-width: 45em) and (max-width: 59.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(75); + transform: scale(75); } } + +@media only screen and (min-width: 60em) and (max-width: 76.1875em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + width: 46.8rem; } + .md-search__scrollwrap { + width: 46.8rem; } + .md-search-result__teaser { + max-height: 5rem; + -webkit-line-clamp: 3; } } + +/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24uMTFlNDE4NTIuY3NzIiwic291cmNlUm9vdCI6IiJ9*/ \ No newline at end of file diff --git a/assets/term-action.png b/assets/term-action.png new file mode 100644 index 000000000..9ff8835df Binary files /dev/null and b/assets/term-action.png differ diff --git a/assets/termPicker-tree-selection.png b/assets/termPicker-tree-selection.png new file mode 100644 index 000000000..fa45a5634 Binary files /dev/null and b/assets/termPicker-tree-selection.png differ diff --git a/assets/termpicker-empty.png b/assets/termpicker-empty.png new file mode 100644 index 000000000..c8587b23b Binary files /dev/null and b/assets/termpicker-empty.png differ diff --git a/assets/termpicker-input-autocomplete.png b/assets/termpicker-input-autocomplete.png new file mode 100644 index 000000000..18b317203 Binary files /dev/null and b/assets/termpicker-input-autocomplete.png differ diff --git a/assets/termpicker-limit-to-group.png b/assets/termpicker-limit-to-group.png new file mode 100644 index 000000000..42fb1363b Binary files /dev/null and b/assets/termpicker-limit-to-group.png differ diff --git a/assets/termpicker-selected-terms.png b/assets/termpicker-selected-terms.png new file mode 100644 index 000000000..05119c8e2 Binary files /dev/null and b/assets/termpicker-selected-terms.png differ diff --git a/assets/toolbar.png b/assets/toolbar.png new file mode 100644 index 000000000..e58f210ee Binary files /dev/null and b/assets/toolbar.png differ diff --git a/assets/userPicker01.png b/assets/userPicker01.png new file mode 100644 index 000000000..3b274ef1f Binary files /dev/null and b/assets/userPicker01.png differ diff --git a/assets/userPicker02.png b/assets/userPicker02.png new file mode 100644 index 000000000..8af21ba93 Binary files /dev/null and b/assets/userPicker02.png differ diff --git a/assets/userPicker03.png b/assets/userPicker03.png new file mode 100644 index 000000000..cff28ef79 Binary files /dev/null and b/assets/userPicker03.png differ diff --git a/assets/webparttitle-control.gif b/assets/webparttitle-control.gif new file mode 100644 index 000000000..818867a8b Binary files /dev/null and b/assets/webparttitle-control.gif differ diff --git a/assets/webparttitle-morelink.png b/assets/webparttitle-morelink.png new file mode 100644 index 000000000..9fae719a4 Binary files /dev/null and b/assets/webparttitle-morelink.png differ diff --git a/beta/index.html b/beta/index.html new file mode 100644 index 000000000..a455694ce --- /dev/null +++ b/beta/index.html @@ -0,0 +1,1666 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Beta testing - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Testing out a beta release

+

All you need to do for testing out a beta release of @pnp/spfx-controls-react is to install the dependency as follows:

+
npm install @pnp/spfx-controls-react@next --save
+
+ +

Beta control documentation

+

The control documentation is only live for public releases, not for beta versions. If you want to checkout the markdown files of all controls in the dev branch: beta documentation.

+

Next Steps

+

Once you installed the beta version, you can start using the controls in your solution. Go to the homepage to get an overview of all the available controls and the steps to get started: home.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/AccessibleAccordion/index.html b/controls/AccessibleAccordion/index.html new file mode 100644 index 000000000..bd2e1cf40 --- /dev/null +++ b/controls/AccessibleAccordion/index.html @@ -0,0 +1,2043 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AccessibleAccordion - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Accessible Accordion

+

This control allows you to render an accordion control. It is an implementation based on React Accessible Accordion Control, that was customized to be more "Fluent".

+

Here is an example of the control in action:

+

Accessible Accordion control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the Accordion control as follows:
  • +
+
import {
+    Accordion,
+    AccordionItem,
+    AccordionItemHeading,
+    AccordionItemButton,
+    AccordionItemPanel,
+}  from "@pnp/spfx-controls-react/lib/AccessibleAccordion";
+
+ +
    +
  • Use the Accordion control in your code as follows:
  • +
+
        <Accordion>
+            <AccordionItem>
+                <AccordionItemHeading>
+                    <AccordionItemButton>
+                        What harsh truths do you prefer to ignore?
+                    </AccordionItemButton>
+                </AccordionItemHeading>
+                <AccordionItemPanel>
+                    <p>
+                        Exercitation in fugiat est ut ad ea cupidatat ut in
+                        cupidatat occaecat ut occaecat consequat est minim minim
+                        esse tempor laborum consequat esse adipisicing eu
+                        reprehenderit enim.
+                    </p>
+                </AccordionItemPanel>
+            </AccordionItem>
+            <AccordionItem>
+                <AccordionItemHeading>
+                    <AccordionItemButton>
+                        Is free will real or just an illusion?
+                    </AccordionItemButton>
+                </AccordionItemHeading>
+                <AccordionItemPanel>
+                    <p>
+                        In ad velit in ex nostrud dolore cupidatat consectetur
+                        ea in ut nostrud velit in irure cillum tempor laboris
+                        sed adipisicing eu esse duis nulla non.
+                    </p>
+                </AccordionItemPanel>
+            </AccordionItem>
+        </Accordion> 
+}
+
+ +

Implementation

+

The Accordion control can be configured with the following properties:

+

Accordion

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
allowMultipleExpandedbooleannoDon't autocollapse items when expanding other items.false
allowZeroExpandedbooleannoAllow the only remaining expanded item to be collapsed.false
preExpandedstring[]noAccepts an array of strings and any AccordionItem whose uuid prop matches any one of these strings will be expanded on mount.[]
classNamestringnoClass(es) to apply to element."accordion"
onChange(string[]) => voidnoCallback which is invoked when items are expanded or collapsed. Gets passed uuids of the currently expanded AccordionItems.
themeIPartialTheme | IThemenoSet Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.
+

AccordionItem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
classNamestringnoClass(es) to apply to element."accordion__item"
uuidstring | numbernoRecommended for use with onChange. Will be auto-generated if not provided.
dangerouslySetExpandedbooleannoEnables external control of the expansion. Warning: This may impact accessibility negatively, use at your own risk
+

AccordionItemHeading

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
classNamestringnoClass(es) to apply to the 'heading' element."accordion__heading"
aria-levelnumbernoSemantics to apply to the 'heading' element. A value of 1 would make your heading element hierarchically equivalent to an <h1> tag, and likewise a value of 6 would make it equivalent to an <h6> tag.3
+

AccordionItemButton

+ + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
classNamestringnoClass(es) to apply to the 'button' element."accordion__button"
+

AccordionItemPanel

+ + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
classNamestringnoClass(es) to apply to element."accordion__panel"
+

AccordionItemState

+ + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
children({ expanded: boolean, disabled: booleam }): JSX.Elementyesitem's children.
+

Helpers

+

resetNextUuid

+
resetNextUuid : () => void
+
+ +

Resets the internal counter for Accordion items' identifiers (including id +attributes). For use in test suites and isomorphic frameworks.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Accordion/index.html b/controls/Accordion/index.html new file mode 100644 index 000000000..eb7d6c4ec --- /dev/null +++ b/controls/Accordion/index.html @@ -0,0 +1,1748 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Accordion - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Accordion

+

This control allows you to render an accordion control.

+

Here is an example of the control in action:

+

Accordion control

+

Here is an example of the control with custom icons:

+

Accordion control with custom icons

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the Accordion control as follows:
  • +
+
import { Accordion } from "@pnp/spfx-controls-react/lib/Accordion";
+
+ +
    +
  • Use the Accordion control in your code as follows:
  • +
+
{
+  sampleItems.map((item, index) => (
+    <Accordion title={item.Question} defaultCollapsed={true} className={"itemCell"} key={index}>
+      <div className={"itemContent"}>
+        <div className={"itemResponse"}>{item.Reponse}</div>
+        <div className={"itemIndex"}>{`Langue :  ${item.Langue.Nom}`}</div>
+      </div>
+    </Accordion>
+  ))
+}
+
+ +
    +
  • For the Accordion control with custom icons:
  • +
+
{
+  <Accordion title={item.Question} defaultCollapsed={true} className={"itemCell"} key={index} collapsedIcon={"Rocket"} expandedIcon={"InkingTool"}>
+}
+
+ +

Implementation

+

The Accordion control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
titlestringyesThe title in the accordion to display.
defaultCollapsedbooleannoIs the accordion by default collapsed?false
classNamestringnoAdditional class name to add to your accordion.
collapsedIconstringnoOptional custom icon when accordion is collapsed See Fluent UI iconsChevronRight
expandedIconstringnoOptional custom icon when accordion is expanded See Fluent UI iconsChevronDown
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/AdaptiveCardDesignerHost/index.html b/controls/AdaptiveCardDesignerHost/index.html new file mode 100644 index 000000000..8a6e7e11c --- /dev/null +++ b/controls/AdaptiveCardDesignerHost/index.html @@ -0,0 +1,1899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AdaptiveCardDesignerHost - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Adaptive Card Designer Host

+

This control allows you to embed the official Adaptive Cards designer inside a React SPFx solution.

+

The control consists of 2 components:

+
    +
  • AdaptiveCardDesigner: implements all the logic to embed the designer control as a React component;
  • +
  • AdaptiveCardDesignerHost: main control to render the designer in a full page Fluent UI panel;
  • +
+

Due to the nature in which the original Adaptive Card Designer control was implemented, it is not possible at this time to adapt it to the current theme applied to the site and especially to localize it to give multilingual support. The designer, therefore, is only available in the English language.

+

This control shares a lot of code with another control in this library, the "AdaptiveCardHost" control. In this way you have a uniformity of display between the cards created with this designer and those rendered with "AdaptiveCardHost". The same thing goes for the various HostContainer objects, so that you can test the cards with the themes available for "AdaptiveCardHost".

+

The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0.

+

All Inputs Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, adding and improving features that are not managed in Microsoft's implementation of the "adaptivecards-fluentui" library (Theme support for example).

+

Thanks to the "context" property that allows you to pass the SPFx context, whether the "data" property is passed or not, a new field called @context will be injected into the data object.

+

This allows, using Adaptive Cards templating syntax and binding feature of the Designer, to access to the context informations.

+

For more info please to refear tot he documentation of AdaptiveCardHost control

+

Here is an example of the control in action inside a Web Part:

+

Adaptive Card Host control

+

How to use this control in your solutions

+
    +
  • +

    Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.

    +
  • +
  • +

    In your component file, import the AdaptiveCardDesignerHost control as follows:

    +
  • +
+
import { AdaptiveCardDesignerHost, HostContainer, BindingPreviewMode, Versions } from "@pnp/spfx-controls-react/lib/AdaptiveCardDesignerHost";
+
+ +
    +
  • Example on use the AdaptiveCardDesignerHost control with only required properties:
  • +
+
<AdaptiveCardDesignerHost
+  headerText="Adaptive Card Designer"
+  buttonText="Open the Designer"
+  context={props.context}
+  onSave={(payload: object) => setCard(payload)}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardDesignerHost control with all properties:
  • +
+
<AdaptiveCardDesignerHost
+  headerText="Adaptive Card Designer"
+  buttonText="Open the Designer"
+  context={props.context}
+  onSave={(payload: object) => setCard(payload)}
+  addDefaultAdaptiveCardHostContainer={true}
+  bindingPreviewMode={BindingPreviewMode.SampleData}
+  theme={props.theme}
+  card={card}
+  data={data}
+  enableDataBindingSupport={true}
+  hostConfig={hostConfig}
+  hostContainers={[]}
+  injectAdaptiveCardHostContextProperty={true}
+  newCardPayload={newCard}
+  selectedHostContainerControlsTargetVersion={false}
+  showCopyToJsonToolbarCommand={true}
+  showDataStructureToolbox={true}
+  showFluentBreakpointsPicker={true}
+  showSampleDataEditorToolbox={true}
+  showTargetVersionMismatchWarning={true}
+  showVersionPicker={true}
+  supportedTargetVersions={[Versions.v1_5]}
+  snippets={snippets}
+/>
+
+ +

Implementation

+

The AdaptiveCardDesignerHost control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault Value
contextBaseComponentContexttrueSet the context from SPFx component-
themeIPartialTheme or IThemefalseSet Fluent UI Theme-
onSave(payload: object) => voidtrueCallback for saving the card-
cardobjectfalseSet Adaptive Card payload-
data{ "$root": object }falseSet Data Source for template rendering-
newCardPayloadobjectfalseSet Adaptive Card payload for the New Card-
hostContainersHostContainer[]falseSet custom HostContainers[]
supportedTargetVersionsVersion[]falseSet the suported Versions[Versions.v1_5]
snippetsIToolboxSnippet[]falseSet the Toolbox Snippets[]
bindingPreviewModeBindingPreviewModefalseSet the Binding preview modeBindingPreviewMode.GeneratedData
enableDataBindingSupportbooleanfalseEnable the support for Data Bindingtrue
selectedHostContainerControlsTargetVersionbooleanfalseEnable the support for Data Bindingfalse
showTargetVersionMismatchWarningbooleanfalseShow the target version mismatch warningtrue
showVersionPickerbooleanfalseShow the Version Pickerfalse
showSampleDataEditorToolboxbooleanfalseShow the Sample Data Editor Toolboxfalse
showDataStructureToolboxbooleanfalseShow the Data Structure Toolboxtrue
showFluentBreakpointsPickerbooleanfalseShow the Fluent UI Breakpoint Pickertrue
showCopyToJsonToolbarCommandbooleanfalseShow the copy to json buttonfalse
addDefaultAdaptiveCardHostContainerbooleanfalseAdd the default Host Containers to the Pickertrue
injectAdaptiveCardHostContextPropertybooleanfalseInject the SPFx Context Property inside the Adaptive Card data objecttrue
headerTextbooleanfalseSet the Header text for the Adaptive Card Designer-
buttonTextbooleanfalseSet the Button text for open the Adaptive Card Designer-
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/AdaptiveCardHost/index.html b/controls/AdaptiveCardHost/index.html new file mode 100644 index 000000000..947272bc2 --- /dev/null +++ b/controls/AdaptiveCardHost/index.html @@ -0,0 +1,1957 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AdaptiveCardHost - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Adaptive Card Host

+

The motivation behind this control is to have a React control that facilitates the use of Adaptive Cards in SPFx by adding some features such as:

+
    +
  • +

    Graphic integration with SharePoint / Microsoft Teams themes, both as regards the color palette and the use of the Fluent UI React controls instead of the classic HTML controls.

    +
  • +
  • +

    Automatic use of Adaptive Cards Templating if an object containing data is passed to the control.

    +
  • +
+

For graphic integration, in the case of SharePoint the current theme (page or section theme) or a custom theme is used. +Three custom themes have been created for Microsoft Teams to emulate the colors of the available themes: Default, Dark and Hight Contrast.

+

All Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, both for SharePoint and Microsoft Teams (in this case the "Fluent UI Northstar" library is not used), adding and improving features that are not managed in Microsoft's implementation of the "adaptivecards-fluentui" library (Theme support for example).

+

Thanks to the "context" property that allows you to pass the SPFx context, whether the "data" property is passed or not, a new field called @context will be injected into the data object.

+

This allows, using Adaptive Cards templating syntax, to access to the context informations using the following fields (for more information on these fields, refer to the BaseComponentContext class): +- "theme": property "theme" from the current theme applied to the card. +- "aadInfo": Azure AD informations retrieved from the SPFx context object. +- "cultureInfo": Culture informations retrieved from the SPFx context object. +- "userInfo": User informations retrieved from the SPFx context object. +- "spListInfo": Current List informations retrieved from the SPFx context object. +- "spListItemInfo": Current List item informations retrieved from the SPFx context object. +- "spSiteInfo": Current Site informations retrieved from the SPFx context object. +- "spWebInfo": Current Web informations retrieved from the SPFx context object.

+

The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0.

+

Here is an example of the control in action inside a Web Part:

+

Adaptive Card Host control

+

Here is an example of the previous Web Part (using different Card), hosted as a Tab in Microsoft Teams:

+

Adaptive Card Host control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the AdaptiveCardHost control as follows:
  • +
+
import { AdaptiveCardHost, IAdaptiveCardHostActionResult, AdaptiveCardHostThemeType, Action, CardElement, CardObjectRegistry, HostCapabilities } from "@pnp/spfx-controls-react/lib/AdaptiveCardHost";
+
+ +
    +
  • Example on use the AdaptiveCardHost control with only required properties:
  • +
+
<AdaptiveCardHost
+  card={card}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with all properties:
  • +
+
<AdaptiveCardHost
+  card={card}
+  data={data}
+  style={null}
+  className={null}
+  theme={this.props.theme}
+  themeType={themeType}
+  hostConfig={null}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  onSetCustomElements={(registry: CardObjectRegistry<CardElement>) => {
+    registry.register("CustomElementName", CustomElement);
+  }}
+  onSetCustomActions={(registry: CardObjectRegistry<Action>) => {
+    registry.register("CustomActionName", CustomAction);
+  }}
+  onUpdateHostCapabilities={(hostCapabilities: HostCapabilities) => {
+    hostCapabilities.setCustomProperty("CustomPropertyName", Date.now);
+  }}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with SharePoint Theme:
  • +
+
<AdaptiveCardHost
+  card={card}
+  themeType={AdaptiveCardHostThemeType.SharePoint}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with SharePoint Theme "Section Variation" ('this.props.theme' is the theme that come from the Web Part) */):
  • +
+
<AdaptiveCardHost
+  card={card}
+  theme={this.props.theme}
+  themeType={AdaptiveCardHostThemeType.SharePoint}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with Teams "Default" Theme:
  • +
+
<AdaptiveCardHost
+  card={card}
+  themeType={AdaptiveCardHostThemeType.Teams}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with Teams "Dark" Theme:
  • +
+
<AdaptiveCardHost
+  card={card}
+  themeType={AdaptiveCardHostThemeType.TeamsDark}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +
    +
  • Example on use the AdaptiveCardHost control with Teams "High Contrast" Theme:
  • +
+
<AdaptiveCardHost
+  card={card}
+  themeType={AdaptiveCardHostThemeType.TeamsHighContrast}
+  onInvokeAction={(action) => alert(JSON.stringify(action))}
+  onError={(error) => alert(error.message)}
+  context={this.props.context}
+/>
+
+ +

Implementation

+

The AdaptiveCardHost control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cardobjectyesSet Adaptive Card payload.
data{ "$root": object }noSet Data Source for template rendering.
styleReact.CSSPropertiesnoSet CSS Style.
classNamestringnoSet CSS Class.
themeIPartialTheme or IThemenoSet Fluent UI Theme. Used only if the "themeType" property is set to 'ThemeType.SharePoint'. If not set or set to null or not defined, the theme passed through context will be searched, or the default theme of the page will be loaded. However, the Theme object will be automatically injected into the data object, so that it can be used by the Adaptive Cards binding engine.
themeTypeThemeTypenoSelect the Type of Theme you want to use. If it is not set or set to null or undefined, the 'ThemeType.SharePoint' value will be used and the "theme" property or the theme passed through the context or default page will be loaded. In other cases, the chosen Microsoft Teams theme will be applied.
hostConfigobjectnoSet custom HostConfig.
onInvokeAction(action: IAdaptiveCardActionResult) => voidyesInvoked every time an Action is performed.
onError(error: Error) => voidyesInvoked every time an exception occurs in the rendering phase.
onSetCustomElements(registry: CardObjectRegistry) => voidnoInvoked to manage Elements to the current Adaptive Card instance.
onSetCustomActions(registry: CardObjectRegistry) => voidnoInvoked to manage Actions to the current Adaptive Card instance.
onUpdateHostCapabilities(hostCapabilities: HostCapabilities) => voidnoInvoked to manage the HostCapabilities object like add custom properties.
contextBaseComponentContextnoSet the context from the SPFx component. If set, some context properties will be automatically injected into the data object, so they can be used by the Adaptive Cards binding engine.
+

Interface IAdaptiveCardHostActionResult

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
typestringyesType of the Action.
titlestringnoTitle of the Action.
urlstringnoUrl of the Action.
dataobjectnoData of the Action.
verbstringnoVerb of the Action.
+

Enum AdaptiveCardHostThemeType

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription
SharePointUse the SharePoint current Theme or Theme Variation
TeamsUse the Fluent UI Teams default theme
TeamsDarkUse the Fluent UI Teams dark theme
TeamsHighContrastUse the Fluent UI Teams high contrast theme
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/AnimatedDialog/index.html b/controls/AnimatedDialog/index.html new file mode 100644 index 000000000..29312ab73 --- /dev/null +++ b/controls/AnimatedDialog/index.html @@ -0,0 +1,2262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AnimatedDialog - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

Animated Dialog

+

Animated Dialog control is an extended version of the Office UI Fabric React Dialog. Animated Dialog control adds the following to the dialog + - Entrance and exit animations + - Animated icon above the title

+

This control uses Animate.css to add the animations.

+

Here is an example of the control in action:

+

Animated dialog control

+

Animate.css and animation names

+

Animate.css is a library that adds css animtions to controls. The website has all the names of the animations and any of them can be used in the Animated Dialog control. The default entrance animation name used in this control is bounceIn and the default exit animaton name is zoomOut.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the AnimatedDialog control as follows:
  • +
+
import { AnimatedDialog } from "@pnp/spfx-controls-react/lib/AnimatedDialog";
+
+ +

Different ways of using the control

+

1. Simple way

+

The code below adds a dialog with an entrance animation of bounceIn and exit animation of zoomOut. (These are the default animations)

+
// Initial state
+this.state = {
+      showAnimatedDialog: false
+}
+...
+...
+// Properties of the dialog
+const animatedDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Animated Dialog',
+      subText: 'Do you like the animated dialog?',
+    };
+
+const animatedModalProps: IModalProps = {
+    isDarkOverlay: true
+};
+...
+...
+// Add a control (like a button) that changes the state showAnimatedDialog to true
+
+//Render the animated dialog
+<AnimatedDialog
+    hidden={!this.state.showAnimatedDialog}
+    onDismiss={() => { this.setState({ showAnimatedDialog: false }); }}
+    dialogContentProps={animatedDialogContentProps}
+    modalProps={animatedModalProps}
+    >
+        <DialogFooter>
+            <PrimaryButton onClick={() => { this.setState({ showAnimatedDialog: false }); }} text="Yes" />
+            <DefaultButton onClick={() => { this.setState({ showAnimatedDialog: false }); }} text="No" />
+        </DialogFooter>
+</AnimatedDialog>
+
+ +

Simple animated dialog

+

Simple animated dialog control

+

2. Adding custom animations

+

The code below adds adds a dialog with an entrance animation of fadeInDown and exit animation of fadeInDown.

+
// Initial state
+this.state = {
+      showAnimatedDialog: false
+}
+...
+...
+// Properties of the dialog
+const animatedDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Animated Dialog',
+      subText: 'Do you like the animated dialog?',
+    };
+
+const animatedModalProps: IModalProps = {
+    isDarkOverlay: true
+};
+...
+...
+// Add a control (like a button) that changes the state showAnimatedDialog to true
+
+//Render the animated dialog
+<AnimatedDialog
+    hidden={!this.state.showAnimatedDialog}
+    onDismiss={() => { this.setState({ showAnimatedDialog: false }); }}
+    dialogContentProps={animatedDialogContentProps}
+    modalProps={animatedModalProps}
+    dialogAnimationInType='fadeInDown'
+    dialogAnimationOutType='fadeOutDown'
+    >
+        <DialogFooter>
+            <PrimaryButton onClick={() => { this.setState({ showAnimatedDialog: false }); }} text="Yes" />
+            <DefaultButton onClick={() => { this.setState({ showAnimatedDialog: false }); }} text="No" />
+        </DialogFooter>
+</AnimatedDialog>
+
+ +

Animated dialog with custom animations

+

Animated dialog control with custom animations

+

3. Adding icons and functions

+

The code below does the following: +- adds an icon (question mark) above the title +- adds Yes and No buttons in the footer as showAnimatedDialogFooter is set to true. +- passes 3 functions + - onOkClick : The function that gets executed when the Ok/Yes button is clicked. + - onSuccess : The function that gets executed on successful operation of the above function. + - onError: The function that gets executed when the onOkClick function fails.

+
// Initial state
+this.state = {
+      showCustomisedAnimatedDialog: false,
+      showSuccessDialog: false,
+      showErrorDialog: false
+}
+...
+...
+const animatedDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Animated Dialog with icon'
+};
+
+const successDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Good answer!'
+};
+
+const animatedModalProps: IModalProps = {
+    isDarkOverlay: true,
+    containerClassName: `${styles.dialogContainer}`
+};
+
+// The operation that does something - e.g. update data
+const timeout = (ms: number): Promise<void> => {
+    return new Promise((resolve, reject) => setTimeout(resolve, ms));
+};
+...
+...
+// Add a control (like a button) that changes the state showAnimatedDialog to true
+
+//Render the animated dialog
+<AnimatedDialog
+    hidden={!this.state.showCustomisedAnimatedDialog}
+    onDismiss={() => { this.setState({ showCustomisedAnimatedDialog: false }); }}
+    dialogContentProps={animatedDialogContentProps}
+    modalProps={animatedModalProps}
+    iconName='UnknownSolid'
+    showAnimatedDialogFooter={true}
+    okButtonText="Yes"
+    cancelButtonText="No"
+    onOkClick={() => timeout(1500)}
+    onSuccess={() => {
+        this.setState({ showCustomisedAnimatedDialog: false });
+        this.setState({ showSuccessDialog: true });
+    }}
+    onError={() => {
+        this.setState({ showCustomisedAnimatedDialog: false });
+        this.setState({ showErrorDialog: true });
+    }}>
+        <div className={styles.dialogContent}>
+            <span>Do you like the animated dialog?</span>
+        </div>
+</AnimatedDialog>
+
+// Render success animated dialog which will appear after the execution 
+// of onSuccess function in the above animated dialog 
+
+<AnimatedDialog
+    hidden={!this.state.showSuccessDialog}
+    onDismiss={() => { this.setState({ showSuccessDialog: false }); }}
+    dialogContentProps={successDialogContentProps}
+    modalProps={animatedModalProps}
+    iconName='CompletedSolid'
+    >
+        <div className={styles.dialogContent}><span>Thank you.</span></div>
+        <div className={styles.resultDialogFooter}>
+            <PrimaryButton onClick={() => { this.setState({ showSuccessDialog: false }); }} text="OK" >
+            </PrimaryButton>
+        </div>
+</AnimatedDialog>
+
+ +

Animated dialog with icon

+

Animated dialog control with icon

+ +

If the dialog content and footer buttons need to be controlled by our code and not the animated dialog control then the code below can be used

+
// Initial state
+this.state = {
+      showCustomisedAnimatedDialog: false,
+      showSuccessDialog: false,
+      showErrorDialog: false,
+      showLoading: false
+}
+...
+...
+const animatedDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Custom content and footer'
+};
+
+const successDialogContentProps: IDialogContentProps = {
+      type: DialogType.normal,
+      title: 'Good answer!'
+};
+
+const animatedModalProps: IModalProps = {
+    isDarkOverlay: true,
+    containerClassName: `${styles.dialogContainer}`
+};
+...
+...
+// Add a control (like a button) that changes the state showAnimatedDialog to true
+
+//Render the animated dialog
+<AnimatedDialog
+    hidden={!this.state.showCustomisedAnimatedDialog}
+    onDismiss={() => { this.setState({ showCustomisedAnimatedDialog: false }); }}
+    dialogContentProps={animatedDialogContentProps}
+    modalProps={animatedModalProps}
+    iconName='UnknownSolid'>
+
+    <div className={styles.dialogContent}>
+    <span>Do you like the animated dialog?</span>
+    </div>
+
+    <div className={styles.dialogFooter}>
+    <PrimaryButton
+        onClick={() => {
+        this.setState({ showLoading: true });
+        setTimeout(() => {
+            this.setState({ showLoading: true });
+            this.setState({ showCustomisedAnimatedDialog: false });
+            this.setState({ showSuccessDialog: true });
+        }, 1500);
+        }}
+        disabled={this.state.showLoading} text={!this.state.showLoading && "Yeah!"}>
+        {this.state.showLoading && <Spinner size={SpinnerSize.medium} />}
+    </PrimaryButton>
+
+    <DefaultButton
+        onClick={() => this.setState({ showCustomisedAnimatedDialog: false })}
+        text="Nope"
+        disabled={this.state.showLoading} />
+    </div>
+</AnimatedDialog>
+
+// Render success animated dialog which will appear after the execution 
+// of the onClick function of the Button in the above animated dialog
+
+<AnimatedDialog
+    hidden={!this.state.showSuccessDialog}
+    onDismiss={() => { this.setState({ showSuccessDialog: false }); }}
+    dialogContentProps={successDialogContentProps}
+    modalProps={animatedModalProps}
+    iconName='CompletedSolid'>
+        <div className={styles.dialogContent}><span>Thank you.</span></div>
+        <div className={styles.resultDialogFooter}>
+            <PrimaryButton onClick={() => { this.setState({ showSuccessDialog: false }); }} text="OK" >
+            </PrimaryButton>
+        </div>
+</AnimatedDialog>
+
+ + +

Animated dialog control with icon

+

SCSS used in the above examples

+
$themePrimary: '[theme:themePrimary, default:#0078d7]';
+
+.dialogContainer {
+  border-top: 4px;
+  border-top-color: $themePrimary;
+  border-top-style: solid;
+  min-width: 400px;
+
+  .dialogContent {
+    text-align: center;
+    padding-bottom: 10px;
+    font-size: 1.125em;
+  }
+
+  .dialogFooter {
+    text-align: right;
+    margin-top: 1.25em;
+
+    button {
+      min-width: 75px;
+      margin: 0px 10px;
+      border-radius: 5px;
+    }
+
+    .loader{
+      margin-top: 15px;
+    }
+  }
+
+  .resultDialogFooter {
+    text-align: center;
+    margin-top: 1.25em;
+
+    button {
+      min-width: 100px;
+      margin: 0px 10px;
+    }
+  }
+}
+
+ +

Implementation

+

In addition to theOffice UI Fabric dialog properties, the AnimatedDialog control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
dialogAnimationInTypestringnoThe name of the dialog entrace animation. See animate.css for valuesbounceIn
dialogAnimationOutTypestringnoThe name of the dialog exit animation. See animate.css for valueszoomOut
iconNamestringnoThe name of the Fabric UI icon that appears above title.
iconAnimationTypestringnoThe name of the icon entrace animation. See animate.css for values.zoomIn
showAnimatedDialogFooterbooleannoShould the animated dialog show it's own footer. See example 3 and 4 above for usage.false
okButtonTextstringnoThe text of the the OK button if showAnimatedDialogFooter is true. See example 3 above for usage.Ok
cancelButtonTextstringnoThe text of the the Cancel button if showAnimatedDialogFooter is true. See example 3 above for usage.Cancel
onOkClickfunctionnoThe function to be executed when Ok button is clicked. Valid only when showAnimatedDialogFooter is true. See example 3 above for usage.
onSuccessfunctionnoThe function to be executed after successful execution of the OK button function. Valid only when showAnimatedDialogFooter is true. See example 3 above for usage.
onErrorfunctionnoThe function to be executed after unsuccessful execution of the OK button function. Valid only when showAnimatedDialogFooter is true. See example 3 above for usage.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Carousel/index.html b/controls/Carousel/index.html new file mode 100644 index 000000000..1f06b6282 --- /dev/null +++ b/controls/Carousel/index.html @@ -0,0 +1,2179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Carousel - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Carousel control

+

A slideshow component for cycling through elements—images or slides of text—like a carousel.

+

Here is an example of the control in action:

+

Carousel control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { Carousel } from "@pnp/spfx-controls-react/lib/Carousel";
+
+ +
    +
  • Use the Carousel control in your code as follows:
  • +
+

Carousel component with provided JSX.Element[] slides

+
<Carousel
+  buttonsLocation={CarouselButtonsLocation.top}
+  buttonsDisplay={CarouselButtonsDisplay.block}
+
+  contentContainerStyles={styles.carouselContent}
+  containerButtonsStyles={styles.carouselButtonsContainer}
+
+  isInfinite={true}
+
+  element={this.carouselElements}
+  onMoveNextClicked={(index: number) => { console.log(`Next button clicked: ${index}`); }}
+  onMovePrevClicked={(index: number) => { console.log(`Prev button clicked: ${index}`); }}
+/>
+
+ +

Carousel component with provided triggerPageEvent

+
<Carousel
+  buttonsLocation={CarouselButtonsLocation.bottom}
+  buttonsDisplay={CarouselButtonsDisplay.buttonsOnly}
+
+  contentContainerStyles={styles.carouselContent}
+  containerButtonsStyles={styles.carouselButtonsContainer}
+
+  canMoveNext={this.state.canMoveNext}
+  canMovePrev={this.state.canMovePrev}
+  triggerPageEvent={this.triggerNextElement}
+  element={this.state.currentCarouselElement}
+/>
+
+ +

Carousel component with provided ICarouselImageProps[] slides:

+
<Carousel
+  buttonsLocation={CarouselButtonsLocation.center}
+  buttonsDisplay={CarouselButtonsDisplay.buttonsOnly}
+  contentContainerStyles={styles.carouselImageContent}
+  isInfinite={true}
+  indicatorShape={CarouselIndicatorShape.circle}
+  pauseOnHover={true}
+
+  element={[
+    {
+      imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
+      title: 'Colosseum',
+      description: 'This is Colosseum',
+      url: 'https://en.wikipedia.org/wiki/Colosseum',
+      showDetailsOnHover: true,
+      imageFit: ImageFit.cover
+    },
+    {
+      imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
+      title: 'Colosseum',
+      description: 'This is Colosseum',
+      url: 'https://en.wikipedia.org/wiki/Colosseum',
+      showDetailsOnHover: true,
+      imageFit: ImageFit.cover
+    },
+    {
+      imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
+      title: 'Colosseum',
+      description: 'This is Colosseum',
+      url: 'https://en.wikipedia.org/wiki/Colosseum',
+      showDetailsOnHover: true,
+      imageFit: ImageFit.cover
+    }
+  ]}
+  onMoveNextClicked={(index: number) => { console.log(`Next button clicked: ${index}`); }}
+  onMovePrevClicked={(index: number) => { console.log(`Prev button clicked: ${index}`); }}
+/>
+
+ +

Implementation

+

The Carousel component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
startIndexnumbernoSpecifies the initial index of the element to be displayed.
isInfinitebooleannoIndicates if infinite scrolling is enabled.
canMoveNextbooleannoProperty indicates if the next item button can be clicked. If not provided, status of the button is calculated based on the current index.
It is mandatory when triggerPageEvent is used.
canMovePrevbooleannoProperty indicates if the previous item button can be clicked. If not provided, status of the button is calculated based on the current index.
It is mandatory when triggerPageEvent is used.
buttonsLocationCarouselButtonsLocationnoSpecifies the location of the buttons inside the container. Default: center
buttonsDisplayCarouselButtonsDisplaynoSpecifies the buttons container display mode. Default: block
containerStylesICssInputnoAllows to specify own styles for carousel container.
loadingComponentContainerStylesICssInputnoAllows to specify own styles for loading component.
contentContainerStylesICssInputnoAllows to specify own styles for elements container.
containerButtonsStylesICssInputnoAllows to specify own styles for buttons container.
prevButtonStylesICssInputnoAllows to specify own styles for previous item button.
nextButtonStylesICssInputnoAllows to specify own styles for next item button.
prevButtonIconNamestringnoName of the icon to be used for PreviousItem button. Default 'ChevronLeft'.
nextButtonIconNamestringnoName of the icon to be used for NextItem button. Default 'ChevronRight'.
triggerPageEvent(index: number) => voidnoTriggers parent control to provide new element to be displayed. After the method is executed, carousel control switches to processing mode and loadingComponent is displayed.
elementJSX.Element | JSX.Element[]yesFixed array of elemenets to be displayed in carousel - if triggerPageEvent is not used.
In case triggerPageEvent is in use, JSX.Element has to be provided. Elements are distinguished based on the 'key' property.
loadingComponentJSX.ElementnoAllows to inject custom component when the carousel is in processing state. If not provided, Spinner is displayed.
onMoveNextClicked(currentIndex: number) => voidnoCallback function called after the next item button is clicked. Not used when triggerPageEvent is specified.
onMovePrevClicked(currentIndex: number) => voidnoCallback function called after the previous item button is clicked. Not used when triggerPageEvent is specified.
elementsCountnumbernoIn case triggerPageEvent is in use, provides total number of slides in the carousel.
onSelect(selectedIndex: number) => voidnoCallback function called when element has been selected in the carousel
slidebooleannoEnables animation on the Carousel as it transitions between slides. This property is ignored if triggerPageEvent is in use.
intervalnumber | nullnoThe amount of time to delay between automatically cycling an item. If null, carousel will not automatically cycle.
pauseOnHoverbooleannoSpecifies if slides cycling should pause when hovering over the content (touchStart on touch devices).
indicatorsbooleannoSpecifies if set of slide position indicators is shown.
indicatorShapeCarouselIndicatorShapenoSpecifies indicators' shape. If onRenderIndicator is provided - this property is ignored
indicatorClassNamestringnoSpecifies additional class applied to slide position indicators
indicatorStyleReact.CSSPropertiesnoSpecifies additional styles applied to slide position indicators
onRenderIndicator(index: number, onClick: (e: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>, selectedIndex: number) => void) => JSX.ElementnoFunction to render indicator element
indicatorsDisplayCarouselIndicatorsDisplaynoSpecifies display mode of the indicators. Default value overlap.
rootStylesICssInputnoAllows to specify own styles for root element
indicatorsContainerStylesICssInputnoAllows to specify own styles for indicators container when indicatorsDisplay is set to "block"
prevButtonAriaLabelstringnoAria label of the PreviousItem button. Default 'Previous item'.
nextButtonAriaLabelstringnoAria label of the NextItem button. Default 'Next item'.
contentHeightnumbernoAllows to specify the height of the content. Can be used instead of providing styles for the content container (contentContainerStyles).
+

enum CarouselButtonsLocation

+

Provides options for carousel buttons location.

+ + + + + + + + + + + + + + + + + + + + + +
ValueDescription
topButtons are going to be placed in the top of the control.
centerButtons are going to be placed in the center of the control.
bottomButtons are going to be placed in the bottom of the control.
+

enum CarouselButtonsDisplay

+

Provides options for carousel buttons display mode.

+ + + + + + + + + + + + + + + + + + + + + +
ValueDescription
blockReserves space for buttons on both sides of the control.
buttonsOnlyOnly icon buttons are displayed.
hiddenButtons are not displayed. They appear onhover event.
+

enum CarouselIndicatorShape

+

Provides options for carousel indicators' shape.

+ + + + + + + + + + + + + + + + + + + + + +
ValueDescription
circleIndicators displayed as cirlces
squareIndicators displayed as squares
rectangleIndicators displayed as rectangles
+

enum CarouselIndicatorsDisplay

+

Provides options for carousel indicators display mode.

+ + + + + + + + + + + + + + + + + +
ValueDescription
overlapIndicators are displayed on top of the carousel content
blockReserves space for indicators
+

Interface ICarouselImageProps

+

Allows to easily render a set of CarouselImage components in the carousel

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
imageSrcstringyesImage source
imageFitImageFitnoSpecifies the method to be used to fit image. Default: ImageFit.none. See Fluent UI Image
urlstringnoURL to be opened when clicking on details
titlestringnoTitle to display in details
descriptionstring | JSX.ElementnoDescription to show in details. Can be either a string (text) or JSX.Element to show HTML.
target"_blank" | "_self"noTarget of the URL to open. Default "_blank"
showDetailsOnHoverbooleannoSpecifies if the details are shown on hover or constantly
classNamestringnoClass to apply to the component
styleReact.CSSPropertiesnoStyles to apply to the component
imgClassNamestringnoClass to apply to the image control
imgStyleReact.CSSPropertiesnoStyles to apply to the image control
detailsClassNamestringnoClass to apply to the details control
detailsStyleReact.CSSPropertiesnoStyles to apply to the details control
titleClassNamestringnoClass to apply to the title control
titleStyleReact.CSSPropertiesnoStyles to apply to the title control
descriptionClassNamestringnoClass to apply to the description control
descriptionStyleReact.CSSPropertiesnoStyles to apply to the description control
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ChartControl/index.html b/controls/ChartControl/index.html new file mode 100644 index 000000000..31e674f38 --- /dev/null +++ b/controls/ChartControl/index.html @@ -0,0 +1,2623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ChartControl - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

ChartControl control

+

This control makes it easy to integrate Chart.js charts into your web parts. It offers most of the functionality available with Chart.js.

+

The control automatically renders responsive charts, uses the environment's theme colors, and renders a hidden table for users with impaired vision.

+

Here is an example of the control in action:

+

ChartControl control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following module to your component:
  • +
+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +
    +
  • Use the ChartControl control in your code as follows:
  • +
+
<ChartControl 
+  type={ChartType.Bar}
+  data={{
+    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
+    datasets: [{
+      label: 'My First dataset',
+      data: [65, 59, 80, 81, 56, 55, 40]
+    }]
+  }} />
+
+ +

Compatibility with Chart.js

+

The majority of Chart.js its options like data, options, type, and plugins will work the same way as is -- except that you use TypeScript syntax.

+

To find sample code that you can use, visit the Chart.Js documentation.

+

For example, to reproduce following Javascript code sample from Chart.js:

+
<canvas id="myChart" width="400" height="400"></canvas>
+<script>
+var ctx = document.getElementById("myChart").getContext('2d');
+var myChart = new Chart(ctx, {
+  type: 'bar',
+  data: {
+    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
+    datasets: [{
+      label: '# of Votes',
+      data: [12, 19, 3, 5, 2, 3],
+      backgroundColor: [
+        'rgba(255, 99, 132, 0.2)',
+        'rgba(54, 162, 235, 0.2)',
+        'rgba(255, 206, 86, 0.2)',
+        'rgba(75, 192, 192, 0.2)',
+        'rgba(153, 102, 255, 0.2)',
+        'rgba(255, 159, 64, 0.2)'
+      ],
+      borderColor: [
+        'rgba(255,99,132,1)',
+        'rgba(54, 162, 235, 1)',
+        'rgba(255, 206, 86, 1)',
+        'rgba(75, 192, 192, 1)',
+        'rgba(153, 102, 255, 1)',
+        'rgba(255, 159, 64, 1)'
+      ],
+      borderWidth: 1
+    }]
+  },
+  options: {
+    scales: {
+      yAxes: [{
+        ticks: {
+            beginAtZero:true
+        }
+      }]
+    }
+  }
+});
+</script>
+
+ +

You would use the following Typescript code:

+
<ChartControl 
+  type={ChartType.Bar}
+  data={{
+    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
+    datasets: [{
+        label: '# of Votes',
+        data: [12, 19, 3, 5, 2, 3],
+        backgroundColor: [
+            'rgba(255, 99, 132, 0.2)',
+            'rgba(54, 162, 235, 0.2)',
+            'rgba(255, 206, 86, 0.2)',
+            'rgba(75, 192, 192, 0.2)',
+            'rgba(153, 102, 255, 0.2)',
+            'rgba(255, 159, 64, 0.2)'
+        ],
+        borderColor: [
+            'rgba(255,99,132,1)',
+            'rgba(54, 162, 235, 1)',
+            'rgba(255, 206, 86, 1)',
+            'rgba(75, 192, 192, 1)',
+            'rgba(153, 102, 255, 1)',
+            'rgba(255, 159, 64, 1)'
+        ],
+        borderWidth: 1
+    }]
+  }}
+  options={{
+    scales: {
+        yAxes: [{
+          ticks: {
+              beginAtZero:true
+          }
+      }]
+    }
+  }}
+/>
+
+ +

The code above will produce the following chart:

+

ChartControl using code from the Chart.js site

+

Specifying Data

+

The data property typically consist of:

+
    +
  • labels: (Optional) An array of strings providing the data labels (e.g.: ['January', 'February', 'March', 'April', 'May', 'June', 'July'])
  • +
  • datasets: At least one dataset, which contains:
      +
    • label: (Optional) A label for the data (e.g.: 'My First Dataset')
    • +
    • data: An array of numbers (e.g.: [65, 59, 80, 81, 56, 55, 40])
    • +
    +
  • +
+

See below for more information on what types of data are required for each type of chart.

+

Specifying Data Promises

+

The ChartControl makes it easy to retrieve data asynchronously with the datapromise property.

+

To use datapromise, add a function to your web part that returns a Promise<Chart.ChartData> as follows:

+
 private _loadAsyncData(): Promise<Chart.ChartData> {
+    return new Promise<Chart.ChartData>((resolve, reject) => {
+      // Call your own service -- this example returns an array of numbers
+      // but you could call
+      const dataProvider: IChartDataProvider = new MockChartDataProvider();
+      dataProvider.getNumberArray().then((numbers: number[]) => {
+        // format your response to ChartData
+        const data: Chart.ChartData =
+        {
+          labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July']
+          datasets: [
+            {
+              label: 'My First dataset',
+              data: numbers
+            }
+          ]
+        };
+
+        // resolve the promise
+        resolve(data);
+      });
+    });
+  }
+
+ +

Then, instead of passing a data property, pass your function to the datapromise property, as follows:

+
<ChartControl
+  type='bar'
+  datapromise={this._loadAsyncData()}
+  />
+
+ +

If you want, you provide a template to display until the datapromise is resolved, as follows:

+
<ChartControl
+  type='bar'
+  datapromise={this._loadAsyncData()}
+  loadingtemplate={() => <div>Please wait...</div>}
+/>
+
+ +

Data Promise with Loading Template

+

You can provide full React controls within the loadingtemplate. For example, to use the Office UI Fabric Spinner control, you would use the following code:

+
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
+...
+<ChartControl
+  type='bar'
+  datapromise={this._loadAsyncData()}
+  loadingtemplate={() => <Spinner size={SpinnerSize.large} label="Loading..."  />}
+/>
+
+ +

Chart Control Data Promise with Spinner

+

You can also provide another template to display when the datapromise is rejected, as follows:

+
<ChartControl
+  type='bar'
+  datapromise={this._loadAsyncData()}
+    loadingtemplate={() => <Spinner size={SpinnerSize.large} label="Loading..."  />}
+  rejectedtemplate={(error: string) => <div>Something went wrong: {error}</div>}
+/>
+
+ +

Chart Control Promise with Reject Template

+

Theme Color Support

+

By default, the ChartControl will attempt to use the environment theme colors and fonts for elements such as the chart background color, grid lines, titles, labels, legends, and tooltips. This includes support for dark themes and high contrast themes.

+

If you wish, you can disable the use of themes by setting the useTheme property to false. Doing so will use the standard Chart.js colors and fonts.

+

Office Color Palettes

+

You can also simplify the majority of code samples by omitting the color properties; the ChartControl will automatically reproduce the color palette that you would get if you used Office to create the chart.

+
<ChartControl type={ChartType.Bar}
+  data={{
+    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
+    datasets: [{
+        label: '# of Votes',
+        data: [12, 19, 3, 5, 2, 3]
+    }]
+  }}
+  options={{
+    scales: {
+      yAxes: [{
+        ticks: {
+          beginAtZero:true
+        }
+      }]
+    }
+  }}
+/>
+
+ +

ChartControl using the default color palette

+

You can also set the palette property to choose one of the Office color palettes. For example, Specifying ChartPalette.OfficeMonochromatic1 will produce the following chart:

+

ChartControl using the Office Monochromatic 1 color palette

+

Responsiveness

+

The ChartControl will automatically expand to fit its container. If you wish to control the size of the chart, set its parent container size, or use the className property to pass your own CSS class and override the dimensions within that class.

+

Accessibility

+

As long as you provide labels for all your data elements, the ChartControl will render a hidden table. Users who are visually impaired and use a screen reader will hear a description of the data in the chart.

+

You can improve the accessible table by adding an alternateText, a caption and a summary. If you do not provide a caption, the control will attempt to use the chart's title.

+

For example:

+
<ChartControl type={ChartType.Bar}
+              accessible={{
+                alternateText: 'Text alternative for this canvas graphic is in the data table below.',
+                summary: 'This is the text alternative for the canvas graphic.',
+                caption: 'Votes for favorite pets'
+              }}
+              data={{
+                    labels: ["Dog", "Cat", "Hamster", "Gerbil", "Hedgehog", "Platypus"],
+                    datasets: [{
+                        label: '# of Votes',
+                        data: [12, 19, 3, 5, 2, 3]
+                    }]
+                }}
+                options={{
+                    scales: {
+                        yAxes: [{
+                            ticks: {
+                                beginAtZero:true
+                            }
+                        }]
+                    }
+                }} />
+
+ +

Implementation

+

ChartControl Properties

+

The ChartControl can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
accessibilityIChartAccessibilitynoOptional property to specify the accessibility options.
classNamestringnoOptional property to specify a custom class that allows you to change the chart's styles.
dataChartDatanoThe data you wish to display.
datapromisePromisenoThe promise to load data asynchronously. Use with loadingtemplate and rejectedtemplate
loadingtemplateJSX.Element
() => JSX.Element
noThe HTML to display while waiting to resolve the datapromise
optionsChartOptionsnoOptional property to set the chart's additional options.
paletteChartPalettenoOptional property to set the desired Office color paette
pluginsobject[]noOptional property to set an array of objects implementing the IChartPlugin interface
rejectedtemplateJSX.Element
() => JSX.Element
noThe HTML to display if the datapromise promise returns an error.
useThemebooleannoOptional property to set whether the ChartControl should attempt to use theme colors. Setting it to false will use the startard Chart.js colors and fonts.
typeChartType or stringyesThe type of chart you wish to render. You can also use the string equivalent.
onClick(event?: MouseEvent, activeElements?: Array<{}>) => voidnoOptional callback method that get called when a user clicks on the chart
onHover(chart: Chart, event: MouseEvent, activeElements: Array<{}>) => voidnoOptional callback method that get called when a user hovers the chart
onResize(chart: Chart, newSize: ChartSize) => voidnoOptional callback method that get called when the window containing the ChartXontrol resizes
+

You can call the following methods to interact with the chart after it has been initialized:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodTypeDescription
clearvoidWill clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
getCanvas() => HTMLCanvasElementReturn the canvass element that contains the chart
getChart() => ChartReturns the Chart.js instance
getDatasetAtEvent(e: MouseEvent) => Array<{}>Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting
getElementAtEvent(e: MouseEvent) => {}Calling getElementAtEvent(event) passing an argument of an event will return the single element at the event position. For example, you can use with onClick event handlers.
getElementsAtEvent(e: MouseEvent) => Array<{}>Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting. Calling getElementsAtEvent(event) passing an argument of an event will return the point elements that are at that the same position of that event.
renderChart(config: {}) => voidTriggers a redraw of all chart elements. Note, this does not update elements for new data. Use .update() in that case.
stopvoidUse this to stop any current animation loop. This will pause the chart during any current animation frame.
toBase64Image() => stringReturns a base 64 encoded string of the chart in it's current state.
update(config?: number | boolean | string) => voidTriggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart.
+

ChartType

+

Defines the type of chart that will be rendered. For more information what data structure is required for each type of chart, review the Chart.js documentation ( links below ).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameChart.js EquivalentDescription
BarbarVertical bar chart
BubblebubbleBubble chart
DoughnutdoughnutDoughnut chart
HorizontalBarhorizontalBarHorizontal bar chart
LinelineLine chart
PiepiePie chart
PolarAreapolarAreaPolar area chart
RadarradarRadar chart
ScatterscatterScatter graph
+

IChartAccessibility

+

The IChartAccessibility interface implements the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
alternateTextstringnoOptional property to provide an accessible alternate text for the chart. We recommend that you use this property with summary
classNamestringnoOptional property to specify a custom CSS class for the accessible table.
captionstringnoOptional property to provide a caption for the accessible table.
enablebooleannoOptional property to turn on or off the rendering of the accessible table.
summarystringnoOptional property to specify the chart's summary. We recommend that you use this property with alternateText
onRenderTable() => JSX.ElementnoOptions callback method that allows you to override the accessible table.
+

ChartPalette

+

Defines one of the possible Office color palette to use in a chart. The color palettes are the same that you find within Office.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameOffice NameDescriptionExample
OfficeColorful1Office Colorful Palette 1Blue, Orange, Grey, Gold, Blue, GreenOffice Colorful 1
OfficeColorful2Office Colorful Palette 2Blue, Grey, Blue, Dark Blue, Dark Grey, Dark BlueOffice Colorful 2
OfficeColorful3Office Colorful Palette 3Orange, Gold, Green, Brown, Dark Yellow, Dark GreenOffice Colorful 3
OfficeColorful4Office Colorful Palette 4Green, Blue, Gold, Dark Green, Dark Blue, Dark YellowOffice Colorful 4
OfficeMonochromatic1Monochromatic Palette 1Blue gradient, dark to lightOffice Monochromatic 1
OfficeMonochromatic2Monochromatic Palette 2Orange gradient, dark to lightOffice Monochromatic 2
OfficeMonochromatic3Monochromatic Palette 3Grey gradient, dark to lightOffice Monochromatic 3
OfficeMonochromatic4Monochromatic Palette 4Gold gradient, dark to lightOffice Monochromatic 4
OfficeMonochromatic5Monochromatic Palette 5Blue gradient, dark to lightOffice Monochromatic 5
OfficeMonochromatic6Monochromatic Palette 6Green gradient, dark to lightOffice Monochromatic 6
OfficeMonochromatic7Monochromatic Palette 7Dark Grey, Light Grey, Grey, Dark Grey, Light Grey, GreyOffice Monochromatic 7
OfficeMonochromatic8Monochromatic Palette 8Blue gradient, light to darkOffice Monochromatic 8
OfficeMonochromatic9Monochromatic Palette 9Orange gradient, light to darkOffice Monochromatic 9
OfficeMonochromatic10Monochromatic Palette 10Grey gradient, light to darkOffice Monochromatic 10
OfficeMonochromatic11Monochromatic Palette 11Gold gradient, light to darkOffice Monochromatic 11
OfficeMonochromatic12Monochromatic Palette 12Blue gradient, light to darkOffice Monochromatic 12
OfficeMonochromatic13Monochromatic Palette 13Green gradient, light to darkOffice Monochromatic 13
+

IChartPlugin

+

The easiest way to customize a chart is to use the plugin functionality provided by Chart.js. In order to use a plugin, simply pass an array of objects that implement the IChartPlugin interface to the plugins property of the ChartControl.

+

If a hook is listed as cancellable, you can return false to cancel the event.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
afterDatasetsDraw(chartInstance: Chart, easing: string, options?: {}) => voidnoCalled after the datasets are drawn but after scales are drawn.
afterDatasetUpdate(chartInstance: Chart, options?: {}) => voidnoCalled after a dataset was updated.
afterDraw(chartInstance: Chart, easing: string, options?: {}) => voidnoCalled after an animation frame was drawn.
afterEvent(chartInstance: Chart, event: Event, options?: {}) => voidnoCalled after an event occurs on the chart.
afterInit(chartInstance: Chart, options?: {}) => voidnoCalled after a chart initializes
afterLayout(chartInstance: Chart, options?: {}) => voidnoCalled after the chart layout was rendered.
afterRender(chartInstance: Chart, options?: {}) => voidnoCalled after a rander.
afterTooltipDraw(chartInstance: Chart, tooltipData?: {}, options?: {}) => voidnoCalled after drawing the tooltip. Note that this hook will not be called if the tooltip drawing has been previously cancelled.
afterUpdate(chartInstance: Chart, options?: {}) => voidnoCalled after a chart updates
beforeDatasetsDraw(chartInstance: Chart, easing: string, options?: {}) => voidnoCalled before the datasets are drawn but after scales are drawn. Cancellable.
beforeDatasetUpdate(chartInstance: Chart, options?: {}) => voidnoCalled before a dataset is updated. Cancellable.
beforeDraw(chartInstance: Chart, easing: string, options?: {}) => voidnoCalled before an animation frame is drawn.
beforeEvent(chartInstance: Chart, event: Event, options?: {}) => voidnoCalled when an event occurs on the chart. Cancellable.
beforeInit(chartInstance: Chart, options?: {}) => voidnoCalled before a chart initializes
beforeLayout(chartInstance: Chart, options?: {}) => voidnoCalled before rendering the chart's layout. Cancellable.
beforeRender(chartInstance: Chart, options?: {}) => voidnoCalled at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw to do something on each animation frame. Cancellable.
beforeTooltipDraw(chartInstance: Chart, tooltipData?: {}, options?: {}) => voidnoCalled before drawing the tooltip. Cancellable. If it returns false, tooltip drawing is cancelled until another render is triggered.
beforeUpdate(chartInstance: Chart, options?: {}) => voidnoCalled before updating the chart. Cancellable.
destroy(chartInstance: Chart) => voidnoCalled when a chart is destroyed.
resize(chartInstance: Chart, newChartSize: Chart.ChartSize, options?: {}) => voidnoCalled when a chart resizes. Cancellable.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ComboBoxListItemPicker/index.html b/controls/ComboBoxListItemPicker/index.html new file mode 100644 index 000000000..5ffa193b0 --- /dev/null +++ b/controls/ComboBoxListItemPicker/index.html @@ -0,0 +1,1870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ComboBoxListItemPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ComboBoxListItemPicker control

+

This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value.

+

Here is an example of the control:

+

ComboBoxComboBoxListItemPicker

+

ComboBoxListItemPicker multiple selection

+

ComboBoxListItemPicker selected Items

+

ComboBoxListItemPicker selected Items (Multiple Options)

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ComboBoxListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
+
+ +
    +
  • Use the ComboBoxListItemPicker control in your code as follows:
  • +
+
<ComboBoxListItemPicker listId='da8daf15-d84f-4ab1-9800-7568f82fed3f'
+                        columnInternalName='Title'
+                        orderBy='Title asc'
+                        keyColumnInternalName='Id'
+                        filter="Title eq 'SPFx'"
+                        onSelectedItem={this.onSelectedItem}
+                        webUrl={this.context.pageContext.web.absoluteUrl}
+                        spHttpClient={this.context.spHttpClient} />
+
+ +
    +
  • Use the ComboBoxListItemPicker with objects passed in defaultSelectedItems
  • +
+
<ComboBoxListItemPicker listId='da8daf15-d84f-4ab1-9800-7568f82fed3f'
+                        columnInternalName='Title'
+                        keyColumnInternalName='Id'
+                        filter="Title eq 'SPFx'"
+                        defaultSelectedItems={[{Id: 2, Title:"Test"}]}
+                        onSelectedItem={this.onSelectedItem}
+                        webUrl={this.context.pageContext.web.absoluteUrl}
+                        spHttpClient={this.context.spHttpClient} />
+
+ +
    +
  • Or only ids
  • +
+
<ComboBoxListItemPicker listId='da8daf15-d84f-4ab1-9800-7568f82fed3f'
+                        columnInternalName='Title'
+                        keyColumnInternalName='Id'
+                        filter="Title eq 'SPFx'" 
+                        defaultSelectedItems={[2]}
+                        onSelectedItem={this.onSelectedItem}
+                        webUrl={this.context.pageContext.web.absoluteUrl}
+                        spHttpClient={this.context.spHttpClient} />
+
+ +
    +
  • The onSelectedItem change event returns the list items selected and can be implemented as follows:
  • +
+
private onSelectedItem(items: []) {
+    console.log("selected items:", items);
+}
+
+ +

If you can provide typing details to the implementation based on columnInternalName and keyColumnInternalName. +For example above:

+
columnInternalName='Title'
+keyColumnInternalName='Id'
+// ...
+private onSelectedItem(items: { Title: string, Id: string }[]) {
+    console.log("selected items:", items);
+}
+
+ +

If you use variables for columnInternalName and keyColumnInternalName the typing will look as follow:

+
const columnInternalName = 'Title';
+const keyColumnInternalName = 'Id';
+
+<ComboBoxListItemPicker listId='da8daf15-d84f-4ab1-9800-7568f82fed3f'
+                        columnInternalName={columnInternalName}
+                        keyColumnInternalName={keyColumnInternalName}
+                        filter="Title eq 'SPFx'" 
+                        defaultSelectedItems={[2]}
+                        onSelectedItem={this.onSelectedItem}
+                        webUrl={this.context.pageContext.web.absoluteUrl}
+                        spHttpClient={this.context.spHttpClient} />
+
+private onSelectedItem(items: { 
+    [columnInternalName]: string, 
+    [keyColumnInternalName]: string 
+  }[]) {
+    console.log("selected items:", items);
+}
+
+ +

Implementation

+

The ComboBoxListItemPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
columnInternalNamestringyesInternalName of column to search and get values.
keyColumnInternalNamestringnoInternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id
webUrlstringyesUrl to web hosting list
spHttpClientRequestClientyesAny implementation of PnPJS RequestClient
listIdstringyesGuid or title of the list.
onSelectedItem(items: any[]) => voidyesCallback function which returns the selected items.
classNamestringnoClassName for the picker.
defaultSelectedItemsany[]noInitial items that have already been selected and should appear in the people picker. Support objects and Ids only
suggestionsHeaderTextstringnoThe text that should appear at the top of the suggestion box.
noResultsFoundTextstringnoThe text that should appear when no results are returned.
disabledbooleannoSpecifies if the control is disabled or not.
filterstringnoCondition to filter list Item, same as $filter ODATA parameter
multiSelectbooleannoAllows multiple selection
onInitialized() => voidnoCalls when component is ready
itemLimitnumbernoMaximum number of items to be displayed in the combobox. Default: 100
labelstringnoSpecifies the text describing the combobox ListItemPicker.
orderBystringnoSpecifies the sequence of the items in the comboBox ,same as $orderBy ODATA parameter
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ContentTypePicker/index.html b/controls/ContentTypePicker/index.html new file mode 100644 index 000000000..e2a856139 --- /dev/null +++ b/controls/ContentTypePicker/index.html @@ -0,0 +1,1834 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentTypePicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ContentTypePicker control

+

This control allows you to select one or multiple available site content types or list content types.

+

Here is an example of the control:

+

ContentTypePicker initial

+

ContentTypePicker single selection mode:

+

ContentTypePicker single selection

+

ContentTypePicker multi selection mode:

+

ContentTypePicker multi selection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ContentTypePicker } from "@pnp/spfx-controls-react/lib/ContentTypePicker";
+
+ +
    +
  • Use the ContentTypePicker control in your code as follows:
  • +
+
<ContentTypePicker
+  context={this.props.context}
+  group="Content Feedback"
+  includeHidden={false}
+  includeReadOnly={false}
+  label="Select your content type"
+  multiSelect={false}
+  orderBy={ContentTypesOrderBy.Name}
+  listId="00000000-0000-0000-0000-000000000000"
+  onSelectionChanged={this.onContentTypePickerChanged}
+  showBlankOption={true}
+/>
+
+ +
    +
  • The onSelectionChanged change event returns the content type(s) and can be implemented as follows:
  • +
+
private onContentTypePickerChanged (contentTypes: ISPContentType | ISPContentType[]) {
+  console.log("Content types:", contentTypes);
+}
+
+ +

Implementation

+

The ContentTypePicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
listIdstringnoThe ID of the list or library you wish to select content type(s) from. When not specified, picker will be populated with site content types.
classNamestringnoIf provided, additional class name to provide on the dropdown element.
disabledbooleannoWhether or not the control is disabled.
includeHiddenbooleannoWhether or not to include hidden content types. Default is true.
includeReadOnlybooleannoWhether or not to include read-only content types. Default is true.
groupstringnoOnly show content types of a certain group.
filterstringnoFilter content types from OData query (takes the upperhand of hidden, readOnly and group Filters).
orderByContentTypesOrderBynoHow to order the content types.
selectedContentTypesstring | string[]noIDs of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed.
multiSelectbooleannoIndicates if multi-choice selections is allowed. Default is false.
labelstringnoThe label to display.
placeholderstringnoInput placeholder text. Displayed until option is selected.
onSelectionChanged(newValue: ISPContentType | ISPContentType[]): voidnoCallback issued when the selected option changes.
filterItems(contentTypes: ISPContentType[]): ISPContentType[]noThis function is invoked after the filtering has been done. This allows you to add additional custom filtering.
webAbsoluteUrlstringnoAbsolute Web Url of target site (user requires permissions).
showBlankOptionbooleannoWhether or not to show a blank option. Default is false. Works only when multiSelect is false.
+

Enum ContentTypesOrderBy

+ + + + + + + + + + + + + + +
Value
Name
Id
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Dashboard/index.html b/controls/Dashboard/index.html new file mode 100644 index 000000000..2f7a5b784 --- /dev/null +++ b/controls/Dashboard/index.html @@ -0,0 +1,2005 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dashboard - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Dashboard control

+

Dashboard component for Microsoft Teams.

+
+

Note

+

As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well.

+
+

Here is an example of the control in action:

+

Carousel control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { WidgetSize, Dashboard } from '@pnp/spfx-controls-react/lib/Dashboard';
+
+ +
    +
  • Use the Dashboard control in your code as follows:
  • +
+
const linkExample = { href: "#" };
+const customizedLinkExample = {
+      href: "#",
+      title: "This is a customized link!",
+      color: "red",
+      target: "_top"
+    };
+const calloutItemsExample = [
+  {
+    id: "action_1",
+    title: "Info",
+    icon: <Icon iconName={'Edit'} />,
+  },
+  { id: "action_2", title: "Popup", icon: <Icon iconName={'Add'} /> },
+];
+// ...
+<Dashboard
+  widgets={[{
+    title: "Card 1",
+    desc: "Last updated Monday, April 4 at 11:15 AM (PT)",
+    widgetActionGroup: calloutItemsExample,
+    size: WidgetSize.Triple,
+    body: [
+      {
+        id: "t1",
+        title: "Tab 1",
+        content: (
+          <Text>
+            Content #1
+          </Text>
+        ),
+      },
+      {
+        id: "t2",
+        title: "Tab 2",
+        content: (
+          <Text>
+            Content #2
+          </Text>
+        ),
+      },
+      {
+        id: "t3",
+        title: "Tab 3",
+        content: (
+          <Text>
+            Content #3
+          </Text>
+        ),
+      },
+    ],
+    link: linkExample,
+  },
+  {
+    title: "Card 2",
+    size: WidgetSize.Single,
+    link: customizedLinkExample,
+  },
+  {
+    title: "Card 3",
+    size: WidgetSize.Double,
+    link: linkExample,
+  }]} />
+
+ +

Implementation

+

The Dashboard component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
widgetsIWidget[]yesWidgets collection.
allowHidingWidgetbooleannoSpecifies if widgets can be hidden from the dashboard.
onWidgetHiding(widget: IWidget) => voidnoHandler of widget hiding event.
toolbarPropsIToolbarPropsnoDashboard toolbar props. See Toolbar.
WidgetContentWrapperReact.ComponentType\>noOptional component which wraps every Widget component. Useful for a custom error handling or styling.
+

Interface IWidget

+

Provides settings of Dashboard's widget

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
sizeWidgetSizeyesSize.
titlestringyesTitle.
descstringnoDescription.
widgetActionGroupIWidgetActionKey[]noActions.
controlOptionsIWidgetControlOptionsnoComponent rendering options.
bodyIWidgetBodyContent[]noWidget's content (children) rendered as tabs.
linkIWidgetLinknoWidget's link rendered at the bottom part of the widget.
+

Interface IWidgetActionKey

+

Provides Dashboard Widget Action properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringyesAction id.
iconJSX.ElementnoAction icon.
titlestringyesAction title.
onClick() => voidnoAction handler.
+

Interface IWidgetControlOptions

+

Provides Widget component options

+ + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
isHiddenbooleannoSpecifies if current widget is hidden.
+

Interface IWidgetBodyContent

+

Provides Widget content (tab) properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringyesContent (tab) id.
titlestringyesContent (tab) title.
contentReact.ReactNodeyesTab content.
+

Interface IWidgetLink

+

Provides Widget link properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
hrefstringyesLink to be opened.
titlestringnoThe text to display for the link, if not provided, the default text will be used.
colorstringnoThe color of the link, if not provided, the "default" color will be used. The available colors can be found on the official Fluent UI documentation of the Text control.
targetstringnoThe target property value for the generated anchor tag, if not provided, the default target will be _blank.
+

Enum WidgetSize

+

Provides size of the widget

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
SingleSingle-sized grid item.
DoubleDouble-width grid item.
TripleTriple width grid item.
QuadrupleQuadruple width grid item.
BoxDouble-width, double-height grid item.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/DateTimePicker/index.html b/controls/DateTimePicker/index.html new file mode 100644 index 000000000..da23e17c5 --- /dev/null +++ b/controls/DateTimePicker/index.html @@ -0,0 +1,1996 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DateTimePicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

DateTimePicker control

+

This control allows you to select dates from a calendar and optionally the time of day using dropdown controls. You can configure the control to use 12 or 24-hour clock.

+

Here are some examples of the control:

+

DateTime Picker 12-hour clock
+DateTimePicker 12-hour clock

+

DateTime Picker 24-hour clock
+DateTimePicker 24-hour clock

+

DateTime Picker Date Only
+DateTimePicker Date Only

+

DateTime Picker No Seconds
+DateTimePicker Date Only

+

DateTime Picker Dropdowns for Time Part
+DateTimePicker Date Only

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component. The DateConvention and TimeConvention controls if the time of day controls are shown and the time format used (12 hours/24 hours).
  • +
+
import { DateTimePicker, DateConvention, TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker';
+
+ +
    +
  • Use the DateTimePicker control in your code as follows, either as an uncontrolled or a controlled component:
  • +
+
// Uncontrolled
+<DateTimePicker label="DateTime Picker - 12h"
+                dateConvention={DateConvention.DateTime}
+                timeConvention={TimeConvention.Hours12} />
+
+// Controlled
+<DateTimePicker label="DateTime Picker - 24h"
+                dateConvention={DateConvention.DateTime}
+                timeConvention={TimeConvention.Hours24}
+                value={this.state.date}
+                onChange={this.handleChange} />
+
+ +

Implementation

+

The DateTimePicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
labelstringnoProperty field label displayed on top.
disabledbooleannoSpecifies if the control is disabled or not.
formatDatefunctionnoDefines a formatDate function that can override the output value in Date picker.
parseDateFromStringfunctionnoOptional method to parse the text input value to date, it is only useful when allowTextInput is set to true
dateConventionDateConventionnoDefines the date convention to use. The default is date and time.
timeConventionTimeConventionnoDefines the time convention to use. The default value is the 24-hour clock convention.
firstDayOfWeekDayOfWeeknoSpecify the first day of the week for your locale.
firstWeekOfYearFirstWeekOfYearnoDefines when the first week of the year should start.
keystringnoA unique key that indicates the identity of this control
onGetErrorMessagefunctionnoThe method is used to get the validation error message and determine whether the input value is valid or not. See this documentation to learn how to use it.
showGoToTodaybooleannoControls whether the "Go to today" link should be shown or not
isMonthPickerVisiblebooleannoControls whether the month picker is shown beside the day picker or hidden.
showMonthPickerAsOverlaybooleannoShow month picker on top of date picker when visible.
showWeekNumbersbooleannoControls whether the calendar should show the week number (weeks 1 to 53) before each week row
allowTextInputbooleannoWhether the user is allowed to enter a date as text instead of picking one from the date picker.
stringsIDatePickerStringsnoLocalized strings to use in the DateTimePicker
valueDatenoDefault value of the DatePicker, if any
onChangefunctionnoCallback issued when date or time is changed
showSecondsbooleannoSpecifies, if seconds dropdown should be shown, defaults to false.
timeDisplayControlTypeTimeDisplayControlTypenoSpecifies what type of control to use when rendering time part.
showLabelsbooleannoSpecifies if labels in front of date and time parts should be rendered.
placeholderstringnoPlaceholder text for the DatePicker.
initialPickerDateDatenoThe initially highlighted date in the calendar picker
maxDateDatenoThe maximum allowable date.
minDateDatenoThe minimum allowable date.
minutesIncrementStepMinutesIncrementnoSpecifies minutes' increment step for TimeDisplayControlType.Dropdow
showClearDatebooleannoControls whether the clearDate iconbutton must be available when date is selected, default to false
showClearDateIconstringnoControls the icon used for clearDate iconbutton. Defaults to 'RemoveEvent'
restrictedDatesDate[]noIf set the Calendar will not allow selection of dates in this array.
+

Enum TimeDisplayControlType

+ + + + + + + + + + + + + + + + + +
NameDescription
TextRenders Time part as Masked Edit
DropdownRenders Time part as Dropdown
+

Enum DateConvention

+ + + + + + + + + + + + + + + + + +
NameDescription
DateTimeShows the date and time picker
DateShows only the date picker
+

Enum TimeConvention

+ + + + + + + + + + + + + + + + + +
NameDescription
Hours12Specify the hours in 12-hours (AM / PM) time convention.
Hours24Specify the hours in 24-hours time convention.
+

Interface IDateTimePickerStrings extends IDatePickerStrings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
dateLabelstringnoLabel for the date selector.
timeLabelstringnoLabel for the time of day selector.
timeSeparatorstringnoSeparator between time of day components (hours, minutes, seconds).
amDesignatorstringnoUsed as AM designator when 12-hour clock is used.
pmDesignatorstringnoUsed as PM designator when 12-hour clock is used.
textErrorMessagestringnoError message when text is entered in the date picker.
+

Type MinutesIncrement

+
type MinutesIncrement = 1 | 5 | 10 | 15 | 30;
+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/DragDropFiles/index.html b/controls/DragDropFiles/index.html new file mode 100644 index 000000000..4e1aa823e --- /dev/null +++ b/controls/DragDropFiles/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DragDropFiles - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

DragDropFiles

+

This control allows to drag and drop files in pre defined areas.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { DragDropFiles } from "@pnp/spfx-controls-react/lib/DragDropFiles";
+
+ +
    +
  • Use the DragDropFiles control in your code as follows:
  • +
+
<DragDropFiles 
+          dropEffect="copy" 
+          enable={true}  
+          onDrop={this._getDropFiles}
+          iconName="Upload"
+          labelMessage= "My custom upload File"
+          >
+  {/* Specify the components to load where Drag and drop area should work */}
+</DragDropFiles>
+
+ +

Content with drag and drop applied

+
 <DragDropFiles 
+          dropEffect="copy" 
+          enable={true}  
+          onDrop={this._getDropFiles}
+          iconName="Upload"
+          labelMessage= "My custom upload File"
+          >
+          Drag and drop here...
+
+          </DragDropFiles>
+
+ +

Custom html with drag and drop

+

ListView with drag and drop applied

+

ListView control with drag and drop Control

+

FilePicker with drag and drop applied

+

FilePicker control with grouping

+
    +
  • With the onDrop handler you can define a method that returns files and files inside folders that where drag and drop by user.
  • +
+

PS: New property "fullPath" was included in file object to allow identify dropped files based on Folders, this allow users to create associated folder path.

+
private _getDropFiles = (files) => {
+    for (var i = 0; i < files.length; i++) {
+      console.log("Filename: " + files[i].name);
+      console.log("Path: " + files[i].fullPath);
+    }
+  }
+
+ +

Implementation

+

The DragDropFiles can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
dropEffectstringnoVisual feedback given to user during a drag and drop operation (copy,move,link,none). Default value is copy.
enablebooleannoOption allow control to be enable or disable. Default value is true
labelMessagestringnoMessage displayed in drag drop preview.
onDropanynoMethod that returns all Files[] from drag and drop file area.
iconNamestringnoIcon Name from Office UI Fabric Icons.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/DynamicForm/index.html b/controls/DynamicForm/index.html new file mode 100644 index 000000000..90364c540 --- /dev/null +++ b/controls/DynamicForm/index.html @@ -0,0 +1,1909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DynamicForm - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

Dynamic Form

+

This control can dynamically generate SharePoint list or SharePoint document library form and everything controlled through list setting.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { DynamicForm } from "@pnp/spfx-controls-react/lib/DynamicForm";
+
+ +
    +
  • Use the DynamicForm control in your code as follows:
  • +
+
<DynamicForm 
+          context={this.props.context} 
+          listId={"3071c058-549f-461d-9d73-8b9a52049a80"}  
+          listItemId={1}
+          onCancelled={() => { console.log('Cancelled') }}
+          onBeforeSubmit={async (listItem) => { return false; }}
+          onSubmitError={(listItem, error) => { alert(error.message); }}
+          onSubmitted={async (listItemData) => { console.log(listItemData); }}>
+</DynamicForm>
+
+ +

DynamicForm

+

File selection

+

To upload a file when creating a new document in a document library you need to specify: +- enableFileSelection: Set this parameter to true to enable file selection. +- contentTypeId: This parameter specifies the target content type ID of the document you are creating. +- supportedFileExtensions: This parameter is optional and is used to specify the supported file extensions if they are different from the default ones.

+

Enabling the file selection will display a new button on top of the form that allow the user to select a file from the recent files, browsing OneDrive or select and upload a file from the computer.

+

DynamicFormWithFileSelection

+

Implementation

+

The DynamicForm can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
listIdstringyesGuid of the list.
listItemIdnumbernolist item ID.
contentTypeIdstringnocontent type ID
disabledbooleannoAllows form to be disabled. Default value is false
disabledFieldsstring[]noInternalName of fields that should be disabled. Default value is false
enableFileSelectionbooleannoSpecify if the form should support the creation of a new list item in a document library attaching a file to it. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document. Default value is false
fieldOrderstring[]noList of fields internal names. Specifies fields custom sorting.
hiddenFieldsstring[]noInternalName of fields that should be hidden. Default value is false
onListItemLoaded(listItemData: any) => Promise<void>noList item loaded handler. Allows to access list item information after it's loaded.
onBeforeSubmit(listItemData: any) => Promise<boolean>noBefore submit handler. Allows to modify the object to be submitted or cancel the submission. To cancel, return true.
onSubmitted(listItemData: any, listItem?: IItem) => voidnoMethod that returns listItem data JSON object and PnPJS list item instance (IItem).
onSubmitError(listItemData: any, error: Error) => voidnoHandler of submission error.
onCancelled() => voidnoHandler when form has been cancelled.
returnListItemInstanceOnSubmitbooleannoSpecifies if onSubmitted event should pass PnPJS list item (IItem) as a second parameter. Default - true
supportedFileExtensionsstring[]noSpecify the supported file extensions for the file picker. Only used when enableFileSelection is true. Default value is ["docx", "doc", "pptx", "ppt", "xlsx", "xls", "pdf"].
webAbsoluteUrlstringnoAbsolute Web Url of target site (user requires permissions).
fieldOverrides{[columnInternalName: string] : {(fieldProperties: IDynamicFieldProps): React.ReactElement\<IDynamicFieldProps>}}noKey value pair for fields you want to override. Key is the internal field name, value is the function to be called for the custom element to render.
respectEtagbooleannoSpecifies if the form should respect the ETag of the item. Default - true
saveDisabledbooleannoSpecifies if save button is disabled.
validationErrorDialogPropsIValidationErrorDialogPropsnoSpecifies validation error dialog properties
customIcons{ [ columnInternalName: string ]: string }noSpecifies custom icons for the form. The key of this dictionary is the column internal name, the value is the Fluent UI icon name.
storeLastActiveTabbooleannoWhen uploading files: Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default - true
folderPathstringnoServer relative or library relative folder to create the item in. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document or Folder. Defaults to the root folder of the library.
+

Validation Error Dialog Properties IValidationErrorDialogProps

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
showDialogOnValidationErrorbooleannoSpecifies if the dialog should be shown on validation error. Default - false
customTitlestringnoSpecifies a custom title to be shown in the validation dialog. Default - empty
customMessagestringnoSpecifies a custom message to be shown in the validation dialog. Default - empty
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/EnhancedThemeProvider/index.html b/controls/EnhancedThemeProvider/index.html new file mode 100644 index 000000000..b70b82d85 --- /dev/null +++ b/controls/EnhancedThemeProvider/index.html @@ -0,0 +1,1798 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EnhancedThemeProvider - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Enhanced Theme Provider

+

The reasons behind this control are many and concern the use of Fluent UI controls currently officially supported by SPFx, that is:

+
    +
  • Problems with Teams theme support, when hosting a web part like Tab or Personal App and specifically the lack of support by this version of Fluent UI React of the high contrast theme.
  • +
  • Lack of basic style, such as fonts, for basic HTML elements when creating web parts hosted in Teams as Tabs or personal App.
  • +
  • Lack of basic style, such as fonts, for basic HTML elements when creating web parts in "isDomainIsolated" mode, aka the Isolated web parts.
  • +
+

Therefore, the control is to be considered as a sort of wrapper for all react and non-react controls that you want to add to the web part.

+

The control extends the functionality of the Fluent UI ThemeProvider control (currently in version 7) by adding some logic thanks to the information contained in the 'context' property, that is:

+
    +
  • If the web part is hosted inside SharePoint, the theme passed through the 'Theme' property will be used or the default one of the current site will be taken.
  • +
  • If the web part is hosted within Teams, the "Theme" property will be ignored and using the "Context" property checks which theme is currently applied and adds a handler to notify when the theme is changed. This allows you to manage the change of theme in Teams in real-time, without having to reload the Tab or the Personal App.
  • +
+

Example of use in SharePoint in a SharePointFullPage - Isolated web parts (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control): +Enhanced Theme Provider - SharePointFullPage - Isolated web parts

+

As for Teams, given the inconsistency of the theme system of Fluent UI NorthStar (used in Teams) and Fluent UI React (used by SPFx), the themes are "emulated".

+

The control contains the refining of Teams' Default, Dark and Hight Contrast themes.

+

The Default and Dark themes were created simply using the Fluent UI Themes designer and the primary colors of their corresponding Teams themes.

+

For the Hight Contrast theme, on the other hand, given the complexity of creating a completely new theme and above all in Hight Contrast mode (neither supported nor gives SharePoint nor gives Fluent UI v7), it was decided to create the theme by hand and support only "main controls".

+

This means that this theme is not perfect and above all not all controls will be displayed correctly.

+

This is not a big deal, as the same theme provided by SharePoint has the same problems, it does not support Hight Contrast rendering for all controls.

+

For the Hight Contrast theme (in Teams), only these controls are supported by this control: ChoiceGroup, Checkbox, ComboBox, DatePicker, SpinButton, TextField, Toggle, PrimaryButton, DefaultButton, CompoundButton, IconButton, other fluent controls may have color rendering problems.

+

Example of use in Teams as a TeamsPersonalApp (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control): +Enhanced Theme Provider - TeamsPersonalApp / TeamsTab

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the EnhancedThemeProvider control as follows:
  • +
+
import { EnhancedThemeProvider, getDefaultTheme, useTheme, ThemeContext } from "@pnp/spfx-controls-react/lib/EnhancedThemeProvider";
+
+ +
    +
  • Example on use the EnhancedThemeProvider control with only required properties:
  • +
+
<EnhancedThemeProvider context={this.props.context}>
+  {/* controls to apply the theme to */}
+</EnhancedThemeProvider>
+
+ +
    +
  • Example on use the EnhancedThemeProvider control with the most important properties:
  • +
+
<EnhancedThemeProvider applyTo="element" context={this.props.context} theme={this.props.themeVariant}>
+  {/* controls to apply the theme to */}
+</EnhancedThemeProvider>
+
+ +

The control provides the passage and/or creation of the theme according to what has been said before. +In order to access the theme, from child controls, there are two modes, one for function-based controls, one for class-based controls.

+
    +
  • Access the theme from the child control using a function component:
  • +
+
export const ChildFunctionComponent = () => {
+  const theme = useTheme();
+
+  return (
+    <DefaultButton theme={theme}>Example Child Control</DefaultButton>
+  );
+}
+
+ +
    +
  • Access the theme from the child control using a class component:
  • +
+
export class ChildClassComponent extends React.Component {
+  public render() {
+    return (
+      <ThemeContext.Consumer>
+        {theme =>
+          <DefaultButton theme={theme}>Example Child Control</DefaultButton>
+        }
+      </ThemeContext.Consumer>
+    )
+  }
+};
+
+ +
    +
  • Usage example using theme in child controls:
  • +
+
<EnhancedThemeProvider applyTo="element" context={this.props.context} theme={this.props.themeVariant}>
+  <ChildFunctionComponent />
+  <ChildClassComponent />
+</EnhancedThemeProvider>
+
+ +

Implementation

+

The EnhancedThemeProvider control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesSets the context from the SPFx component (a web part, an application customizer or a form customizer).
asReact.ElementTypenoA component that should be used as the root element of the ThemeProvider component.
refReact.RefnoOptional ref to the root element.
themePartialTheme | ThemenoDefines the theme provided by the user.
rendererStyleRenderernoOptional interface for registering dynamic styles. Defaults to using merge-styles. Use this to opt into a particular rendering implementation, such as emotion, styled-components, or jss. Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation.
applyTo'element' | 'body' | 'none'noDefines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of ThemeProvider. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FieldCollectionData/index.html b/controls/FieldCollectionData/index.html new file mode 100644 index 000000000..88b3ad5b5 --- /dev/null +++ b/controls/FieldCollectionData/index.html @@ -0,0 +1,2089 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldCollectionData - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldCollectionData control

+

This control gives you the ability to insert a list / collection data which can be used in your web part / application customizer. For example: you want to specify multiple locations for showing a weather information.

+

The control allows you to specify multiple data types like: string, number, boolean, or dropdown. It also provides the possibility to render custom field.

+

FieldCollectionData

+

Code editor initial

+

The type of data you get returned depends on the fields you defined. For the example above, the data looks like this:

+
[
+  { 
+    "Field1": "String value", "Field2": "123", "Field3": "https://pnp.github.io/", "Field4": true
+  }
+]
+
+ +

How to use this control in your solutions

+
    +
  1. Check that you installed the @pnp/spfx-controls-react dependency. Check out The getting started page for more information about installing the dependency.
  2. +
  3. Import the following modules to your component:
  4. +
+
import { FieldCollectionData, CustomCollectionFieldType } from '@pnp/spfx-controls-react/lib/FieldCollectionData';
+
+ +
    +
  1. Add the control to the render method:
  2. +
+
<FieldCollectionData 
+  key={"FieldCollectionData"} 
+  label={"Fields Collection"} 
+  manageBtnLabel={"Manage"} onChanged={(value) => { console.log(value); }}
+  panelHeader={"Manage values"}
+
+  executeFiltering={(searchFilter: string, item: any) => {
+    return item["Field2"] === +searchFilter;
+  }}
+  itemsPerPage={3}
+  fields={[
+    {id: "Field1", title:"String field", type: CustomCollectionFieldType.string, required: true},
+    {id: "Field2", title:"Number field", type: CustomCollectionFieldType.number},
+    {id: "Field3", title:"URL field", type: CustomCollectionFieldType.url},
+    {id: "Field4", title:"Boolean field", type: CustomCollectionFieldType.boolean}
+  ]}
+  value={[
+    { 
+      "Field1": "String value", "Field2": "123", "Field3": "https://pnp.github.io/", "Field4": true
+    }
+  ]}
+/>
+
+ +

Sample of custom field rendering

+

Here is an example of how you can render your own controls in the FieldCollectionData control:

+
{
+  id: "customFieldId",
+  title: "Custom Field",
+  type: CustomCollectionFieldType.custom,
+  onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
+    return (
+      React.createElement("div", null,
+        React.createElement("input", { key: itemId, value: value, onChange: (event: React.FormEvent<HTMLInputElement>) => {
+          if (event.currentTarget.value === "error") {
+            onError(field.id, "Value shouldn't be equal to error");
+          } else {
+            onError(field.id, "");
+          }
+          onUpdate(field.id, event.currentTarget.value);
+        }}), " 🎉"
+      )
+    );
+  }
+}
+
+ +

Implementation

+

The FieldCollectionData control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault Value
keystringyesAn unique key that indicates the identity of this control.
labelstringnoProperty field label displayed on top.
panelHeaderstringyesLabel to be used as the header in the panel.
panelDescriptionstringnoProperty that allows you to specify a description in the collection panel.
manageBtnLabelstringyesLabel of the button to open the panel.
saveBtnLabelstringnoLabel of the save button.
saveAndAddBtnLabelstringyesLabel of the save and add button.
cancelBtnLabelstringyesLabel of the cancel button.
fieldsICustomCollectionField[]yesThe fields to be used for the list of collection data.
valueany[]yesThe collection data value.
enableSortingbooleannoSpecify if you want to be able to sort the items in the collection.false
disabledbooleannoSpecify if the control is disabled.false
disableItemCreationbooleannoAllows you to specify if user can create new items.false
disableItemDeletionbooleannoAllows you to specify if users can delete already inserted items.false
panelClassNamestringnoAllows you to specify a custom CSS class name for the collection data panel.
tableClassNamestringnoAllows you to specify a custom CSS class name for the collection data table inside the panel.
itemsPerPagenumbernoAllows you to specify the amount of items displayed per page. Paging control is added automatically.
executeFiltering(searchFilter: string, item: any) => booleannoAllows you to show Search Box and specify own filtering logic.
panelPropsIPanelPropsnoAllows you to pass in props of the panel such as type and customWidth to control the underlying panel.
contextBaseComponentContextnoNeeded if peoplepicker field type is used
usePanelbooleannoSpecify if you want the control to opened in a panel or directly on the page (only useful within webpart)true
noDataMessagestringnoSpecify the message when no items are added to the collection
+

Interface ICustomCollectionField

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringyesID of the field.
titlestringyesTitle of the field. This will be used for the label in the table.
typeCustomCollectionFieldTypeyesSpecifies the type of field to render.
disableEditbooleannoAllows you to specify if a field is disabled for editing.
requiredbooleannoSpecify if the field is required.
optionsIDropdownOption[] IComboboxOption[]noDropdown options. Only necessary when dropdown or combobox type is used.
onRenderOptionIRenderFunctionnoDropdown custom options render method. Only for the dropdown field type.
placeholderstringnoPlacehoder text which will be used for the input field. If not provided the input title will be used.
defaultValueanynoSpecify a default value for the input field.
deferredValidationTimenumbernoField will start to validate after users stop typing for deferredValidationTime milliseconds. Default: 200ms.
onGetErrorMessage(value: any, index: number, crntItem: any): string | PromisenoThe method is used to get the validation error message and determine whether the input value is valid or not. It provides you the current row index and the item you are currently editing.
onCustomRender(field: ICustomCollectionField, value: any, onUpdate: (fieldId: string, value: any) => void, item: any, itemUniqueId: string, onCustomFieldValidation: (fieldId: string, errorMessage: string) => void) => JSX.ElementnoThis property is only required if you are using the custom field type and it can be used to specify the custom rendering of your control in the collection data.
multiSelectbooleannoSpecifies multiple options can be selected (combobox) or mutliple users can be selected (peoplepicker)
allowFreeformbooleannoSpecifies that own options can be entered. Only for combobox field type
minimumUsersnumbernoSpecifies the minimum number of users to be entered for peoplepicker field type
minimumUsersMessagestringnoSpecifies the message to be displayed if minimumUsers are not entered for peoplepicker field type
maximumUsersnumbernoSpecifies the maximum number of users to be entered for peoplepicker field type
+

Enum CustomCollectionFieldType

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription
stringText field
numberNumber field
booleanCheckbox
dropdownDropdown field. You will have to specify the options property when using this field type
comboboxCombobox field. You wil have to specify the options property, optional specify allowFreeform and multiSelect
fabricIconName of the Office UI Fabric icon
urlURL field
peoplepickerPeoplepicker control
customThis gives you control over the whole field rendering. Be sure to provide the onCustomRender method to render your control in the collection data.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FieldPicker/index.html b/controls/FieldPicker/index.html new file mode 100644 index 000000000..aefdc1481 --- /dev/null +++ b/controls/FieldPicker/index.html @@ -0,0 +1,1834 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldPicker control

+

This control allows you to select one or multiple available site fields or list fields.

+

Here is an example of the control:

+

FieldPicker initial

+

FieldPicker single selection mode:

+

FieldPicker single selection

+

FieldPicker multi selection mode:

+

FieldPicker multi selection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { FieldPicker } from "@pnp/spfx-controls-react/lib/FieldPicker";
+
+ +
    +
  • Use the FieldPicker control in your code as follows:
  • +
+
<FieldPicker
+  context={this.props.context}
+  group="Content Feedback"
+  includeHidden={false}
+  includeReadOnly={false}
+  label="Select your field(s)"
+  multiSelect={false}
+  orderBy={FieldsOrderBy.Title}
+  listId="00000000-0000-0000-0000-000000000000"
+  onSelectionChanged={this.onFieldPickerChanged}
+  showBlankOption={true}
+/>
+
+ +
    +
  • The onSelectionChanged change event returns the field(s) and can be implemented as follows:
  • +
+
private onFieldPickerChanged (fields: ISPField | ISPField[]) {
+  console.log("Fields:", fields);
+}
+
+ +

Implementation

+

The FieldPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
listIdstringnoThe ID of the list or library you wish to select a column(s) from. When not specified, picker will be populated with site columns.
classNamestringnoIf provided, additional class name to provide on the dropdown element.
disabledbooleannoWhether or not the control is disabled.
includeHiddenbooleannoWhether or not to include hidden fields. Default is true.
includeReadOnlybooleannoWhether or not to include read-only fields. Default is true.
groupstringnoOnly show fields of a certain group.
filterstringnoFilter fields from OData query (takes the upperhand of hidden, readOnly and group Filters).
orderByFieldsOrderBynoHow to order the fields.
selectedFieldsstring | string[]noInternal names of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed.
multiSelectbooleannoIndicates if multi-choice selections is allowed. Default is false.
labelstringnoThe label to display.
placeholderstringnoInput placeholder text. Displayed until option is selected.
onSelectionChanged(newValue: ISPField | ISPField[]): voidnoCallback issued when the selected option changes.
filterItems(fields: ISPField[]): ISPField[]noThis function is invoked after the filtering has been done. This allows you to add additional custom filtering.
webAbsoluteUrlstringnoAbsolute Web Url of target site (user requires permissions).
showBlankOptionbooleannoWhether or not to show a blank option. Default is false. Works only when multiSelect is false.
+

Enum FieldsOrderBy

+ + + + + + + + + + + + + + +
Value
Title
InternalName
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FilePicker/index.html b/controls/FilePicker/index.html new file mode 100644 index 000000000..0d6a9f533 --- /dev/null +++ b/controls/FilePicker/index.html @@ -0,0 +1,2019 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FilePicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FilePicker control

+

File picker control allows to browse and select a file from various places. +Currently supported locations +- Recent files - tab allows to select a file from recently modified files based on the search results. +- Web search - tab uses Bing cognitive services to look for a file. (Only images) +- OneDrive - tab allows to select a file from the user's One Drive. +- Site document libraries - tab allows to select a file from the existing site document libraries. +- Upload - tab allows to upload a file from local drive. +- Multi-Upload - tab allows to upload multiple files from local drive. +- From a link - tab allows to paste a link to the document.

+

Overview

+

The control supports all types of file, however it also allows to specify list of extensions for the files that are going to be looked displayed. Currently, only single file selection is supported. +File Picker overview

+

Different display types

+

File picker support 3 types of views : List, Compact list and Tiles. In case Tiles view is selected, the control shows the thumbnail of the file. +File Picker views

+ +

The control displays breadcrumb navigation that allows to easily switch folders or document libraries. +File Picker breadcrumb

+

Paged data load

+

File picker doesn't load all the files that exist in the folder. Instead, it allows to specify how many results are loaded in a batch, and executes paged requests when new data is required. +File Picker paged data load

+

How to use this control

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following module to your component:
  • +
+
import { FilePicker, IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker';
+
+ +
    +
  • Use the FilePicker control in your code as follows:
  • +
+
<FilePicker
+  bingAPIKey="<BING API KEY>"
+  accepts= {[".gif", ".jpg", ".jpeg", ".bmp", ".dib", ".tif", ".tiff", ".ico", ".png", ".jxr", ".svg"]}
+  buttonIcon="FileImage"
+  onSave={(filePickerResult: IFilePickerResult[]) => { this.setState({filePickerResult }) }}
+  onChange={(filePickerResult: IFilePickerResult[]) => { this.setState({filePickerResult }) }}
+  context={this.props.context}
+/>
+
+ +
    +
  • Sample onSave handler:
  • +
+
  private _onFilePickerSave = async (filePickerResult: IFilePickerResult[]) => {
+    this.setState({ filePickerResult: filePickerResult });
+    if (filePickerResult && filePickerResult.length > 0) {
+      for (var i = 0; i < filePickerResult.length; i++) {
+        const item = filePickerResult[i];
+        const fileResultContent = await item.downloadFileContent();
+        console.log(fileResultContent);
+      }
+    }
+  }
+
+ +

Implementation

+

The FilePicker component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
labelstringnoSpecifies the text describing the file picker.
buttonLabelstringnoSpecifies the label of the file picker button.
buttonIconstringnoIn case it is provided the file picker will be rendered as an action button.
buttonIconPropsIIconPropsnoIn case it is provided the file picker will be rendered as an Icon the and all can define Properties for Icon
defaultFolderAbsolutePathstringnoOptional string parameter to set a default active folder/library for the SiteFilesTab. E.g. "https://contoso.sharepoint.com/teams/siteName/documentLibrary/Folder 1/SubFolder 1"
onSave(filePickerResult: IFilePickerResult[]) => voidyesHandler when the file has been selected and picker has been closed.
onChange(filePickerResult: IFilePickerResult[]) => voidnoHandler when the file selection has been changed.
onCancel() => voidnoHandler when file picker has been cancelled.
contextBaseComponentContextyesCurrent context.
acceptsstring[]noArray of strings containing allowed files extensions. E.g. [".gif", ".jpg", ".jpeg", ".bmp", ".dib", ".tif", ".tiff", ".ico", ".png", ".jxr", ".svg"]
requiredbooleannoSets the label to inform that the value is required.
bingAPIKeystringnoUsed to execute WebSearch. If not provided SearchTab will not be available. The API key can be created on a Azure account (Bing image search API), a free version exist for 1000 query per month (Pricing)
disabledbooleannoSpecifies if the picker button is disabled
hiddenbooleannoSpecifies if the picker button is hidden (if hidden, panel visibility can still be controlled with isPanelOpen)
itemsCountQueryLimitnumbernoNumber of items to obtain when executing REST queries. Default 100.
hideRecentTabbooleannoSpecifies if RecentTab should be hidden.
hideWebSearchTabbooleannoSpecifies if WebSearchTab should be hidden.
hideStockImagesbooleannoSpecifies if StockImagesTab should be hidden.
hideOrganisationalAssetTabbooleannoSpecifies if OrganisationalAssetTab should be hidden.
hideOneDriveTabbooleannoSpecifies if OneDriveTab should be hidden.
hideSiteFilesTabbooleannoSpecifies if SiteFilesTab should be hidden.
hideLocalUploadTabbooleannoSpecifies if LocalUploadTab should be hidden.
hideLocalMultipleUploadTabbooleannoSpecifies if LocalMultipleUploadTab should be hidden.
hideLinkUploadTabbooleannoSpecifies if LinkUploadTab should be hidden.
storeLastActiveTabbooleannoSpecifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default true
isPanelOpenbooleannoSpecifies if the file picker panel is open by default or not
renderCustomUploadTabContent(filePickerResult: IFilePickerResult) => JSX.Element | nullnoOptional renderer to add custom user-defined fields to "Upload" tab
renderCustomMultipleUploadTabContent(filePickerResult: IFilePickerResult[]) => JSX.Element | nullnoOptional renderer to add custom user-defined fields to "Multi-Upload" tab
renderCustomLinkTabContent(filePickerResult: IFilePickerResult) => JSX.Element | nullnoOptional renderer to add custom user-defined fields to "Link" tab
includePageLibrariesbooleannoSpecifies if Site Pages library to be visible on Sites tab
allowExternalLinksbooleannoSpecifies if external links should be allowed.
checkIfFileExistsbooleannoWhen using file links, this property allows the user to choose if the control should check if the link point to a file that exists or not.
+

interface IFilePickerResult

+

Provides options for carousel buttons location.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueTypeDescription
fileNamestringFile name of the result with the extension.
fileNameWithoutExtensionstringFile name of the result without the extension.
fileAbsoluteUrlstringAbsolute URL of the file. Null in case of file upload.
fileSizenumberSize of the result (in bytes). Set only for file upload
downloadFileContent() => PromiseFunction allows to download file content. Returns File object.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FileTypeIcon/index.html b/controls/FileTypeIcon/index.html new file mode 100644 index 000000000..9f92e1074 --- /dev/null +++ b/controls/FileTypeIcon/index.html @@ -0,0 +1,1765 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FileTypeIcon - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FileTypeIcon control

+

This control returns the file type icon based on a specified file path or application.

+

FileTypeIcon control output

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FileTypeIcon, ApplicationType, IconType, ImageSize } from "@pnp/spfx-controls-react/lib/FileTypeIcon";
+
+ +
    +
  • Use the FileTypeIcon control in your code as follows:
  • +
+
/* Showing the icons font */
+<FileTypeIcon type={IconType.font} application={ApplicationType.Word} />
+<FileTypeIcon type={IconType.font} application={ApplicationType.Excel} />
+<FileTypeIcon type={IconType.font} path="https://contoso.sharepoint.com/documents/filename.docx" />
+<FileTypeIcon type={IconType.font} path="https://contoso.sharepoint.com/documents/filename.xslx" />
+
+/* Showing the icon image */
+<FileTypeIcon type={IconType.image} application={ApplicationType.Word} />
+<FileTypeIcon type={IconType.image} path="https://contoso.sharepoint.com/documents/filename.docx" />
+
+/* Icon image allows three different sizes */
+<FileTypeIcon type={IconType.image} size={ImageSize.small} application={ApplicationType.Excel} />
+<FileTypeIcon type={IconType.image} size={ImageSize.medium} application={ApplicationType.Excel} />
+<FileTypeIcon type={IconType.image} size={ImageSize.large} application={ApplicationType.Excel} />
+
+ +

Implementation

+

The FileTypeIcon component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
applicationApplicationTypenoType of the application for which you want to show the icon. Use the ApplicationType enum to get the list of available applications.
pathstringnoPath to the document. If this is provided, the control will use the file extension to display the corresponding icon.
sizeImageSizenoThis is a property that only needs to be used when the type is set to image. It allows you to specify the image size. small (16px), normal (20px), medium (48px) and large (96px) are possible. Use the ImageSize enum to get the list of available images sizes.
typeIconTypeyesThis property specifies is you want to use the icon font or image. Use the IconType enum to get the list of available icon types.
onClickReact.MouseEvent<HTMLElement>noEvent triggered when the icon is clicked.
onDoubleClickReact.MouseEvent<HTMLElement>noEvent triggered when the icon is double clicked.
onMouseEnterReact.MouseEvent<HTMLElement>noEvent triggered when the mouse cursor enters the icon (without event bubbling).
onMouseLeaveReact.MouseEvent<HTMLElement>noEvent triggered when the mouse cursor leaves the icon.
onMouseOverReact.MouseEvent<HTMLElement>noEvent triggered when the mouse cursor enters the icon (with event bubbling).
onMouseUpReact.MouseEvent<HTMLElement>noEvent triggered when the mouse button is released after clicked on the icon.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FolderExplorer/index.html b/controls/FolderExplorer/index.html new file mode 100644 index 000000000..8e7b09ac2 --- /dev/null +++ b/controls/FolderExplorer/index.html @@ -0,0 +1,1780 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FolderExplorer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FolderExplorer control

+

This control allows you to explore a folder structure by clinking on a folder to load it's sub-folders and using a breadcrumb navigation to navigate back to a previous level. +It also allows the user to create a new folder at the current level being explored.

+

Here is an example of the control:

+

FolderExplorer

+

FolderExplorer folder creation:

+

FolderExplorer add folder

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { FolderExplorer, IFolder } from "@pnp/spfx-controls-react/lib/FolderExplorer";
+
+ +
    +
  • Use the FolderExplorer control in your code as follows:
  • +
+
<FolderExplorer context={this.props.context}
+                rootFolder={{
+                  Name: 'Documents',
+                  ServerRelativeUrl: `/sites/TestSite/Shared Documents`
+                }}
+                defaultFolder={{
+                  Name: 'Documents',
+                  ServerRelativeUrl: `/sites/TestSite/Shared Documents`
+                }}
+                onSelect={this._onFolderSelect}
+                canCreateFolders={true} />
+
+ +
    +
  • The onSelect change event returns the selected folder and can be implemented as follows:
  • +
+
private _onFolderSelect = (folder: IFolder): void => {
+  console.log('selected folder', folder);
+}
+
+ +

Implementation

+

The FolderExplorer control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
siteAbsoluteUrlstringnoThe absolute url of the target site. Only required if not the current site.
rootFolderIFolderyesThe lowest level folder that can be explored. This can be the root folder of a library. If site url is provided, it will allow the user to select a document library
defaultFolderIFolderyesThe default folder to be explored.
canCreateFoldersbooleannoAllow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions.
hiddenBreadcrumbbooleannoHide the breadcrumb control.
initialBreadcrumbItemsIBreadcrumbItemnoAdditional items to be added to the beginning of the breadcrumb.
hiddenFilterBoxbooleannoHide the filter box
onSelect(folder: IFolder): voidnoCallback function called after a folder is selected.
orderbystringnoThe name of the folder field on which to sort. Name will be used as default. Other examples: Name, TimeCreated, TimeLastModified
orderAscendingbooleannoIf set to true, results will be sorted in ascending order. Otherwise, descending will be used as default
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/FolderPicker/index.html b/controls/FolderPicker/index.html new file mode 100644 index 000000000..ddb2ebc10 --- /dev/null +++ b/controls/FolderPicker/index.html @@ -0,0 +1,1796 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FolderPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FolderPicker control

+

This control allows you to explore and select a folder. +It also allows the user to create a new folder at the current level being explored.

+

Here is an example of the control:

+

FolderPicker

+

FolderPicker no selection:

+

FolderPicker no selection

+

FolderPicker selection:

+

FolderPicker selection

+

FolderPicker selected:

+

FolderPicker selected

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { FolderPicker, IFolder } from "@pnp/spfx-controls-react/lib/FolderPicker";
+
+ +
    +
  • Use the FolderPicker control in your code as follows:
  • +
+
<FolderPicker context={this.props.context}
+                label='Folder Picker'
+                required={true}
+                rootFolder={{
+                  Name: 'Documents',
+                  ServerRelativeUrl: `/sites/TestSite/Shared Documents`
+                }}                
+                onSelect={this._onFolderSelect}
+                canCreateFolders={true} />
+
+ +
    +
  • To use the FolderExplorer control to fetch folders from different sitecollection in your code as follows:
  • +
+
<FolderExplorer context={this.props.context}
+                rootFolder={{
+                  Name: 'Documents',
+                  ServerRelativeUrl: `/sites/TestSite2/Shared Documents`
+                }}
+                onSelect={this._onFolderSelect}
+                canCreateFolders={true} 
+                siteAbsoluteUrl="https://xxxx.sharepoint.com/sites/TestSite2"/>
+
+ +
    +
  • The onSelect change event returns the selected folder and can be implemented as follows:
  • +
+
private _onFolderSelect = (folder: IFolder): void => {
+  console.log('selected folder', folder);
+}
+
+ +
    +
  • If you want to pick a folder outside the current site collection (not the one targeted by the SPFx context), you have to specify which site collection owns the folder. You can do this by setting the siteAbsoluteUrl property to the URL of the site collection that owns the folder.
  • +
+
<FolderPicker context={this.props.context}
+                label='Folder Picker'
+                rootFolder={{
+                  Name: 'Documents',
+                  ServerRelativeUrl: '/sites/anotherSite/Shared Documents'
+                }}
+                siteAbsoluteUrl="https://contoso.sharepoint.com/sites/anotherSite"             
+                onSelect={this._onFolderSelect} />
+
+ +

Implementation

+

The FolderPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
labelstringyesThe label for the control.
rootFolderIFolderyesThe lowest level folder that can be explored. This can be the root folder of a library.
siteAbsoluteUrlstringnoThe absolute url of the target site. Only required if rootFolder does not belongs to the current site
defaultFolderIFoldernoThe default folder to be selected or explored.
requiredbooleannoIs selection required.
disabledbooleannoIs the control disabled.
canCreateFoldersbooleannoAllow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions.
onSelect(folder: IFolder): voidnoCallback function called after a folder is selected.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/GridLayout/index.html b/controls/GridLayout/index.html new file mode 100644 index 000000000..1718b0f21 --- /dev/null +++ b/controls/GridLayout/index.html @@ -0,0 +1,1832 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayout - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Grid Layout control

+

This control renders a responsive grid layout for your web parts. The grid layout behaves according to the SharePoint web part layouts design pattern.

+

Grid Layout Control

+

The grid layout will automatically reflow grid items according to the space available for the control. On mobile devices and 1/3 column layouts, it will render a compact layout.

+

Grid Layout Reflow

+

Although it is best used with the Fabric UI DocumentCard control, it will render any rectangular content you wish to display.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { GridLayout } from "@pnp/spfx-controls-react/lib/GridLayout";
+
+ +
    +
  • Retrieve the items you wish to display in your grid control. For example, you can place them in your component's state:
  • +
+
// This sample places loads items in the constructor. You may wish to load
+// your items in the componentDidUpdate
+constructor(props: IMyWebPartProps) {
+    super(props);
+
+    this.state = {
+      items: [{
+        thumbnail: "https://pixabay.com/get/57e9dd474952a414f1dc8460825668204022dfe05555754d742e7bd6/hot-air-balloons-1984308_640.jpg",
+        title: "Adventures in SPFx",
+        name: "Perry Losselyong",
+        profileImageSrc: "https://robohash.org/blanditiisadlabore.png?size=50x50&set=set1",
+        location: "SharePoint",
+        activity: "3/13/2019"
+      }, {
+        thumbnail: "https://pixabay.com/get/55e8d5474a52ad14f1dc8460825668204022dfe05555754d742d79d0/autumn-3804001_640.jpg",
+        title: "The Wild, Untold Story of SharePoint!",
+        name: "Ebonee Gallyhaock",
+        profileImageSrc: "https://robohash.org/delectusetcorporis.bmp?size=50x50&set=set1",
+        location: "SharePoint",
+        activity: "6/29/2019"
+      }, {
+        thumbnail: "https://pixabay.com/get/57e8dd454c50ac14f1dc8460825668204022dfe05555754d742c72d7/log-cabin-1886620_640.jpg",
+        title: "Low Code Solutions: PowerApps",
+        name: "Seward Keith",
+        profileImageSrc: "https://robohash.org/asperioresautquasi.jpg?size=50x50&set=set1",
+        location: "PowerApps",
+        activity: "12/31/2018"
+      }, {
+        thumbnail: "https://pixabay.com/get/55e3d445495aa514f1dc8460825668204022dfe05555754d742b7dd5/portrait-3316389_640.jpg",
+        title: "Not Your Grandpa's SharePoint",
+        name: "Sharona Selkirk",
+        profileImageSrc: "https://robohash.org/velnammolestiae.png?size=50x50&set=set1",
+        location: "SharePoint",
+        activity: "11/20/2018"
+      }, {
+        thumbnail: "https://pixabay.com/get/57e6dd474352ae14f1dc8460825668204022dfe05555754d742a7ed1/faucet-1684902_640.jpg",
+        title: "Get with the Flow",
+        name: "Boyce Batstone",
+        profileImageSrc: "https://robohash.org/nulladistinctiomollitia.jpg?size=50x50&set=set1",
+        location: "Flow",
+        activity: "5/26/2019"
+      }]
+    };
+  }
+
+ +
    +
  • Because you will implement the method to render each item in your web part, your items can be anything you'd like. Our sample data defines a thumbnail, title, name, profileImageSrc, location and activity to coincide with the Fabric UI DocumentCard elements, but you can use any properties you need.
  • +
  • In the component that will call the GridLayout control, create callback function to render every item in the grid. You can return any rectangular element you want. For example, this code uses the Fabric UI DocumentCard control.
  • +
+
import {
+  DocumentCard,
+  DocumentCardActivity,
+  DocumentCardPreview,
+  DocumentCardDetails,
+  DocumentCardTitle,
+  IDocumentCardPreviewProps,
+  DocumentCardLocation,
+  DocumentCardType
+} from 'office-ui-fabric-react/lib/DocumentCard';
+import { ImageFit } from 'office-ui-fabric-react/lib/Image';
+import { ISize } from 'office-ui-fabric-react/lib/Utilities';
+
+...
+
+ private _onRenderGridItem = (item: any, finalSize: ISize, isCompact: boolean): JSX.Element => {
+    const previewProps: IDocumentCardPreviewProps = {
+      previewImages: [
+        {
+          previewImageSrc: item.thumbnail,
+          imageFit: ImageFit.cover,
+          height: 130
+        }
+      ]
+    };
+
+    return <div
+      data-is-focusable={true}
+      role="listitem"
+      aria-label={item.title}
+    >
+      <DocumentCard
+        type={isCompact ? DocumentCardType.compact : DocumentCardType.normal}
+        onClick={(ev: React.SyntheticEvent<HTMLElement>) => alert("You clicked on a grid item")}
+
+      >
+        <DocumentCardPreview {...previewProps} />
+        {!isCompact && <DocumentCardLocation location={item.location} />}
+        <DocumentCardDetails>
+          <DocumentCardTitle
+            title={item.title}
+            shouldTruncate={true}
+          />
+          <DocumentCardActivity
+            activity={item.activity}
+            people={[{ name: item.name, profileImageSrc: item.profileImageSrc }]}
+          />
+        </DocumentCardDetails>
+      </DocumentCard>
+    </div>;
+  }
+
+ +
+

Note that the sample code above uses the isCompact parameter to remove DocumentCard elements and to render a compact layout. You may choose to ignore the isCompact parameter if you do not wish to handle compact layouts.

+
+
    +
  • Use the GridLayout control in your code as follows:
  • +
+
 <GridLayout
+            ariaLabel="List of content, use right and left arrow keys to navigate, arrow down to access details."
+            items={this.state.items}
+            onRenderGridItem={(item: any, finalSize: ISize, isCompact: boolean) => this._onRenderGridItem(item, finalSize, isCompact)}
+          />
+
+ +

Implementation

+

The grid layout control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
ariaLabelstringnoThe accessible text you wish to display for the grid control. We recommend that you use "List of content, use right and left arrow keys to navigate, arrow down to access details.".
itemsany[]yesThe array of items you wish to display.
listPropsIListPropsnoProvides additional list properties to customize the underlaying list.
onRenderGridItemfunctionyesonRenderGridItem handler for the grid layout. Use this handler to specify how you wish to render each grid item
+

Telemetry

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/HoverReactionsBar/index.html b/controls/HoverReactionsBar/index.html new file mode 100644 index 000000000..726306bf9 --- /dev/null +++ b/controls/HoverReactionsBar/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HoverReactionsBar - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

HoverReactionsBar

+

This control allows you to select an emoji from emoji bar or select from picker.

+

HoverReactionsBar

+

hoverReactions3Bar

+

hoverReactionsBar2

+

hoverReactionsBar1

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { HoverReactionsBar } from '@pnp/spfx-controls-react/lib/HoverReactionsBar';
+
+ +
    +
  • Use the HoverReactionsBar control in your code as follows:
  • +
+
<HoverReactionsBar
+  isOpen={isOpenHoverReactionBar}
+  onSelect={onSelectEmoji}
+  onDismiss={(): void => {
+    setIsOpenHoverReactionBar(false);
+  }}
+  target={divRefAddReaction.current as HTMLDivElement}
+/>
+
+ +
    +
  • With the onSelect property you can get the selected emoji:
  • +
+
const onSelectEmoji = React.useCallback(async (emoji: string, emojiInfo: IEmojiInfo) => {
+  console.log('emoji', emoji);
+  console.log('emojiInfo object',emojiInfo);
+  setIsOpenHoverReactionBar(false);
+}, []);
+
+onSelect: (emoji: string | undefined, emojiInfo?: IEmojiInfo) => void;
+  isOpen: boolean;
+  onDismiss: () => void;
+  top4Reactions?: string[];
+  target: HTMLDivElement;
+  themeV8?: Theme ;
+
+ +

Implementation

+

The HoverReactionsBar control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
isOpenbooleanyesshow hoverReactionsBar
onSelectedonSelect: (emoji: string, emojiInfo?: IEmojiInfo) => void;yesselected Emoji
top4Reactionsstring[]noname of emojis to show on the bar
targetHTMLDivElementyescontainer of controls who fire the HoverReactionsBar
onDismisonDismiss: () => void;yesfunction to call to dismiss HoverReactionsBar
themeV8ThemeNoSet Fluent UI Theme
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/IFrameDialog/index.html b/controls/IFrameDialog/index.html new file mode 100644 index 000000000..071ea5957 --- /dev/null +++ b/controls/IFrameDialog/index.html @@ -0,0 +1,1803 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IFrameDialog - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

IFrameDialog control

+

This control renders a Dialog with an iframe as content.

+

Here is an example of the control in action:

+

IFrameDialog control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { IFrameDialog } from "@pnp/spfx-controls-react/lib/IFrameDialog";
+
+ +
    +
  • Use the IFrameDialog control in your code as follows (this._onIframeLoaded and this._onDialogDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively):
  • +
+
<IFrameDialog 
+    url={this.state.lookupDispFormUrl}
+    iframeOnLoad={this._onIframeLoaded.bind(this)}
+    hidden={this.state.hideDialog}
+    onDismiss={this._onDialogDismiss.bind(this)}
+    modalProps={{
+        isBlocking: true,
+        containerClassName: styles.dialogContainer
+    }}
+    dialogContentProps={{
+        type: DialogType.close,
+        showCloseButton: true
+    }}
+    width={'570px'}
+    height={'315px'}/>
+
+ +

Implementation

+

The IFrameDialog component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
dialogContentPropsIDialogContentPropsnoProps to be passed through to Dialog Content.
hiddenbooleannoWhether the dialog is hidden.
modalPropsIModalPropsnoProps to be passed through to Modal.
onDismiss(ev?: React.MouseEvent) => anynoA callback function for when the Dialog is dismissed from the close button or light dismiss. Can also be specified separately in content and modal.
urlstringyesiframe Url
iframeOnloadiframeOnLoad?: (iframe: any) => {}noiframe's onload event handler
widthstringyesiframe's width
heigthstringyesiframe's height
allowFullScreenbooleannoSpecifies if iframe content can be displayed in a full screen
allowTransparencybooleannoSpecifies if transparency is allowed in iframe
marginHeightnumbernoSpecifies the top and bottom margins of the content of an iframe
marginWidthnumbernoSpecifies the left and right margins of the content of an iframe
namestringnoSpecifies the name of an iframe
sandboxstringnoEnables an extra set of restrictions for the content in an iframe
scrollingstringnoSpecifies whether or not to display scrollbars in an iframe
seamlessstringnoWhen present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/IFramePanel/index.html b/controls/IFramePanel/index.html new file mode 100644 index 000000000..4d811c82e --- /dev/null +++ b/controls/IFramePanel/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IFramePanel - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

IFramePanel control

+

This control renders a Panel with an iframe as content.

+

Here is an example of the control in action:

+

IFrameDialog control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { IFramePanel } from "@pnp/spfx-controls-react/lib/IFramePanel";
+
+ +
    +
  • +

    The IFramePanel uses the Office Fabric UI implemenation of the panel. The properties of this control inherit the panel properties.

    +
  • +
  • +

    Use the IFramePanel control in your code as follows (this._onIframeLoaded and this._onDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively.)

    +
  • +
+
<IFramePanel url={this.state.iFrameUrl}
+             type={PanelType.medium}
+             headerText="Panel Title"
+             closeButtonAriaLabel="Close"
+             isOpen={this.state.iFramePanelOpened}
+             onDismiss={this._onDismiss.bind(this)}
+             iframeOnLoad={this._onIframeLoaded.bind(this)} />
+
+ +

Implementation

+

The IFramePanel component extends the properties from the Fabric UI IPanelProps + along with the additional following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
urlstringyesiframe Url
heigthstringyesiframe's height, if empty it will be dynamically set to the full height available in the panel's content area
iframeOnloadiframeOnLoad?: (iframe: any) => {}noiframe's onload event handler
namestringnoSpecifies the name of an iframe
allowFullScreenbooleannoSpecifies if iframe content can be displayed in a full screen
allowTransparencybooleannoSpecifies if transparency is allowed in iframe
sandboxstringnoEnables an extra set of restrictions for the content in an iframe
scrollingstringnoSpecifies whether or not to display scrollbars in an iframe
seamlessstringnoWhen present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/IconPicker/index.html b/controls/IconPicker/index.html new file mode 100644 index 000000000..e1cbbe097 --- /dev/null +++ b/controls/IconPicker/index.html @@ -0,0 +1,1810 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IconPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

IconPicker control

+

Control that allows to search and select an icon from office-ui-fabric-react icons.

+

Overview

+

The control allows selecting an icon from the list of icons available in the office-ui-fabric-react library. Icon list is a static copy of available icons. Currently, only one icon selection is supported. +Icon Picker overview

+

Displayed in the panel

+

Icon picker always opens a new panel where you can pick an icon. The panel displays all the icons and maintains readability. Picker does not displays selected icon outside the panel. +Icon Picker panel

+

Displayed in the dialog

+

Icon picker always opens a new dialog where you can pick an icon. The dialog displays all the icons and maintains readability. Picker does not displays selected icon outside the dialog. +Icon Picker panel

+

How to use this control

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following module to your component:
  • +
+
import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker';
+
+ +
    +
  • Use the IconPicker control in your code as follows:
  • +
+
<IconPicker buttonLabel={'Icon'}
+            onChange={(iconName: string) => { this.setState({icon: iconName}); }}
+            onSave={(iconName: string) => { this.setState({icon: iconName}); }} />
+
+ +
<IconPicker buttonLabel={'Icon'}
+            renderOption={'dialog'}
+            onChange={(iconName: string) => { this.setState({icon: iconName}); }}
+            onSave={(iconName: string) => { this.setState({icon: iconName}); }} />
+
+ +

Implementation

+

The IconPicker component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
buttonLabelstringnoSpecifies the label of the icon picker button.
onSave(iconName: string) => voidyesHandler when the icon has been selected and picker has been closed.
onCancel() => voidnoHandler when the panel is closed.
onChange(iconName: string) => voidnoHandler when the icon selection has been changed.
disabledbooleannoSpecifies if the picker button is disabled
buttonClassNamebooleannoIf provided, additional class name will be added to the picker button
panelClassNamebooleannoIf provided, additional class name will be added to the picker panel
currentIconstringnoSpecifies default selected icon
renderOptiondialog, panelnoSpecifies how to render list of Icons, Values : 'Panel' or 'Dialog' defualt value 'Panel'
useStartsWithSearchbooleannoSpecifies if we need to use startsWith when searching for the icons.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ImagePicker/index.html b/controls/ImagePicker/index.html new file mode 100644 index 000000000..6bb1b6f7b --- /dev/null +++ b/controls/ImagePicker/index.html @@ -0,0 +1,1665 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HoverReactionsBar - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

HoverReactionsBar

+

This control allows you to select or Upload Image from SharePoint, Ondrive or Stock Images.

+

ImagePicker

+

imagepicker

+

imagepicker

+

imagepicker

+

imagepicker

+

imagepicker

+

imagepicker

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { ImagePicker } from '@pnp/spfx-controls-react/lib/ImagePicker';
+
+ +
    +
  • Use the ImagePicker control in your code as follows:
  • +
+
  <ImagePicker
+  onFileSelected={handleFileSelected}
+  onDeleteFile={handleDeleteFile}
+  selectedFileUrl={selectedImageUrl}
+  context={appContext}
+ >
+
+ +
    +
  • With the onFileSelect property you can get the selected image:
  • +
+

typescript + const handleFileSelected = React.useCallback(async (file: IFilePickerResult) => { + console.log("file", file); + }, []);

+
    +
  • With the onDelete property you can execute a callback after delete the image:
  • +
+
const onDeleteFile = React.useCallback(async () => {
+  console.log("onDeleteFile");
+}, []);
+
+ +

Implementation

+

The HoverReactionsBar control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
onFileSelectedonFileSelect: (file: IFilePickerResult ) => void;yesOnSelectedFile Callback
onDeleteFileonDeleteFile: () => voidnoonDeleteFile CallBack
selectedFileUrlstringnoDefault Selected Image
contextBaseComponentContextyesContext
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListItemAttachments/index.html b/controls/ListItemAttachments/index.html new file mode 100644 index 000000000..924b76d3a --- /dev/null +++ b/controls/ListItemAttachments/index.html @@ -0,0 +1,1765 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListItemAttachments - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ListItemAttachments control

+

This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments are listed in tile view.

+

Here is an example of the control:

+

ListItemAttachments Upload

+

ListItemAttachments Tiles

+

ListItemAttachments Confirm Delete

+

ListItemAttachments Attachment Deleted

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttachments';
+
+ +
    +
  • Use the ListItemAttachments control in your code as follows:
  • +
+
<ListItemAttachments listId='dfa283f4-5faf-4d54-b6b8-5bcaf2725af5'
+                     itemId={1}
+                     context={this.props.context}
+                     disabled={false} />
+
+ +
    +
  • If You want to use ListItemAttachments controls with new form You have to use React.createRef.
  • +
+

Following example will add selected attachments to list item with id = 1

+
let listItemAttachmentsComponentReference = React.createRef<ListItemAttachments>();
+...
+      <ListItemAttachments 
+        ref={listItemAttachmentsComponentReference} 
+        context={this.props.context} 
+        listId="dfcfdb95-2488-4757-b55b-14d94166ad87" 
+        itemId={0} />
+...
+<PrimaryButton text="Save to Item with id 1" onClick={()=>{
+        //@ts-ignore
+        listItemAttachmentsComponentReference.current.uploadAttachments(1);
+      }} />
+
+ +

Implementation

+

The ListItemAttachments control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesSPFx web part or extention context
itemIdnumbernoList Item Id
listIdstringyesGuid of the list.
webUrlstringnoURL of the site. By default it uses the current site URL.
labelstringnoMain text to display on the placeholder, next to the icon.
descriptionstringnoDescription text to display on the placeholder, below the main text and icon.
disabledbooleannoSpecifies if the control is disabled or not.
openAttachmentsInNewWindowbooleannoSpecifies if the attachment should be openend in a separate browser tab. Use this property set to true if you plan to use the component in Microsoft Teams.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListItemComments/index.html b/controls/ListItemComments/index.html new file mode 100644 index 000000000..fdb637ebd --- /dev/null +++ b/controls/ListItemComments/index.html @@ -0,0 +1,1794 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListItemComments - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

ListItemComments control

+

This control allows you to manage list item comments, you can add or delete comments to an item. The comments are listed in tile view. +user can scroll to load more comments if they exist (infinite scroll);

+

Here is an example of the control:

+

ListItemComments

+

ListItemComments

+

ListItemComments

+

ListItemComments

+

ListItemComments

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ListItemComments } from '@pnp/spfx-controls-react/lib/ListItemComments';
+
+ +
    +
  • Use the ListItemComments control in your code as follows:
  • +
+
<ListItemComments webUrl='{"https://contoso.sharepoint.com/sites/ThePerspective"}'
+                  listId='dfa283f4-5faf-4d54-b6b8-5bcaf2725af5'
+                  itemId={1}
+                  serviceScope={serviceScope}
+                  numberCommentsPerPage={10}
+                  label="ListItem Comments"
+                  />
+
+ + +

SharePoint will send a comment notification if someone has been "@" in the comment. This comment notification mail contains a Go to comment button.

+

ListItemComments

+

The "Go to Comment" link is like https://xxx.sharepoint.com/sites/xxxx/Lists/MyList/DispForm.aspx?ID=1&commentId=1&e=LURoEsg5Zki4cS4SgcIG7w&at=15&CT=1674882847351&OR=OWA-NT&CID=c3a04ee0-40b5-9591-e6a4-3fac33046a64, which contains commentId in url parameter.

+

The comment whose id is commentId will be highlighted in the OOTB SharePoint List Item page. +You can use highlightedCommentId to specify the comment you want to highlight in ListItemComments control.

+
<ListItemComments webUrl='{"https://contoso.sharepoint.com/sites/ThePerspective"}'
+                  listId='dfa283f4-5faf-4d54-b6b8-5bcaf2725af5'
+                  itemId={1}
+                  serviceScope={serviceScope}
+                  numberCommentsPerPage={10}
+                  highlightedCommentId={"1"}
+                  label="ListItem Comments"
+                  />
+
+ +

The specified comment will be highlighted with different border and background color (Use theme color). +ListItemComments

+

Implementation

+

The ListItemComments control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
serviceScopeServiceScopeyesSPFx Service Scope
itemIdnumberyesList Item Id
listIdstringyesGuid of the list.
webUrlstringnoURL of the site. By default it uses the current site URL.
labelstringnoLabel for control
numberCommentsPerPagenumbernonumber of comments per page possible values 5
highlightedCommentIdstringnoThe commend Id (e.g. "1") you want to highlight. This selected comment will show with different border and background color based on site theme
+

MSGraph Permissions required

+

This control requires at least the flowing scopes: People.Read, User.ReadBasic.All

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListItemPicker/index.html b/controls/ListItemPicker/index.html new file mode 100644 index 000000000..4f7078544 --- /dev/null +++ b/controls/ListItemPicker/index.html @@ -0,0 +1,1827 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListItemPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ListItemPicker control

+

This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value.

+

Here is an example of the control:

+

ListItemPicker select list items

+

ListItemPicker select list items

+

ListItemPicker selected Items

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
+
+ +
    +
  • Use the ListItemPicker control in your code as follows:
  • +
+
<ListItemPicker listId='da8daf15-d84f-4ab1-9800-7568f82fed3f'
+                columnInternalName='Title'
+                keyColumnInternalName='Id'
+                filter="Title eq 'SPFx'"
+                orderBy={"Id desc"}
+                itemLimit={2}
+                onSelectedItem={this.onSelectedItem}
+                context={this.props.context} />
+
+ +
    +
  • The onSelectedItem change event returns the list items selected and can be implemented as follows:
  • +
+
private onSelectedItem(data: { key: string; name: string }[]) {
+  for (const item of data) {
+    console.log(`Item value: ${item.key}`);
+    console.log(`Item text: ${item.name}`);
+  }
+}
+
+ +

Implementation

+

The ListItemPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
columnInternalNamestringyesInternalName of column to search and get values.
keyColumnInternalNamestringnoInternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id
contextBaseComponentContextyesSPFx web part or extention context
listIdstringyesGuid or title of the list.
itemLimitnumberyesNumber of items which can be selected
onSelectedItem(items: any[]) => voidyesCallback function which returns the selected items.
classNamestringnoClassName for the picker.
webUrlstringnoURL of the site. By default it uses the current site URL.
defaultSelectedItemsany[]noInitial items that have already been selected and should appear in the people picker.
suggestionsHeaderTextstringnoThe text that should appear at the top of the suggestion box.
noResultsFoundTextstringnoThe text that should appear when no results are returned.
disabledbooleannoSpecifies if the control is disabled or not.
filterstringnocondition to filter list Item, same as $filter ODATA parameter
orderBystringnocondition to order by list Item, same as $orderby ODATA parameter
placeholderstringnoShort text hint to display in empty picker
substringSearchbooleannoSpecifies if substring search should be used
labelstringnoSpecifies the text describing the ListItemPicker.
enableDefaultSuggestionsbooleannoEnable default suggestions. All options are displayed by default when clicking on the control.
itemsQueryCountLimitnumbernoNumber of items to display in a lookup field
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListPicker/index.html b/controls/ListPicker/index.html new file mode 100644 index 000000000..458835000 --- /dev/null +++ b/controls/ListPicker/index.html @@ -0,0 +1,1824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ListPicker control

+

This control allows you to select one or multiple available lists/libraries of the current site.

+

Here is an example of the control:

+

ListPicker initial

+

ListPicker single selection mode:

+

ListPicker single selection

+

ListPicker multi-selection mode

+

ListPicker multi selection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ListPicker } from "@pnp/spfx-controls-react/lib/ListPicker";
+
+ +
    +
  • Use the ListPicker control in your code as follows:
  • +
+
<ListPicker context={this.props.context}
+            label="Select your list(s)"
+            placeHolder="Select your list(s)"
+            baseTemplate={100}
+            contentTypeId="0x0101"
+            includeHidden={false}
+            multiSelect={false}
+            onSelectionChanged={this.onListPickerChange} />
+
+ +
    +
  • The onSelectionChanged change event returns the list(s) and can be implemented as follows:
  • +
+
private onListPickerChange (lists: string | string[]) {
+  console.log("Lists:", lists);
+}
+
+ +

Implementation

+

The ListPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
classNamestringnoIf provided, additional class name to provide on the dropdown element.
disabledbooleannoWhether or not the control is disabled.
baseTemplatenumber | number[]noThe SharePoint BaseTemplate ID to filter the list options by.
filterstringnoFilter list from OData query (takes precendents over Hidden and BaseTemplate Filters).
includeHiddenbooleannoWhether or not to include hidden lists. Default is true.
orderByLibsOrderBynoHow to order the lists retrieved from SharePoint.
selectedListstring OR string[]noKeys(list Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed.
multiSelectbooleannoOptional mode indicates if multi-choice selections is allowed. Default to false.
labelstringnoLabel to use for the control.
placeHolderstringnoPlaceholder label to show in the dropdown. Deprecated. Use placeholder instead.
placeholderstringnoPlaceholder label to show in the dropdown.
onSelectionChanged(newValue: string OR string[]): voidnoCallback function when the selected option changes.
webAbsoulteUrlstringnoAbsolute Web Url of target site (user requires permissions)
contentTypeIdstringnoThe Id if a content type which must be present in a list in order for the list to appear in the picker.
refreshTogglebooleannoIf present can be used to force the control to refresh the list of lists by toggling its value
+

Enum LibsOrderBy

+ + + + + + + + + + + + + + +
Value
Id
Title
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListView.ContextualMenu/index.html b/controls/ListView.ContextualMenu/index.html new file mode 100644 index 000000000..393042908 --- /dev/null +++ b/controls/ListView.ContextualMenu/index.html @@ -0,0 +1,1771 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListView: add a contextual menu - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ListView: Add a contextual menu

+

The ContextualMenu component

+

In order to create a contextual menu for your list view, you first need to create a new component which will use a combination of an IconButton and ContextualMenu controls from the Office UI Fabric React.

+

Here is some sample code:

+
import * as React from 'react';
+import { Layer, IconButton, IButtonProps } from 'office-ui-fabric-react';
+import { ContextualMenuItemType } from 'office-ui-fabric-react/lib/ContextualMenu';
+// The following are project specific components
+import { IECBProps } from './IECBProps';
+import styles from './ECB.module.scss';
+import { IListitem } from '../../model/IListitem';
+
+export class ECB extends React.Component<IECBProps, {}> {
+
+  public constructor(props: IECBProps) {        
+    super(props);
+
+    this.state = {
+      panelOpen: false
+    };
+  }
+
+  public render() {      
+    return (
+      <div className={styles.ecb}>
+        <IconButton id='ContextualMenuButton1'
+                    className={styles.ecbbutton}
+                    text=''
+                    width='30'
+                    split={false}
+                    iconProps={ { iconName: 'MoreVertical' } }
+                    menuIconProps={ { iconName: '' } }
+                    menuProps={{
+                      shouldFocusOnMount: true,
+                      items: [
+                        {
+                          key: 'action1',
+                          name: 'Action 1',
+                          onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 1')
+                        },
+                        {
+                          key: 'divider_1',
+                          itemType: ContextualMenuItemType.Divider
+                        },
+                        {
+                          key: 'action2',
+                          name: 'Action 2',
+                          onClick: this.handleClick.bind(this, this.props.item.Firstname + ' Action 2')
+                        },
+                        {
+                          key: 'action3',
+                          name: 'Action 3',
+                          onClick: this.handleClick.bind(this, this.props.item.Lastname + ' Action  3')
+                        },
+                        {
+                          key: 'disabled',
+                          name: 'Disabled action',
+                          disabled: true,
+                          onClick: () => console.error('Disabled action should not be clickable.')
+                        }
+                      ]
+                    }} />
+      </div>
+    );
+  }
+
+  private handleClick(source:string, event) {
+    alert(`${source} clicked`);
+  }
+}
+
+ +

The ListView column

+

Once the ECB component is created, you can add the contextual menu to the ListView control. In order to do this, you have to insert another Viewfield in code at the position of our choice. For instance after the Lastname:

+
{
+  name: "",
+  sorting: false,
+  maxWidth: 40,
+  render: (rowitem: IListitem) => {
+    const element:React.ReactElement<IECBProps> = React.createElement(
+      ECB, 
+      {
+        item: rowitem
+      }
+    );
+    return element;
+  }      
+}
+
+ +

Inside the render method of the IViewField, the ECB component gets created and the current item will be used as a reference for the clicked row.

+

The result

+

The result will look like the following:

+

ContextualMenu_shown

+

Once you click on an action, you will see the alert:

+

ContextualMenu_clicked

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ListView/index.html b/controls/ListView/index.html new file mode 100644 index 000000000..e21f659e0 --- /dev/null +++ b/controls/ListView/index.html @@ -0,0 +1,1966 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListView - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ListView control

+

This control renders a list view for the given set of items.

+

ListView control output

+

List view control with grouping applied

+

ListView control with grouping

+

List view control with drag and drop applied

+

ListView control with grouping

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
+
+ +
    +
  • Use the ListView control in your code as follows:
  • +
+
<ListView
+  items={items}
+  viewFields={viewFields}
+  iconFieldName="FileRef"
+  compact={true}
+  selectionMode={SelectionMode.multiple}
+  selection={this._getSelection}
+  showFilter={true}
+  defaultFilter="John"
+  filterPlaceHolder="Search..."
+  groupByFields={groupByFields}
+  dragDropFiles={true}
+  onDrop={this._getDropFiles}
+  stickyHeader={true}
+  className={styles.listWrapper}
+  listClassName={styles.list} />
+
+ +
    +
  • +

    The control provides full text filtering through all the columns. If you want to execute filtering on the specified columns, you can use syntax : <ColumnName>:<FilterValue>. Use ':' as a separator between column name and value. Control support both 'fieldName' and 'name' properties of IColumn interface.

    +
  • +
  • +

    With the selection property you can define a method that which gets called when the user selects one or more items in the list view:

    +
  • +
+
private _getSelection(items: any[]) {
+  console.log('Selected items:', items);
+}
+
+ +
    +
  • With the groupByFields property you can define an array of field objects which will be used for grouping.
  • +
+

Important: the same order of the fields defines how grouping will be applied. In the snippet the ListView control will first group by the Extension and after that by the Author field.

+
const groupByFields: IGrouping[] = [
+  {
+    name: "Extension", 
+    order: GroupOrder.ascending 
+  }, {
+    name: "Author", 
+    order: GroupOrder.descending
+  }
+];
+
+ +
+

Extend ListView with a ContextualMenu

+

To extend the ListView control with a ContextualMenu refer to ListView.ContextualMenu.

+
+
    +
  • With the onDrop handler you can define a method that returns files that where drag and drop by user in the list view:
  • +
+
private _getDropFiles = (files) => {
+    for (var i = 0; i < files.length; i++) {
+      console.log(files[i].name);
+    }
+  }
+
+ +

Implementation

+

The ListView control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
iconFieldNamestringnoSpecify the items' property name that defines the file URL path which will be used to show the file icon. This automatically creates a column and renders the file icon.
itemsany[]noItems to render in the list view.
viewFieldsIViewField[]noThe fields you want to render in the list view. Check the IViewField implementation to see which properties you can define.
compactbooleannoBoolean value to indicate if the control should render in compact mode. By default this is set to false.
selectionModeSelectionModenoSpecify if the items in the list view can be selected and how. Options are: none, single, multi.
selectionfunctionnoSelection event that passes the selected item(s) from the list view.
groupByFieldsIGrouping[]noDefines the field on which you want to group the items in the list view.
defaultSelectionnumber[]noThe index of the items to be select by default
filterPlaceHolderstringnoSpecify the placeholder for the filter text box. Default 'Search'
showFilterbooleannoSpecify if the filter text box should be rendered.
defaultFilterstringnoSpecify the initial filter to be applied to the list.
dragDropFilesbooleannoSpecify the drag and drop files area option. Default false.
onDropfilenoEvent handler returns files from drag and drop.
stickyHeaderbooleannoSpecifies if the header of the ListView, including search box, is sticky
onRenderRow(props: IDetailsRowProps) => JSX.Element | nullnoCallback to override the default row rendering.
sortItems(items: any[], columnName: string, descending: boolean) => any[]noCustom sorting function to handle sorting by column
classNamestringnoClass name to apply additional styles on list view wrapper
listClassNamestringnoClass name to apply additional styles on list view
+

The IViewField has the following implementation:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
namestringyesName of the field.
displayNamestringnoName that will be used as the column title. If not defined, the name property will be used.
linkPropertyNamestringnoSpecify the field name that needs to be used to render a link for the current field.
sortingbooleannoSpecify if you want to enable sorting for the current field.
minWidthnumbernoSpecify the minimum width of the column.
maxWidthnumbernoSpecify the maximum width of the column.
isResizablebooleannoDetermines if the column can be resized.
renderfunctionnoOverride how the field has to get rendered.
+

The IGrouping has the following implementation:

+ + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
namestringyesName of the field
orderGroupOrderyesSpecify how the group needs to be ordered.
+

enum GroupOrder

+ + + + + + + + + + + + + + + + + +
ValueDescription
ascendingOrder the group in ascending order.
descendingOrder the group in descending order.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/LivePersona/index.html b/controls/LivePersona/index.html new file mode 100644 index 000000000..8a9a1a35b --- /dev/null +++ b/controls/LivePersona/index.html @@ -0,0 +1,1754 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LivePersona - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

LivePersona control

+

This control allows you to use LivePersona Card available on SharePoint Online.

+

Considerations/Disclaimer

+

The LivePersona Card uses an internal SharePoint Component and it can be changed in the future. Use at your own risk and be conscious that it's behaviour can be changed

+

Example

+

Here is an example of the control:

+

LivePersona

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { LivePersona } from "@pnp/spfx-controls-react/lib/LivePersona";
+
+ +
    +
  • Use the LivePersona control in your code as follows:
  • +
+
<LivePersona upn="joao.j.mendes@spteck.com"
+  template={
+    <>
+      <Persona text="João Mendes" secondaryText="joao.j.mendes@sapteck.com" coinSize={48} />
+    </>
+  }
+ serviceScope={this.context.serviceScope}
+/>
+
+ +

Implementation

+

The LivePersona control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
serviceScopeServiceScopeyesThe SPFx ServiceScope object loaded from context of web part or extension.
upnstringyesUser UPN.
disableHoverbooleannoIf info should not appear on hover.
templatestring | JSX.ElementyesThe content to wrap with persona info.
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/LocationPicker/index.html b/controls/LocationPicker/index.html new file mode 100644 index 000000000..3a126e66d --- /dev/null +++ b/controls/LocationPicker/index.html @@ -0,0 +1,1784 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LocationPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Location Picker

+

This control allows you to search and select the Location, also allows enter a custom location.

+

How to use this control in your solutions

+
    +
  • +

    Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.

    +
  • +
  • +

    Import the following modules to your component:

    +
  • +
+
import { LocationPicker,ILocationPickerItem } from  "@pnp/spfx-controls-react/lib/LocationPicker";
+
+ +
    +
  • Use the LocationPicker control in your code as follows:
  • +
+
<LocationPicker
+          context={this.props.context}
+          label="Location"
+          onChange={(locValue: ILocationPickerItem) => {
+            console.log(locValue.DisplayName + ", " + locValue.Address.Street)
+          }
+          }/>
+
+ + + + + + + + + + + + +
Location searching mode
Location Picker search
+ + + + + + + + + + + +
Entering into edit mode
Location Picker Edit
+ + + + + + + + + + + +
Readonly mode
Location Picker Read
+

Implementation

+

The LocationPicker can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextWebPartContext or ExtensionContextyesThe context object of the SPFx loaded webpart or customizer.
disabledbooleannoOption allows to be enable or disable. Default value is false
defaultValueILocationPickerItemnoOption allows set default value
errorMessagestringnoStatic error message displayed below the picker.
classNamestringnoApplies custom styling
labelstringnoLabel to use for the control.
placeholderstringnoPlaceholder label to show in the dropdown.
onChange(locItem: ILocationPickerItem) => voidnoThe method that returns location data JSON object.
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Map/index.html b/controls/Map/index.html new file mode 100644 index 000000000..2dc92a8a5 --- /dev/null +++ b/controls/Map/index.html @@ -0,0 +1,1844 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Map - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Map control

+

This control renders a map in your solution. The control has also the ability to search for new locations.

+

Here is an example of the control in action:

+

Map control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the Map control as follows:
  • +
+
import { Map, ICoordinates, MapType } from "@pnp/spfx-controls-react/lib/Map";
+
+ +
    +
  • Use the Map control in your code as follows:
  • +
+
<Map titleText="New of London"
+     coordinates={{ latitude: 51.507351, longitude: -0.127758 }}
+     enableSearch={true} />
+
+ +

Implementation

+

The Map control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
titleTextstringnoTitle label to show above the control.
coordinatesICoordinatesyesCoordinates required for rendering the control.
enableSearchbooleannoAllow the user to search for new locations.
zoomnumbernoZoom level for the maps on display (range 1-15).10
widthnumbernoWidth of the maps area in percentage.100%
heightnumbernoHeight of the maps area.300px
mapTypeMapTypenoType of the map to render.standard
loadingMessagestringnoCustom loading message.
errorMessagestringnoCustom error message.
mapsClassNamestringnoCustom CSS class name.
errorMessageClassNamestringnoCustom CSS error class name.
onUpdateCoordinates(coordinates: ICoordinates) => voidnoCallback to let your solution knows the new coordinates when a search was performed.
+

ICoordinates interface:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
latitudenumberyesLatitude of the map to display.
longitudenumberyesLongitude of the map to display.
displayNamestringnoDisplay Name of the location.
addressanynoAddress of the location.
+

MapType enum:

+ + + + + + + + + + + + + + + + + + + + +
Name
standard
cycle
normal
transport
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ModernAudio/index.html b/controls/ModernAudio/index.html new file mode 100644 index 000000000..6851a4431 --- /dev/null +++ b/controls/ModernAudio/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModernAudio - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Modern Audio

+

This control renders an Audio Control in a modern and themable way. It is controllable with Fluent UI icons instead of old-fashioned standard HTML5 Audio control.

+
+

Note

+

Originally it's coming from the following community Teams app sample.

+
+

Modern Audio control rendered with label and default label positioning

+

Modern Audio

+

Modern Audio control rendered with dark (lime) theme and label positioned BottomLeft

+

Modern Audio dark

+

Modern Audio control in action with label positioned at BottomCenter

+

Modern Audio in action

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { ModernAudio, ModernAudioLabelPosition } from "@pnp/spfx-controls-react/lib/ModernAudio";
+
+ +
    +
  • Use the ModernAudio control in your code as follows:
  • +
+
<ModernAudio 
+    audioUrl='https://www.winhistory.de/more/winstart/mp3/vista.mp3'
+    label="Audio Control"
+    labelPosition={ModernAudioLabelPosition.TopCenter} />
+
+ +

Implementation

+

The Modern Audio control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
audioUrlstringyesUrl to the audio src
labelstringnoLabel to use for the control.blank
labelPositionModernAudioLabelPositionnoDefine position of label: TopLeft, TopCenter, BottomLeft, BottomCenter.TopLeft
+

Enum ModernAudioLabelPosition

+

The ModernAudioLabelPosition enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValuePosition
TopLeft1On top, left aligned
TopCenter2On top, centered
BottomLeft3At bottom, left aligned
BottomCenter4At bottom, centered
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ModernTaxonomyPicker/index.html b/controls/ModernTaxonomyPicker/index.html new file mode 100644 index 000000000..69fef5765 --- /dev/null +++ b/controls/ModernTaxonomyPicker/index.html @@ -0,0 +1,2021 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModernTaxonomyPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Modern Taxonomy Picker

+

This control allows you to select one or more Terms from a TermSet via its TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the anchorTermId. This is the modern version of the taxonomy picker that uses the REST API and makes use of some load on demand features which makes it well suited for large term sets.

+
+

Disclaimer

+

Since this control is meant to look as and work in the same way as the out-of-the-box control it lacks some of the features from the legacy TaxonomyPicker control. If you need some of those features please continue using the legacy version.

+
+

Empty term picker

+

Empty term picker

+

Selecting terms

+

Selecting terms

+

Selected terms in picker

+

Selected terms in the input

+

Term picker: Auto Complete

+

Selected terms in the input

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { ModernTaxonomyPicker } from "@pnp/spfx-controls-react/lib/ModernTaxonomyPicker";
+
+ +
    +
  • Use the ModernTaxonomyPicker control in your code as follows:
  • +
+
<ModernTaxonomyPicker allowMultipleSelections={true}
+  termSetId="f233d4b7-68fb-41ef-8b58-2af0bafc0d38"
+  panelTitle="Select Term"
+  label="Taxonomy Picker"
+  context={this.props.context}
+  onChange={this.onTaxPickerChange}
+/>
+
+ +
    +
  • With the onChange property you can capture the event of when the terms in the picker has changed:
  • +
+
private onTaxPickerChange(terms : ITermInfo[]) {
+  console.log("Terms", terms);
+}
+
+ +

Advanced example

+

Custom rendering of a More actions button that displays a context menu for each term in the term set and the term set itself and with different options for the terms and the term set. This could for example be used to add terms to an open term set. It also shows how to set the initialsValues property when just knowing the name and the id of the term.

+
const termSetId = "36d21c3f-b83b-4acc-a223-4df6fa8e946d";
+const [clickedActionTerm, setClickedActionTerm] = React.useState<ITermInfo>();
+
+const addChildTerm = (parentTermId, updateTaxonomyTreeViewCallback): void => {
+  spPost(sp.termStore.sets.getById(termSetId).terms.getById(parentTermId).children, {
+    body: JSON.stringify({
+      "labels": [
+        {
+          "languageTag": "en-US",
+          "name": "Test",
+          "isDefault": true
+        }
+      ]
+    }),
+  })
+  .then(addedTerm => {
+    return sp.termStore.sets.getById(termSetId).terms.getById(addedTerm.id).expand("parent")();
+  })
+  .then(term => {
+    updateTaxonomyTreeViewCallback([term], null, null);
+  });
+}
+
+...
+
+<ModernTaxonomyPicker
+  allowMultipleSelections={true}
+  termSetId={termSetId}
+  panelTitle="Panel title"
+  label={"Field title"}
+  context={this.props.context}
+  required={false}
+  initialValues={[{labels: [{name: "Subprocess A1", isDefault: true, languageTag: "en-US"}], id: "29eced8f-cf08-454b-bd9e-6443bc0a0f5e"}]}
+  onChange={this.onTaxPickerChange}
+  disabled={false}
+  customPanelWidth={700}
+  isLightDismiss={false}
+  isBlocking={false}
+  onRenderActionButton={(
+      termStoreInfo: ITermStoreInfo, 
+      termSetInfo: ITermSetInfo, 
+      termInfo: ITermInfo
+      updateTaxonomyTreeViewCallback?: (newTermItems?: ITermInfo[], updatedTermItems?: ITermInfo[], deletedTermItems?: ITermInfo[]) => void
+    ): JSX.Element => {
+    const menuIcon: IIconProps = { iconName: 'MoreVertical', "aria-label": "More actions", style: { fontSize: "medium" } };
+    if (termInfo) {
+      const menuProps: IContextualMenuProps = {
+        items: [
+          {
+            key: 'addTerm',
+            text: 'Add Term',
+            iconProps: { iconName: 'Tag' },
+            onClick: () => addChildTerm(termInfo.id, updateTaxonomyTreeViewCallback)
+          },
+          {
+            key: 'deleteTerm',
+            text: 'Delete term',
+            iconProps: { iconName: 'Untag' },
+            onClick: () => deleteTerm(termInfo.id, updateTaxonomyTreeViewCallback)
+          },
+        ],
+      };
+
+      return (
+        <IconButton
+          menuProps={menuProps}
+          menuIconProps={menuIcon}
+          style={clickedActionTerm && clickedActionTerm.id === termInfo.id ? {opacity: 1} : null}
+          onMenuClick={(ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>, button?: IButtonProps) => {
+            setClickedActionTerm(termInfo));
+          }}
+          onAfterMenuDismiss={() => setClickedActionTerm(null)}
+        />
+      );
+    }
+    else {
+      const menuProps: IContextualMenuProps = {
+        items: [
+          {
+            key: 'addTerm',
+            text: 'Add term',
+            iconProps: { iconName: 'Tag' },
+            onClick: () => addTerm(termInfo.id, updateTaxonomyTreeViewCallback)
+          },
+        ],
+      };
+      return (
+        <IconButton
+          menuProps={menuProps}
+          menuIconProps={menuIcon}
+          style={{opacity: 1}}
+        />
+      );
+    }
+  }}
+/>
+
+ +

Implementation

+

The ModernTaxonomyPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
panelTitlestringyesTermSet Picker Panel title.
labelstringyesText displayed above the Taxonomy Picker.
disabledbooleannoSpecify if the control should be disabled. Default value is false.
contextBaseComponentContextyesContext of the current web part or extension.
initialValuesITermInfo[]noDefines the terms selected by default. This will only set the initial values and cannot be used to use the control in a controlled way. ITermInfo comes from PnP/PnPjs and can be imported with
import { ITermInfo } from '@pnp/sp/taxonomy';
allowMultipleSelectionsbooleannoDefines if the user can select only one or multiple terms. Default value is false.
termSetIdstringyesThe Id of the TermSet that you would like the Taxonomy Picker to select terms from.
onChangefunctionnoCaptures the event of when the terms in the picker has changed.
anchorTermIdstringnoSet the id of a child term in the TermSet to be able to select terms from that level and below.
placeHolderstringnoShort text hint to display in picker.
requiredbooleannoSpecifies if to display an asterisk near the label. Default value is false.
customPanelWidthnumbernoCustom panel width in pixels.
termPickerPropsIModernTermPickerPropsnoCustom properties for the term picker (More info: IBasePickerProps interface).
themeVariantIReadonlyThemenoThe current loaded SharePoint theme/section background (More info: Supporting section backgrounds).
isLightDismissbooleannoWhether the panel can be light dismissed.
isBlockingbooleannoWhether the panel uses a modal overlay or not.
onRenderActionButtonfunctionnoOptional custom renderer for adding e.g. a button with additional actions to the terms in the tree view.
isPathRenderedbooleannoWhether the terms will be rendered with the term label or the full path up to the root.
allowSelectingChildrenbooleannoWhether child terms can be selected. Default value is true.
+

Standalone TaxonomyTree control

+

You can also use the TaxonomyTree control separately to just render a stand-alone tree-view of a term set with action buttons.

+
    +
  • Use the TaxonomyTree control in your code as follows:
    + Initialize the taxonomy service and state, load basic info from term store and display the TaxonomyTree component.
  • +
+
import * as React from "react";
+import { Guid } from "@microsoft/sp-core-library";
+import { WebPartContext } from "@microsoft/sp-webpart-base";
+import { sp } from "@pnp/sp";
+import { ITermInfo, ITermSetInfo, ITermStoreInfo } from "@pnp/sp/taxonomy";
+import { SPTaxonomyService, TaxonomyTree } from "@pnp/spfx-controls-react";
+
+export interface ITestTaxonomyTreeReactHooksProps {
+  context: WebPartContext;
+  termSetId: string;
+  onRenderActionButton?: (termStoreInfo: ITermStoreInfo, termSetInfo: ITermSetInfo, termInfo: ITermInfo, updateTaxonomyTreeViewCallback?: (newTermItems?: ITermInfo[], updatedTermItems?: ITermInfo[], deletedTermItems?: ITermInfo[]) => void) => JSX.Element;
+}
+
+export function TestTaxonomyTreeReactHooks(
+    props: ITestTaxonomyTreeReactHooksProps
+): React.ReactElement<ITestTaxonomyTreeReactHooksProps> {
+  const taxonomyService = new SPTaxonomyService(props.context);
+  const [terms, setTerms] = React.useState<ITermInfo[]>([]);
+  const [currentTermStoreInfo, setCurrentTermStoreInfo] = React.useState<ITermStoreInfo>();
+  const [currentTermSetInfo, setCurrentTermSetInfo] = React.useState<ITermSetInfo>();
+  const [currentLanguageTag, setCurrentLanguageTag] = React.useState<string>("");
+
+  React.useEffect(() => {
+    sp.setup(props.context);
+    taxonomyService.getTermStoreInfo()
+      .then((termStoreInfo) => {
+        setCurrentTermStoreInfo(termStoreInfo);
+        setCurrentLanguageTag(props.context.pageContext.cultureInfo.currentUICultureName !== '' ?
+          props.context.pageContext.cultureInfo.currentUICultureName :
+          currentTermStoreInfo.defaultLanguageTag);
+      });
+    taxonomyService.getTermSetInfo(Guid.parse(props.termSetId))
+      .then((termSetInfo) => {
+        setCurrentTermSetInfo(termSetInfo);
+      });
+  }, []);
+
+  return (
+    currentTermStoreInfo && currentTermSetInfo && currentLanguageTag && (
+      <TaxonomyTree
+        languageTag={currentLanguageTag}
+        onLoadMoreData={taxonomyService.getTerms}
+        pageSize={50}
+        setTerms={setTerms}
+        termSetInfo={currentTermSetInfo}
+        termStoreInfo={currentTermStoreInfo}
+        terms={terms}
+        onRenderActionButton={props.onRenderActionButton}
+        hideDeprecatedTerms={false}
+        showIcons={true}
+      />
+    ) || null
+  );
+}
+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/MonacoEditor/index.html b/controls/MonacoEditor/index.html new file mode 100644 index 000000000..d9e0ea598 --- /dev/null +++ b/controls/MonacoEditor/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MonacoEditor - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Monaco Editor control

+

This control is an implementation of the Monaco Editor. The Monaco Editor is the code editor that powers VS Code.

+

Here is an example of the control:

+

monacoeditor

+

MonacoEditor dark theme:

+

monacoeditor

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { MonacoEditor } from "@pnp/spfx-controls-react/lib/MonacoEditor";
+
+ +
    +
  • Use the MonacoEditor control in your code as follows:
  • +
+
 <MonacoEditor value={defaultValue}
+               showMiniMap={true}
+               onValueChange={onValueChange}
+               language={"javascript"}/>
+
+ +
    +
  • The onValueChange change event returns the upadated code and array with messages of errors on validation and can be implemented as follows:
  • +
+
+

This validation is only available for JSON language

+
+

Your onValueChange handler would follow a similar format to this:

+
   const onValueChange = (newValue: string, validationErrors: string[]): void => { console.log(newValue); };
+
+ +

Or, if using React Hooks:

+
  const onValueChange = React.useCallback((newValue: string, validationErrors: string[]): void => {console.log(newValue);} , []);
+
+ +

Implementation

+

The MonacoEditor control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
valuestringyesdefault content for editor
themestringnotheme used by editor, two themes are supported 'vs' and 'vs-dark', default 'vs'
readOnlybooleannoindicate if editor is in read-only mode
showLineNumbersbooleannoeditor show line number or not, default : yes
onValueChange(newValue:string, validationErrors:string[]) => voidnofunction to get code changes, return an array with validation error in case of language is 'JSON'
languagestringyeseditor code language, please see https://microsoft.github.io/monaco-editor/index.html for supported languages
jsonDiagnosticsOptionsmonaco.languages.json.DiagnosticsOptionsnodefine options to JSON validation, please see https://microsoft.github.io/monaco-editor/index.html for more details
jscriptDiagnosticsOptionsmonaco.languages.typescript.DiagnosticsOptionsnodefine options to javascript or typescript validation, please see https://microsoft.github.io/monaco-editor/index.html for more details
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/MyTeams/index.html b/controls/MyTeams/index.html new file mode 100644 index 000000000..0a3c95c54 --- /dev/null +++ b/controls/MyTeams/index.html @@ -0,0 +1,1785 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyTeams - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

MyTeams control

+

This control show all Teams the user has access (joined),and for each Team the user can see the channels has permissions and quick open the channel or if callback is specified can return the Team Id and Channel Id for use in App.

+

The user can quick see the members and owner of the group. +This control uses the People component from mgt-toolkit that can be configured to show Person Card on hover. Please refer to required dependencies section to install the mgt-spfx library in your tenant.

+

Here is an example of the control:

+

myTeams

+

myTeams

+

myTeams

+

Required dependencies

+

In order to resolve an issue using controls from mgt-toolkit within SharePoint Framework solutions, the mgt team created an SPFx library that should be deployed to your tenant. For the MyTeams control to work, we had no other option but to add a dependency on the mgt-spfx library. More information about mgt-spfx is available here

+

Simply download the mgt-spfx-2.2.0.sppkg file from the link below and deploy to the SharePoint app catalog, making the solution available to all sites in the tenant.

+

mgt-spfx direct download link

+

myTeams

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { MyTeams } from "@pnp/spfx-controls-react/lib/MyTeams";
+
+ +
    +
  • Use the MyTeams control in your code as follows:
  • +
+
 <MyTeams
+            title="My Teams"
+            webPartContext={context}
+            themeVariant={themeVariant}/>
+
+ +
  <MyTeams
+            title="My Teams"
+            webPartContext={context}
+            themeVariant={themeVariant}
+            enablePersonCardInteraction={true}
+            onSelectedChannel={onSelectedChannel}
+          />
+
+ +
    +
  • The onSelectedChannel callback returns the teamId and ChannelId and can be implemented as follows:
  • +
+
 const  onSelectedChannel = (teamsId: string, channelId: string) => {
+        console.log("TeamsId", teamsId);
+        console.log("ChannelId", channelId);
+  };
+
+ +

Implementation

+

The MyTeams control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
webPartContextWebPartContextyesThe context object of the SPFx loaded webpart
titlestringnoTitle of WebPart
themeVariantIReadonlyThemenothemeVariant
enablePersonCardInteractionbooleannoShow Person Card on hover
onSelectedChannel(teamId:string,channelId:string) => void;nocallBack with TeamId and ChannelId Selected
+

MSGraph Permissions required

+

This control required the flowing scopes :

+

at least : Team.ReadBasic.All, Channel.ReadBasic.All, TeamMember.Read.All +and all Scopes used by mgt-people, +and Person-Card components

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Pagination/index.html b/controls/Pagination/index.html new file mode 100644 index 000000000..7f5ae763f --- /dev/null +++ b/controls/Pagination/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pagination - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Pagination Control

+

This control renders a Pagination component which can be used to show limited information of data. For example, you can set up your search result for the first 10 and then when clicking on a new page make a new request for other 10 elements.

+

Pagination on the page

+

Pagination control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
+
+ +
    +
  • Use the Pagination control in your code as follows:
  • +
+
<Pagination
+  currentPage={3}
+  totalPages={13} 
+  onChange={(page) => this._getPage(page)}
+  limiter={3} // Optional - default value 3
+  hideFirstPageJump // Optional
+  hideLastPageJump // Optional
+  limiterIcon={"Emoji12"} // Optional
+/>
+
+ +
    +
  • With the onChange property you can get the selected Page in the Pagination component:
  • +
+
private _getPage(page: number){
+  console.log('Page:', page);
+}
+
+ +

Implementation

+

The Pagination control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
currentPagenumberyesThe page initial selected
totalPagesnumberyesThe total of page that you want to show on control
onChangestringyesWhen the page number change send the page number selected
limiterstringnoThe number of pages showing before the icon3
hideFirstPageJumpbooleannoHide the quick jump to the first pagefalse
hideLastPageJumpbooleannoHide the quick jump to the last pagefalse
limiterIconstringnoLimitir icon form Fluent IUMore
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/PeoplePicker/index.html b/controls/PeoplePicker/index.html new file mode 100644 index 000000000..60ea0baa4 --- /dev/null +++ b/controls/PeoplePicker/index.html @@ -0,0 +1,2009 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PeoplePicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

People Picker

+

This control renders a People picker field which can be used to select one or more users from a SharePoint group or site. The control can be configured as mandatory. It will show a custom error message if field is empty.

+
+

Note

+

You can also check out People Picker component in the Microsoft Graph Toolkit.

+
+

Empty People Picker control with error message and tooltip

+

People Picker

+

Selecting People

+

Selecting People

+

Selected people

+

Selected people

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { IPeoplePickerContext, PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
+
+ +
    +
  • Use the PeoplePicker control in your code as follows:
  • +
+
const peoplePickerContext: IPeoplePickerContext = {
+    absoluteUrl: this.props.context.pageContext.web.absoluteUrl,
+    msGraphClientFactory: this.props.context.msGraphClientFactory,
+    spHttpClient: this.props.context.spHttpClient
+};
+
+<PeoplePicker
+    context={peoplePickerContext}
+    titleText="People Picker"
+    personSelectionLimit={3}
+    groupName={"Team Site Owners"} // Leave this blank in case you want to filter from all users
+    showtooltip={true}
+    required={true}
+    disabled={true}
+    searchTextLimit={5}
+    onChange={this._getPeoplePickerItems}
+    showHiddenInUI={false}
+    principalTypes={[PrincipalType.User]}
+    resolveDelay={1000} />
+
+ +
    +
  • With the onChange property you can get the selected People in the PeoplePicker :
  • +
+
private _getPeoplePickerItems(items: any[]) {
+  console.log('Items:', items);
+}
+
+ + +

Sometimes, depending on how your organization is configured regarding users and groups, performing search can be tricky. As the PeoplePicker is using the SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser endpoint under the hood, there is an optional parameter called useSubstrateSearch. Setting this to true will perform a search using the Microsoft 365 Substrate, which will go through centralized stored data in order to find requested info. More details about this feature can be found here and here.

+

Implementation

+

The People picker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
contextIPeoplePickerContextyesContext of the component, based on the SPFx context (BaseComponentContext).
titleTextstringnoText to be displayed on the control
groupNamestringnoGroup from which users are fetched. Leave it blank if need to filter all users. When both groupName and groupId specified groupName takes precedence.none
groupIdnumber | string | (string|number)[]noGroup from which users are fetched. Leave it blank if need to filter all users. When both groupId and groupName specified groupName takes precedence. If string is specified, Microsoft 365 Group is used. If array is used, fetch results from multiple groupsnone
personSelectionLimitnumbernoDefines the limit of people that can be selected in the control1
requiredbooleannoSet if the control is required or notfalse
disabledbooleannoSet if the control is disabled or notfalse
errorMessagestringnoStatic error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence).
onGetErrorMessage(items: IPersonaProps[]) => string | Promise<string>noThe method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this).
When it returns string:
  • If valid, it returns empty string.
  • If invalid, it returns the error message string to be shown below the picker.

When it returns Promise<string>:
  • The resolved value is display as error message.
  • The rejected, the value is thrown away.
errorMessageClassNamestringnoapplies custom styling to the error message section
showtooltipbooleannoDefines if need a tooltip or notfalse
tooltipMessagestringnoSpecify the tooltip message to display
tooltipDirectionalDirectionalHintnoDirection where the tooltip would be shown
onChange(items: IPersonaProps[]) => voidnoGet the selected users in the control.
peoplePickerWPclassNamestringnoapplies custom styling to the people picker element
peoplePickerCntrlclassNamestringnoapplies custom styling to the people picker control only
defaultSelectedUsersstring[]noDefault selected user emails or login names, optionally append /title with forward slash. If user is not found then only optional title will be shown. If you do not have email or login name of inactive users just pass /title alone prefixed with slash.
webAbsoluteUrlstringnoSpecify the site URL on which you want to perform the user query call. If not provided, the people picker will perform a tenant wide people/group search. When provided it will search users/groups on the provided site.
principalTypesPrincipalType[]noDefine which type of data you want to retrieve: User, SharePoint groups, Security groups. Multiple are possible.
ensureUserbooleannoWhen ensure user property is true, it will return the local user ID on the current site when doing a tenant wide search.false
allowUnvalidatedbooleannoWhen true, allow email addresses that have not been validated to be entered, effectively allowing any user.false
suggestionsLimitnumbernoMaximum number of suggestions to show in the full suggestion list.5
resolveDelaynumbernoAdd delay to resolve and search users200
placeholderstringnoShort text hint to display in empty picker
stylesPartial<IBasePickerStyles>noStyles to apply on control
searchTextLimitnumbernoSpecifies the minimum character count needed to begin retrieving search results.2
useSubstrateSearchbooleannoWhen true, performs a wider search using Microsoft 365 Substrate.false
+

Enum PrincipalType

+

The PrincipalType enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
User1
DistributionList2
SecurityGroup4
SharePointGroup8
+

Interface IPeoplePickerContext

+

Provides mandatory properties to search users on the tenant

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ValueTypeDescription
absoluteUrlstringCurrent SPWeb absolute URL.
msGraphClientFactoryMSGraphClientFactoryInstance of MSGraphClientFactory used for querying Microsoft Graph REST API.
spHttpClientSPHttpClientInstance of SPHttpClient used for querying SharePoint REST API.
+

MSGraph Permissions required

+

This control requires at least one the following scopes if groupId is of type string:

+
    +
  • GroupMember.Read.All + User.ReadBasic.All
  • +
  • Directory.Read.All
  • +
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Placeholder/index.html b/controls/Placeholder/index.html new file mode 100644 index 000000000..efe0e68de --- /dev/null +++ b/controls/Placeholder/index.html @@ -0,0 +1,1788 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Placeholder - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Placeholder control

+

This control renders a placeholder which can be used to show a message that the web part still has to be configured.

+

Placeholder control output

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
+
+ +
    +
  • Use the Placeholder control in your code as follows:
  • +
+
<Placeholder iconName='Edit'
+             iconText='Configure your web part'
+             description='Please configure the web part.'
+             buttonLabel='Configure'
+             onConfigure={this._onConfigure}
+             theme={this.props.themeVariant} />
+
+ +
    +
  • With custom element for description:
  • +
+
<Placeholder iconName='Edit'
+             iconText='Configure your web part'
+             description={defaultClassNames => <span className={`${defaultClassNames} ${additionalStyles}`}>Please configure the web part.</span>}
+             buttonLabel='Configure'
+             onConfigure={this._onConfigure}
+             theme={this.props.themeVariant} />
+
+ +
    +
  • With the onConfigure property you can define what it needs to do when you click on the button. Like for example opening the property pane:
  • +
+
private _onConfigure = () => {
+  // Context of the web part
+  this.props.context.propertyPane.open();
+}
+
+ +

Sample of using the hideButton functionality for hiding the button when page is in read mode:

+
<Placeholder iconName='Edit'
+             iconText='Configure your web part'
+             description='Please configure the web part.'
+             buttonLabel='Configure'
+             hideButton={this.props.displayMode === DisplayMode.Read}
+             onConfigure={this._onConfigure}
+             theme={this.props.themeVariant} />
+
+ +

Sample to only display Placeholder when the web part is in edit mode:

+
{
+  this.displayMode === DisplayMode.Edit ?
+  <Placeholder iconName='Edit'
+               iconText='Configure your web part'
+               description='Please configure the web part.'
+               buttonLabel='Configure'
+               onConfigure={this._onConfigure}
+               theme={this.props.themeVariant} /> :
+  <div />
+}
+
+ +

Implementation

+

The placeholder control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
buttonLabelstringnoText label to be displayed on the button bellow the description. The button is optional.
contentClassNamestringnoThis is the className that is applied to the root element of the content zone. You can use this to apply custom styles to the placeholder.
descriptionstring | ((defaultClassNames: string) => React.ReactElement)yesText description or render function for the placeholder. This appears bellow the Icon and IconText.
iconNamestringyesThe name of the icon that will be used in the placeholder. This is the same name as you can find on the Office UI Fabric icons page: Office UI Fabric icons. For example: Page or Add.
iconTextstring | ((defaultClassNames: string) => React.ReactElement)yesHeading text or render function which is displayed next to the icon.
hideButtonbooleannoSpecify if you want to hide the button. Default is false.
onConfigurefunctionnoonConfigure handler for the button. The button is optional.
themeIPartialTheme | IThemenoSet Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Progress/index.html b/controls/Progress/index.html new file mode 100644 index 000000000..17b22348f --- /dev/null +++ b/controls/Progress/index.html @@ -0,0 +1,1856 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Progress - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Progress control

+

This control shows progress of multiple SEQUENTIALLY executed actions.

+

Here is an example of the control in action:

+

Progress control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { Progress } from "@pnp/spfx-controls-react/lib/Progress";
+
+ +
    +
  • Use the Progress control in your code as follows:
  • +
+
<Progress title={'Progress Test'}
+          showOverallProgress={true}
+          showIndeterminateOverallProgress={false}
+          hideNotStartedActions={false}
+          actions={this.state.progressActions}
+          currentActionIndex={this.state.currentProgressActionIndex}
+          longRunningText={'This operation takes longer than expected'}
+          longRunningTextDisplayDelay={7000}
+          height={'350px'} />
+
+ +

Note: the control itself is not responsible for actions' execution. It only renders the actions, overall progress and actions' execution states. +When using the control, you should implement actions execution. +As example, you can have a base class that implements IProgressAction interface and has an execute method:

+
class BaseAction implements IProgressAction {
+  public get title(): string { ... }
+  public get subActionsTitles(): string[] { ... }
+  public get hasError(): boolean { ... }
+  public get errorMessage(): string { ... }
+  public async execute(): Promise<void> { ... }
+}
+
+ +

Then, you have multiple actions derived from the base one:

+
class FirstAction extends BaseAction {
+  public async execute(): Promise<void> { 
+    // implementation for FirstAction
+  }
+}
+
+class SecondAction extends BaseAction {
+  public async execute(): Promise<void> {
+    // implementation for SecondAction
+  }
+}
+
+ +

Now, in a component, where Progress is used you can have code as below:

+
export interface IYourComponentState {
+  progressActions: IProgressAction[];
+  currentProgressActionIndex?: number;
+  // other state properties
+}
+
+// ...
+
+export class YourComponent extends React.Component<IYourComponentProps, IYourComponentState> {
+  // all other code, including render with Progress reference listed above
+
+  private _initActions() {
+    this.setState({
+      progressActions: [
+        new FirstAction(),
+        new SecondAction()
+      ]
+    });
+  }
+
+  private async _execute() {
+    for (let i = 0; i <= this.state.actions.length; i++) {
+      this.setState(currentProgressActionIndex: i);
+
+      if (i < this.state.actions.length) {
+        await this.state.actions[i].execute();
+      }
+    }
+  }
+}
+
+ +

Implementation

+

The Progress component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
titlestringnoTitle, or header, of the progress.
showOverallProgressbooleantrueSpecifies if overall progress indicator should be shown.
showIndeterminateOverallProgressbooleannoSpecifies if indeterminate overall progress animation will be shown.
hideNotStartedActionsbooleanyesSpecifies if not started actions should not be rendered.
actionsIProgressAction[]yesProgress actions
currentActionIndexnumbernoIndex of currently executing action
heigthstringnoHeight of the component
longRunningTextstringnoText to be displayed for long running operations
longRunningTextDisplayDelaynumbernoDelay until longRunningText is displayed im milliseconds. If not set or 0 longRunningText is displayed right away.
classNamestringnoClass name to be applied to the component
headerClassNamestringnoHeader class name. Header contains title, progress indicator, and delay text
actionsContainerClassNamestringnoActions container class name
actionClassNamestringnoSingle action class name
successIconNamestringnoSuccess icon name. Default is CheckMark
errorIconNamestringnoError icon name. Default is Error
inProgressIconNamestringnoInProgress icon name. Default is '', spinner is displayed.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ProgressStepsIndicator/index.html b/controls/ProgressStepsIndicator/index.html new file mode 100644 index 000000000..6abb3288c --- /dev/null +++ b/controls/ProgressStepsIndicator/index.html @@ -0,0 +1,1734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProgressStepsIndicator - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Progress Steps Indicator

+

This control shows a progress of steps.

+

Here is an example of the control in action:

+

ProgressStepsIndicator

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the ProgressStepsIndicator control as follows:
  • +
+
import { ProgressStepsIndicator } from '"@pnp/spfx-controls-react/lib/ProgressStepsIndicator';
+
+const progressSteps: IStep[] = [
+  { id: 0, title: "Step 1", description: "Step 1 Description" },
+  { id: 1, title: "Step 2", description: "Step 2 Description" },
+  { id: 3, title: "Step 3", description: "Step 3 Description" },
+  { id: 4, title: "Step 4", description: "Step 4 Description" },
+  { id: 5, title: "Step 5", description: "Step 5 Description" },
+  { id: 6, title: "Step 6", description: "Step 6 Description" },
+];
+
+ +
    +
  • Use the ProgressStepsIndicator control in your code as follows:
  • +
+
{
+     <ProgressStepsIndicator steps={progressSteps} currentStep={0} themeVariant={props.themeVariant} />
+}
+
+ +

Implementation

+

The ProgressStepsIndicator control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
stepsISteps[]yesPerogress Steps
currentStepnumberyesindex of current stepdefault is 0
themeVariantIReadonlyThemeundefinednoTheme
+

The IStep Interface definition:

+
Interface IStep {
+  id?:number;
+  title:string;
+  description:string;
+}
+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/RichText/index.html b/controls/RichText/index.html new file mode 100644 index 000000000..68bb3a4c5 --- /dev/null +++ b/controls/RichText/index.html @@ -0,0 +1,1849 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichText - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

RichText control

+

This control provides rich text editing and display capability.

+

RichText control output

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { RichText } from "@pnp/spfx-controls-react/lib/RichText";
+
+ +
    +
  • The simplest way to use the RichText control in your code is as follows:
  • +
+
<RichText value={this.props.value}
+          onChange={(text)=>this.onTextChange(text)}
+/>
+
+ +
    +
  • The value property should contain the HTML that you wish to display
  • +
  • The onChange handler will be called every time a user changes the text. For example, to have your web part store the rich text as it is updated, you would use the following code:
  • +
+
private onTextChange = (newText: string) => {
+  this.properties.myRichText = newText;
+  return newText;
+}
+
+ +

It is possible to use the onChange handler as users type -- for example, the following code replaces all instance of the word bold with bold text.

+
private onTextChange = (newText: string) => {
+  newText = newText.replace(" bold ", " <strong>bold</strong> ");
+  this.properties.description = newText;
+  return newText;
+}
+
+ +
    +
  • By adding label property, the control is better identified, especially when used in a form
  • +
+
<RichText label="My multiline text field" value={this.props.value} />
+
+ +

It is also possible to customize the control label's rendering:

+
const richText = (
+  <RichText id="spfxRichText" label="My multiline text field"
+            onRenderLabel={onRenderCustomLabel}
+            value={this.props.value} />
+);
+
+const onRenderCustomLabel = (rtProps: IRichTextProps): JSX.Element => {
+  return <Label htmlFor={rtProps.id}>{rtProps.label}</Label>;
+}
+
+ +

Implementation

+

The RichText control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringnoThe ID to apply to the RichText control.
labelstringnoThe label displayed above the RichText control.
classNamestringnoThe custom CSS class to apply to the RichText control.
styleReact.CSSPropertiesnoThe custom styles to apply to the RichText control.
isEditModebooleannotrue indicates that users will be able to edit the content of the RichText control. false will display the rich text as read-only.
styleOptionsStyleOptionsnoDefine the styles you want to show or hide for the rich text editor
valuestringnoSets the rich text to display in the RichText control.
onChange(text: string) => stringnoonChange handler for the RichText control. The function must return a string containing the rich text to display in the RichText control.
onRenderLabel(props: IRichTextProps) => JSX.ElementnoCustom renderer for the RichText control's label. The function must return a JSX.Element.
+

StyleOptions interface

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
showAlignbooleannoIndicates whether to show the Align toolbar button or not. Default value is true
showBoldbooleannoIndicates whether to show the Bold toolbar button or not. Default value is true
showItalicbooleannoIndicates whether to show the Italic toolbar button or not. Default value is true
showLinkbooleannoIndicates whether to show the Hyperlink toolbar button or not. Default value is true
showListbooleannoIndicates whether to show the List toolbar button or not. Default value is true
showMorebooleannoIndicates whether to show the More toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true
showStylesbooleannoIndicates whether to show the Headings toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true
showUnderlinebooleannoIndicates whether to show the Underline toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true
+
+

Note that setting showAlign, showBold, showItalic, showLink, showList, showStyles, or +showUnderline to false does not remove the user's ability to apply the button's associated formatting -- it only hides the toolbar option. Also, if showMore is true, all options remain available in the formatting pane -- regardless whether they were turned off using show___. To prevent users from applying specific formats, use the onChange handler to parse the rich text and remove the formatting as desired.

+
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/SecurityTrimmedControl/index.html b/controls/SecurityTrimmedControl/index.html new file mode 100644 index 000000000..51220c3bc --- /dev/null +++ b/controls/SecurityTrimmedControl/index.html @@ -0,0 +1,1837 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SecurityTrimmedControl - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

SecurityTrimmedControl

+

This control is intended to be used when you want to show or hide components based on the user permissions. The control can be used to check the user’s permissions on the current site / list were the solution is loaded, or on a remote site / list.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { SecurityTrimmedControl, PermissionLevel } from "@pnp/spfx-controls-react/lib/SecurityTrimmedControl";
+import { SPPermission } from '@microsoft/sp-page-context';
+
+ +
    +
  • You can use the SecurityTrimmedControl as follows in your solutions:
  • +
+

Checking permissions on the current site

+
<SecurityTrimmedControl context={this.props.context}
+                        level={PermissionLevel.currentWeb}
+                        permissions={[SPPermission.viewPages]}>
+  {/* Specify the components to load when user has the required permissions */}
+</SecurityTrimmedControl>
+
+ +

Checking permissions on the current list

+
<SecurityTrimmedControl context={this.props.context}
+                        level={PermissionLevel.currentList}
+                        permissions={[SPPermission.addListItems]}>
+  {/* Specify the components to load when user has the required permissions */}
+</SecurityTrimmedControl>
+
+ +

Checking permissions on remote site

+
<SecurityTrimmedControl context={this.props.context}
+                        level={PermissionLevel.remoteWeb}
+                        remoteSiteUrl="https://<tenant>.sharepoint.com/sites/<siteName>"
+                        permissions={[SPPermission.viewPages, SPPermission.addListItems]}>
+  {/* Specify the components to load when user has the required permissions */}
+</SecurityTrimmedControl>
+
+ +

Checking permissions on remote list / library

+
<SecurityTrimmedControl context={this.props.context}
+                        level={PermissionLevel.remoteListOrLib}
+                        remoteSiteUrl="https://<tenant>.sharepoint.com/sites/<siteName>"
+                        relativeLibOrListUrl="/sites/<siteName>/<list-or-library-URL>"
+                        permissions={[SPPermission.addListItems]}>
+  {/* Specify the components to load when user has the required permissions */}
+</SecurityTrimmedControl>
+
+ +

Show a control when the user doesn't have permissions

+
<SecurityTrimmedControl context={this.props.context}
+                        level={PermissionLevel.remoteListOrLib}
+                        remoteSiteUrl="https://<tenant>.sharepoint.com/sites/<siteName>"
+                        relativeLibOrListUrl="/sites/<siteName>/<list-or-library-URL>"
+                        permissions={[SPPermission.addListItems]}
+                        noPermissionsControl={<p>SOrry, you don't have permissions to this list.</p>}>
+  {/* Specify the components to load when user has the required permissions */}
+</SecurityTrimmedControl>
+
+ +

Implementation

+

The SecurityTrimmedControl can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesContext of the web part, application customizer, field customizer, or list view command set.
permissionsSPPermission[]yesThe permissions to check for the user.
levelPermissionLevelyesSpecify where to check the user permissions: current site or list / remote site or list.
remoteSiteUrlstringnoThe URL of the remote site. Required when you want to check permissions on remote site or list.
relativeLibOrListUrlstringnoThe relative URL of the list or library. Required when you want to check permissions on remote list.
folderPathstringnoSpecify the name of a folder to check the user permissions against. Will be overridden if itemId is present.
itemIdnumbernoSpecify the ID of the item to check the user permissions against. Takes precedence over folder.
classNamestringnoSpecify the className to be used on the parent element.
noPermissionsControlJSX.ElementnoOptional. Specify the control you want to render if user doesn't have permissions.
showLoadingAnimationbooleannoOptional. Specify should render loading animation.
+

The PermissionLevel enum has the following values:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescriptionRequired properties
currentWebChecks permissions on the current webcontext, permissions
currentListChecks permissions in the current loaded listcontext, permissions
remoteWebChecks permissions on the specified site URLcontext, permissions, remoteSiteUrl
remoteListOrLibChecks permissions on the specified list/library URL in combination with the site URLcontext, permissions, remoteSiteUrl, relativeLibOrListUrl
remoteListItemCheck permissions on a specific item in a list/librarycontext, permissions, remoteSiteUrl, relativeLibOrListUrl, itemId
remoteFolderCheck permissions on a specific foldercontext, permissions, remoteSiteUrl, relativeLibOrListUrl, folderPath
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/SiteBreadcrumb/index.html b/controls/SiteBreadcrumb/index.html new file mode 100644 index 000000000..5d418b93f --- /dev/null +++ b/controls/SiteBreadcrumb/index.html @@ -0,0 +1,1699 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SiteBreadcrumb - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

SiteBreadcrumb control

+

This control returns a breadcrumb based on the current location.

+

SiteBreadcrumb control output +Hover over an item

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { SiteBreadcrumb } from "@pnp/spfx-controls-react/lib/SiteBreadcrumb";
+
+ +
    +
  • Use the SiteBreadcrumb control in your code as follows:
  • +
+
<SiteBreadcrumb context={this.props.context} />
+
+ +

Implementation

+

The SiteBreadcrumb control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesPass the context of your web part or application customizer extension.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/SitePicker/index.html b/controls/SitePicker/index.html new file mode 100644 index 000000000..578577728 --- /dev/null +++ b/controls/SitePicker/index.html @@ -0,0 +1,1852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SitePicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

SitePicker control

+

This control allows you to select one or multiple available sites, site collections or hub sites.

+

Here is an example of the control.

+

SitePicker single selection mode:

+

SitePicker Single Select

+

SitePicker multi-selection mode

+

SitePicker Multi Select

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { SitePicker } from "@pnp/spfx-controls-react/lib/SitePicker";
+
+ +
    +
  • Use the SitePicker control in your code as follows:
  • +
+
<SitePicker
+  context={this.props.context}
+  label={'Select sites'}
+  mode={'site'}
+  allowSearch={true}
+  multiSelect={false}
+  onChange={(sites) => { console.log(sites); }}
+  placeholder={'Select sites'}
+  searchPlaceholder={'Filter sites'} />
+
+ +
    +
  • The onChange change event returns the selected site(s).
  • +
+

Implementation

+

The SitePicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
allowSearchbooleannoSpecifies if search box is displayed for the component. Default: true.
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
deferredSearchTimenumbernoThe list will be filtered after users stop typing for deferredSearchTime milliseconds. Default: 200.
classNamestringnoIf provided, additional class name to provide on the dropdown element.
disabledbooleannoWhether or not the control is disabled.
initialSitesISite[]noIntial data to load in the 'Selected sites' area (optional).
isDescbooleannoSpecifies if the list is sorted in descending order. Default: false.
labelstringnoLabel to use for the control.
limitToCurrentSiteCollectionbooleannoSpecifies if the options should be limited by the current site collections. Taken into consideration if selectionMode is set to web.
mode'associatedsites' | 'site' | 'web' | 'hub'noDefines what entities are available for selection: site collections, sites, hub sites and sites inside hub. Default: web.
multiSelectbooleannoOptional mode indicates if multi-choice selections is allowed. Default: true.
onChange(selectedSites: ISite[]) => voidyesSelection change handler.
orderBy'title' | 'url'noSpecifices if the list is sorted by title or url. Default: title.
placeholderstringnoPlaceholder label to show in the dropdown.
searchPlaceholderstringnoSearch input placeholder text. Displayed until search text is entered.
trimDuplicatesbooleannoSpecifies if the duplicates should be trimmed. false by default. Applicable if mode is set to site or web.
additionalQuerystringnoIf provided will be added to the search query as AND part. Applicable if mode is set to site or web.
+

Interface ISite

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringnoID of the site collection.
titlestringnoTitle of the site.
urlstringnoURL of the site.
webIdstringnoID of the site. **Note: the value is not populated if the mode is set to hub.
hubSiteIdstringnoID of the hub site.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/TaxonomyPicker/index.html b/controls/TaxonomyPicker/index.html new file mode 100644 index 000000000..eac7d2946 --- /dev/null +++ b/controls/TaxonomyPicker/index.html @@ -0,0 +1,2175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TaxonomyPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Taxonomy Picker

+

This control allows you to select one or more Terms from a TermSet via its name or TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the AnchorId.

+
+

Disclaimer

+

This control makes use of the ProcessQuery API end-points to retrieve the managed metadata information. This will get changed once the APIs for managing managed metadata will become available.

+
+

Empty term picker

+

Empty term picker

+

Selecting terms

+

Selecting terms

+

Selected terms in picker

+

Selected terms in the input

+

Term picker: Auto Complete

+

Selected terms in the input

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";
+
+ +
    +
  • Use the TaxonomyPicker control in your code as follows:
  • +
+
<TaxonomyPicker allowMultipleSelections={true}
+                termsetNameOrID="Countries"
+                panelTitle="Select Term"
+                label="Taxonomy Picker"
+                context={this.props.context}
+                onChange={this.onTaxPickerChange}
+                isTermSetSelectable={false} />
+
+ +
    +
  • With the onChange property you can capture the event of when the terms in the picker has changed:
  • +
+
private onTaxPickerChange(terms : IPickerTerms) {
+  console.log("Terms", terms);
+}
+
+ +
    +
  • With the onNewTerm property you can capture the event, when text is in the input field and +enter/return is pressed. With a controlled TaxonomyPicker, this enables you to create the term +and have the same flow as in SharePoint Keywords fields.
  • +
+
    const onNewTerm = (value: IPickerTerm): void => {
+            if(value?.name && EmptyGuid === value.key ){
+                console.log(`TaxonmyPicker.onNewTerm name=${value.name}`, value );
+                // Create keyword
+            } else {
+                console.error(`TaxonmyPicker.onNewTerm name=${value?.name}`, value );
+            }
+        };
+
+ +

Term actions

+

Since version 1.12.0, you can apply term actions to all terms or specific ones. Term actions could for instance be used to retrieve the labels of the term, or retrieve other information. These term actions can be implemented as follows:

+
<TaxonomyPicker allowMultipleSelections={true}
+                termsetNameOrID="Countries"
+                panelTitle="Select Term"
+                label="Taxonomy Picker"
+                context={this.props.context}
+                onChange={this.onServicePickerChange}
+                isTermSetSelectable={false}
+                termActions={{
+                  actions: [{
+                    title: "Get term labels",
+                    iconName: "LocaleLanguage",
+                    id: "test",
+                    invokeActionOnRender: true,
+                    hidden: true,
+                    actionCallback: async (taxService: SPTermStorePickerService, term: ITerm) => {
+                      console.log(term.Name, term.TermsCount);
+                      return {
+                        updateActionType: UpdateType.updateTermLabel,
+                        value: `${term.Name} (updated)`
+                      };
+                    },
+                    applyToTerm: (term: ITerm, triggerActionCb: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: "disabled" | "hidden", value: boolean) => void) => (term && term.Name && term.Name === "internal")
+                  },
+                  {
+                    title: "Hide term",
+                    id: "hideTerm",
+                    invokeActionOnRender: true,
+                    hidden: true,
+                    actionCallback: async (taxService: SPTermStorePickerService, term: ITerm) => {
+                      return {
+                        updateActionType: UpdateType.hideTerm,
+                        value: true
+                      };
+                    },
+                    applyToTerm: (term: ITerm, triggerActionCb: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: "disabled" | "hidden", value: boolean) => void) => (term && term.Name && (term.Name.toLowerCase() === "help desk" || term.Name.toLowerCase() === "multi-column valo site page"))
+                  },
+                  {
+                    title: "Disable term",
+                    id: "disableTerm",
+                    invokeActionOnRender: true,
+                    hidden: true,
+                    actionCallback: async (taxService: SPTermStorePickerService, term: ITerm) => {
+                      return {
+                        updateActionType: UpdateType.disableTerm,
+                        value: true
+                      };
+                    },
+                    applyToTerm: (term: ITerm, triggerActionCb: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: "disabled" | "hidden", value: boolean) => void) => (term && term.Name && term.Name.toLowerCase() === "secured")
+                  },
+                  {
+                    title: "Disable or hide term",
+                    id: "disableOrHideTerm",
+                    invokeActionOnRender: true,
+                    hidden: true,
+                    actionCallback: async (taxService: SPTermStorePickerService, term: ITerm) => {
+                      if (term.TermsCount > 0) {
+                        return {
+                          updateActionType: UpdateType.disableTerm,
+                          value: true
+                        };
+                      }
+                      return {
+                        updateActionType: UpdateType.hideTerm,
+                        value: true
+                      };
+                    },
+                    applyToTerm: (term: ITerm, triggerActionCb: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: "disabled" | "hidden", value: boolean) => void) => true
+                  }]
+                }} />
+
+ +

Term action sample

+

We also provided a default term action which you can use to retrieve the term its labels and will update the term text in the TaxonomyPicker hierarchy.

+
<TaxonomyPicker allowMultipleSelections={true}
+                termsetNameOrID="Countries"
+                panelTitle="Select Term"
+                label="Taxonomy Picker"
+                context={this.props.context}
+                onChange={this.onServicePickerChange}
+                isTermSetSelectable={false}
+                termActions={{
+                  actions: [new TermLabelAction("Get Labels")]
+                }} />
+
+ +

Implementation

+

The TaxonomyPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
panelTitlestringyesTermSet Picker Panel title.
labelstringyesText displayed above the Taxonomy Picker.
disabledbooleannoSpecify if the control needs to be disabled.
contextBaseComponentContextyesContext of the current web part or extension.
initialValuesIPickerTermsnoDefines the terms selected by default. For each term object selected by default, an empty string can be provided for the path and termset properties as these properties are ignored when setting initial values.
allowMultipleSelectionsbooleannoDefines if the user can select only one or many term sets. Default value is false.
termsetNameOrIDstringyesThe name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from.
onChangefunctionnocaptures the event of when the terms in the picker has changed.
onNewTermfunctionnocaptures the event when text is in the input field and the user presses return
isTermSetSelectablebooleannoSpecify if the TermSet itself is selectable in the tree view.
disabledTermIdsstring[]noSpecify which terms should be disabled in the term set so that they cannot be selected.
disableChildrenOfDisabledParentsbooleannoSpecify if you want to disable the child terms when their parent is disabled.
anchorIdstringnoSet the anchorid to a child term in the TermSet to be able to select terms from that level and below.
termActionsITermActionsnoAllows to execute custom action on the term like e.g. get other term labelsITermActions.
hideTagsNotAvailableForTaggingbooleannoSpecifies if the tags marked with 'Available for tagging' = false should be hidden
validateOnLoadbooleannoSpecifies if the initial values will be validated, when the component is loaded. Default value is false
validateInputbooleannoSpecifies if the input text will be validated, when the component focus is changed
hideDeprecatedTagsbooleannoSpecifies if deprecated tags should be hidden
placeholderstringnoShort text hint to display in empty picker
errorMessagestringnoStatic error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence).
onGetErrorMessage(value: IPickerTerms) => string | Promise<string>noThe method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this).
When it returns string:
  • If valid, it returns empty string.
  • If invalid, it returns the error message string to be shown below the picker.

When it returns Promise<string>:
  • The resolved value is display as error message.
  • The rejected, the value is thrown away.
requiredbooleannoSpecifies if to display an asterisk near the label. Note that error message should be specified in onGetErrorMessage or errorMessage
useSessionStoragebooleannoSpecify if the control uses session storage. Default is set to true for better performance.
onPanelSelectionChange(prevValue: IPickerTerms, newValue: IPickerTerms) => voidnoPanel selection change handler. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked.
selectChildrenIfParentSelectedbooleannoSpecifies if the children should be selected when parent item is selected (defaults to false).
+

Interface IPickerTerm

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
keystringyesThe ID of the term
namestringyesThe name of the term
pathstringyesThe path of the term
termSetstringyesThe Id of the parent TermSet of the term
termSetNamestringnoThe Name of the parent TermSet of the term
+

Interface IPickerTerms

+

An Array of IPickerTerm

+

Interface ITermActions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescriptionDefault
actionsITermAction[]yesThe array of supported actions
termActionsDisplayStyleTermActionsDisplayStylenoDefines how to display term action button, available options: text, icon, text and icontext
termActionsDisplayModeTermActionsDisplayModenoDefines how to display term actions, as buttons or dropdownbuttons
initialize(spTermService: SPTermStorePickerService) => Promise\<void>noInitializes the term action with the taxonomy service
+

Interface ITreeItemAction

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringyesUnique id of the term action
titlestringyesAction title
iconNamestringnoName of the icon to be used to display action
hiddenbooleannoSpecify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering.
invokeActionOnRenderbooleannoSpecifies if you want to invoke the action on render
applyToTerm(currentTerm: ITerm, triggerActionCallback: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: "disabled" | "hidden", value: boolean) => void) => Promise\<boolean> | booleanyesMethod checks if the current term is supported for the action. The method provices a couple of additional callback functions to make it possibe to programatically change the terms and its actions.
actionCallback(spTermService: SPTermStorePickerService, currentTerm: ITerm) => Promise\<UpdateAction>yesMethod to be executed when action is fired
+

Interface UpdateAction

+ + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
updateActionTypeUpdateTypeyesDefines the type of update you want to perform
valuestring | booleannoWhen updateTermLabel is used, it should return a string. When hideTerm or disableTerm are used, you should return a boolean.
+

Enum UpdateType

+ + + + + + + + + + + + + + + + + + + + + + + +
Value
updateTermLabel
updateTermsTree
hideTerm
disableTerm
selectTerm
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/TeamChannelPicker/index.html b/controls/TeamChannelPicker/index.html new file mode 100644 index 000000000..109b62de1 --- /dev/null +++ b/controls/TeamChannelPicker/index.html @@ -0,0 +1,1770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TeamChannelPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

TeamChannelPicker control

+

This control allows you to select one or multiple Team Channels based on user's permissions.

+
+

Note

+

You can also check out Microsoft Teams Channel Picker component in the Microsoft Graph Toolkit.

+
+

Here is an example of the control:

+

TeamChannelPicker

+

SelectTeamChannelPicker single selection mode:

+

Teamselection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { TeamChannelPicker } from "@pnp/spfx-controls-react/lib/TeamChannelPicker";
+
+ +
    +
  • Use the TeamChannelPicker control in your code as follows:
  • +
+
<TeamChannelPicker    label="Select Team channel"
+                            teamId={teamId}
+                            selectedChannels={selectedTeamChannels}
+                            appcontext={webpartContext}
+                            itemLimit={1}
+                            onSelectedChannels={_onSelectedTeamChannels}/>
+
+ +
    +
  • The _onSelectedTeamChannels change event returns the team channel(s) and can be implemented as follows:
  • +
+
const _onSelectedTeamChannels ((tagList: ITag[]) => {
+              console.log(tagList);
+      }
+
+ +

Implementation

+

The SelectTeamChannelPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
teamIdstringyesId of Team to get channels
appcontextWebPartContext | ExtensionContextyesThe context object of the SPFx loaded webpart or customizer.
selectedChannelsITag[]yesArray with selected channels
itemLimitnumbernonumber of allowed selected channels
labelstringnoLabel of Picker
stylesIBasePickerStylesnoCustomer Styles of Picker
onSelectedChannels:(tagsList:ITag[]) => void;yescallBack with channels Selected
+

MSGraph Permissions required

+

This control required the flowing scopes :

+

at least : Team.ReadBasic.All, Channel.ReadBasic.All,

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/TeamPicker/index.html b/controls/TeamPicker/index.html new file mode 100644 index 000000000..1bc18f8c2 --- /dev/null +++ b/controls/TeamPicker/index.html @@ -0,0 +1,1745 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TeamPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

TeamPicker control

+

This control allows you to select one or multiple Teams based on user's permissions.

+

Here is an example of the control:

+

TeamPicker

+

SelectTeamPicker single selection mode:

+

Teamselection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { SelectTeamPicker } from "@pnp/spfx-controls-react/lib/TeamPicker";
+
+ +
    +
  • Use the SelectTeamPicker control in your code as follows:
  • +
+
<TeamPicker   label="Select Team"
+                    selectedTeams={selectedTeams}
+                    appcontext={webpartContext}
+                    itemLimit={1}
+                    onSelectedTeams={_onSelectedTeams}/>
+
+ +
    +
  • The _onSelectedTeams change event returns the team(s) and can be implemented as follows:
  • +
+
const _onSelectedTeams ((tagList: ITag[]) => {
+              console.log(tagList);
+      }
+
+ +

Implementation

+

The TeamPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
appcontextWebPartContext | ExtensionContextyesThe context object of the SPFx loaded webpart or customizer.
selectedTeamsITag[]yesArray with Selected Teams
itemLimitnumbernonumber of allowed selected items
labelstringnoLabel of Picker
stylesIBasePickerStylesnoCustomer Styles of Picker
onSelectedTeams:(tagsList:ITag[]) => void;yescallBack with teams Selected
+

## MSGraph Permissions required

+

This control required the flowing scopes :

+

at least : Team.ReadBasic.All, Channel.ReadBasic.All,

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/TermSetNavigation/index.html b/controls/TermSetNavigation/index.html new file mode 100644 index 000000000..4a8e34448 --- /dev/null +++ b/controls/TermSetNavigation/index.html @@ -0,0 +1,1780 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TermSetNavigation - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

TermSetNavigation

+

This control allows you to navigate and select a Term from a TermSet. You can also configure a context menu for a term to execute a specific action.

+

TermSetNavigation

+

termsetNavigation

+

termsetNavigation

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { TermSetNavigation } from '@pnp/spfx-controls-react/lib/TermSetNavigation';
+
+ +
    +
  • Use the TermSetNavigation control in your code as follows:
  • +
+
<TermSetNavigation
+          context={context}
+          themeVariant={themeVariant}
+          termSetId={"289180a0-4a8b-4f08-ae6e-ea3fb1b669e2"}
+          showContextMenu={true}
+          contextMenuItems={[
+            {
+              key: "add",
+              text: "Add",
+              iconProps: { iconName: "add" },
+            },
+            {
+              key: "adit",
+              text: "Edit",
+              iconProps: { iconName: "Edit" },
+            },
+            {
+              key: "remove",
+              text: "Remove",
+              iconProps: { iconName: "delete" },
+            },
+          ]}
+          onSelected={onSelect}
+          onSelectedTermAction={onSelectedTermAction}
+        />
+
+ +
    +
  • With the onSelected property you can get the selcted term:
  • +
+
 const onSelect = React.useCallback((selected: TermStore.Term) => {
+    console.log(selected);
+  }, []);
+
+ +
    +
  • With the onSelectedTermAction property you can get the the action on the contextMenu for tghe selcted term:
  • +
+
  const onSelectedTermAction = React.useCallback((selected: TermStore.Term, option:string) => {
+    console.log(selected, option);
+  }, []);
+
+ +

Implementation

+

The TermSetNavigation control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
themeVariantIReadonlyThemeyesThemeVariant
termSetIdstringyesTerm Set Id
contextBaseComponentContextyesContext of the current web part or extension.
showContextMenubooleannoIf show ConextMenu for term
contextMenuItemsIContextualMenuItem[]noarray of action to show on contextMenu, if is un defined the conbtecxtMenu won't be available
onSelectedonSelected?: (term: TermStore.Term) => voidnoreturn Term Sselcted
onSelectedTermActiononSelectedTermAction?: (term : TermStore.Term, option:string) => voidnoreturn the action selected to to term
+

## MSGraph Permissions required

+

This control required the flowing scopes :

+

at least : , TermStore.Read.All, TermStore.ReadWrite.All,

+

please use M365Cli or PnP Powershell to add these permissions.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/Toolbar/index.html b/controls/Toolbar/index.html new file mode 100644 index 000000000..b35d61460 --- /dev/null +++ b/controls/Toolbar/index.html @@ -0,0 +1,1844 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toolbar - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+ +
+ + +
+
+ + + + + +

Dashboard control

+

Toolbar component for Microsoft Teams.

+
+

Note

+

As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well.

+
+

Here is an example of the control in action:

+

Carousel control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { Toolbar } from '@pnp/spfx-controls-react/lib/Toolbar';
+
+ +
    +
  • Use the Toolbar control in your code as follows:
  • +
+
<Toolbar actionGroups={{
+    'group1': {
+      'action1': {
+        title: 'Edit',
+        iconName: 'Edit',
+        onClick: () => { console.log('Edit action click'); }
+      },
+      'action2': {
+        title: 'New',
+        iconName: 'Add',
+        onClick: () => { console.log('New action click'); }
+      }
+    }
+  }}
+  filters={[{
+    id: "f1",
+    title:
+      "Fruits (any sweet, edible part of a plant that resembles fruit, even if it does not develop from a floral ovary)",
+    items: [
+      { id: "f1f1", title: "Pomes" },
+      { id: "f1f2", title: "Drupes" },
+      { id: "f1f3", title: "Citruses" },
+      { id: "f1f4", title: "Berries" },
+      { id: "f1f5", title: "Melons" },
+    ],
+  },
+  {
+    id: "f3",
+    title: "Cacti",
+  },]}
+  find={true} />
+
+ +

Controlled or uncontrolled management of selected filters

+

The Toolbar component can internally manage the set of selected filters (uncontrolled) or the set of selected filters can be defined using property, selectedFilterIds(controlled).

+

If property selectedFilterIds is undefined then the set of selected filter IDs is uncontrolled and the Toolbar will initialise with an empty set of selected filters. As the user toggles the Toolbar's filters the function set on property, onSelectedFiltersChange, will be called with an array parameter of the currently selected filter IDs. The implementation of this function can return void or an array of filter IDs that the Toolbar should set. By returning an array of filter IDs the onSelectedFiltersChange implementation can alter the selected filters of an uncontrolled Toolbar in response to user attempts to set/clear filters.

+

If the selectedFilterIds property is defined then the set of selected filter IDs is controlled and the Toolbar shall display selected filters according the contents of the array property. The onSelectedFiltersChange function will still be called, but the returned value will have no effect on the filters displayed as selected by the Toolbar.

+

Implementation

+

The Toolbar component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
actionGroupsTActionGroupsyesToolbar actions groups.
filtersTFiltersnoToolbar filters.
findbooleannoSpecifies if searchbox should be displayed.
filtersSingleSelectbooleannoSpecifies if a user can select only one filter at a time.
onSelectedFiltersChange(selectedFilters: string[]) => (string[] | void)noFilter changed handler. Called when user toggles selection of a filter.
selectedFilterIdsstring[]noSpecifies the IDs of the filters which should be displayed as selected by the Toolbar.
onFindQueryChange(findQuery: string) => stringnoSearch query changed handler.
+

Type TActionGroups

+

Provides Toolbar action groups settings

+
type TActionGroups = {
+    [slug: string]: TActions;
+};
+
+ +

Type TActions

+

Provides Toolbar actions settings

+
type TActions = {
+    [actionKey: string]: TAction;
+};
+
+ +

Type TAction

+

Provides Toolbar action settings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
titlestringyesAction title.
iconNamestringnoAction icon name.
multibooleannoFor future.
onClickComponentEventHandler<ToolbarItemProps>noAction onClick handler.
+

Type TFilters

+

Provides Toolbar filters settings

+
type TFilters = ObjectShorthandCollection<TreeItemProps, never>;
+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/TreeView/index.html b/controls/TreeView/index.html new file mode 100644 index 000000000..ec1399cac --- /dev/null +++ b/controls/TreeView/index.html @@ -0,0 +1,2162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeView - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

TreeView

+ +

TreeView control

+

This graphical control allows to present a hierarchical view of information. Each tree item can have a number of subitems. This is often visualized by indentation in a list. A tree item can be expanded to reveal subitems (if exist), and collapsed to hide subitems.

+

Here are examples of the control in action:

+

Tree View control

+

With all possible options

+

Tree View control

+

Without check boxes or when selection mode is 'None'

+

Tree View control

+

Without check boxes, and selection mode is multiple

+

Tree View control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { TreeView, ITreeItem, TreeViewSelectionMode } from "@pnp/spfx-controls-react/lib/TreeView";
+
+ +
    +
  • Use the TreeView control in your code as follows:
  • +
+
<TreeView 
+    items={treeitems}
+    defaultExpanded={false}
+    selectionMode={TreeViewSelectionMode.Multiple}
+    selectChildrenMode={SelectChildrenMode.Select | SelectChildrenMode.Unselect}
+    showCheckboxes={true}
+    treeItemActionsDisplayMode={TreeItemActionsDisplayMode.ContextualMenu}
+    defaultSelectedKeys={['key1', 'key2']}
+    expandToSelected={true}
+    defaultExpandedChildren={true}
+    onSelect={this.onTreeItemSelect}
+    onExpandCollapse={this.onTreeItemExpandCollapse}
+    onRenderItem={this.renderCustomTreeItem}
+    theme={this.props.themeVariant} />
+
+ +
    +
  • With the onSelect property you can capture the event of when the tree item in the TreeView has changed the selection:
  • +
+
private onTreeItemSelect(items: ITreeItem[]) {
+    console.log("Items selected: ", items);
+}
+
+ +
    +
  • With the onExpandCollapse property you can capture the event of when the tree item in the TreeView has expanded or collapsed:
  • +
+
private onTreeItemExpandCollapse(item: ITreeItem, isExpanded: boolean) {
+    console.log((isExpanded ? "Item expanded: " : "Item collapsed: ") + item);  
+}
+
+ +

Custom Rendering

+

You can fully customize how tree items are rendered by providing the onRenderItem callback function and returning whatever JSX.Element you want.

+

For example, you can define your function in a .tsx file like this:

+
import * as React from 'react';
+
+private renderCustomTreeItem(item: ITreeItem): JSX.Element {
+  return (
+    <span>
+      {
+        item.iconProps &&
+        <i className={"ms-Icon ms-Icon--" + item.iconProps.iconName} style={{ paddingRight: '4px' }} />
+      }
+      {item.label}
+    </span>
+  );
+}
+
+ +

Implementation

+

The TreeView control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
itemsITreeItem[]yesAn array of tree items to display. refer example.
defaultExpandedbooleannoSpecify if the tree items are displayed as expanded by default (defaults to false.
selectionModeenumnoSpecifies the selection mode of tree view (defaults to Single selection).
selectChildrenIfParentSelectedbooleannoSpecifies if the children should be selected when parent item is selected (defaults to false). Deprecated: prefer usage of selectChildrenMode for more flexibility.
selectChildrenModeSelectChildrenModenoSpecifies if the children should be selected when parent item is selected (defaults to None). Flagged enum, values can be combined eg. SelectChildrenMode.Select \| SelectChildrenMode.Unselect
showCheckboxesbooleanyesSpecify if the checkboxes should be displayed for selection.
treeItemActionsDisplayModeTreeItemActionsDisplayModenoSpecifies the display mode of the tree item actions.
defaultSelectedKeysstring[]noSpecifies keys of items to be selected by default.
expandToSelectedbooleannoSpecifies if the tree view is expanded to display selected nodes.
onExpandCollapsefunctionnoDefines a onExpandCollapse function to raise when the tree item has expanded or collapsed.
onSelectfunctionnoCaptures the event of when the tree item selection has changed.
onRenderItemfunctionnoOptional callback to provide custom rendering of the item (default is simple text of item label and a checkbox for selection).
defaultExpandedChildrenbooleannoDefault expand / collapse behavior for the child nodes. By default this is set to true.
defaultExpandedKeysstring[]noKeys of items expanded by default.
themeIPartialTheme | IThemenoSet Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.
+

Enum TreeViewSelectionMode

+

Specifies the selection mode of tree item.

+ + + + + + + + + + + + + + + + + +
Value
Single
Multiple
None
+

Enum SelectChildrenMode

+

Specifies when the children of a selected item need to be automatically selected.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
NoneChildren are never selected
SelectWhen selecting an item, its children are also selected
UnselectWhen unselecting an item, its children are also unselected
MountWhen the component is mounted, all children of selected items are also selected
UpdateWhen the component receives new props, all children of selected items are also selected
AllShorthand for a combination of all of the above, same as SelectChildrenMode.Select \| SelectChildrenMode.Unselect \| SelectChildrenMode.Mount \| SelectChildrenMode.Update
+

Interface ITreeItem

+

Each tree item in the treeitems property is defined as ITreeItem as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
keystringyesThe unique ID of the tree item.
labelstringyesText displayed next to checkbox.
subLabelstringnoThe sub label of the tree item.
iconPropsIIconPropsnoCustom icon to be rendered before label.
disabledbooleannoSpecify if the tree item needs to be disabled. Default is false.
selectablebooleannoSpecify if the tree item can be selected. Default is true.
dataanynoSpecify an additional data of the tree item.
actionsITreeItemAction[]noSpecify list of actions for the tree item.
childrenITreeItem[]noSpecify list of child tree items.
+

Interface ITreeItemAction

+

Specifies the list of actions for the tree item.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
idstringyesUnique id of the action.
titlestringyesTitle of the action.
iconPropsIIconPropsnoName of the icon to be used to display action.
hiddenbooleannoSpecify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering.
invokeActionOnRenderbooleannoSpecifies if you want to invoke the action on render.
actionCallback(currentTreeItem: ITreeItem) => voidyesMethod to be executed when action is fired.
+

Enum TreeItemActionsDisplayMode

+

Specifies the display mode of the tree item action.

+ + + + + + + + + + + + + + +
Value
Buttons
ContextualMenu
+

Example of array of tree items used to render control as in 2nd screenshot

+
items: [
+          {
+            key: "R1",
+            label: "Root",
+            subLabel: "This is a sub label for node",
+            iconProps: skypeCheckIcon,
+            actions: [{
+              title: "Get item",
+              iconProps: {
+                iconName: 'Warning',
+                style: {
+                  color: 'salmon',
+                },
+              },
+              id: "GetItem",
+              actionCallback: async (treeItem: ITreeItem) => {
+                console.log(treeItem);
+              }
+            }],
+            children: [
+              {
+                key: "1",
+                label: "Parent 1",
+                selectable: false,
+                children: [
+                  {
+                    key: "3",
+                    label: "Child 1",
+                    subLabel: "This is a sub label for node",
+                    actions: [{
+                      title:"Share",
+                      iconProps: {
+                        iconName: 'Share'
+                      },
+                      id: "GetItem",
+                      actionCallback: async (treeItem: ITreeItem) => {
+                        console.log(treeItem);
+                      }
+                    }],
+                    children: [
+                      {
+                        key: "gc1",
+                        label: "Grand Child 1",
+                        actions: [{
+                          title: "Get Grand Child item",
+                          iconProps: {
+                            iconName: 'Mail'
+                          },
+                          id: "GetItem",
+                          actionCallback: async (treeItem: ITreeItem) => {
+                            console.log(treeItem);
+                          }
+                        }]
+                      }
+                    ]
+                  },
+                  {
+                    key: "4",
+                    label: "Child 2",
+                    iconProps: skypeCheckIcon
+                  }
+                ]
+              },
+              {
+                key: "2",
+                label: "Parent 2"
+              },
+              {
+                key: "5",
+                label: "Parent 3",
+                disabled: true
+              },
+              {
+                key: "6",
+                label: "Parent 4",
+                selectable: true
+              }
+            ]
+          },
+          {
+            key: "R2",
+            label: "Root 2",
+            children: [
+              {
+                key: "8",
+                label: "Parent 5"
+              }
+            ]
+          }
+        ]
+
+ +

IconpProps in above example can be declared as below

+
private skypeCheckIcon: IIconProps = { iconName: 'SkypeCheck' };
+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/UploadFiles/index.html b/controls/UploadFiles/index.html new file mode 100644 index 000000000..5fa4c213e --- /dev/null +++ b/controls/UploadFiles/index.html @@ -0,0 +1,1734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UploadFiles - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

UploadFiles

+

This control allows to drag and drop files and manage files before upload.

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import {
+  UploadFiles,
+} from '@pnp/spfx-controls-react/lib/UploadFiles';
+
+ +
    +
  • Use the UploadFiles control in your code as follows:
  • +
+
 <UploadFiles
+          pageSize={20}
+          context={context}
+          title="Upload Files"
+          onUploadFiles={(files) => {
+            console.log("files", files);
+          }}
+          themeVariant={themeVariant}
+        />
+
+ +

uploadFiles +uploadFiles +uploadFiles

+

Implementation

+

The UploadFiles can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
pageSizenumbernonumber of files to show per page base on this value the height of control is calculate, default 15
contextWebPartContextyeswebPartContext
titlestringyestitle
onUploadFiles(files: File[]) => void;yesMethod that returns all Files[]
themeVariantIReadonlyThemenoTheme Variant
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/UserPicker/index.html b/controls/UserPicker/index.html new file mode 100644 index 000000000..e391be5ba --- /dev/null +++ b/controls/UserPicker/index.html @@ -0,0 +1,1741 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + User Picker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

User Picker

+

This control allows you to select one or more user from a AAD via its name or starting characters.

+

!

+

Empty user picker

+

Empty user picker

+

Selecting Users

+

Selecting users

+

Selected users in picker

+

Selected users in the input

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { UserPicker } from '@pnp/spfx-controls-react/lib/userPicker';
+import { IUserInfo } from '@pnp/spfx-controls-react/lib/userPicker/models/IUserInfo';
+
+ +
    +
  • Use the UserPicker control in your code as follows:
  • +
+
 <UserPicker
+        context={context}
+        secondaryTextPropertyName="mail"
+        theme={theme}
+        label={
+          <div className={styles.attributeHader}>
+            <Person20Filled color={tokens.colorBrandForeground1} />
+            <Body1>Select User</Body1>
+          </div>
+        }
+        placeholder={"Search User"}
+        onSelectedUsers={onSelectedUsers}
+        onRemoveSelectedUser={onRemovedUser}
+/>
+
+ +
    +
  • With the onSelectedUsers property you can capture the event of when the user in the picker has changed:
  • +
+
const onSelectedUsers = React.useCallback((users: IUserInfo[]) => {
+  console.log(users);
+}, []);
+
+ +
    +
  • With the onRemoveSelectedUser property you can capture the event, when the user is removed from picker.
  • +
+
const onRemovedUser = React.useCallback((user: IUserInfo) => {
+  console.log(user);
+}, []);
+
+ +

Implementation

+

The UseryPicker control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
userSelectionLimitnumbernoNumber selected users allowed
labelstring or JSX.ElementnoText or control displayed above the User Picker.
requiredbooleannoSpecify if the control is required
contextBaseComponentContextyesContext of the current web part or extension.
validationMessagestringnoDefines message to show on picker
messageType"error", "success" , "warning" , "none"noDefines message type to show if validationMessage is defined
onSelectedUsers(users: IUserInfo[]) => voidnocaptures the event of when the users in the picker has changed.
onRemoveSelectedUser(user: IUserInfo) => voidnocaptures the event of when the user in the picker was removed
placeholderstringnoplaceholder to show
defaultSelectdUsersIUserInfo[]nodefault users to show on the picker
themeIReadonlyThemenotheme
secondaryTextPropertyNamevalues :"jobTitle" , "department" , "mail", "officeLocation" , "mobilePhone" , "businessPhones" , "userPrincipalName"nosecondary text to show on persona card
+

Interface IUserInfo extends User interface from `@microsoft/microsoft-graph-types``

+ + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
userPhotostringyesuserPhoto to show on Person card
presencePresenceyesuser Presence
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/VariantThemeProvider/index.html b/controls/VariantThemeProvider/index.html new file mode 100644 index 000000000..ffd7586e4 --- /dev/null +++ b/controls/VariantThemeProvider/index.html @@ -0,0 +1,1815 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VariantThemeProvider - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Variant Theme Provider

+

This control is a super set of the Theme Provider control, which not only allows you to pass the FluentUI Theme to the child controls, but also allows you to apply "variants" or generate a theme starting from the three basic colors, primary color, text color and color background.

+

The idea comes from the possibility of "highlighting" a Web Part in the page or section where it is contained.

+

By default, the SharePoint Modern Pages allow to change the set of colors which are then applied to all controls, but this can only be done at the site level (changing the site theme) or at the page section level (applying variations from the site theme).

+

With this control we have the possibility to apply the variants to the single Web Part or to a portion of it.

+

Here is an example of the control in action inside a Web Part:

+

Variant Theme Provider control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In your component file, import the VariantThemeProvider control as follows:
  • +
+
import { VariantThemeProvider, VariantType, IThemeColors } from "@pnp/spfx-controls-react/lib/VariantThemeProvider";
+
+ +
    +
  • Example on use the VariantThemeProvider control with the 'Neutral' variant on custom theme generated from the 'themeColors' property:
  • +
+
const customThemeColors: IThemeColors = {
+    primaryColor: "#0078d4",
+    textColor: "#323130",
+    backgroundColor: "#ffffff"
+  }
+<VariantThemeProvider 
+    themeColors={customThemeColors} 
+    variantType={VariantType.Neutral}>
+    {/* Child controls */}
+</VariantThemeProvider>
+
+ +
    +
  • Example on use the VariantThemeProvider control with the 'Strong' variant on theme passed with the from the 'theme' property:
  • +
+
<VariantThemeProvider 
+    theme={theme}
+    variantType={VariantType.Strong}>
+    {/* Child controls */}
+</VariantThemeProvider>
+
+ +

Implementation

+

The VariantThemeProvider control can be configured with the following properties (inherits all the properties present in the FluentUI ThemeProvider control):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
asReact.ElementTypenoA component that should be used as the root element of the ThemeProvider component.
refReact.RefnoOptional ref to the root element.
themePartialTheme | ThemenoDefines the theme provided by the user.
rendererStyleRenderernoOptional interface for registering dynamic styles. Defaults to using merge-styles. Use this to opt into a particular rendering implementation, such as emotion, styled-components, or jss. Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation.
applyToelement | body | nonenoDefines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of this control. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body.
variantTypeVariantTypenoVariant type to apply to the theme.
themeColorsIThemeColorsnoObject used to generate a new theme from colors.
+

Interface IThemeColors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
primaryColorstringyesPrimary Color of the theme.
textColorstringyesText Color of the theme.
backgroundColorstringyesBackground Color of the theme.
+

Enum VariantType

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription
NoneApply the theme without variations.
NeutralApply the 'Neutral' variation to the theme.
SoftApply the 'Soft' variation to the theme.
StrongApply the 'Strong' variation to the theme.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/ViewPicker/index.html b/controls/ViewPicker/index.html new file mode 100644 index 000000000..790440cf9 --- /dev/null +++ b/controls/ViewPicker/index.html @@ -0,0 +1,1809 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ViewPicker - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ViewPicker control

+

This control allows you to select available views from lists/libraries of the current site.

+

Here is an example of the control:

+

ViewPicker initial

+

ViewPicker single selection mode:

+

ViewPicker single selection

+

ViewPicker multi selection mode:

+

ViewPicker multi selection

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the control into your component:
  • +
+
import { ViewPicker } from "@pnp/spfx-controls-react/lib/ViewPicker";
+
+ +
    +
  • Use the ViewPicker control in your code as follows:
  • +
+
    <ViewPicker context={this.props.context}
+        listId={"9f3908cd-1e88-4ab3-ac42-08efbbd64ec9"}
+        placeholder={'Select list view(s)'}
+        orderBy={orderBy.Title}
+        multiSelect={true}
+        onSelectionChanged={this.onViewPickerChange} />
+
+ +
    +
  • The onSelectionChanged change event returns the selected view(s) and can be implemented as follows in your webpart:
  • +
+
  private onViewPickerChange = (views: string | string[]) => {
+    console.log("Views:", views);
+  }
+
+ +

Implementation

+

The ViewPicker control can be configured with the following properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
contextBaseComponentContextyesThe context object of the SPFx loaded webpart or customizer.
classNamestringnoIf provided, additional class name to provide on the dropdown element.
disabledbooleannoWhether or not the view picker control is disabled.
filterstringnoFilter views from Odata query.
labelstringnoLabel to use for the control.
listIdstringnoThe List Id of the list.
placeholderstringnoPlaceholder label to show in the dropdown.
orderByEnumnoHow to order the set of views (By ID or Title).
selectedViewstring OR string[]noKeys(View Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed.
multiSelectbooleannoOptional mode indicates if multi-choice selections is allowed. Default to false.
showBlankOptionbooleannoWhether or not to show a blank option. Default to false.
viewsToExcludestring[]noDefines view titles which should be excluded from the view picker control.
webAbsoulteUrlstringnoAbsolute Web Url of target site (user requires permissions)
onSelectionChanged(newValue: string OR string[]): voidnoCallback function when the selected option changes.
+

Enum orderBy

+ + + + + + + + + + + + + + +
Value
Id
Title
+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/WebPartTitle/index.html b/controls/WebPartTitle/index.html new file mode 100644 index 000000000..29995bc4e --- /dev/null +++ b/controls/WebPartTitle/index.html @@ -0,0 +1,1802 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebPartTitle - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

WebPartTitle control

+

This control renders a web part title that is changeable when the page is in edit mode.

+

Here is an example of the control in action:

+

WebPartTitle control

+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • In the root web part file, the one that extends from the BaseClientSideWebPart class. Pass the following properties to your web part main component:
  • +
+
const element: React.ReactElement<IControlsTestProps> = React.createElement(
+  ControlsTest,
+  {
+    title: this.properties.title,
+    displayMode: this.displayMode,
+    updateProperty: (value: string) => {
+      this.properties.title = value;
+    }
+  }
+);
+
+ +
    +
  • Add the title, displayMode, and updateProperty properties to the properties interface of your component:
  • +
+
import { DisplayMode } from '@microsoft/sp-core-library';
+
+export interface IControlsTestProps {
+  title: string;
+  displayMode: DisplayMode;
+  updateProperty: (value: string) => void;
+}
+
+ +
    +
  • In your component file, import the WebPartTitle control as follows:
  • +
+
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
+
+ +
    +
  • Use the WebPartTitle control in your code as follows:
  • +
+
<WebPartTitle displayMode={this.props.displayMode}
+              title={this.props.title}
+              updateProperty={this.props.updateProperty} />
+
+ + +

Since version 1.13.0 the WebPartTitle control has the ability to show a "see all" link by using the moreLink property. The property gives you the flexibility to render the link or component you want to show next to the web part title.

+

You can do this as like in the following example code:

+
<WebPartTitle displayMode={this.props.displayMode}
+              title={this.props.title}
+              updateProperty={this.props.updateProperty}
+              moreLink={
+                <Link href="https://pnp.github.io/sp-dev-fx-controls-react/">See all</Link>
+              } />
+
+ +

If you wish, you may pass a callback function instead, as per the following example code:

+
<WebPartTitle displayMode={this.props.displayMode}
+              title={this.props.title}
+              updateProperty={this.props.updateProperty}
+              moreLink={
+                ()=> {
+                  return (<Link href="https://pnp.github.io/sp-dev-fx-controls-react/">See all</Link>);
+                }
+              } />
+
+ +

The resulting web part title will look like the following:

+

More Link

+

Implementation

+

The WebPartTitle control can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
displayModeDisplayModeyesThis tells the control in which page mode it is rendering.
titlestringyesThe title value for the web part.
updatePropertyFunctionyesFunction that you can pass to update the title in the root web part.
classNamestringnoOptional property to specify a custom class that allows you to change the web part title style.
placeholderstringnoOptional property to specify a custom placeholder to display when the title is editable.
themeVariantIReadonlyThemenoThe current loaded SharePoint theme/section background (More info: Supporting section backgrounds).
moreLinkFunction | JSX.ElementnoOptional property to render a See all link in the web part title.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/BarChart/index.html b/controls/charts/BarChart/index.html new file mode 100644 index 000000000..c98b79944 --- /dev/null +++ b/controls/charts/BarChart/index.html @@ -0,0 +1,2215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bar Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Bar Chart

+

Bar charts represent data values as vertical bars.

+

Default Bar Chart

+

Example Usage

+

To create a bar chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Bar}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+    labels:
+      [
+        'January', 'February', 'March', 'April', 'May', 'June', 'July'
+      ],
+    datasets:
+      [{
+        label: 'My First Dataset',
+        data:
+          [
+            65, 59, 80, 81, 56, 55, 40
+          ],
+        backgroundColor:
+          [
+            'rgba(255, 99, 132, 0.2)',
+            'rgba(255, 159, 64, 0.2)',
+            'rgba(255, 205, 86, 0.2)',
+            'rgba(75, 192, 192, 0.2)',
+            'rgba(54, 162, 235, 0.2)',
+            'rgba(153, 102, 255, 0.2)',
+            'rgba(201, 203, 207, 0.2)'
+          ],
+        borderColor:
+          [
+            'rgb(255, 99, 132)',
+            'rgb(255, 159, 64)',
+            'rgb(255, 205, 86)',
+            'rgb(75, 192, 192)',
+            'rgb(54, 162, 235)',
+            'rgb(153, 102, 255)',
+            'rgb(201, 203, 207)'
+          ],
+        borderWidth: 1
+      }]
+  };
+
+// set the options
+const options: Chart.ChartOptions = {
+  scales:
+  {
+    yAxes:
+      [
+        {
+          ticks:
+          {
+            beginAtZero: true
+          }
+        }
+      ]
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Bar}
+    data={data}
+    options={options}
+  />);
+
+ +

You can omit the backgroundColor, borderColor, and borderWidth values from the code above to render a chart using the default Office palette:

+
// set the data
+const data: Chart.ChartData = {
+    labels:
+      [
+        'January', 'February', 'March', 'April', 'May', 'June', 'July'
+      ],
+    datasets:
+      [{
+        label: 'My First Dataset',
+        data:
+          [
+            65, 59, 80, 81, 56, 55, 40
+          ]
+      }]
+  };
+
+// set the options
+const options: Chart.ChartOptions = {
+  scales:
+  {
+    yAxes:
+      [
+        {
+          ticks:
+          {
+            beginAtZero: true
+          }
+        }
+      ]
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Bar}
+    data={data}
+    options={options}
+  />);
+
+ +

Which will produce the following chart:

+

Default Chart Colors

+

As with all charts, the backgroundColor and borderColor values can be one of the following:

+
    +
  • Array of colors (string[]): each data element in the dataset will be assigned a different color in the same order as they are listed in the array. If there are more data elements than colors, the remaining data elements will have a grey color.
  • +
  • A single color (string): every data element in the dataset will use the same color.
  • +
+

Variations

+

Stacked Bar Chart

+

Stacked Bar Chart

+

If your bar chart has multiple datasets, you can render it as a stacked bar chart by changing the settings on the X and Y axes to enable stacking, as follows:

+
const options: Chart.ChartOptions = {
+  scales: {
+      xAxes: [{
+          stacked: true
+      }],
+      yAxes: [{
+          stacked: true
+      }]
+  }
+};
+
+ +

In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset:

+
const data: Chart.ChartData = {
+      labels:
+        [
+          'January',
+          'February',
+          'March',
+          'April',
+          'May',
+          'June',
+          'July'
+        ],
+      datasets:
+        [
+          {
+            label: 'My First Dataset',
+            data:
+              [
+                65,
+                59,
+                80,
+                81,
+                56,
+                55,
+                40
+              ],
+            fill: false,
+            backgroundColor: 'rgba(255, 99, 132, 0.2)', // same color for all data elements
+            borderColor: 'rgb(255, 99, 132)', // same color for all data elements
+            borderWidth: 1
+          },
+          {
+            label: 'My Second Dataset',
+            data:
+              [
+                15,
+                29,
+                30,
+                8,
+                26,
+                35,
+                20
+              ],
+            fill: false,
+            backgroundColor: 'rgba(255, 159, 64, 0.2)', // same color for all data elements
+            borderColor: 'rgb(255, 159, 64)', // same color for all data elements
+            borderWidth: 1
+          }
+        ]
+    };
+
+ +

Horizontal Bar Chart

+

Horizontal Bar Chart

+

To render a horizontal bar, use the following code:

+
<ChartControl
+    type={ChartType.HorizontalBar}
+    data={data}
+    options={options}
+  />
+
+ +

Using the same options as above. Note that horizontal bar charts can also be stacked using the same approach as above.

+

Dataset Properties

+

Bar charts allow each dataset to have different configuration properties.

+

Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+

For example, the following code will apply the value 'red:' to every element in the dataset.

+
const data: Chart.ChartData = {
+      datasets:
+        [
+          {
+            label: 'My First Dataset',
+            data:
+              [
+                10,
+                20,
+                30,
+              ],
+            backgroundColor: 'red'
+          }
+    };
+
+ +

Whereas the following code will set 10 to backgroundColor 'red', 20 to 'green', and 30 to 'blue'.

+
const data: Chart.ChartData = {
+      datasets:
+        [
+          {
+            label: 'My First Dataset',
+            data:
+              [
+                10,
+                20,
+                30,
+              ],
+            backgroundColor: ['red', 'green', 'blue']
+          }
+    };
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
labelstringDataset label. Appears in the legend and tooltips.
xAxisIDstringThe axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis
yAxisIDstringThe axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis
backgroundColorColor OR Color[]The bar fill color.
borderColorColor OR Color[]The bar border color.
borderWidthnumber OR number[]The bar's border width. Measured in pixels.
borderSkipped'bottom'
'left'
'top'
'right'
Specifies which border should be hidden when rendering bars. This option is useful when custom-rendering charts.
datanumber[]
{ t: Date, y: number}
The chart's data. Required.
hoverBackgroundColorColor OR Color[]The bar's fill color when a mouse hovers over it
hoverBorderColorColor OR Color[]The bar's border color when a mouse hovers over it.
hoverBorderWidthnumber OR number[]The bar's border width when a mouse hovers over it.
+

Data Structure

+

number[]

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, 10, 33, 47]
+
+ +

The chart elements will be rendered in the same order as found in the array.

+

Time Scales

+

You can also provide dates and times instead of labels for each data element. Time scales should be provided as t (as in ticks) and y coordinates:

+
data: [
+  { "t": new Date('December 1 2018'), "y": 46 },
+  { "t": new Date('December 3 2018'), "y": 9 },
+  { "t": new Date('December 7 2018'), "y": 48 },
+  { "t": new Date('December 10 2018'), "y": 13 },
+  { "t": new Date('December 20 2018'), "y": 12 },
+ ]
+
+ +

Or, if you prefer using moment.js:

+
data: [
+  { "t": moment('December 1 2018').valueOf(), "y": 46 },
+  { "t": moment('December 3 2018').valueOf(), "y": 9 },
+  { "t": moment('December 7 2018').valueOf(), "y": 48 },
+  { "t": moment('December 10 2018').valueOf(), "y": 13 },
+  { "t": moment('December 20 2018').valueOf(), "y": 12 },
+]
+
+ +

(add the following to your imports:)

+
import * as moment from 'moment';
+
+ +

To render horizontal axis as a time series, use the following options:

+
options={{
+    scales: {
+      xAxes: [{
+        type: 'time',
+        time: {
+          displayFormats: {
+            // choose the scale that applies to your data,
+            // or pass all the scales
+            'millisecond': 'MMM DD YYYY', // use your own date format
+            'second': 'MMM DD YYYY',
+            'minute': 'MMM DD YYYY',
+            'hour': 'MMM DD YYYY',
+            'day': 'MMM DD YYYY',
+            'week': 'MMM DD YYYY',
+            'month': 'MMM DD YYYY',
+            'quarter': 'MMM DD YYYY',
+            'year': 'MMM DD YYYY',
+          }
+        }
+      }]
+    }
+  }}
+
+ +

Which will produce the following chart:

+

Bar Chart Time Series

+
+

NOTE: As with regular data elements, you should pass the time scale array in the order that you want them to appear. Otherwise, you will get disappointing results.

+
+

Configuration

+

The following configuration options are specific to bar charts:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
barPercentagenumber0.9How much of the category should each bar occupy, in percent. Value should be between 0 and 1.
categoryPercentagenumber0.8How much each category should occupy, in percent. Value should be between 0 and 1.
barThicknessnumber OR "flex"Sets the thickness of each bar. If the default value is used, the bars will be equally sized to match the smallest interval.
If number value is provided, the bar width will be set in pixels and barPercentage and categoryPercentage will be ignored.
If "flex" is used, the widths are calculated automatically based on the previous and following samples so that they take the full available widths without overlap
maxBarThicknessnumberSets the maximum width of every bar.
gridLines.offsetGridLinesbooleantruetrue, bars will fall between the grid lines; grid lines will shift to the left by half a tick interval.
If false, grid line will align with the middle of the bars.
+

For More Information

+

For more information on what options are available with Bar charts, refer to the Bar Chart documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/BubbleChart/index.html b/controls/charts/BubbleChart/index.html new file mode 100644 index 000000000..0233eff09 --- /dev/null +++ b/controls/charts/BubbleChart/index.html @@ -0,0 +1,1844 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bubble Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Bubble Chart

+

Bubble chart show elements across three dimensions. Each bubble in the chart is located according to the first two dimensions. The size of each bubble represents the thid dimension.

+

Default Bubble Chart

+

Example Usage

+

To create a bubble chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Bubble}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  datasets: [
+    {
+      label: "Bubble",
+      data:
+        [
+          { x: 10, y: 20, r: 20 },
+          { x: 85, y: 50, r: 35 },
+          { x: 70, y: 70, r: 5 },
+          { x: 40, y: 100, r: 5 },
+          { x: 50, y: 50, r: 12 },
+          { x: 30, y: 80, r: 15 },
+          { x: 20, y: 30, r: 15 },
+          { x: 40, y: 10, r: 10 }
+        ]
+    }]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: false
+  },
+  title: {
+    display: true,
+    text: "My First Bubbles"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Bubble}
+    data={data}
+    options={options}
+  />);
+
+ +

Dataset Properties

+

Bubble charts allow each dataset to have different configuration properties.

+

Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
backgroundColorColor OR Color[]The bubble's fill color. Default is 'rgba(0,0,0,0.1)'.
borderColorColor OR Color[]The bubble's border color. Default is 'rgba(0,0,0,0.1)'.
borderWidthnumber OR number[]The width of the bubble's border. Measured in pixels. Default is 3.
data{ x: number, y:number, r: number}[]The data to render. Required.
hoverBackgroundColorColor OR Color[]The bubble's background color when a mouse hovers over it.
hoverBorderColorColor OR Color[]The bubble's border color when a mouse hovers over it.
hoverBorderWidthnumber OR number[]The bubble's border width when a mouse hovers over it. Default is 1.
hoverRadiusnumber OR number[]The bubble's radius when a mouse hovers over it. Default is 4.
hitRadiusnumber OR number[]The bubble's radius when a mouse click event occurs. Default is 1.
labelstringThe dataset's label
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
HTMLImageElement
HTMLCanvasElement
HTMLImageElement[]
HTMLCanvasElement[]
Style of bubble. Default is 'circle'
rotationnumber OR number[]The bubble's rotation, in degrees. Default is 0.
radiusnumber OR number[]The bubble's radius. Default is 3.
+

Data Structure

+

The data property of each dataset item consists of an x, y, and r coordinate.

+
{
+    // X Value
+    x: number,
+
+    // Y Value
+    y: number,
+
+    // Bubble radius in pixels
+    r: number
+}
+
+ +
+

NOTE: Unlike the x and y, the r value is measured in pixels and does not scale with the chart.

+
+

For More Information

+

For more information on what options are available with Bubble charts, refer to the Bubble Chart documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/DoughnutChart/index.html b/controls/charts/DoughnutChart/index.html new file mode 100644 index 000000000..295c1ef79 --- /dev/null +++ b/controls/charts/DoughnutChart/index.html @@ -0,0 +1,1859 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Doughnut Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Doughnut Chart

+

Doughnut charts are divided into segments, each of which shows the proportional value of the data.

+

Default Donut Chart

+

Example Usage

+

To create a donut chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Doughnut}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+    labels:
+      [
+        'January', 'February', 'March', 'April', 'May', 'June', 'July'
+      ],
+    datasets: [
+      {
+        label: 'My First Dataset',
+        data:
+          [
+            65, 59, 80, 81, 56, 55, 40
+          ]
+      }
+    ]
+  };
+
+// set the options
+const options: Chart.ChartOptions = {
+    legend: {
+      display: true,
+      position: "left"
+    },
+    title: {
+      display: true,
+      text: "My First Donut"
+    }
+  };
+
+return (
+  <ChartControl
+    type={ChartType.Doughnut}
+    data={data}
+    options={options}
+  />);
+
+ +

Dataset Properties

+

Doughnut charts allow each dataset to have different configuration properties.

+

Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
backgroundColorColor[]The segment's fill color.
borderColorColor[]The segment's border color.
borderWidthnumber[]The segment's border width. Measured in pixels.
datanumber[]The chart's data. Required.
hoverBackgroundColorColor[]The segment's fill color when a mouse hovers over it
hoverBorderColorColor[]The segment's border color when a mouse hovers over it.
hoverBorderWidthnumber[]The segment's border width when a mouse hovers over it.
+

Data Structure

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, 10, 33, 47]
+
+ +

Configuration

+

The following configuration options are specific to doughnut charts:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
cutoutPercentagenumber50The percentage of the chart that is cut out of the middle.
rotationnumber-0.5 * Math.PIThe angle at which the doughtnut segments start
circumferencenumber2 * Math.PIThe total circumference of the donut chart.
animation.animateRotatebooleantruetrue will animate the chart while rotating it.
animation.animateScalebooleanfalsetrue will animate the chart while scaling it.
+

For More Information

+

For more information on what options are available with Doughnut charts, refer to the Doughnut and Pie documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/LineChart/index.html b/controls/charts/LineChart/index.html new file mode 100644 index 000000000..7b101691f --- /dev/null +++ b/controls/charts/LineChart/index.html @@ -0,0 +1,2462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Line Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Line Chart

+

Line charts represent data values as plotted points on a line.

+

Default Line Chart

+

Example Usage

+

To create a line chart, add the ChartControl import:

+
import { ChartControl } from "@pnp/spfx-controls-react/lib/ChartControl";
+
+ +

Then render the ChartControl:

+
<ChartControl
+    type='line'
+    data={data}
+    options={options}
+  />
+
+ +

Alternatively, you can use the following import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Followed by:

+
 <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      fill: false,
+      lineTension: 0,
+      data:
+        [
+          65, 59, 80, 81, 56, 55, 40
+        ]
+    }
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: false,
+  },
+  title: {
+    display: true,
+    text: "My First Line Chart"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />);
+
+ +

Variations

+

Curved lines

+

Curved Line Chart

+

You can render curved lines instead of straight lines by removing the lineTension setting from each dataset, or by setting it to a value other than 0.

+

For example, to render the above chart, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+        label: 'My First Dataset',
+        fill: false,
+        //lineTension: 0, -- removed
+        data:
+          [
+            -65, -59, 80, 81, -56, 55, 40
+          ],
+        backgroundColor: "rgba(255, 99, 132, 0.2)",
+        borderColor: "rgb(255, 99, 132)",
+        borderWidth: 1
+      },
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: false,
+  },
+  title: {
+    display: true,
+    text: "My First Curved Line Chart"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />);
+
+ +

Area Chart

+

Area Chart

+

To render an area chart, change the fill setting of the dataset to true.

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      fill: true,
+      lineTension: 0,
+      data:
+        [
+          65, 59, 80, 81, 56, 55, 40
+        ]
+    }
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: false,
+  },
+  title: {
+    display: true,
+    text: "My First Area Chart"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />);
+
+ +

If your chart has negative and positive values, you can control where the filled area by setting the fill setting to one of the following value:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
fill ValueDescriptionSample
'start'Fill from the bottom of the chartstart fill
'end'Fill from the top of the chartend fill
'origin'Fill from the 'zero' line Same as trueorigin fill
+

For example, the code below will set the fill value to start:

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      fill: 'start',
+      lineTension: 0,
+      data:
+        [
+          -65, -59, 80, 81, -56, 55, 40
+        ]
+    }
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: false,
+  },
+  title: {
+    display: true,
+    text: "My First Area Chart"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />);
+
+ +

Which renders the following chart:

+

Area Chart with Fill = 'start'

+

Stacked Area Chart

+

Stacked Area Chart

+

If your bar chart has multiple datasets, you can render it as a stacked area chart by changing the settings on the Y axis to enable stacking, as follows:

+
const options: Chart.ChartOptions = {
+  scales: {
+      yAxes: [{
+          stacked: true
+      }]
+  }
+};
+
+ +

In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset.

+

For example, to render the above chart, use the following code:

+
const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      fill: true,
+      lineTension: 0,
+      data:
+        [
+          -65, -59, 80, 81, -56, 55, 40
+        ],
+      backgroundColor: "rgba(255, 99, 132, 0.2)",
+      borderColor: "rgb(255, 99, 132)",
+      borderWidth: 1
+    },
+    {
+      label: 'My Second Dataset',
+      fill: true,
+      lineTension: 0,
+      data:
+        [
+          45, 49, 88, 71, -36, 35, 60
+        ],
+      backgroundColor: 'rgba(255, 159, 64, 0.2)',
+      borderColor: 'rgb(255, 159, 64)',
+      borderWidth: 1
+    }
+
+  ]
+};
+
+const options: Chart.ChartOptions =  {
+  legend: {
+    display: false,
+  },
+  title: {
+    display: true,
+    text: "My First Stacked Area Chart"
+  },
+  scales: {
+    yAxes: [{
+      stacked: true
+    }]
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Line}
+    data={data}
+    options={options}
+  />);
+
+ +

As with lines, you can set the lineTension value to render curved lines instead of straight lines:

+

Curved Area Chart

+

In addition to the fill values listed above, you can specify how each dataset fill:

+ + + + + + + + + + + + + + + + + + + + +
fill Value TypeDescriptionSample Values
numberFill to dataset by its absolute index1, 2, 3, ...
stringFill to dataset by its relative index'-3', '-2', '-1', '+1', '+2', '+3', ...
+

For example, if you use declare your datasets with the following fill values:

+
const data: Chart.ChartData = {
+      labels:
+        [
+          'January', 'February', 'March', 'April', 'May', 'June', 'July'
+        ],
+      datasets: [
+        {
+          label: 'My First Dataset',
+          fill: "start",
+          lineTension: 0,
+          data:
+            [
+              -65, -59, 80, 81, -56, 55, 40
+            ],
+          backgroundColor: "rgba(255, 99, 132, 0.2)",
+          borderColor: "rgb(255, 99, 132)",
+          borderWidth: 1
+        },
+        {
+          label: 'My Second Dataset',
+          fill: '-1',
+          lineTension: 0,
+          data:
+            [
+              45, 49, 88, 71, -36, 35, 60
+            ],
+          backgroundColor: 'rgba(255, 159, 64, 0.2)',
+          borderColor: 'rgb(255, 159, 64)',
+          borderWidth: 1
+        }
+
+      ]
+    };
+
+ +

Will cause the first dataset to fill from the bottom of the chart, while the second dataset will fill to the previous dataset (by it's relative index of -1)

+

Stacked Area Chart with fill values start and '-1'

+

Dataset Properties

+

Line charts allow each dataset to have different configuration properties.

+

Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
labelstringDataset label. Appears in the legend and tooltips.
xAxisIDstringThe axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis
yAxisIDstringThe axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis
backgroundColorColor OR Color[]The fill color under the line.
borderColorColor OR Color[]The color of the line.
borderWidthnumber OR number[]The width of the line. Measured in pixels.
borderDashnumber[]The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid.
borderDashOffsetnumberThe distance to offset dashes.
borderCapStyle'butt'
'round'
'square'
Specifies the end of the lines. Default is 'butt'.
borderJoinStyle'bevel'
'round'
'miter'
Determines the shape used to join two line segments where they meet. Default is 'miter'.
cubicInterpolationMode'default'
'monotone'
Determins which algorithm is used to interpolate a smooth curve between data points.
datanumber[]
Point[]
The chart's data. Required.
fillfalse
number
string
'start'
'end'
'origin'
Controls how the dataset's area is filled.
lineTensionnumberTtension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone.
pointBackgroundColorColor OR Color[]The point's fill color.
pointBorderColorColor OR Color[]The point's border color.
pointBorderWidthnumber OR number[]The point's border width.
pointRadiusnumber OR number[]The point's fill color.
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
HTMLImageElement
HTMLCanvasElement
HTMLImageElement[]
HTMLCanvasElement[]
Style of point.
pointRotationnumber OR number[]The point's roation, in degrees.
pointHitRadiusnumber OR number[]The point's border width.
pointHoverBackgroundColorColor OR Color[]The point's background color when a mouse hovers over it.
pointHoverBorderColorColor OR Color[]The point's border color when a mouse hovers over it.
pointHoverBorderWidthnumber OR number[]The point's border width when a mouse hovers over it.
pointHoverRadiusnumber OR number[]The point's radius width when a mouse hovers over it.
showLinebooleanThe point's radius width when a mouse hovers over it.
spanGapsbooleanThe point's radius width when a mouse hovers over it.
steppedLineboolean
'before'
'after'
Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting.
+

Data Structure

+

number[]

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, -10, 33, -47]
+
+ +

The chart elements will be rendered in the same order as found in the array.

+

Point[]

+

You can also provide data elements with x and y coordinates:

+
data: [{
+    x: 10,
+    y: 20
+}, {
+    x: 15,
+    y: 10
+}]
+
+ +

Point Configuration

+

Point elements can be configured to change their appearance using the following configuration options:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
radiusnumber3Point radius.
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
'circle'Style of point.
rotationnumber0Rotation of the point, in degrees.
backgroundColorColor'rgba(0,0,0,0.1)Fill color.
borderWidthnumber1Stroke width.
borderColorColor'rgba(0,0,0,0.1)Stroke color.
hitRadiusnumber1Extra radius added around the point to make it easier to detect mouse events.
hoverRadiusnumber4Point radius, when mouse hovers over point.
hoverBorderWidthnumber1Stroke width, when mouse hovers over point.
+

Configuration

+

The following configuration options are specific to line charts:

+ + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
showLinesbooleantrueIndicates whether a line will be drawn between each data point. A value of false will not render lines.
spanGapsbooleanfalseIndicates whether invalid number values (NaN) will cause a break in the line . A value of false will not span data gaps and cause a break in the line.
+

For More Information

+

For more information on what options are available with Line charts, refer to the Line Chart documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/PieChart/index.html b/controls/charts/PieChart/index.html new file mode 100644 index 000000000..8c77126ab --- /dev/null +++ b/controls/charts/PieChart/index.html @@ -0,0 +1,1970 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pie Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Pie Chart

+

Pie charts are divided into segments, each of which shows the proportional value of the data.

+

Default Pie Chart

+

Example Usage

+

To create a pie chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Pie}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+ const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      data:
+        [
+          10, 50, 20, 60, 30, 70, 40
+        ]
+    }
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: true,
+    position: "left"
+  },
+  title: {
+    display: true,
+    text: "My First Pie"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Pie}
+    data={data}
+    options={options}
+  />);
+
+ +

Variations

+

Half-Moon Pie charts

+

Half-Moon Pie Chart

+

By default, pie charts (and doughnut charts) render a whole circle. You can change the chart's circumference option to render partial circles.

+

The default circumference value is 2 * Math.PI. To render a half-moon, specify a half value (i.e.: Math.PI), as follows:

+
 const options: Chart.ChartOptions = {
+      circumference: Math.PI,
+      legend: {
+        display: true,
+        position: "left"
+      },
+      title: {
+        display: true,
+        text: "My First Pie"
+      }
+    };
+
+ +

Which renders the following half-moon:

+

Sideway Half-Moon Pie Chart

+

To rotate the pie chart 90 degrees to the left, specify a rotation value in the chart's options. For example, to render the horizontal half-moon chart shown at the top of this section, use the following options:

+
 const options: Chart.ChartOptions = {
+      circumference: Math.PI,
+      rotation: -1 * Math.PI,
+      legend: {
+        display: true,
+        position: "left"
+      },
+      title: {
+        display: true,
+        text: "My First Pie"
+      }
+    };
+
+ +

Doughnut charts

+

Technically, doughnut charts and pie charts are derived from the same class in Chart.js, where a doughnut chart's cutoutPercentage is set to 50.

+

If you wish to render simple doughnut charts, use the Doughnut Chart type.

+

However, if you wish to customize how the pie/doughtnut chart is rendered, you can set the cutout percentage to a different value.

+

For example, you can use the following code to render a custom "fuel-gauge" chart:

+
 const options: Chart.ChartOptions = {
+      circumference: 1 * Math.PI,
+      rotation: 1 * Math.PI,
+      cutoutPercentage: 60,
+      legend: {
+        display: true,
+        position: "left"
+      },
+      title: {
+        display: true,
+        text: "My First Pie"
+      }
+    };
+
+ +

Will produce the following chart:

+

Vroom vroom!

+

Dataset Properties

+

Pie charts allow each dataset to have different configuration properties.

+

Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
backgroundColorColor[]The segment's fill color.
borderColorColor[]The segment's border color.
borderWidthnumber[]The segment's border width. Measured in pixels.
datanumber[]The chart's data. Required.
hoverBackgroundColorColor[]The segment's fill color when a mouse hovers over it
hoverBorderColorColor[]The segment's border color when a mouse hovers over it.
hoverBorderWidthnumber[]The segment's border width when a mouse hovers over it.
+

Data Structure

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, 10, 33, 47]
+
+ +

Configuration

+

The following configuration options are specific to pie charts:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
cutoutPercentagenumber50The percentage of the chart that is cut out of the middle.
rotationnumber-0.5 * Math.PIThe angle at which the pie segments start
circumferencenumber2 * Math.PIThe total circumference of the donut chart.
animation.animateRotatebooleantruetrue will animate the chart while rotating it.
animation.animateScalebooleanfalsetrue will animate the chart while scaling it.
+

For More Information

+

For more information on what options are available with Pie charts, refer to the Doughtnut and Pie documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/PolarAreaChart/index.html b/controls/charts/PolarAreaChart/index.html new file mode 100644 index 000000000..5c360d5de --- /dev/null +++ b/controls/charts/PolarAreaChart/index.html @@ -0,0 +1,1847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Polar Area Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Polar Chart

+

Polar charts are similar to pie charts, except that each segment has the same angle, and the radius of each segment differs depending on the value.

+

Default Polar Chart

+

Example Usage

+

To create a polar area chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.PolarArea}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    [
+      'January', 'February', 'March', 'April', 'May', 'June', 'July'
+    ],
+  datasets: [
+    {
+      label: 'My First Dataset',
+      data:
+        [
+          10, 50, 20, 60, 30, 70, 40
+        ]
+    }
+  ]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  legend: {
+    display: true,
+    position: "left"
+  },
+  title: {
+    display: true,
+    text: "My First Polar"
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.PolarArea}
+    data={data}
+    options={options}
+  />);
+
+ +

Dataset Properties

+

Polar area charts allow each dataset to have different configuration properties.

+

Properties are provided as arrays. The settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
backgroundColorColor[]The segment's fill color.
borderColorColor[]The segment's border color.
borderWidthnumber[]The segment's border width. Measured in pixels.
datanumber[]The chart's data. Required.
hoverBackgroundColorColor[]The segment's fill color when a mouse hovers over it
hoverBorderColorColor[]The segment's border color when a mouse hovers over it.
hoverBorderWidthnumber[]The segment's border width when a mouse hovers over it.
+

Data Structure

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, 10, 33, 47]
+
+ +

Configuration

+

The following configuration options are specific to polar area charts:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
rotationnumber-0.5 * Math.PIThe angle at which the polar segments start
animation.animateRotatebooleantruetrue will animate the chart while rotating it.
animation.animateScalebooleanfalsetrue will animate the chart while scaling it.
+

For More Information

+

For more information on what options are available with Polar Area charts, refer to the Polar Area documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/RadarChart/index.html b/controls/charts/RadarChart/index.html new file mode 100644 index 000000000..d23e91099 --- /dev/null +++ b/controls/charts/RadarChart/index.html @@ -0,0 +1,1891 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Radar Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Radar Chart

+

Radar charts are best used when comparing points of two or more datasets.

+

Default Radar Chart

+

Example Usage

+

To create a radar chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Radar}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  labels:
+    ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
+  datasets: [
+    // It is better to use multiple datasets for radar charts
+    {
+      label: "My First Dataset",
+      data: [65, 59, 90, 81, 56, 55, 40],
+      fill: true,
+      // semi-transparent colors are best
+      backgroundColor: "rgba(255, 99, 132, 0.2)",
+      borderColor: "rgb(255, 99, 132)",
+      pointBackgroundColor: "rgb(255, 99, 132)",
+      pointBorderColor: "#fff",
+      pointHoverBackgroundColor: "#fff",
+      pointHoverBorderColor: "rgb(255, 99, 132)"
+    },
+    {
+      label: "My Second Dataset",
+      data: [28, 48, 40, 19, 96, 27, 100],
+      fill: true,
+      backgroundColor: "rgba(54, 162, 235, 0.2)",
+      borderColor: "rgb(54, 162, 235)",
+      pointBackgroundColor: "rgb(54, 162, 235)",
+      pointBorderColor: "#fff",
+      pointHoverBackgroundColor: "#fff",
+      pointHoverBorderColor: "rgb(54, 162, 235)"
+    }]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  // Using an aspect ratio of 1 will render a square chart area
+  aspectRatio: 1,
+  elements: {
+    line: {
+      tension: 0,
+      borderWidth: 3
+    }
+  }
+};
+
+// render the chart
+return (
+  <ChartControl
+    type={ChartType.Radar}
+    data={data}
+    options={options}
+  />);
+
+ +

Dataset Properties

+

Radar charts allow each dataset to have different configuration properties.

+

Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
labelstringDataset label. Appears in the legend and tooltips.
backgroundColorColor OR Color[]The fill color under the line.
borderColorColor OR Color[]The color of the line.
borderWidthnumber OR number[]The width of the line. Measured in pixels.
borderDashnumber[]The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid.
borderDashOffsetnumberThe distance to offset dashes.
borderCapStyle'butt'
'round'
'square'
Specifies the end of the lines. Default is 'butt'.
borderJoinStyle'bevel'
'round'
'miter'
Determines the shape used to join two line segments where they meet. Default is 'miter'.
datanumber[]The chart's data. Required.
fillfalse
number
string
'start'
'end'
'origin'
Controls how the dataset's area is filled.
lineTensionnumberTtension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone.
pointBackgroundColorColor OR Color[]The point's fill color.
pointBorderColorColor OR Color[]The point's border color.
pointBorderWidthnumber OR number[]The point's border width.
pointRadiusnumber OR number[]The point's fill color.
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
HTMLImageElement
HTMLCanvasElement
HTMLImageElement[]
HTMLCanvasElement[]
Style of point.
pointRotationnumber OR number[]The point's roation, in degrees.
pointHitRadiusnumber OR number[]The point's border width.
pointHoverBackgroundColorColor OR Color[]The point's background color when a mouse hovers over it.
pointHoverBorderColorColor OR Color[]The point's border color when a mouse hovers over it.
pointHoverBorderWidthnumber OR number[]The point's border width when a mouse hovers over it.
pointHoverRadiusnumber OR number[]The point's radius width when a mouse hovers over it.
+

Data Structure

+

The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis:

+
data: [20, 10, 33, 47]
+
+ +

For More Information

+

For more information on what options are available with Radar charts, refer to the Radar documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/charts/ScatterChart/index.html b/controls/charts/ScatterChart/index.html new file mode 100644 index 000000000..15af517ed --- /dev/null +++ b/controls/charts/ScatterChart/index.html @@ -0,0 +1,2095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Scatter Chart - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

ChartControl - Scatter Chart

+

Scatter charts are similar to line charts, except that the X axis (the horizontal axis) uses data values.

+

Unlike other charts, scatter charts use x and y coordinates.

+

Default Scatter Chart

+

Example Usage

+

To create a scatter chart, add the ChartControl import:

+
import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
+ +

Then render the ChartControl:

+
 <ChartControl
+    type={ChartType.Scatter}
+    data={data}
+    options={options}
+  />
+
+ +

For example, to render the chart above, use the following code:

+
// set the data
+const data: Chart.ChartData = {
+  datasets: [{
+    label: 'Scatter Dataset',
+    data: [
+      {
+        x: -10,
+        y: 0
+      },
+      {
+        x: 0,
+        y: 10
+      },
+      {
+        x: 6,
+        y: 4
+      },
+      {
+        x: 2,
+        y: 6
+      },
+      {
+        x: -4,
+        y: 7
+      },
+      {
+        x: -8,
+        y: 5
+      },
+      {
+        x: 10,
+        y: 5
+      }]
+  }]
+};
+
+// set the options
+const options: Chart.ChartOptions = {
+  scales: {
+    xAxes: [{
+      type: 'linear',
+      position: 'bottom'
+    }]
+  }
+};
+
+return (
+  <ChartControl
+    type={ChartType.Scatter}
+    data={data}
+    options={options}
+  />);
+
+ +

Dataset Properties

+

Scatter charts allow each dataset to have different configuration properties.

+

Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
labelstringDataset label. Appears in the legend and tooltips.
xAxisIDstringThe axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis
yAxisIDstringThe axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis
backgroundColorColor OR Color[]The fill color under the line.
borderColorColor OR Color[]The color of the line.
borderWidthnumber OR number[]The width of the line. Measured in pixels.
borderDashnumber[]The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid.
borderDashOffsetnumberThe distance to offset dashes.
borderCapStyle'butt'
'round'
'square'
Specifies the end of the lines. Default is 'butt'.
borderJoinStyle'bevel'
'round'
'miter'
Determines the shape used to join two line segments where they meet. Default is 'miter'.
cubicInterpolationMode'default'
'monotone'
Determins which algorithm is used to interpolate a smooth curve between data points.
dataPoint[]The chart's data. Required.
fillfalse
number
string
'start'
'end'
'origin'
Controls how the dataset's area is filled.
lineTensionnumberTtension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone.
pointBackgroundColorColor OR Color[]The point's fill color.
pointBorderColorColor OR Color[]The point's border color.
pointBorderWidthnumber OR number[]The point's border width.
pointRadiusnumber OR number[]The point's fill color.
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
HTMLImageElement
HTMLCanvasElement
HTMLImageElement[]
HTMLCanvasElement[]
Style of point.
pointRotationnumber OR number[]The point's roation, in degrees.
pointHitRadiusnumber OR number[]The point's border width.
pointHoverBackgroundColorColor OR Color[]The point's background color when a mouse hovers over it.
pointHoverBorderColorColor OR Color[]The point's border color when a mouse hovers over it.
pointHoverBorderWidthnumber OR number[]The point's border width when a mouse hovers over it.
pointHoverRadiusnumber OR number[]The point's radius width when a mouse hovers over it.
showLinebooleanThe point's radius width when a mouse hovers over it.
spanGapsbooleanThe point's radius width when a mouse hovers over it.
steppedLineboolean
'before'
'after'
Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting.
+

Data Structure

+

The data property of each dataset item consists of an array of points. Each point in the array consist of an x and y coordinate.

+
data:
+[{
+  x: 10,
+  y: 20
+}, {
+  x: 15,
+  y: 10
+}]
+
+ +

Point Configuration

+

Point elements can be configured to change their appearance using the following configuration options:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
radiusnumber3Point radius.
pointStyle'circle'
'cross'
'crossRot'
'dash'
'line'
'rect'
'rectRounded'
'rectRot'
'star'
'triangle'
'circle'Style of point.
rotationnumber0Rotation of the point, in degrees.
backgroundColorColor'rgba(0,0,0,0.1)Fill color.
borderWidthnumber1Stroke width.
borderColorColor'rgba(0,0,0,0.1)Stroke color.
hitRadiusnumber1Extra radius added around the point to make it easier to detect mouse events.
hoverRadiusnumber4Point radius, when mouse hovers over point.
hoverBorderWidthnumber1Stroke width, when mouse hovers over point.
+

You can change the point configuration in the chart via the options.elements.point configuration.

+

Scatter with Point Styles

+

For example, to render the above chart, use the following code:

+
 const options: Chart.ChartOptions = {
+      elements: {
+        point: {
+          pointStyle: "triangle",
+          radius: 10,
+          hoverRadius: 15
+        }
+      },
+      scales: {
+        xAxes: [{
+          type: 'linear',
+          position: 'bottom'
+        }]
+      }
+    };
+
+ +

You can also control point configurations at the dataset level. + TypeScript + const data: Chart.ChartData = { + datasets: [{ + label: 'Triangle', + data: [ + { + x: -10, + y: 0 + }, + { + x: 0, + y: 10 + }], + pointStyle: "triangle", + backgroundColor: 'red' + }, + { + label: 'Rectangle', + data: [ + { + x: -6, + y: 6 + }, + { + x: -4, + y: 4 + }], + pointStyle: "rectRounded", + backgroundColor: 'green' + }, + { + label: 'Circle', + data: [ + { + x: 2, + y: 6 + }, + { + x: 8, + y: 2 + } + ], + pointStyle: "circle", + backgroundColor: 'blue' + } + ] + };

+

Which renders the following chart: + Dataset Styles

+

For More Information

+

For more information on what options are available with Scatter charts, refer to the Scatter documentation on Chart.js.

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldAttachmentsRenderer/index.html b/controls/fields/FieldAttachmentsRenderer/index.html new file mode 100644 index 000000000..5e119185d --- /dev/null +++ b/controls/fields/FieldAttachmentsRenderer/index.html @@ -0,0 +1,1729 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldAttachmentsRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldAttachmentsRenderer control

+

This control renders Clip icon based on the provided count property is defined and greater than 0.

+

FieldAttachmentsRenderer control output

+

Note: this control displays correctly starting with SharePoint Framework v1.4

+

Covered Fields

+
    +
  • Attachments
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldAttachmentsRenderer } from "@pnp/spfx-controls-react/lib/FieldAttachmentsRenderer";
+
+ +
    +
  • Use the FieldAttachmentsRenderer control in your code as follows:
  • +
+
<FieldAttachmentsRenderer count={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldAttachmentsRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
countnumbernoAmount of attachments. The icon is displayed if the property is defined and greater than 0
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldDateRenderer/index.html b/controls/fields/FieldDateRenderer/index.html new file mode 100644 index 000000000..3b76b24f4 --- /dev/null +++ b/controls/fields/FieldDateRenderer/index.html @@ -0,0 +1,1729 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldDateRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldDateRenderer control

+

This control renders date string as a simple text.

+

FieldDateRenderer control output

+

Covered Fields

+
    +
  • Date and Time
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldDateRenderer } from "@pnp/spfx-controls-react/lib/FieldDateRenderer";
+
+ +
    +
  • Use the FieldDateRenderer control in your code as follows:
  • +
+
<FieldDateRenderer text={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Note: FieldDateRenderer doesn't provide functionality to render date in friendly format. It just renders the provided text as is. To learn more about friendly formatting please refer to FieldRendererHelper implementation.

+

Implementation

+

The FieldDateRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
textstringnoText to be rendered
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldFileTypeRenderer/index.html b/controls/fields/FieldFileTypeRenderer/index.html new file mode 100644 index 000000000..7dea70ed1 --- /dev/null +++ b/controls/fields/FieldFileTypeRenderer/index.html @@ -0,0 +1,1735 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldFileTypeRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldFileTypeRenderer control

+

This control renders document or folder icon based on file path. Office UI Fabric icons font is used to render the icons.

+

Note: this control displays correctly starting with SharePoint Framework v1.4

+

FieldFileTypeRenderer control output

+

Covered Fields

+
    +
  • Type (DocIcon)
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldFileTypeRenderer } from "@pnp/spfx-controls-react/lib/FieldFileTypeRenderer";
+
+ +
    +
  • Use the FieldFileTypeRenderer control in your code as follows:
  • +
+
<FieldFileTypeRenderer path={fileLeafRef} isFolder={false} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldFileTypeRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
pathstringyesdocument/file path
isFolderbooleannotrue if the icon should be rendered for a folder, not file
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldLookupRenderer/index.html b/controls/fields/FieldLookupRenderer/index.html new file mode 100644 index 000000000..1bc84306b --- /dev/null +++ b/controls/fields/FieldLookupRenderer/index.html @@ -0,0 +1,1754 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldLookupRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldLookupRenderer control

+

This control renders lookup values. Each lookup item is clickable. Click on the lookup item leads to opening of referenced item's display form.

+

Note: this control displays correctly starting with SharePoint Framework v1.4

+

FieldLookupRenderer control output +FieldLookupRenderer dialog

+

Covered Fields

+
    +
  • Lookup (single, multi)
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldLookupRenderer } from "@pnp/spfx-controls-react/lib/FieldLookupRenderer";
+
+ +
    +
  • Use the FieldLookupRenderer control in your code as follows:
  • +
+
<FieldLookupRenderer lookups={event.fieldValue} fieldId={'<field-guid>'} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldLookupRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
lookupsISPFieldLookupValue[]yesLookup field values.
dispFormUrlbooleannoUrl of Display form for the list that is referenced by the lookup.
onClick(args: ILookupClickEventArgs) => {}noCustom event handler of lookup item click. If not set the dialog with Display Form will be shown.
fieldIdstringField's id
contextIContextCustomizer context. Must be providede if fieldId is set
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldNameRenderer/index.html b/controls/fields/FieldNameRenderer/index.html new file mode 100644 index 000000000..dd10fe332 --- /dev/null +++ b/controls/fields/FieldNameRenderer/index.html @@ -0,0 +1,1766 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldNameRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldNameRenderer control

+

This control renders document's name as a link. The link provides either preview (if it is available) or direct download. Additionally, new documents are marked with "Glimmer" icon.

+

Note: The Name column in document libraries is marked as noneditable. See this issue for details. +Note Glimmer icon displays correctly starting with SharePoint Framework v1.4

+

FieldNameRenderer control output

+

Covered Fields

+
    +
  • Document Name (LinkFilename, LinkFilenameNomenu, FileLieafRef)
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldNameRenderer } from "@pnp/spfx-controls-react/lib/FieldNameRenderer";
+
+ +
    +
  • Use the FieldNameRenderer control in your code as follows:
  • +
+
<FieldNameRenderer text={'Technical Requirements'} isLink={true} isNew={false} filePath={'https://contoso.sharepoint.com/Documents/tech-requirements.pdf'} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldNameRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
textstringnoText to be rendered.
isLinkbooleanyesTrue if the name should be rendered as a link.
isNewbooleannoTrue if the document is new.
filePathstringnoPath to the document.
hasPreviewbooleannoTrue if the document has preview and link href should be constructed to display the preview (instead of direct document's link). The flag works only if onClick property is NOT defined.
onClick(args: INameClickEventArgs) => {}noCustom handler for link click. If not set link click will lead to rendering document preview. Works if isLink is set to true
onDoubleClick(args: INameClickEventArgs) => {}noCustom handler for link double click. If not set link If not set link will use OOTB behavior. Works if isLink is set to true
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldRendererHelper/index.html b/controls/fields/FieldRendererHelper/index.html new file mode 100644 index 000000000..1d98026ce --- /dev/null +++ b/controls/fields/FieldRendererHelper/index.html @@ -0,0 +1,1740 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldRendererHelper - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldRendererHelper class

+

FieldRendererHelper class is used to automatically apply needed Field Control based on current Field parameters.

+

How to use this class in your solutions

+
    +
  • +

    Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.

    +
  • +
  • +

    Import the following modules to your component:

    +
  • +
+
import { FieldRendererHelper } from "@pnp/spfx-controls-react/lib/Utilities";
+
+ +
    +
  • Use the FieldRendererHelper.getFieldRenderer method to asynchronously request proper React control (As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render):
  • +
+
public componentWillMount() {
+    FieldRendererHelper.getFieldRenderer(fieldValue, {
+      className: this.props.className,
+      cssProps: this.props.cssProps
+    }, this.props.listItem, this.props.context).then(fieldRenderer => {
+        // update state to re-render the Field Customizer
+      this.setState({
+        fieldRenderer: fieldRenderer
+      });
+    });
+  }
+
+ +
    +
  • Render the requestted fieldRenderer:
  • +
+
public render(): React.ReactElement<{}> {
+    return (
+      <div className={styles.cell}>
+        {this.state.fieldRenderer}
+      </div>
+    );
+  }
+
+ +

Implementation

+

The FieldRendererHelper class contains single method getFieldRenderer with next signature:

+
public static getFieldRenderer(fieldValue: any, props: IFieldRendererProps, listItem: ListItemAccessor, context: IContext): Promise<JSX.Element>
+
+ +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescription
fieldValueanyValue of the field.
propsIFieldRendererPropsBasic properties interface for Field Controls. Contains className and cssProps properties
listItemListItemAccessorCurrent List Item
contextIContextSPFx Context
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldTaxonomyRenderer/index.html b/controls/fields/FieldTaxonomyRenderer/index.html new file mode 100644 index 000000000..ab81ebe4b --- /dev/null +++ b/controls/fields/FieldTaxonomyRenderer/index.html @@ -0,0 +1,1728 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldTaxonomyRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldTaxonomyRenderer control

+

This control renders terms from Managed Metadata field.

+

FieldTaxonomyRenderer control output

+

Covered Fields

+
    +
  • Managed Metadata
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldTaxonomyRenderer } from "@pnp/spfx-controls-react/lib/FieldTaxonomyRenderer";
+
+ +
    +
  • Use the FieldTaxonomyRenderer control in your code as follows:
  • +
+
<FieldTaxonomyRenderer terms={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldTaxonomyRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
termsITerm[]yesManaged Metadata terms.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldTextRenderer/index.html b/controls/fields/FieldTextRenderer/index.html new file mode 100644 index 000000000..359ba7808 --- /dev/null +++ b/controls/fields/FieldTextRenderer/index.html @@ -0,0 +1,1734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldTextRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldTextRenderer control

+

This control renders simple text.

+

FieldTextRenderer control output

+

Covered Fields

+
    +
  • Single line of text
  • +
  • Multiple lines of text
  • +
  • Choice
  • +
  • Number
  • +
  • Currency
  • +
  • Yes/No
  • +
  • Default renderer for uncovered types of fields
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldTextRenderer } from "@pnp/spfx-controls-react/lib/FieldTextRenderer";
+
+ +
    +
  • Use the FieldTextRenderer control in your code as follows:
  • +
+
<FieldTextRenderer text={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldTextRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
textstringnoText to be rendered
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldTitleRenderer/index.html b/controls/fields/FieldTitleRenderer/index.html new file mode 100644 index 000000000..b47851848 --- /dev/null +++ b/controls/fields/FieldTitleRenderer/index.html @@ -0,0 +1,1758 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldTitleRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldTitleRenderer control

+

This control renders title either as a simple text or as a link to the Display Form. Additional actions like Share and Context Menu are not implemented.

+

FieldTitleRenderer control output

+

Covered Fields

+
    +
  • List Item Title (Title, LinkTitle, LinkTitleNoMenu)
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldTitleRenderer } from "@pnp/spfx-controls-react/lib/FieldTitleRenderer";
+
+ +
    +
  • Use the FieldTitleRenderer control in your code as follows:
  • +
+
<FieldTitleRenderer text={'Technical Requirements'} isLink={true} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldTitleRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
textstringnoText to be rendered.
isLinkbooleanyesTrue if the name should be rendered as a link.
baseUrlstringnoWeb Url. Should be provided if onClick is not defined
listIdstringnoList Id. Should be provided if onClick is not defined
idnumbernoItem Id. Should be provided if onClick is not defined
onClick(args: ITitleClickEventArgs) => {}noCustom title click event handler. If not set Display form for the item will be displayed.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldUrlRenderer/index.html b/controls/fields/FieldUrlRenderer/index.html new file mode 100644 index 000000000..bdeff64a1 --- /dev/null +++ b/controls/fields/FieldUrlRenderer/index.html @@ -0,0 +1,1746 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldUrlRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldUrlRenderer control

+

This control renders Hyperlink or Picture field value as a link or image.

+

FieldUrlRenderer Url control output +FieldUrlRenderer Image control output

+

Covered Fields

+
    +
  • Hyperlink or Image
  • +
  • Url in Links List
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldUrlRenderer } from "@pnp/spfx-controls-react/lib/FieldUrlRenderer";
+
+ +
    +
  • Use the FieldUrlRenderer control in your code as follows:
  • +
+
// to show Url
+<FieldUrlRenderer text={'microsoft'} url={'http://www.microsoft.com'} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+// to show Image
+<FieldUrlRenderer url={'http://cdn.contoso.com/images/logo.png'} isImageUrl={true} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldUrlRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
textstringnoText to be rendered.
urlstringyesUrl.
isImageUrlbooleannoTrue if the control should be rendered as an image.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/FieldUserRenderer/index.html b/controls/fields/FieldUserRenderer/index.html new file mode 100644 index 000000000..149a84fb6 --- /dev/null +++ b/controls/fields/FieldUserRenderer/index.html @@ -0,0 +1,1736 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FieldUserRenderer - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FieldUserRenderer control

+

This control renders each referenced user/group as a link on a separate line. Hovering the link for users (not groups) leads to opening of Persona control.

+

FieldUserRenderer control output +FieldUserRenderer Persona

+

Note: some icons may be rendered incorrectly if used with SharePoint Framework v1.3 or earlier

+

Covered Fields

+
    +
  • Person or Group
  • +
+

How to use this control in your solutions

+
    +
  • Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency.
  • +
  • Import the following modules to your component:
  • +
+
import { FieldUserRenderer } from "@pnp/spfx-controls-react/lib/FieldUserRenderer";
+
+ +
    +
  • Use the FieldUserRenderer control in your code as follows:
  • +
+
<FieldUserRenderer users={event.fieldValue} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
+
+ +

Implementation

+

The FieldUserRenderer component can be configured with the following properties:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeRequiredDescription
cssPropsReact.CSSPropertiesnoCSS styles to apply to the renderer.
classNameICssInputnoCSS classes to apply to the renderer.
usersIPrincipalnoUsers/groups to be displayed as they appear in event.fieldValue for Field Customizer's onRenderCell event.
contextIContextyesSPFx context.
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/controls/fields/main/index.html b/controls/fields/main/index.html new file mode 100644 index 000000000..d38a60459 --- /dev/null +++ b/controls/fields/main/index.html @@ -0,0 +1,1728 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Getting started - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Field Customizer Out-of-the-box Fields Controls

+

These controls represent React controls that can be used in SPFx Field Customizers to provide rendering of the fields similar to out of the box experience. Additional benefit is ability to set custom css classes and styles to the component. +Related UserVoice requests:
+https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/18810637-access-to-re-use-modern-field-render-controls
+https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/31530607-field-customizer-ability-to-call-ootb-render-meth

+

Usage

+

The main scenario to use this package is to import FieldRendererHelper class and to call getFieldRenderer method. This method returns a Promise with a proper field renderer (Promise<JSX.Element>) based on field's type. It means that it will automatically select proper component that should be rendered in this or that field. This method also contains logic to correctly process field's value and get correct text to display (for example, Friendly Text for DateTime fields). +As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render. The resulting field renderer could be saved in the element's state and used later in render method. +Here is an example on how it can be used inside custom Field Customizer component (.tsx file):

+
export interface IOotbFieldsState {
+  fieldRenderer?: JSX.Element;
+}
+
+//...
+
+@override
+  public componentWillMount() {
+    FieldRendererHelper.getFieldRenderer(this.props.value, {
+      className: this.props.className,
+      cssProps: this.props.cssProps
+    }, this.props.listItem, this.props.context).then(fieldRenderer => {
+      this.setState({
+        fieldRenderer: fieldRenderer
+      });
+    });
+  }
+
+public render(): React.ReactElement<{}> {
+    return (
+      <div className={styles.cell}>
+        {this.state.fieldRenderer}
+      </div>
+    );
+  }
+
+ +

Additionally, any of included components can be used by itself.

+

FieldRendererHelper

+

FieldRendererHelper class is a recommended way to use Field Controls as it provides additional functionality to automatically render the content for any type of fields.

+

Available Controls

+

The following Field Controls are currently available:

+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/css/extra.css b/css/extra.css new file mode 100644 index 000000000..18a925402 --- /dev/null +++ b/css/extra.css @@ -0,0 +1,32 @@ +.md-logo { + height: 32px; + width: 150px; +} + +.md-logo img { + width: 100% !important; + height: auto !important; + margin-top: -0.25em; +} + +.md-header{ + height: 75px; +} + +.md-container{ + padding-top: 70px; +} + +.md-sidebar[data-md-state="lock"]{ + padding-top: 75px; +} + +.md-footer { + margin-top: 5em; +} + +@media only screen and (max-width: 76.1875em) { + .md-nav--primary .md-nav__title--site .md-nav__button { + width: 150px; + } +} diff --git a/guides/contributing/index.html b/guides/contributing/index.html new file mode 100644 index 000000000..9981b3c9d --- /dev/null +++ b/guides/contributing/index.html @@ -0,0 +1,1760 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Contributing - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

Contribution guidelines

+

We appreciate that you're interested in helping with moving the project forward. Before you submit your first PR, please read the following guide. We'd hate to see you work on something that someone else is already working on, something that we agreed not to do or something that doesn't match the project.

+

Sharing is caring!

+

You have an idea for a new component

+

Awesome! Good ideas are invaluable for every product. Before you start hacking away, please check if there is no similar idea already listed in the issue list. If not, please create a new issue describing your idea. Once we agree on the feature scope and architecture, the feature will be ready for building. Don't hesitate to mention in the issue if you'd like to build the feature yourself.

+

When building a new control, try to add your control to the default provided web part so that everyone can test it out. Please also provide the documentation for your controls in the documentation section.

+

You have a suggestion for improving an existing component

+

Nothing is perfect. If you have an idea how to improve an existing command or the CLI, let us know by submitting an issue in the issue list. Some things are done for a reason, but some are not. Let's discuss what you think and see how the project could be improved for everyone.

+

You've found a bug

+

Bugs happen. When you find a bug, please have a look at the issue list if a similar bug has already been logged. If not, let us know what doesn't work and how we can reproduce it. If we can't reproduce your bug, we will ask you for clarification, which will only make it longer to fix it.

+

Fixing typos

+

Typos are embarrassing! Most PR's that fix typos will be accepted immediately. In order to make it easier to review the PR, please narrow the focus instead of sending a huge PR of fixes.

+

Tips

+

Before contributing:

+
    +
  • ensure that the dev branch on your fork is in sync with the original sp-dev-fx-controls-react repository
  • +
+
# assuming you are in the folder of your locally cloned fork....
+git checkout dev
+
+# assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo
+git fetch upstream
+
+# update your local dev to be a mirror of what's in the main repo
+git pull --rebase upstream dev
+
+ +
    +
  • create a feature branch for your change. If you'll get stuck on an issue or merging your PR will take a while, this will allow you to have a clean dev branch that you can use for contributing other changes
  • +
+
git checkout -b my-contribution
+
+ +

DO's & DON'Ts

+
    +
  • DO follow the same project and test structure as the existing project.
  • +
  • DO include tests when adding new functionality and features. When fixing bugs, start with adding a test that highlights how the current behavior is broken.
  • +
  • DO keep discussions focused. When a new or related topic comes up it's often better to create new issue than to side track the conversation.
  • +
  • DO NOT submit PR's for coding style changes.
  • +
  • DO NOT surprise us with big PR's. Instead file an issue & start a discussion so we can agree on a direction before you invest a large amount of time.
  • +
  • DO NOT commit code you didn't write.
  • +
  • DO NOT submit PR's that refactor existing code without a discussion first.
  • +
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/guides/index.html b/guides/index.html new file mode 100644 index 000000000..bd39db101 --- /dev/null +++ b/guides/index.html @@ -0,0 +1,1610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overview - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Project guides

+

Following is an overview of guides for this project. If you're considering contributing to the project, reading up on these guides will help you understand the project structure and get started developing for it.

+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/guides/migrate-from-v1/index.html b/guides/migrate-from-v1/index.html new file mode 100644 index 000000000..ac2b10ee3 --- /dev/null +++ b/guides/migrate-from-v1/index.html @@ -0,0 +1,1773 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Migrate v1 to v2 - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Migrating from v1 to v2

+

Most of the controls have no breaking changes when moving from v1 to v2. However, some APIs were changed to make the library more stable and controls behavior more even.

+

Also, we've bumped up React and Fluent UI versions used in the library. It means you will need to update the package.json file in your SPFx projects.

+

The below guide is an overview of what it takes to migrate from v1 to v2. If we missed something, please let us know on the issues list so we can update the guide. Thanks!

+

v2 Supports SharePoint Online only

+

V2 of Reusable Controls is based on SharePoint Framework 1.11. Due to this change, it does not support SharePoint on-premises. Please, use v1 if you plan to deploy your solution on-premises.

+

React and Fluent UI versions

+

V2 of Reusable Controls uses React.js v16.8.5 and Fluent UI (Office UI Fabric React) v6.214.0.

+

Although it is not necessary to use the same modules' versions in your project, we highly recommend to update your solution accordingly:

+
"dependencies": {
+    // other dependencies
+    "office-ui-fabric-react": "6.214.0",
+    "react": "16.8.5",
+    "react-dom": "16.8.5"
+  },
+  "devDependencies": {
+    "@types/react": "16.8.8",
+    "@types/react-dom": "16.8.3",
+  },
+
+ +

The easiest way to upgrade the SharePoint Framework solution is to use Office365 CLI spfx project upgrade command.

+

APIs Changes

+

PeoplePicker

+
    +
  • isRequired is renamed to required
  • +
  • The property has been renamed to use the common approach for mandatory field naming.
  • +
  • errorMessage represents a static error message to be displayed in the control.
  • +
  • In v1 errorMessage is used to provide the text that will be displayed if the field is set as required and no value is selected.
  • +
  • In v2 you can use this property to display an error message for whatever reason statically.
  • +
+
/**
+ * Static error message displayed below the text field. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence).
+ */
+  errorMessage?: string;
+
+ +
    +
  • onGetErrorMessage to get error messages dynamically.
  • +
  • The method is used to get the validation error message and determine whether the input value is valid. Mutually exclusive with the static string errorMessage (it will take precedence over this).
  • +
+
/**
+ * The method is used to get the validation error message and determine whether the picker value is valid.
+ * Mutually exclusive with the static string errorMessage (it will take precedence over this).
+ *
+ *   When it returns string:
+ *   - If valid, it returns empty string.
+ *   - If invalid, it returns the error message string and the picker will
+ *     show an error message below the picker.
+ *
+ *   When it returns Promise<string>:
+ *   - The resolved value is display as error message.
+ *   - The rejected, the value is thrown away.
+ *
+ */
+  onGetErrorMessage?: (items: IPersonaProps[]) => string | Promise<string>;
+
+ +
    +
  • showRequiredError has been deleted.
  • +
  • Use errorMessage or onGetErrorMessage to provide the error message.
  • +
  • selectedItems is renamed to onChange
  • +
  • onChange better describes the purpose of the property.
  • +
+

### FolderPicker + FolderPicker default picker has been removed. + If you used FolderPicker as: + typescript + import FolderPicker from '@pnp/spfx-controls-react/lib/controls/folderPicker/FolderPicker'; + You should update to + typescript + import { FolderPicker } from '@pnp/spfx-controls-react/lib/FolderPicker';

+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/guides/mpa/index.html b/guides/mpa/index.html new file mode 100644 index 000000000..b752d47ab --- /dev/null +++ b/guides/mpa/index.html @@ -0,0 +1,1806 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Minimal Path to Awesome - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Minimal Path to Awesome

+

The shortest way to prepare your local copy of the project for development and testing.

+

Install prerequisites

+

Before you start contributing to this project, you will need Node.js. This project (current version 3.x) has been tested with the 18.x version of Node.js and the version of NPM that comes with it. You can use Node Version Manager or Node Version Switcher to switch between different versions of Node.js.

+

Get the local version of the project

+
    +
  • fork this repository
  • +
  • clone your fork
  • +
  • in the command line, run the following commands:
  • +
  • npm install to restore dependencies
  • +
  • npm install -g gulp-cli in order to run gulp commands (run npm list -g gulp-cli to check if already installed on your machine or not)
  • +
  • gulp serve to serve your project (or npm run serve if you want to use spfx-fast-serve)
  • +
  • Start making your changes
  • +
+

Run the project locally

+

As this project embeds a SPFx solution, you have the ability to test all the controls on your machine.

+

You can also debug the controls in any supported language by running one of the following commands (for example in french):

+
    +
  • gulp serve --locale=fr-fr
  • +
  • npx fast-serve --locale=fr-fr (if using spfx-fast-serve)
  • +
+

Beware that both argument and value have to be lower case. Supported locales are listed in the following project's path: src\loc.

+
+

Warning

+

As long as you have access to a SharePoint Online environment (for v2 and after), you can test the components from your machine. But to test the web part as a Teams Tab, you have to first deploy the SPFx solution (and sync it to Teams). You also have to deploy the SharePoint Framework library for Microsoft Graph Toolkit v2.9.0. So be sure to be at least SharePoint Administrator.

+
+

SPFx web part

+

The web part is called ControlsTest and is available for both SharePoint Online and Teams. To test it on SharePoint, go to the workbench page https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/workbench.aspx and add the web part.

+

To test it on Teams, once the project deployed on the tenant accordingly, add the web part as a Tab (from a team for example).

+

To update the host component, open the ControlsTest React component located in the following project's relative path: src\webparts\controlsTest\components\ControlsTest.tsx.

+

SPFx application customizer

+

This extension is called TestApplicationCustomizer. To test it, go to the following URL (after updating the parameters):

+

https://[SHAREPOINT_SITE].sharepoint.com?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={"ca9eac70-7343-4972-88d6-672d50e9cf38":{"location":"ClientSideExtension.ApplicationCustomizer"}}

+

To update the host component, open the TestApp React component located in the following project's relative path: src\extensions\testApp\TestApp.tsx.

+

SPFx form customizer

+

This extension is called TestForm. To test it, you have to configure it first:

+
    +
  1. Open the serve.json file (located in the config folder)
  2. +
  3. Replace the rootFolder property (under serveConfigurations ==> default ==> formCustomizer), which contains a server relative URL, to target the list on which you want to test the extension
  4. +
+

Then go to the following URL (after updating the parameters):

+

https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/SPListForm.aspx?debugManifestsFile=https://localhost:4321/temp/manifests.js&loadSPFX=true&componentId=f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8&PageType=8&RootFolder=[OPTIONAL_SERVER_RELATIVE_URL]/Lists/[LIST_NAME]

+

To update the host component, open the TestForm React component located in the following project's relative path: src\extensions\testForm\components\TestForm.tsx.

+

Documentation

+

SharePoint Framework React Controls uses MkDocs to publish documentation pages. See more information about installing MkDocs on your operating system at http://www.mkdocs.org/#installation.

+

Also, documentation uses custom MkDocs theme that should be installed as well. See Material theme for MkDocs. Currently, documentation is working with version 3.1.0.

+

Once you have MkDocs installed on your machine, in the command line:

+
    +
  • run cd ./docs/documentation to change directory to where the manual pages are stored
  • +
  • run mkdocs serve to start the local web server with MkDocs and view the documentation in the web browser
  • +
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/guides/submitting-pr/index.html b/guides/submitting-pr/index.html new file mode 100644 index 000000000..30fbeb171 --- /dev/null +++ b/guides/submitting-pr/index.html @@ -0,0 +1,1632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Submitting a PR - @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Submitting a PR

+

We appreciate your initiative and would love to integrate your work with the rest of the project! Here is how you can help us do it as quickly as possible.

+ +
# assuming you are in the folder of your locally cloned fork....
+git checkout dev
+
+# assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo
+git fetch upstream
+
+# update your local dev branch to be a mirror of what's in the main repo
+git pull --rebase upstream dev
+
+# switch to your branch where you are working, say "issue-xyz"
+git checkout issue-xyz
+
+# update your branch to update its fork point to the current tip of dev & put your changes on top of it
+git rebase dev
+
+ +
    +
  • submit PR to the dev branch of the main repo. PRs submitted to other branches will be declined
  • +
  • let us know what's in the PR: is it a new command, bug fix or a minor update in the docs? The clearer the information you provide, the quicker your PR can be verified and merged
  • +
  • ideally 1 PR = 1 commit - this makes it easier to keep the log clear for everyone and track what's changed. If you're new to working with git, we'll squash your commits for you when merging your changes into the main repo
  • +
  • don't worry about changing the version or adding yourself to the list of contributors in package.json. We'll do that for you when merging your changes.
  • +
+

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..59a0bfab3 --- /dev/null +++ b/index.html @@ -0,0 +1,1860 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @pnp/spfx-controls-react + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + +
+ +
+ +
+ + + + + + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Reusable React controls for your SharePoint Framework solutions

+

This repository provides developers with a set of reusable React controls that can be used in SharePoint Framework (SPFx) solutions. The project provides controls for building web parts and extensions.

+

Placeholder example

+
+

Attention

+

In order to migrate to v3 it is adviced to follow this guide: Migrating from V1.

+
+

Library Versions

+

Currently there are 3 active versions of the controls. Please, reference the table below to see what version to use in your project.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionSPFx minimal dependencyFluent UI (Office UI Fabric React) versionSharePoint VersionComments
v31.13.*7.174.1OnlineThe most current, actively maintained version of the library.
v21.11.06.214.0OnlineThe last major version is 2.9.0.
We strongly recommend to update to SPFx 1.13.* and v3 of Controls.
v11.3.05.131.0On-PremThe version is maintained for SharePoint On-Prem 2016 and 2019 implementations. Be aware that the controls might not work in solutions you're building for on-premises as SharePoint On-Prem is based on SPFx 1.1.0.
+
+

Attention

+

If you are using v3 of the Controls with SPFx 1.12.1 you will need to cast web part context to any to pass it to the controls.

+
+

Getting started

+

Installation

+

To get started you have to install the following dependency to your project: @pnp/spfx-controls-react.

+

Enter the following command to install the dependency to your project:

+
npm install @pnp/spfx-controls-react --save --save-exact
+
+ +

Configuration

+
+

Note

+

Since v1.4.0 the localized resource path will automatically be configured during the dependency installing.

+
+

Once the package is installed, you will have to configure the resource file of the property controls to be used in your project. You can do this by opening the config/config.json and adding the following line to the localizedResources property:

+
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
+
+ +

Telemetry

+

All controls gather telemetry to verify the usage. Only the name of the control and related data gets captured.

+
+

More information about the service that we are using for this can be found here: PnP Telemetry Proxy.

+
+

Since version 1.17.0 it is possible to opt-out of the telemetry by adding the following code to your web part:

+
import PnPTelemetry from "@pnp/telemetry-js";
+...
+const telemetry = PnPTelemetry.getInstance();
+telemetry.optOut();
+
+ +

Available controls

+

The following controls are currently available:

+ +

Field customizer controls:

+
+

Note

+

If you want to use these controls in your solution, first check out the start guide for these controls: using the field controls.

+
+ +

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..da2932d72 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Reusable React controls for your SharePoint Framework solutions \u00b6 This repository provides developers with a set of reusable React controls that can be used in SharePoint Framework (SPFx) solutions. The project provides controls for building web parts and extensions. Attention In order to migrate to v3 it is adviced to follow this guide: Migrating from V1 . Library Versions \u00b6 Currently there are 3 active versions of the controls. Please, reference the table below to see what version to use in your project. Version SPFx minimal dependency Fluent UI (Office UI Fabric React) version SharePoint Version Comments v3 1.13.* 7.174.1 Online The most current, actively maintained version of the library. v2 1.11.0 6.214.0 Online The last major version is 2.9.0 . We strongly recommend to update to SPFx 1.13.* and v3 of Controls. v1 1.3.0 5.131.0 On-Prem The version is maintained for SharePoint On-Prem 2016 and 2019 implementations. Be aware that the controls might not work in solutions you're building for on-premises as SharePoint On-Prem is based on SPFx 1.1.0 . Attention If you are using v3 of the Controls with SPFx 1.12.1 you will need to cast web part context to any to pass it to the controls. Getting started \u00b6 Installation \u00b6 To get started you have to install the following dependency to your project: @pnp/spfx-controls-react . Enter the following command to install the dependency to your project: npm install @pnp/spfx-controls-react --save --save-exact Configuration \u00b6 Note Since v1.4.0 the localized resource path will automatically be configured during the dependency installing. Once the package is installed, you will have to configure the resource file of the property controls to be used in your project. You can do this by opening the config/config.json and adding the following line to the localizedResources property: \"ControlStrings\" : \"node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js\" Telemetry \u00b6 All controls gather telemetry to verify the usage. Only the name of the control and related data gets captured. More information about the service that we are using for this can be found here: PnP Telemetry Proxy . Since version 1.17.0 it is possible to opt-out of the telemetry by adding the following code to your web part: import PnPTelemetry from \"@pnp/telemetry-js\" ; ... const telemetry = PnPTelemetry . getInstance (); telemetry . optOut (); Available controls \u00b6 The following controls are currently available: AccessibleAccordion (Control to render an accordion. React AccessibleAccordion -based implementation) Accordion (Control to render an accordion) AdaptiveCardHost (Control to render Adaptive Cards) AdaptiveCardDesignerHost (Control to render Adaptive Cards Designer) AnimatedDialog (Animated dialog control) Carousel (Control displays children elements with 'previous/next element' options) Charts (makes it easy to integrate Chart.js charts into web part) ComboBoxListItemPicker (allows to select one or more items from a list) ContentTypePicker (Control to pick a content type) Dashboard (Control to render dashboard in Microsoft Teams) DateTimePicker (DateTime Picker) DragDropFiles (Allow drag and drop of files in selected areas) DynamicForm (Dynamic Form component) EnhancedThemeProvider (Enhanced version of Fluent UI Theme Provider control used to improve support for themes and fonts when creating Tab or Personal App in SPFx for Teams or creating Isolated Web Parts) FieldCollectionData (control gives you the ability to insert a list / collection data which can be used in your web part / application customizer) FieldPicker (control to pick one or multiple fields from a list or a site) FilePicker (control that allows to browse and select a file from various places) FileTypeIcon (Control that shows the icon of a specified file path or application) FolderExplorer (Control that allows to browse the folders and sub-folders from a root folder) FolderPicker (Control that allows to browse and select a folder) GridLayout (control that renders a responsive grid layout for your web parts) HoverReactionsBar (control that allows you to select an emoji from emoji bar or select from picker) IconPicker (control that allows to search and select an icon from office-ui-fabric icons) IFrameDialog (renders a Dialog with an iframe as a content) IFramePanel (renders a Panel with an iframe as a content) ListItemComments (controls that allows to manage list item comments similarly to out-of-the box experience) ListItemPicker (allows to select one or more items from a list) ListPicker (allows to select one or multiple available lists/libraries of the current site) ListView (List view control) LivePersona (Live Persona control) LocationPicker (Location Picker control) Map (renders a map in a web part) ModernAudio (Modern Audio control) ModernTaxonomyPicker (Modern Taxonomy Picker) MonacoEditor (Monaco Editor) MyTeams (My Teams) PeoplePicker (People Picker) Placeholder (shows an initial placeholder if the web part has to be configured) Progress (shows progress of multiple SEQUENTIALLY executed actions) ProgressStepsIndicator.md (shows a progress of steps) SecurityTrimmedControl (intended to be used when you want to show or hide components based on the user permissions) SiteBreadcrumb (Breadcrumb control) SitePicker (Site Picker control) TaxonomyPicker (Taxonomy Picker) TeamChannelPicker (Team Channel Picker) TeamPicker (Team Picker) TermSetNavigation (Team Picker) Toolbar (Control to render Toolbar in Microsoft Teams) TreeView (Tree View) UploadFiles (Upload Files) VariantThemeProvider (Variant Theme Provider) ViewPicker (View Picker Control) WebPartTitle (Customizable web part title control) Field customizer controls: Note If you want to use these controls in your solution, first check out the start guide for these controls: using the field controls . FieldAttachmentsRenderer (renders Clip icon based on the provided count property is defined and greater than 0) FieldDateRenderer (renders date string as a simple text) FieldFileTypeRenderer (renders document or folder icon based on file path) FieldLookupRenderer (renders lookup values) FieldNameRenderer (renders document's name as a link) FieldTaxonomyRenderer (renders terms from Managed Metadata field) FieldTextRenderer (renders simple text) FieldTitleRenderer (renders title either as a simple text or as a link to the Display Form) FieldUrlRenderer (renders Hyperlink or Picture field value as a link or image) FieldUserRenderer (renders each referenced user/group as a link on a separate line)","title":"Home"},{"location":"#reusable-react-controls-for-your-sharepoint-framework-solutions","text":"This repository provides developers with a set of reusable React controls that can be used in SharePoint Framework (SPFx) solutions. The project provides controls for building web parts and extensions. Attention In order to migrate to v3 it is adviced to follow this guide: Migrating from V1 .","title":"Reusable React controls for your SharePoint Framework solutions"},{"location":"#library-versions","text":"Currently there are 3 active versions of the controls. Please, reference the table below to see what version to use in your project. Version SPFx minimal dependency Fluent UI (Office UI Fabric React) version SharePoint Version Comments v3 1.13.* 7.174.1 Online The most current, actively maintained version of the library. v2 1.11.0 6.214.0 Online The last major version is 2.9.0 . We strongly recommend to update to SPFx 1.13.* and v3 of Controls. v1 1.3.0 5.131.0 On-Prem The version is maintained for SharePoint On-Prem 2016 and 2019 implementations. Be aware that the controls might not work in solutions you're building for on-premises as SharePoint On-Prem is based on SPFx 1.1.0 . Attention If you are using v3 of the Controls with SPFx 1.12.1 you will need to cast web part context to any to pass it to the controls.","title":"Library Versions"},{"location":"#getting-started","text":"","title":"Getting started"},{"location":"#installation","text":"To get started you have to install the following dependency to your project: @pnp/spfx-controls-react . Enter the following command to install the dependency to your project: npm install @pnp/spfx-controls-react --save --save-exact","title":"Installation"},{"location":"#configuration","text":"Note Since v1.4.0 the localized resource path will automatically be configured during the dependency installing. Once the package is installed, you will have to configure the resource file of the property controls to be used in your project. You can do this by opening the config/config.json and adding the following line to the localizedResources property: \"ControlStrings\" : \"node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js\"","title":"Configuration"},{"location":"#telemetry","text":"All controls gather telemetry to verify the usage. Only the name of the control and related data gets captured. More information about the service that we are using for this can be found here: PnP Telemetry Proxy . Since version 1.17.0 it is possible to opt-out of the telemetry by adding the following code to your web part: import PnPTelemetry from \"@pnp/telemetry-js\" ; ... const telemetry = PnPTelemetry . getInstance (); telemetry . optOut ();","title":"Telemetry"},{"location":"#available-controls","text":"The following controls are currently available: AccessibleAccordion (Control to render an accordion. React AccessibleAccordion -based implementation) Accordion (Control to render an accordion) AdaptiveCardHost (Control to render Adaptive Cards) AdaptiveCardDesignerHost (Control to render Adaptive Cards Designer) AnimatedDialog (Animated dialog control) Carousel (Control displays children elements with 'previous/next element' options) Charts (makes it easy to integrate Chart.js charts into web part) ComboBoxListItemPicker (allows to select one or more items from a list) ContentTypePicker (Control to pick a content type) Dashboard (Control to render dashboard in Microsoft Teams) DateTimePicker (DateTime Picker) DragDropFiles (Allow drag and drop of files in selected areas) DynamicForm (Dynamic Form component) EnhancedThemeProvider (Enhanced version of Fluent UI Theme Provider control used to improve support for themes and fonts when creating Tab or Personal App in SPFx for Teams or creating Isolated Web Parts) FieldCollectionData (control gives you the ability to insert a list / collection data which can be used in your web part / application customizer) FieldPicker (control to pick one or multiple fields from a list or a site) FilePicker (control that allows to browse and select a file from various places) FileTypeIcon (Control that shows the icon of a specified file path or application) FolderExplorer (Control that allows to browse the folders and sub-folders from a root folder) FolderPicker (Control that allows to browse and select a folder) GridLayout (control that renders a responsive grid layout for your web parts) HoverReactionsBar (control that allows you to select an emoji from emoji bar or select from picker) IconPicker (control that allows to search and select an icon from office-ui-fabric icons) IFrameDialog (renders a Dialog with an iframe as a content) IFramePanel (renders a Panel with an iframe as a content) ListItemComments (controls that allows to manage list item comments similarly to out-of-the box experience) ListItemPicker (allows to select one or more items from a list) ListPicker (allows to select one or multiple available lists/libraries of the current site) ListView (List view control) LivePersona (Live Persona control) LocationPicker (Location Picker control) Map (renders a map in a web part) ModernAudio (Modern Audio control) ModernTaxonomyPicker (Modern Taxonomy Picker) MonacoEditor (Monaco Editor) MyTeams (My Teams) PeoplePicker (People Picker) Placeholder (shows an initial placeholder if the web part has to be configured) Progress (shows progress of multiple SEQUENTIALLY executed actions) ProgressStepsIndicator.md (shows a progress of steps) SecurityTrimmedControl (intended to be used when you want to show or hide components based on the user permissions) SiteBreadcrumb (Breadcrumb control) SitePicker (Site Picker control) TaxonomyPicker (Taxonomy Picker) TeamChannelPicker (Team Channel Picker) TeamPicker (Team Picker) TermSetNavigation (Team Picker) Toolbar (Control to render Toolbar in Microsoft Teams) TreeView (Tree View) UploadFiles (Upload Files) VariantThemeProvider (Variant Theme Provider) ViewPicker (View Picker Control) WebPartTitle (Customizable web part title control) Field customizer controls: Note If you want to use these controls in your solution, first check out the start guide for these controls: using the field controls . FieldAttachmentsRenderer (renders Clip icon based on the provided count property is defined and greater than 0) FieldDateRenderer (renders date string as a simple text) FieldFileTypeRenderer (renders document or folder icon based on file path) FieldLookupRenderer (renders lookup values) FieldNameRenderer (renders document's name as a link) FieldTaxonomyRenderer (renders terms from Managed Metadata field) FieldTextRenderer (renders simple text) FieldTitleRenderer (renders title either as a simple text or as a link to the Display Form) FieldUrlRenderer (renders Hyperlink or Picture field value as a link or image) FieldUserRenderer (renders each referenced user/group as a link on a separate line)","title":"Available controls"},{"location":"beta/","text":"Testing out a beta release \u00b6 All you need to do for testing out a beta release of @pnp/spfx-controls-react is to install the dependency as follows: npm install @pnp/spfx-controls-react@next --save Beta control documentation \u00b6 The control documentation is only live for public releases, not for beta versions. If you want to checkout the markdown files of all controls in the dev branch: beta documentation . Next Steps \u00b6 Once you installed the beta version, you can start using the controls in your solution. Go to the homepage to get an overview of all the available controls and the steps to get started: home .","title":"Beta testing"},{"location":"beta/#testing-out-a-beta-release","text":"All you need to do for testing out a beta release of @pnp/spfx-controls-react is to install the dependency as follows: npm install @pnp/spfx-controls-react@next --save","title":"Testing out a beta release"},{"location":"beta/#beta-control-documentation","text":"The control documentation is only live for public releases, not for beta versions. If you want to checkout the markdown files of all controls in the dev branch: beta documentation .","title":"Beta control documentation"},{"location":"beta/#next-steps","text":"Once you installed the beta version, you can start using the controls in your solution. Go to the homepage to get an overview of all the available controls and the steps to get started: home .","title":"Next Steps"},{"location":"about/license/","text":"License MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","title":"License"},{"location":"about/release-notes/","text":"Releases \u00b6 3.20.0 \u00b6 Enhancements \u00b6 Dashboard : added new WidgetSize #1845 Dashboard : IWidgetLink improvements #1813 DynamicForm : custom sorting #1802 ImagePicker : new Control ImagePicker #1820 UserPicker : new Control UserPicker #1675 DynamicForm : DynamicForm storeLastActiveTab option #1879 #1879 FilePicker : Image picker enhancements #1805 DynamicForm : Adds ability to create files/folders in subfolder using DynamicForm. #1901 Fixes \u00b6 Debug Controls in any language #1882 AdaptiveCardHost : lock down adaptive-expression package version #1876 ListItemPicker : PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. #1887 ListItemAttachments : Fix 1858 to correct Chinese localization files #1894 #1894 DynamicForm : Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type #1872 GridLayout : A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. 1851 DynamicForm : Always Show Required Field Validation Error In FormDisplayMode.Edit Mode #1775 DynamicForm : Required Field Validation won't work #1760 DynamicForm : Adds ability to render file/folder name field in DynamicForm and Field. #1906 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alex Terentiev , Antanina Druzhkina , Guido Zambarda , IRRDC , joaojmendes , Martin Lingstuyl , Micha\u00ebl Maillot , Nishkalank Bezawada , srpmtt , wilecoyotegenius , wuxiaojun514 . 3.19.0 \u00b6 Enhancements \u00b6 SharePoint Framework v1.19.0 support #1857 DynamicForm : enable/disable save button #1810 PeoplePicker : add new prop - useSubstrateSearch #1819 SitePicker : add button to clear single / multiple selection #1839 Fixes \u00b6 DynamicForm : more than 100 lookups and date format in lookup field #1722 Richtext : can not undo ordered lists #1135 FilePicker : fixing organization tab browsing issue #1861 PeoplePicker : method to clear the array #1838 SitePicker : documentation patch #1842 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alex Terentiev , Antanina Druzhkina , Guido Zambarda , Luccas Castro , Micha\u00ebl Maillot , Niels S\u00f6th , srpmtt . 3.18.1 \u00b6 Fixes \u00b6 FilePicker : Fix issue with adding link by typing in 'From a link' tab #1814 Update nl-nl.ts #1823 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Antanina Druzhkina , Elio Struyf . 3.18.0 \u00b6 Enhancements \u00b6 DynamicField : Added orderBy to DynamicField props for lookup fields #1747 DateTimePicker : disable array of dates #516 DynamicForm : new customIcons property to allow custom icons for the form #1745 RichText : Added style property to Rich text control #1773 fast-serve : Fast-serve update to match the most recent changes. #1782 PeoplePicker : Added context optimization #1764 Multiple controls : Wrong fluentui imports cause webpack build errors #1763 FileTypeIcon : Added standard events #1789 Fixes \u00b6 FolderPicker : Update documentation on how to use the control with siteAbsoluteUrl property #1743 Readme documents highlight extension does not work correctly #1495 DynamicForm : Error on rendering DynamicForm when having a Date Field with internal name starting with underscore ('_') #1738 DynamicForm : Dynamic form loading error in other site #1758 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Guido Zambarda , Harminder Singh , IRRDC , Matthias Z'Brun , Micha\u00ebl Maillot , Nishkalank Bezawada , Sergei Sergeev , srpmtt . 3.17.0 \u00b6 Enhancements \u00b6 DyanmicForm : Added file handling #1625 DynamicForm : Custom Formatting and Validation, ControlsTestWebPart updates #1672 PeoplePicker : Added custom filter to PeoplePicker selection #1657 RichText : Align RichText heading styles and font sizes with OOB SharePoint text web part #1706 Fixes \u00b6 Build fails due to missing @iconify/react dependency after upgrade to 3.16.0 #1719 ModernTaxonomyPicker : not displaying suggestions when typing in values - API not found error #1688 DynamicForm : Disable issue on fieldOverrides field control when onBeforeSubmit return true #1715 PeoplePicker : PeoplePicker returns no results with webAbsoluteUrl and ensureUser #1669 DynamicForm : [DynamicForm] Fixing multi taxonomy field (loading + saving existing item) #1739 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Guido Zambarda , Lars Fernhomberg , Mark Bice , Micha\u00ebl Maillot , Nishkalank Bezawada , Tom G , wuxiaojun514 . 3.16.2 \u00b6 Fixes \u00b6 DynamicForm : Fixing the previous version's issue #1736 (introduced in #1718 ) Contributors \u00b6 Special thanks to our contributor: IRRDC . 3.16.1 \u00b6 Fixes \u00b6 DynamicForm : Additional check to see if DefaultValue is an object. No more null comparisons, which should have been undefined comparisons Contributors \u00b6 Special thanks to our contributor: IRRDC . 3.16.0 \u00b6 New control(s) \u00b6 ViewPicker : new control ViewPicker #1439 HoverReactionsBar : new control HoverReactionsBar #1652 Enhancements \u00b6 FieldCollectionData : render on page instead of panel and added combobox and peoplepicker controls #1588 FieldCollectionData : added date field control and updated number field #1600 ListItemComments : Added ListItemComments component to Controls.tsx #1621 FolderPicker : Improve documentation of FolderPicker #1379 RichText : Add https:// as placeholder instead of textbox value when adding url #1651 Fix package.json to remove phantom dependencies issues #1660 PeoplePicker : new property to starting the search after n characters #374 SharePoint Framework v1.18.2 support Fixes \u00b6 AccessibleAccordion : fix typo in documentation #1634 DynamicForm : fix issue with MultiChoice field #1510 Localization : Update dutch translations #1635 TaxonomyPicker : suggested item contains double termset name #1597 DynamicForm : DynamicForm does not properly handle NULL default values for Taxonomy fields #1267 DynamicForm : New items are always created with the default content type if the list has multiple content types #1626 PeoplePicker :PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) DynamicForm : Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results #1614 DynamicForm : Number validations are working, but the percentage values are not getting saved #1601 DynamicForm : Number validation is preventing form save in certain circumstances, not enabled for currency fields #1604 ListItemAttachments : Inconsistent file handling #1644 Localization : Update Japanese translations #1686 ListItemPicker : Fix docs for onSelectedItem #1690 ComboBoxListItemPicker : Fix docs for onSelectedItem #1690 ListItemAttachments : Fix click behavior in ListItemAttachments component #1692 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Dan Toft , Gerke van Garderen , Guido Zambarda , Joakim , Micha\u00ebl Maillot , Nils Andresen , Nishkalank Bezawada , Rico van de Ven , Steve Beaug\u00e9 , wuxiaojun514 , Tetsuya Kawahara , Tom G , Yannik Reiter . 3.15.0 \u00b6 New control(s) \u00b6 TermSetNavigation : new control TermSetNavigation #1527 Enhancements \u00b6 FolderExplorer : show files on folder explorer control #1502 DynamicForm : Fixed typo in property name #1529 DynamicForm : validation error dialog added #1531 DateTimePicker : Add new property initialPickerDate #1581 ModernTaxonomyPicker : can't find term when UI is in language not supported by term store #1573 AdaptiveCardHost : Add null check for adaptive card elements #1574 ControlsTestWebPart : Updated the ControlsTestWebPart to show the controls filtered by control type #1547 fast-serve : Fast-serve updated to the latest version and serve warnings fixed #1589 DynamicForm : DynamicForm Number min max #1585 Fixes \u00b6 FieldPicker : Changed react import to fix cannot be used as a JSX component error #1500 Localization : Fixes to Italian localization #1532 Localization : Fixes to Netherlands localization #1537 ListItemAttachments : Fix the OnClick handler when clicking on the document card #1541 fast-serve : Fix issue with File and Directory Entries API #1555 FilePicker : Tile view issue on first render #1558 DynamicForm lookups - first time you select an option from a lookup, it doesnt select it #1535 DynamicForm : Fields of type Note don't get disabled #1264 ListItemAttachments : Fix for files containing dots in the name #1580 PeoplePicker : Shows wrong value in Dynamic Form when null is provided #1421 DynamicForm : Error on save when clearing person from Person or Group field and leaving it blank #1578 DynamicForm : Number validation is not working, if the field is set to minimum and maximum value #1571 DynamicForm : controls are shown with error messages even if the values are assigned #1133 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Andreas Omayrat , Ayoub , Desislav , Guido Zambarda , Jo\u00e3o Mendes , Nishkalank Bezawada , Patrik Hellgren , Rico van de Ven , Sergei Sergeev , Sharepointalist , Zhephyr . 3.14.0 \u00b6 Enhancements \u00b6 DateTimePicker : Fixed DateTimePicker strings in Danish Locale #1498 SharePoint Framework v1.17.1 support FieldCollectionData : Adds panelProps property to FieldCollectionData #1525 Fixes \u00b6 DynamicForm : Fixes DynamicForm trying to load TaxonomyFields with wrong display name #1422 ListItemAttachments : FIX: Cannot download items when it has a ilegal character #1484 FilePicker : FIX: recent tab empty until re-render #1482 Dynamic Form : Adds onListItemLoaded handler to DynamicForm #1472 Dynamic Form : Fix for the DynamicForm when a defaultValue is null and the code try to call the split method on it. #1486 DynamicForm : DynamicForm - Fixing Required Multi Field Saving Problem #1489 FolderExplorer : FolderExplorer doesn't explore folders with ' in the name #1491 DynamicForm : cannot display lookup value when the source field is not Title #1511 FilePicker :Features/1478 filepicker tiles view #1521 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Dan Toft , Guido Zambarda , Martin Lingstuyl , Nishkalank Bezawada , Sergio Villalta , Josef Benda , Victor Romanov , wuxiaojun514 , Zied FEHRI . 3.13.0 \u00b6 New control(s) \u00b6 UploadFiles : New Upload Files control #1388 Enhancements \u00b6 ListItemPicker : use list name as well as GUID to point to list #1355 ListItemPicker : Add Styles property to ListItemPicker and ComboBoxListItemPicker #1407 SitePicker : Pass styles property to Dropdown #1389 FilePicker : Site Tab - Many Document Libraries No Scrolling #1413 DynamicForm : Add respectETag option to DynamicForm #1395 MonacoEditor : Fixed minor typos and misleading instructions #1415 SharePoint Framework v1.16.1 support #1427 RichText : label property is missing #1375 PeoplePicker : PeopleSearch service should also find people by userPrincipalName when group transitive membership check is used. #1446 Update the SPFx source project to add an extension + form customizer #1410 AdaptiveCardDesignerHost : Add Sample Data to Adaptive Card Editor #1425 AdaptiveCardHost : Logic to prevent re-renders (flicker) #1425 ListItemComments : Add new parameter for ListItemComments to highlight comment #1430 ComboBoxListItemPicker : Update ComboBoxListItemPicker.md #1470 Fixes \u00b6 DateTimePicker : broken link for getErrorMessage property fixed #1277 ProgressStepsIndicator : Fix missing image reference in Progress Steps Indicator #1409 DynamicForm : Dynamicform is hanging on the loading screen if the list has a single value list lookup field #1393 ListView : Update ListView control docs to use a valid field for the icon #1398 Accordion : Fixing Accordion control documentation image issue #1408 DynamicForm : Cannot read properties of undefined (reading 'startsWith') when submitting the form with contentType={undefined] #1431 FilePicker : Fix site breadcrumb navigation #1368 DynamicForm : Initialize changedValue with defaultValue #1454 DynamicForm : Fix image path #1455 DynamicForm : Check empty array and trasform it in set as null #1456 FilePicker : Fix site browser resize #1457 ModernTaxonomyPicker Fix - Show ModernTaxonomyPicker label in correct form #1459 DynamicForm : Update DynamicForm.tsx #1462 FilePicker : Fix breadcrumb nav #1458 DateTimePicker : Date picker locale #1464 DateTimePicker : Date picker locale #1095 RichText : Use theme colors - fix dark mode #669 FilePicker : Use theme colors - fix dark mode #1132 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): araver , Brian Krainer Jacobsen , Edin Kapic , Eduard Paul , Fredrik Ekstr\u00f6m , Guido Zambarda , Harminder Singh , Hugo Bernier , Jo\u00e3o Mendes , mgitta , Micha\u00ebl Maillot , mikezimm , Nikolay Belykh , Patrik Hellgren , Rico van de Ven , Samuele Furnari , sambilfinger , wuxiaojun514 . 3.12.0 \u00b6 Enhancements \u00b6 DynamicForm : support cretion of document sets #1335 SitePicker : add HubId to filter to only sites within a hub #1346 SharePoint Framework v1.16.0 support Fixes \u00b6 FilePicker : panel causes SharePoint to Throttle due to infinite loop fetching files #1325 ContentTypePicker : problem importing control #1337 FilePicker : correctly request data from provided webAbsoluteUrl #1340 ModernTaxonomyPicker : Fix infinite loop #1342 ModernTaxonomyPicker : improve display of the term path to align with out of the box control UI #1343 FolderPicker : get folders of other site url instead of the current context/site #1305 FilePicker : browsing Site / Doclibs loops and floods SPO Service with requests and causes http 429 #1350 Remove invalid comma in tsconfig.json #1341 TaxonomyPicker : control allows select deprecated/untaggable terms when typing #1093 SitePicker : prevent infinite loop when fetching sites #1346 DynamicForm : AnchorId of TaxonomyField gets ignored and the whole tree is rendered #1310 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Carlos Marins Jr , Edin Kapic , Josef Benda , Nello D'Andrea , Nishkalank Bezawada , Nizar Grindi , Paolo Pialorsi , Patrik Hellgren , Peter Paul Kirschner , Victor Romanov . 3.11.0 \u00b6 New control(s) \u00b6 ProgressStepsIndicator : New control that shows a progress of steps. #1322 Enhancements \u00b6 DynamicForm : Add taxonomy tree to test harness #1269 ModernTaxonomyPicker : ability to disallow selecting children #1279 PeoplePicker : Use webAbsoluteUrl if provided through props to ensure user #1273 DynamicForm : Support for hidden fields #1307 Placeholder : Documentation example to only display in edit mode #1280 DynamicForm : Update documentation regarding onBeforeSubmit #1319 DynamicForm : FirstDayOfWeek in DatePickers from webs regional settings #1317 Fixes \u00b6 PeoplePicker : fixes where people picker returns no results #1292 FilePicker : Tile view fix #1272 Issues with v1.15.2 #1288 RichText : Fix broken arrow icons #1302 TaxonomyPicker : Does not show term set labels in Version 3.10.0 #1299 TaxonomyPicker : Dynamic form select term not working #1303 DynamicForm : Check if hiddenfields property is undefined #1314 DynamicForm : PeoplePicker preselects wrong user if PrincipalType allows groups #1315 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Hilton Giesenow , Jake Stanger , Jasey Waegebaert , Jo\u00e3o Mendes , Josef Benda , Mark Bice , Paolo Pialorsi , Victor Romanov . 3.10.0 \u00b6 Enhancements \u00b6 DynamicForm : possibility to override field rendering for individual fields #1257 ModernTaxonomyPicker : Display the full path of a term #1172 SharePoint Framework v1.15.2 support #1261 Fixes \u00b6 DateTimePicker : onChange not triggered when clearing date #1277 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Bart-Jan Dekker , Edin Kapic , Milan Holemans , Steve Beaug\u00e9 . 3.9.0 \u00b6 New control(s) \u00b6 EnhancedThemeProvider : Added 'EnhancedThemeProvider' control #1202 FieldPicker : Added FieldPicker control #1219 ContentTypePicler : Added ContentTypePicker control #1220 ModernAudio : Added ModernAudio control #1224 AdaptiveCardDesignerHost : Added AdaptiveCardDesignerHost control #1237 Enhancements \u00b6 DateTimePicker : Added button to clear date #1217 Toolbar : Allow filters on a Toolbar to be controlled externally #1222 PeoplePicker : add new allowUnvalidated option to allow adding non-tenant users #1232 DynamicForm : Add support for webAbsoluteUrl #1244 Fixes \u00b6 Localization : Updates to English localizations #1207 Localization : Updates to Dutch localizations #1209 Localization : Updates to Danish localizations #1233 TaxonomyPicker : Check if cultureInfo is valid #1226 FieldCollectionData : Updated docs to fix duplicated property #1236 Changelog : Fix changelog script by setting CHANGELOG.JSON filename extension to lower case #1242 PeoplePicker : PeoplePicker validation on focus out #1221 DynamicForm : Cannot display lookup value when the source field is not Title #1215 FilePicker : the endPoint for webSearch do not work #1256 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Annie-Johnson , Daniel Watford , Dennis Kuhn , Fabio Franzini , Jake Stanger , Joseph Halvey , Markus M\u00f6ller , Milan Holemans , Morten Andersen , Richard Gigan , Rico van de Ven , ryanexner , Sergio Villalta . 3.8.1 \u00b6 Fixes \u00b6 LivePersona : Fix LivePersona not showing card on hover #1241 3.8.0 \u00b6 Enhancements \u00b6 PeoplePicker : Allow the use of multiple groupId-s #1163 PeoplePicker : search users in nested security groups #1173 ModenrTaxonomyPicker : Add more complete example of TaxonomyTree usage #1190 AdaptiveCardHost : Add SPFx Context property #1145 AdaptiveCardHost : Remove the isUniqueControlInPage from the control by rebuilding the way to apply AC CSS class names #1154 ListView : Different background color to even and odd rows in ListView #1153 AccessibleAccordion : Support of section variations #1195 TreeView : Support of section variations #1196 Fixes \u00b6 LocationPicker : Resolve issue when in root site #1162 LocationPicker : Trigger onChange on picker clear action #1165 TreeView : TreeView Control is broken after updating to v3.7.0 #1170 TreeView : collapses on selection of a child node #1182 TreeView : expanded nodes state is getting lost after refresh #1062 NPM Audit Critical Issues #1187 Bump momentjs from 2.29.1 to 2.29.2 #1185 TaxonomyPicker : Sorting the terms in locale language #1160 ComboboxListItemPicker : options are not reloaded after the filter is changed #1180 FieldRendererHelper : Add missing PnPjs import to SPHelper #1140 RichText : Update font style and font size on property pane #1151 Placeholder : Support section variations for themes #1193 3.7.2 \u00b6 3.7.0 \u00b6 New control(s) \u00b6 VariantThemeProvider : new VariantThemeProvider control #1120 MonacoEditor : new MonacoEditor control #1134 Enhancements \u00b6 Carousel : Prev and Next Buttons are not labeled, and read as 'Unlabeled button' by screen readers #1137 TreeView : Ability to set keys of items that should be expanded by default #1084 SharePoint Framework v1.14.0 support Fixes \u00b6 FilePicker : defaultFolderAbsolutePath doesn't work with webAbsoluteUrl #1129 LocationPicker : Location picker not resolving locations #1149 DynamicForm : RichText Field losing focus on typing #1024 LivePersona : Documentation fix for template type #1147 3.6.0 \u00b6 New control(s) \u00b6 AdaptiveCardHost : React control that allows you to render an Adaptive Card as a component #1096 Enhancements \u00b6 ModernTaxonomyPicker : ability to add action buttons to terms #1058 FilePicker : allow to select files from other sites #907 Localization : Update Swedish translations #1099 FilePicker : ability to allow external link and disable file existance chech commit FilePicker : support for multi-select on additional sources #1047 DateTimePicker : new property for allowTextInput #1094 Fixes \u00b6 LivePersona : Cannot find module '@pnp/spfx-controls-react/lib/LivePersona' #1069 ListView : documentation spelling mistake 'ColumndName' #1063 Fixes for Norwegian localization #1083 DynamicForm : doesn't load or save correctly when field name starts with a special character #1077 DynamicForm : fields in DynamicForm do not honour regional settings #1075 DynamicForm : Boolean fields do not honour the default value in list settings #1073 TaxonomyPicker : table markdown fix in documentation #1072 WebPartTitle : Fix for styling of WebPartTitle to better match the styling of the oob webpart titles. #1088 LivePersona : fix for documentation typos #1106 LivePersona : remove property for SPFx context #1108 Documentation fix for swedish translations #1100 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alexander M , Carlos Marins Jr , Fabio Franzini , Henrik , Jasey Waegebaert , Jo\u00e3o Mendes , Milan Holemans , MonalisaBaltatescu , Patrik Hellgren , Tom G . 3.5.0 \u00b6 Enhancements \u00b6 Update mgt package to the latest version #1038 ListView : Add ability to provide CSS class names for list wrapper and list itself #1007 IconPicker : onCancel property is added #1043 SharePoint Framework v1.13.* support DynamicForm : disabledFields property added #987 ListPicker : Add multi numbers support for baseTemplate option #1016 ComboboxListItemPicker : Add option to sort the items in the picker #985 PeoplePicker : Added filter for Microsoft 365 Group #985 Accordion : Added custom icons #1033 Localization: Correction for german localizations #1059 Localization: Corrections for norwegian localizations #1060 PeoplePicker : Added Styles property #1061 Localization: Update pt-pt and pt-br loc files #1066 Fixes \u00b6 FilePicker : defaultFolderAbsolutePath does not work Out of context #1023 ModernTaxonomyPicker : correctly display with RTL mode #1041 FilePicker : Fixed showing the selection circle on recent tabs #1048 FilePicker : Your organisation tab breadcrumb not working #1056 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Gautam Sheth , Jouni Pohjolainen , jumpei-yamauchi , Louis Pineau , Michalis Koutroupis , MonalisaBaltatescu , Patrik Hellgren , Xiyitifu , Russell gove , Andreas Omayrat , Abderahman Moujahid , Alexander M , Jo\u00e3o Mendes . 3.4.0 \u00b6 New control(s) \u00b6 ModernTaxonomyPicker : New control ModernTaxonomyPicker #1014 Enhancements \u00b6 Translations: Update translation keys #994 LocationPicker : Update docs #1009 FileTypeIcon : Add support of 20px icons #1013 Pagination : Update import from lodash #1021 Fixes \u00b6 ChartControl : Charts not updating properly when properties are changed #997 TaxonomyPicker : suggestions language is always English #879 TaxonomyPicker : errorMessage label not being removed #953 FilePicker : Sorting Not Working as Expected in Site Tab #1011 FilePicker : Site Tab - Lots of file types don't have appropriate icons #1012 LocationPicker : Correct documentation #1019 FilePicker : fileNameWithoutExtension not calculated right #1022 FieldUserRenderer : Add missing PnPJS imports #1025 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Dennis Kuhn , Gautam Sheth , Jean-Luc Richer , hesperanca , Kiryl Shchasny , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy . 3.3.0 \u00b6 New control(s) \u00b6 LivePersona : New Control LivePersona #969 ListItemComments : New Control ListItemComments #979 Enhancements \u00b6 FilePicker : spanish translation for Stock Images labels #946 FilePicker : Add support for a defaultFolderAbsolutePath prop #947 DynamicForm : Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944 DateTimePicker : Add property for minutes dropdown increment #939 ListItemPicker : add property to show all options by default #955 ListItemPicker : Missing translation keys, improved FI, NL translation #957 TaxonomyPicker : Added onNewTerm called when enter is pressed #967 DynamicForm : Principal Types support #956 DateTimePicker : Expose allowTextInput from the underlying date picker #928 Dynamic Form : Show field descriptions #975 Fixes \u00b6 RichText : Image button is checked when hyperlink is added to the text #948 RichText : impossible to display link with the text equal to the url #949 ComboBoxListItemPicker : defaultSelectedItems not working #954 Dynamic Form : query items in a folder (managed metadata field) #973 PeoplePicker : Default selected items for groups #958 Documentation: corrected Twitter handle for M365PnP #984 Carousel : Carousel is missing import of ICarouselImageProps #986 Documentation fix - DynamicForm example has incorrect syntax #990 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alexey Morozov , Daniel Stratton , Dennis Kuhn , Gautam Sheth , Jo\u00e3o Mendes , Ketill Anton\u00edus \u00c1g\u00fastsson , kmrshubham0 , Modern Dev Dude , Ravichandran Krishnasamy , Sergio Ortega Mart\u00edn , Yannick Reekmans . 3.2.1 \u00b6 Enhancements \u00b6 ListItemAttachments : Add new label and description properties #943 Fixes \u00b6 ListPicker : ListPicker stopped working in upgrade from 3.1.0 to 3.2.0 #945 ListItemAttachments : Fixed multiple bugs #943 3.2.0 \u00b6 New control(s) \u00b6 DynamicForm : New Control: Dynamic form #878 LocationPicker : New Control - Location Picker #915 Enhancements \u00b6 fast-serve : Add fast-serve support #916 ComboBoxListItemPicker and ListItemPicker : Add label to control #914 PeoplePicker : new property groupId . #917 ListPicker : add contenttype id to list picker #894 ListPicker : Few more tests with a little better description #906 Translations: Improved Finnish translations #937 Fixes \u00b6 Documentation for RichText : correct event handler name #898 SitePicker : SitePicker does not display initial sites until you click the dropdown to select #895 DatePicker : Fix Spanish loc strings #923 FilePicker : invalid CSS: relative in quotes. #930 MyTeams : Update MyTeams to use new library mgt-spfx #918 FieldCollectionData : FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Nikolay Belykh , Eduard Paul , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy , Russell gove , Sergei Sergeev , Jo\u00e3o Mendes , Marcin Wojciechowski , Gautam Sheth . 3.1.0 \u00b6 New control(s) \u00b6 TeamPicker : new Team Picker control #846 TeamChannelPicker : new Team Channel Picker control #846 SitePicker : new Site Picker control #868 DocumentLibraryBrowser , SiteFilePickerTab : jest unit tests #866 DragDropFiles : new DragDropFiles control #861 MyTeams : new MyTeams control #874 TeamChannelPicker : new TeamChannelPicker control #874 TeamPicker : new TeamPicker control #874 Enhancements \u00b6 ListView : Use new DragDropFiles control #861 FilePicker : Use new DragDropFiles control #861 SharePoint Framework v1.12.1 support ListView : Ability to provide custom sorting function #880 FilePicker : Allow panel on FilePicker to be invoked after first load #886 FilePicker : Allow FilePicker button to be hidden #887 FilePicker : Change same function to return an array of objects Fixes \u00b6 Documentation for ListView : typos fixes #855 Documentation fix: type on index page #852 PeoplePicker : error message isn't cleared after onGetErrorMessage returns an empty string #841 TreeView : Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870 FilePicker : React crash on large folders #826 ListItemAttachments : updated filename replacement logic #873 RichText : Adding a link does not work #875 FilePicker : Stock images url is getting a 404 server error #882 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Ari Gunawan , aroraans1512 , cwparsons , joaojmendes , Kunj Balkrishna Sangani , Marcin Wojciechowski , Yannick Reekmans , Andr\u00e9 Lage . 3.0.0 \u00b6 Enhancements \u00b6 SharePoint Framework v1.12 support (breaking change) Fluent UI v7 support 2.9.0 \u00b6 Enhancements \u00b6 FilePicker : spanish translation for Stock Images labels #946 FilePicker : Add support for a defaultFolderAbsolutePath prop #947 DynamicForm : Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944 DateTimePicker : Add property for minutes dropdown increment #939 DynamicForm : Principal Types support #956 Dynamic Form : Show field descriptions #975 Fixes \u00b6 RichText : Image button is checked when hyperlink is added to the text #948 RichText : impossible to display link with the text equal to the url #949 ComboBoxListItemPicker : defaultSelectedItems not working #954 PeoplePicker : Default selected items for groups #958 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alexey Morozov , Daniel Stratton , Ketill Anton\u00edus \u00c1g\u00fastsson , Ravichandran Krishnasamy , Sergio Ortega Mart\u00edn . 2.8.0 \u00b6 New control(s) \u00b6 DynamicForm : New Control: Dynamic form #878 LocationPicker : New Control - Location Picker #915 Enhancements \u00b6 ComboBoxListItemPicker and ListItemPicker : Add label to control #910 PeoplePicker : new property groupId . #917 Fixes \u00b6 SitePicker : SitePicker does not display initial sites until you click the dropdown to select #895 FilePicker : invalid CSS: relative in quotes. #930 FieldCollectionData : FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Nikolay Belykh , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy . 2.7.0 \u00b6 New control(s) \u00b6 DragDropFiles : new DragDropFiles control #856 SitePicker new Site Picker control #867 Controls Add locale strings for pt-br #865 Enhancements \u00b6 ListView : Use new DragDropFiles control #856 FilePicker : Use new DragDropFiles control #856 ListView : Ability to provide custom sorting function #880 FilePicker : Allow panel on FilePicker to be invoked after first load #886 FilePicker : Allow FilePicker button to be hidden #887 FilePicker : Changed save function to return an array of objects Fixes \u00b6 PeoplePicker : error message isn't cleared after onGetErrorMessage returns an empty string #841 TreeView : Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870 FilePicker : React crash on large folders #826 ListItemAttachments : updated filename replacement logic #873 RichText : Adding a link does not work #875 FilePicker : Stock images url is getting a 404 server error #882 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Andr\u00e9 Lage , cwparsons , Kunj Balkrishna Sangani , Yannick Reekmans . 2.6.0 \u00b6 New control(s) \u00b6 AnimatedDialog : new Animated Dialog control #815 Jest unit tests #834 Enhancements \u00b6 IconPicker : search icons using contains comparison. FilePicker : default alphabet sorting #824 ListItemPicker : ability to provide orderBy #829 Dashboard : Dashboard widget wrapper for styling and error catching #836 FolderExplorer : Update folder explorer documentation #835 Fixes \u00b6 IconPicker : Fix case sensitive fluent icon search service #814 Carousel : documentation fix - broken table style #817 AccessibleAccordion : documentation link is broken #818 Documentation: Controls link in the menu is broken #821 TreeView : Fix two potential null reference issues #832 RichText : Problem with bullets and number list #795 FolderPicker : Correct FolderPicker link alignment Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Anoop Tatti , Ari Gunawan , Gautam Sheth , Kunj Balkrishna Sangani , Marcin Wojciechowski , Mark Bice , Nizar Grindi , Yannick Reekmans . 2.5.0 \u00b6 Enhancements \u00b6 TreeView : Adding support to clear TreeView selected items by passing an empty array. #787 FilePicker : new property includePageLibraries to optionally display Site Pages library on Site tab #601 ListItemPicker : Support of Calculated columns #805 Progress : Documentation update to have consistency in variables names #811 FolderExplorer : Add support for sorting folder explorer items #812 Fixes \u00b6 ListView : Selection is reset when putting a ListView inside a React Component that controls its items and selection props #251 Documentation fix for PeoplePicker : Removed unwanted new line in help content. #783 Documentation fix for TreeView : TreeViewSelectionMode added in the import #780 Documentation fix for TreeView : removed unwanted comma #779 IFrameDialog : height unable to resize relative to screen size, even if we provide in % it is taking default value. #636 DateTimePicker : Clear Date functionality #799 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Ari Gunawan , Joel Rodrigues , Mike Myers , Ravichandran Krishnasamy , San . 2.4.0 \u00b6 New control(s) \u00b6 AccessibleAccordion control #770 Enhancements \u00b6 Placeholder : support of custom rendering for iconText and description PeoplePicker : ability just to display inactive users name (ideally the value fetched from 'Author/Title') #768 TaxonomyPicker : New onPanelSelectionChange property added. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. #761 TaxonomyPicker : selectChildrenIfParentSelected property added. Specifies if the children should be selected when parent item is selected (defaults to false). #765 ListPicker : ability to pick lists from specified site using webAbsoluteUrl property. FilePicker : buttonIconProps to define properties of the button's icon #770 Fixes \u00b6 DateTimePicker : documentation fix #767 PeoplePicker : documentation fix - Changed isRequired property to new required #769 Documentation fix - missing IFramePanel link on home page #775 Documentation fix for FilePicker : updated onChaged to onChange #776 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Andr\u00e9 Lage , Christian Metz , Gaurav Goyal , Leif Frederiksen , Ravichandran Krishnasamy , San , Jo\u00e3o Mendes . 2.3.0 \u00b6 New control(s) \u00b6 Dashboard control for Microsoft Teams #758 Toobar control for Microsoft Teams #758 Enhancements \u00b6 TaxonomyPicker : Added useSessionStorage property #759 Fixes \u00b6 FilePicker : documentation fix: '|' not escaped #756 TaxonomyPicker : Return TermSetId for suggestions #762 WebPartTitle : Fluent UI Updates to SharePoint - WebPartTitle control too thin now #605 ListView : Sticky Header scrolling issue #734 DateTimePicker : hours dropdown not re-rendered when state changed programmatically #757 RichText : controlled mode doesn't work #666 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Gautam Sheth , Marcin Wojciechowski , Nikolay Belykh , Andr\u00e9 Lage . 2.2.0 \u00b6 Enhancements \u00b6 RichText : Add image support #705 FilePicker : Add file size to the Upload tab and IFilePickerResult #706 FieldCollectionData : SearchBox instead of TextBox #719 TaxonomyPicker : control does not show an error message for an invalid/unresolved input #728 Canadian French localization #671 FilePicker : reduce bundle size #732 FilePicker : Custom render callbacks for the 'Upload' and 'Link' tabs #746 Fixes \u00b6 Localization: Fixing some wrong localizations for the DatePicker short day in Spanish. #702 ListItemPicker : When use defaultSelectedItems, ListItemPicker allows you to select dublicate entries #722 Deprecated stuff is removed #733 DateTimePicker : time portion not re-rendered when state changed programmatically - when time is displayed as dropdown only #713 PeoplePicker : errorMessage not being removed #730 ListItemAttachment : the control is not fully disabled #736 TaxonomyPicker : icons are not being rendered on Classic SharePoint pages #735 FilePicker : Site Tab does not load document if we access SharePoint site in different language than default language of the site #724 Documentation fix for 'attention' block on index page #740 TaxonomyPicker : sessionStorage exceeds max-size when browsing large termsets #739 FolderExplorer and FolderPicker do not seem to work for document libraries #741 FilePicker : onChange event does not exist despite being documented #747 ListItemPicker : Selected values are not getting cleared or reset #659 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Abderahman Moujahid , avadhootdindorkar , Devang Bhavsar , Gautam Sheth , Konrad K. , Nikolay Belykh , Vertamin . 2.1.0 \u00b6 Enhancements \u00b6 Carousel : Ability to display indicators in a dedicated block #681 FilePicker : Org Assets are not displayed for non-admin users #687 ListView : Drag and Drop option #679 FolderExplorerService : support special characters if folder name #691 ListView : Sticky Header #634 IconPicker : get icons from @uifabric/icons/lib/data/AllIconNames.json ListView : Sticky header with className instead of additional components #696 ListView : StickyHeader code consistency #697 TreeView : Added (optional) property 'defaultExpandedChildren' that controls the behavior of the expansion of child elements. #698 Fixes \u00b6 RichText : Cannot add link in first line #672 TaxonomyPicker : Ability to reset the TaxonomyPicker (Remove all selected Terms) #367 Documentation fix for TaxonomyPicker : the disabled property is a boolean and not a string as currently specified #695 ComboBoxListItemPicker : update options when listId has been changed #683 FilePicker : styles are updated to match OOB control #700 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Abderahman88 , Andr\u00e9 Lage , Gautam Sheth . 2.0.0 \u00b6 Enhancements \u00b6 FilePicker : added additional properties - isPanelOpen and onCancel #668 Fixes \u00b6 PeoplePicker : Disabled doesn't work #484 Pagination : control not re-rendering when currentPage is updated in state #663 Contributors \u00b6 Special thanks to our contributor: Gautam Sheth . 1.20.0 \u00b6 New control(s) \u00b6 Accordion control #638 FieldCollectionData control #591 Enhancements \u00b6 FilePicker : Stock images option added #593 TaxonomyPicker : Add the 'required' property #216 TaxonomyPicker : Add errorMessage and onGetErrorMessage props #600 ListItemPicker : ability to use substring search instead of startswith #583 Map : return display name and address details for the location #585 Map : support for draggable and static Bing maps #586 TaxonomyPicker : onLoad validation #602 FieldCollectionData : Add pagining and filtering #617 TaxonomyPicker : Finding terms with labels #288 FileTypeIcon : Added support for additional file type in Image mode #640 Fixes \u00b6 ComboBoxListItemPicker : fetching only 100 items #569 TaxonomyPicker : browse (tree view) doesn't work with SP 2016 On-Premises #183 FilePicker : default tab when opened shows hidden RecentTab #477 PeoplePicker : The required error message not showing #590 ListItemAttachments : fails in Microsoft Teams Tab SPFx applications #582 Carousel : Changing pages doesn't work #609 TaxonomyPicker : no suggestions are displayed if anchorId is not set TaxonomyPicker : Suggestion/match does not work as expected #604 TaxonomyPicker : Include check for separator while filtering path of terms when anchorId is configured #625 FilePicker : Bing API search issue #633 ListView : Sort fires selection #621 Map : A minor issue in componentWillUpdate method to get the next props rather than the current props. #641 IFrameDialog : dialog size is incorrect when opening the dialog second time #615 FolderPicker : imports don't work #614 FilePicker : Yor Organization tab is not shown #596 FolderPicker , FolderExplorer : Controls don't let you explore sub folders if parent folder has apostrophe (') in its name. #644 PeoplePicker : image for a user picked in PeoplePicker didn't get resolved #646 Documentation fix for IconPicker : renderOption dialog should be lowercased. #649 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Alexey Sadomov , Anoop Tatti , Devang Bhavsar , Gautam Sheth , geltapatio , Joel Jeffery , juhaalhojoki , Piotr Siatka , Rabia Williams , Ravichandran Krishnasamy , Victor Pollet . 1.19.0 \u00b6 Enhancements \u00b6 ListView : Add clear button to filter text box #549 FolderExplorer : Add clear button to filter text box #553 TreeView : there should be possibility to collapse the first level nodes by default #561 TreeView : Expand to selected #559 DateTimePicker : When using the datetimePicker I would like to have an opportunity to set maximum/minimum date like in Office UI Fabric #497 TaxonomyPicker : Added the selectTerm , hideTerm , and disableTerm actions #578 TaxonomyPicker : Added the functionality to enable/disable term actions on the fly #578 Carousel : indicators, slide animation, auto cycling, easier basic usage #587 Fixes \u00b6 TaxonomyPicker : Correct the AnchorID getting all TermSet search options #150 Documentation fix for TreeView : Some tables in TreeView documentation are displayed as plain text. #562 ComboBoxListItemPicker , ListItemPicker : Show error span if error is present #557 TreeView : defaultExpanded: true doesn't work #560 IListPicker : typo fix #574 DateTimePicker : DateTime Picker noon/midnight issue with 12 hour format #576 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Gautam Sheth , Koen Zomers , Markus Langer , Nanddeep Nachan , Prasad Kasireddy , David Ramalho , Siddharth Vaghasia . 1.18.0 \u00b6 New control(s) \u00b6 Pagination Control #535 TreeView Control #536 FolderPicker Control #525 Enhancements \u00b6 FolderExplorer updates: allow selection of libraries if site url is used as the root, allow passing items to be passed as a property and added to the breadcrumb, add support for loading folders from a different site, fix breadcrumb names for document libraries #534 IconPicker : renderOption property to render icons list as a panel or dialog #537 Fixes \u00b6 ComboBoxListItemPicker documentation fix: Updated import statement in docs for ComboBoxListItemPicker #510 Documentation fix: add the new control ComboBoxListItemPicker component to landing page #511 FilePicker : While using the control, if hideOrganisationalAssetTab is set to true, even then an additional HTTP request is made. IconPicker : search fix and updated list of icons #533 ListItemAttachment : when I upload a file that contains an hyphen, the \"-\" char is replaced by an empty string #526 IconPicker shows selected icon only during the first opening #513 ComboBoxListItemPicker : onSelectedItem passing data to callback method but with attributes value as undefined #519 FilePicker : filename is not visible on Upload tab #518 IconPicker : Search doesn't work at all #512 ComboBoxListItemPicker documentation fix: correct onSelectedItem notation #547 Documentation: Fix mistranslation in Japanese #545 FieldUserRenderer : displayName in FieldUserHoverCard is not updated if props of the FIeldUserRenderer have been changed #542 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): David Ramalho , Gautam Sheth , Gregghis , Jo\u00e3o Mendes , Joel Rodrigues , Nanddeep Nachan , Prasad Kasireddy , Siddharth Vaghasia , Takashi Shinohara . 1.17.0 \u00b6 New control(s) \u00b6 ComboBoxListItemPicker component #292 Localization : Project now supports localization of all SharePoint Online languages (auto translation via Cognitive Services) #456 IconPicker : component #485 FolderExplorer component #499 Enhancements \u00b6 SecurityTrimmedControl : Added the option to show a control when the user doesn't have permissions 307 PnP Telemetry service opt-out support #475 TaxonomyPicker : Possibility to hide deprecated and \"Available for Tagging\"= false terms #421 FilePicker - French translation #449 Slovak localization #457 TaxonomyPicker : Placeholder for Taxonomy Picker #464 ListItemPicker , PeoplePicker : Placeholder for ListItemPicker and PeoplePicker #486 FilePicker : Do not store active tab in url's hash #488 DateTimePicker : Placeholder property option added #503 Fixes \u00b6 RichText : problem with edit mode #445 ListView documentation: Typo - the first occurrence of maxWidth should be minWidth #400 RichText : Text indent buttons were copy-paste of subscript and superscript buttons. Clicking on the text-indent buttons would call subscript or superscript instead. #454 RichText : Fix of removing text and inserting link instead #455 FilePicker : Read file content in IE11 #444 ListPicker : listPicker always return \"test\" when multiple allowed #458 FilePicker : Button text overflow fix + global classnames and properties FieldUserRenderer : implementation of api/SP.UserProfiles.PeopleManager/GetPropertiesFor is not working on on-prem #468 Placeholder : Placeholder component is not rendering after a string change in it's properties #469 ListView documentation update: minWidth instead of maxWidth #480 DateTimePicker : Minutes and Seconds validation #495 FilePicker : bingAPIKey not working #489 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Richard Gigan , Reginald Johnson , JonasBjerke89 , Prasad Kasireddy , Alexander Kleshcheov , Konradox , L\u00e9o Maradan , Matej , mgwojciech , Joel Rodrigues , Jason S , Piotr Siatka , Rabia Williams . 1.16.0 \u00b6 Enhancements \u00b6 FilePicker : Fixes for OneDrive CORS issues #407 ListItemPicker : added new control property filter #392 allowing to use context from any type of SPFx extensions: #419 Placeholder : remove unused and vendor specific CSS #426 Fixes \u00b6 Documentation fix for FilePicker : updated accepts value in props #404 The FilePicker control doesn't work in many languages due to missing localization keys #412 Documentation fix for broken links of Property Controls landing page #388 Documentation fix to include new components from v 1.15.0 #394 DateTimePicker : dropdown for time not handling AM/PM correctly #405 Documentation fix for index page: updated link to Chart controls #417 Documentation update for SPFx On Premises notice: #418 Documentation update for ListItemPicker : valueColumnInternalName should be keyColumnInternalName RichText : Fix \"Align Left\" button #429 Documentation update for FilePicker : misspelling #432 IFramePanel : Fix doubled scroll issue when iframe content is higher than frame height #431 PeoplePicker : errorMessage not showing #420 IFrameDialog : commitPopUp typo causes popups with classic forms to not close after hitting save #433 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Piotr Siatka , Dani Dom\u00ednguez , Siddharth Vaghasia , Jo\u00e3o Mendes , PrasadKasireddy , Chad Eiserloh , Koen Zomers , Dmitry Rogozhny , Alexander Kleshcheov , Hugo Bernier , Beniamin , Giovani Martini . 1.15.0 \u00b6 New control(s) \u00b6 FilePicker : New control added to the library #366 GridLayout : New control added to the library #350 Carousel : New control added to the library #227 Enhancements \u00b6 TaxonomyPicker : Localization keys added to the buttons #361 Swedish localization support added #359 Improved German translations #338 DateTimePicker : added options to render time part as mask or dropdown #330 ListItemPicker : option to select a key column #350 , #381 Improved Russian translations #384 RichText : Added the ability to add a third Color Swatch Group called custom. This will allow you to add custom colors to the font color selector. #385 Fixes \u00b6 TaxonomyPicker : Tags icon styling issue on IE11 #356 DateTimePicker : Does not respect dateLabel and timeLabel #346 PeoplePicker : Get loginName with ensureUser #342 PeoplePicker : Fix missing required field label #371 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): amortsell , Hugo Bernier , Robert Lindstr\u00f6m , pfc2k8 , Piotr Siatka , Alex Terentiev , Luis Robertto Mello , eweintraub . 1.14.0 \u00b6 Enhancements \u00b6 German translations added for attachment and RichText controls #333 SecurityTrimmedControl : Added a wrapper className property for the parent element #325 ListPicker : Add ability to filter the control via OData #319 IFrameDialog : closing dialog on commit #313 WebPartTitle add support for section background color #258 Fixes \u00b6 Fix in return type of onClick and onDoubleClick events #321 ListPicker : Fix for available dropdown selection after selection was done #315 Fixes to French translations #312 RichText : Issue on rendering the control in view mode #287 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Amr Fouad , Joel Jeffery , Mark Powney , Dominik Schmieder , Alex Terentiev , Zhephyr . 1.13.2 \u00b6 Enhancements \u00b6 Improvements to the Lithuanian localization #285 Fixes \u00b6 IFrameDialog : dimensions issue #303 DateTimePicker : IE11 layout issue #301 FileTypeIcon : Only displays PDF's in SPFx 1.8.2 #300 FieldNameRenderer : Fails to encode URI when hasPreview #296 TaxonomyPicker : Cannot find name `TermLabelAction #293 ListItemAttachments : Move deleted attachments to the recycle bin #291 DateTimePicker : Does not respect isMonthPickerVisible prop #283 ListItemAttachments : Render issue fixed + improvements to the attachment API calls #282 RichText : Fixes an issue when hitting enter in the control #277 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Tautvydas Duda , Thomas Granheim , Robert Lindstr\u00f6m , Alex Terentiev . 1.13.1 \u00b6 Fixes \u00b6 WebPartTitle : Fix for className property which is not defined #281 RichText : Fix issue where control turns drop-downs black #279 Contributors \u00b6 Special thanks to our contributor: Hugo Bernier . 1.13.0 \u00b6 New control(s) \u00b6 Progress : New control added #230 DateTimePicker : New control added #21 RichText : New control added #20 Enhancements \u00b6 SecurityTrimmedControl : Support for item and folder permission checks added #271 Retrieve the user its profile picture from SharePoint instead of Office 365 / Outlook #248 Added Lithuanian localization #247 FileTypeIcon : Added support for PDF icon file types #260 WebPartTitle : Added the ability to render a see all link or custom component #228 Fixes \u00b6 PeoplePicker : Fix for single quotes around the ms-peoplepicker class #275 RichText : Fix for toolbar that appears at top of the page #265 ListItemAttachments : Updated import statement reference in the documentation #254 ListView : Updated documentation for the iconFieldName property #245 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Francis , Fredrik Andreasson , Hugo Bernier , Tautvydas Duda , \u00d6zg\u00fcr Ersoy , Robert Lindstr\u00f6m , Alex Terentiev . 1.12.0 \u00b6 New control(s) \u00b6 ListItemAttachments : New control added #177 IFramePanel : New control added #226 Enhancements \u00b6 Added Russian localization #214 TaxonomyPicker : Ability to specify term actions #237 Fixes \u00b6 TaxonomyPicker : Terms are sorted incorrectly under the wrong parent #199 #229 TaxonomyPicker : Issue with custom sort order of items underneath root terms #231 PeoplePicker : Fix for issue where values couldn't be cleared #234 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Patrik Hellgren , Jo\u00e3o Mendes , David Opdendries , Piotr Siatka , Alex Terentiev , Tse Kit Yam . 1.11.0 \u00b6 New control(s) \u00b6 Map : Newly introduced map control is available #14 ChartControl : Newly introduced control to render charts #15 Enhancements \u00b6 PeoplePicker : Allow the people picker to search on site level and on tenant level #97 ListView : Added support for filtering #99 PeoplePicker : Make the titleText property not required #184 Placeholder : Added the ability to specify if the button can be hidden #206 Updated the office-ui-fabric-react to the same version as in SPFx 1.7.0 Fixes \u00b6 IFrameDialog : fix for spinner which keeps appearing on the iframe #154 PeoplePicker : fix SharePoint groups which could not be retrieved #161 TaxonomyPicker : fix sort order with lowercased terms #205 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Hugo Bernier , joaojmendes , Asish Padhy , Piotr Siatka , Anoop Tatti , Alex Terentiev , Tse Kit Yam . 1.10.0 \u00b6 New control(s) \u00b6 ListItemPicker : New field control #165 Enhancements \u00b6 Dutch localization added #100 German localization added #101 French localization added #102 PeoplePicker : Move defaultSelectedUsers from ComponentWillMount to ComponentDidUpdate Lifecycle #135 PeoplePicker : Initialize with users from a list item #138 PeoplePicker : Remove Messagebar error handling to match Office UI Fabric field error styling #140 PeoplePicker : REST API filter and nometadata header added to reduce payload #139 PeoplePicker : Allow to set the maximum number of suggestions suggestionsLimit #143 #148 TaxonomyPicker : retreiving the terms in the correct custom sort order #146 PeoplePicker : Documentation format updated to make it easier to check the default values #159 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Marc D Anderson , Ole Bergtun , Jo\u00e3o Mendes , Markus M\u00f6ller , Asish Padhy , PooLP , Gautam Sheth , Tse Kit Yam . 1.9.0 \u00b6 Enhancements \u00b6 Optimize bundle size for latest SPFx version due to Office UI Fabric specific versioning #136 Fixes \u00b6 FieldLookupRenderer : Lookup dialog is empty #131 IFrameDialog : Unnecessary horizontal scroll in IFrame dialog #132 PeoplePicker : Suggested People not loading after first selection #134 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Gautam Sheth , Alex Terentiev . 1.8.0 \u00b6 Enhancements \u00b6 PeoplePicker : Specify to hide or show the users/groups which are hidden in the UI #122 WebPartTitle : changing font-sizes on different resolutions #114 WebPartTitle : Added accessibility tags for web part title #121 ListView : Resizable columns - introduced a isResizable property #119 FieldNameRenderer double click support added #116 TaxonomyPicker : table markup changed to DIV #113 PeoplePicker : ability to specify the source site to load users from #110 TaxonomyPicker : Disable the terms which are set as deprecated or unavailable for tagging #109 PeoplePicker : Specify principle type to retrieve (users, groups, ...) #94 Fixes \u00b6 FieldLookupRenderer : Fixed URL querystring params #126 IFrameDialog : dialog width is not correct in IE11 #118 PeoplePicker : fix freezes when typing in search values #117 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Thomas Lamb , Joel Rodrigues , Mikael Svenson , Alex Terentiev . 1.7.0 \u00b6 Enhancements \u00b6 PeoplePicker : added functionality to initialize the control with person(s) or group(s) #98 PeoplePicker : support for searching on contains #93 PeoplePicker : find user based on email address #95 Bundle size: statically reference Office UI Fabric components in the FieldRenderer controls #107 Fixes \u00b6 FieldNameRenderer onClick does not suppress default link behavior #103 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Octavie van Haaften, Asish Padhy, Mikael Svenson, Alex Terentiev. 1.6.0 \u00b6 Enhancements \u00b6 Disabled property for PeoplePicker #88 Fixes \u00b6 New telemetry approach which allows you to use Application Insights #81 PeoplePicker property selectedItems not implemented? #90 Contributors \u00b6 Special thanks to our contributor: Octavie van Haaften. 1.5.0 \u00b6 New control(s) \u00b6 New PeoplePicker control added #19 Enhancements \u00b6 Added properties to the TaxonomyPicker to specify which terms are disabled/not-selectable #82 Fixes \u00b6 Bug in TaxonomyPicker where values are not updated by an async change #83 FieldUserRenderer uses email prop for GetPropertiesFor #84 Fixed issue in single selection mode when all group items were selected in the ListView when user clicked on the group header #86 Contributors \u00b6 Special thanks to our contributors (in alphabetical order): Asish Padhy, Alex Terentiev. 1.4.0 \u00b6 New control(s) \u00b6 SecurityTrimmedControl control got added #74 Enhancements \u00b6 Allow the TaxonomyPicker to also be used in Application Customizer #77 Add npm postinstall script to automatically add the locale config #78 Fixes \u00b6 Icon not showing up in the Placeholder control #76 1.3.0 \u00b6 Enhancements \u00b6 TaxonomyPicker control got added #22 #63 #64 ListPicker control got added #34 Fixes \u00b6 Issue fixed when the optional selection property was not provided to the ListView #65 1.2.5 \u00b6 Fixes \u00b6 Undo ListView item selection after items array updates #55 1.2.4 \u00b6 Enhancements \u00b6 Hiding placeholder title on small zones Fixes \u00b6 iFrame dialog reference fix #52 1.2.3 \u00b6 Enhancements \u00b6 Optimized telemetry so that it only pushes control data WebPartTitle hide control completely when empty 1.2.2 \u00b6 Fixes \u00b6 Fixes an issue sorting in the ListView control while items were selected. Indexes were not updated. 1.2.1 \u00b6 Fixes \u00b6 FieldTaxonomyRenderer got fixed to support single and multiple values 1.2.0 \u00b6 New control(s) \u00b6 Field controls are added to the project IFrameDialog was added to the project Fixes \u00b6 Fixed theming in the WebPartTitle control 1.1.3 \u00b6 Fixes \u00b6 FileTypeIcon icon fixed where it did not render an icon. This control should now works in SPFx extensions. 1.1.2 \u00b6 Enhancements \u00b6 Improved telemetry with some object checks Fixes \u00b6 Fix for WebPartTitle control to inherit color 1.1.1 \u00b6 Enhancements \u00b6 Removed operation name from telemetry 1.1.0 \u00b6 Enhancements \u00b6 Telemetry added 1.0.0 \u00b6 New control(s) \u00b6 WebPartTitle control got added Enhancements \u00b6 ListView control got extended with the ability to specify a set of preselected items. Beta 1.0.0-beta.8 \u00b6 Fixes \u00b6 Fix for the ListView control when selection is used in combination with setState . Beta 1.0.0-beta.7 \u00b6 New control(s) \u00b6 Grouping functionality added to the ListView control Beta 1.0.0-beta.6 \u00b6 New control(s) \u00b6 Initial release","title":"Release notes"},{"location":"about/release-notes/#releases","text":"","title":"Releases"},{"location":"about/release-notes/#3200","text":"","title":"3.20.0"},{"location":"about/release-notes/#enhancements","text":"Dashboard : added new WidgetSize #1845 Dashboard : IWidgetLink improvements #1813 DynamicForm : custom sorting #1802 ImagePicker : new Control ImagePicker #1820 UserPicker : new Control UserPicker #1675 DynamicForm : DynamicForm storeLastActiveTab option #1879 #1879 FilePicker : Image picker enhancements #1805 DynamicForm : Adds ability to create files/folders in subfolder using DynamicForm. #1901","title":"Enhancements"},{"location":"about/release-notes/#fixes","text":"Debug Controls in any language #1882 AdaptiveCardHost : lock down adaptive-expression package version #1876 ListItemPicker : PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. #1887 ListItemAttachments : Fix 1858 to correct Chinese localization files #1894 #1894 DynamicForm : Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type #1872 GridLayout : A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. 1851 DynamicForm : Always Show Required Field Validation Error In FormDisplayMode.Edit Mode #1775 DynamicForm : Required Field Validation won't work #1760 DynamicForm : Adds ability to render file/folder name field in DynamicForm and Field. #1906","title":"Fixes"},{"location":"about/release-notes/#contributors","text":"Special thanks to our contributors (in alphabetical order): Alex Terentiev , Antanina Druzhkina , Guido Zambarda , IRRDC , joaojmendes , Martin Lingstuyl , Micha\u00ebl Maillot , Nishkalank Bezawada , srpmtt , wilecoyotegenius , wuxiaojun514 .","title":"Contributors"},{"location":"about/release-notes/#3190","text":"","title":"3.19.0"},{"location":"about/release-notes/#enhancements_1","text":"SharePoint Framework v1.19.0 support #1857 DynamicForm : enable/disable save button #1810 PeoplePicker : add new prop - useSubstrateSearch #1819 SitePicker : add button to clear single / multiple selection #1839","title":"Enhancements"},{"location":"about/release-notes/#fixes_1","text":"DynamicForm : more than 100 lookups and date format in lookup field #1722 Richtext : can not undo ordered lists #1135 FilePicker : fixing organization tab browsing issue #1861 PeoplePicker : method to clear the array #1838 SitePicker : documentation patch #1842","title":"Fixes"},{"location":"about/release-notes/#contributors_1","text":"Special thanks to our contributors (in alphabetical order): Alex Terentiev , Antanina Druzhkina , Guido Zambarda , Luccas Castro , Micha\u00ebl Maillot , Niels S\u00f6th , srpmtt .","title":"Contributors"},{"location":"about/release-notes/#3181","text":"","title":"3.18.1"},{"location":"about/release-notes/#fixes_2","text":"FilePicker : Fix issue with adding link by typing in 'From a link' tab #1814 Update nl-nl.ts #1823","title":"Fixes"},{"location":"about/release-notes/#contributors_2","text":"Special thanks to our contributors (in alphabetical order): Antanina Druzhkina , Elio Struyf .","title":"Contributors"},{"location":"about/release-notes/#3180","text":"","title":"3.18.0"},{"location":"about/release-notes/#enhancements_2","text":"DynamicField : Added orderBy to DynamicField props for lookup fields #1747 DateTimePicker : disable array of dates #516 DynamicForm : new customIcons property to allow custom icons for the form #1745 RichText : Added style property to Rich text control #1773 fast-serve : Fast-serve update to match the most recent changes. #1782 PeoplePicker : Added context optimization #1764 Multiple controls : Wrong fluentui imports cause webpack build errors #1763 FileTypeIcon : Added standard events #1789","title":"Enhancements"},{"location":"about/release-notes/#fixes_3","text":"FolderPicker : Update documentation on how to use the control with siteAbsoluteUrl property #1743 Readme documents highlight extension does not work correctly #1495 DynamicForm : Error on rendering DynamicForm when having a Date Field with internal name starting with underscore ('_') #1738 DynamicForm : Dynamic form loading error in other site #1758","title":"Fixes"},{"location":"about/release-notes/#contributors_3","text":"Special thanks to our contributors (in alphabetical order): Guido Zambarda , Harminder Singh , IRRDC , Matthias Z'Brun , Micha\u00ebl Maillot , Nishkalank Bezawada , Sergei Sergeev , srpmtt .","title":"Contributors"},{"location":"about/release-notes/#3170","text":"","title":"3.17.0"},{"location":"about/release-notes/#enhancements_3","text":"DyanmicForm : Added file handling #1625 DynamicForm : Custom Formatting and Validation, ControlsTestWebPart updates #1672 PeoplePicker : Added custom filter to PeoplePicker selection #1657 RichText : Align RichText heading styles and font sizes with OOB SharePoint text web part #1706","title":"Enhancements"},{"location":"about/release-notes/#fixes_4","text":"Build fails due to missing @iconify/react dependency after upgrade to 3.16.0 #1719 ModernTaxonomyPicker : not displaying suggestions when typing in values - API not found error #1688 DynamicForm : Disable issue on fieldOverrides field control when onBeforeSubmit return true #1715 PeoplePicker : PeoplePicker returns no results with webAbsoluteUrl and ensureUser #1669 DynamicForm : [DynamicForm] Fixing multi taxonomy field (loading + saving existing item) #1739","title":"Fixes"},{"location":"about/release-notes/#contributors_4","text":"Special thanks to our contributors (in alphabetical order): Guido Zambarda , Lars Fernhomberg , Mark Bice , Micha\u00ebl Maillot , Nishkalank Bezawada , Tom G , wuxiaojun514 .","title":"Contributors"},{"location":"about/release-notes/#3162","text":"","title":"3.16.2"},{"location":"about/release-notes/#fixes_5","text":"DynamicForm : Fixing the previous version's issue #1736 (introduced in #1718 )","title":"Fixes"},{"location":"about/release-notes/#contributors_5","text":"Special thanks to our contributor: IRRDC .","title":"Contributors"},{"location":"about/release-notes/#3161","text":"","title":"3.16.1"},{"location":"about/release-notes/#fixes_6","text":"DynamicForm : Additional check to see if DefaultValue is an object. No more null comparisons, which should have been undefined comparisons","title":"Fixes"},{"location":"about/release-notes/#contributors_6","text":"Special thanks to our contributor: IRRDC .","title":"Contributors"},{"location":"about/release-notes/#3160","text":"","title":"3.16.0"},{"location":"about/release-notes/#new-controls","text":"ViewPicker : new control ViewPicker #1439 HoverReactionsBar : new control HoverReactionsBar #1652","title":"New control(s)"},{"location":"about/release-notes/#enhancements_4","text":"FieldCollectionData : render on page instead of panel and added combobox and peoplepicker controls #1588 FieldCollectionData : added date field control and updated number field #1600 ListItemComments : Added ListItemComments component to Controls.tsx #1621 FolderPicker : Improve documentation of FolderPicker #1379 RichText : Add https:// as placeholder instead of textbox value when adding url #1651 Fix package.json to remove phantom dependencies issues #1660 PeoplePicker : new property to starting the search after n characters #374 SharePoint Framework v1.18.2 support","title":"Enhancements"},{"location":"about/release-notes/#fixes_7","text":"AccessibleAccordion : fix typo in documentation #1634 DynamicForm : fix issue with MultiChoice field #1510 Localization : Update dutch translations #1635 TaxonomyPicker : suggested item contains double termset name #1597 DynamicForm : DynamicForm does not properly handle NULL default values for Taxonomy fields #1267 DynamicForm : New items are always created with the default content type if the list has multiple content types #1626 PeoplePicker :PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) DynamicForm : Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results #1614 DynamicForm : Number validations are working, but the percentage values are not getting saved #1601 DynamicForm : Number validation is preventing form save in certain circumstances, not enabled for currency fields #1604 ListItemAttachments : Inconsistent file handling #1644 Localization : Update Japanese translations #1686 ListItemPicker : Fix docs for onSelectedItem #1690 ComboBoxListItemPicker : Fix docs for onSelectedItem #1690 ListItemAttachments : Fix click behavior in ListItemAttachments component #1692","title":"Fixes"},{"location":"about/release-notes/#contributors_7","text":"Special thanks to our contributors (in alphabetical order): Dan Toft , Gerke van Garderen , Guido Zambarda , Joakim , Micha\u00ebl Maillot , Nils Andresen , Nishkalank Bezawada , Rico van de Ven , Steve Beaug\u00e9 , wuxiaojun514 , Tetsuya Kawahara , Tom G , Yannik Reiter .","title":"Contributors"},{"location":"about/release-notes/#3150","text":"","title":"3.15.0"},{"location":"about/release-notes/#new-controls_1","text":"TermSetNavigation : new control TermSetNavigation #1527","title":"New control(s)"},{"location":"about/release-notes/#enhancements_5","text":"FolderExplorer : show files on folder explorer control #1502 DynamicForm : Fixed typo in property name #1529 DynamicForm : validation error dialog added #1531 DateTimePicker : Add new property initialPickerDate #1581 ModernTaxonomyPicker : can't find term when UI is in language not supported by term store #1573 AdaptiveCardHost : Add null check for adaptive card elements #1574 ControlsTestWebPart : Updated the ControlsTestWebPart to show the controls filtered by control type #1547 fast-serve : Fast-serve updated to the latest version and serve warnings fixed #1589 DynamicForm : DynamicForm Number min max #1585","title":"Enhancements"},{"location":"about/release-notes/#fixes_8","text":"FieldPicker : Changed react import to fix cannot be used as a JSX component error #1500 Localization : Fixes to Italian localization #1532 Localization : Fixes to Netherlands localization #1537 ListItemAttachments : Fix the OnClick handler when clicking on the document card #1541 fast-serve : Fix issue with File and Directory Entries API #1555 FilePicker : Tile view issue on first render #1558 DynamicForm lookups - first time you select an option from a lookup, it doesnt select it #1535 DynamicForm : Fields of type Note don't get disabled #1264 ListItemAttachments : Fix for files containing dots in the name #1580 PeoplePicker : Shows wrong value in Dynamic Form when null is provided #1421 DynamicForm : Error on save when clearing person from Person or Group field and leaving it blank #1578 DynamicForm : Number validation is not working, if the field is set to minimum and maximum value #1571 DynamicForm : controls are shown with error messages even if the values are assigned #1133","title":"Fixes"},{"location":"about/release-notes/#contributors_8","text":"Special thanks to our contributors (in alphabetical order): Andreas Omayrat , Ayoub , Desislav , Guido Zambarda , Jo\u00e3o Mendes , Nishkalank Bezawada , Patrik Hellgren , Rico van de Ven , Sergei Sergeev , Sharepointalist , Zhephyr .","title":"Contributors"},{"location":"about/release-notes/#3140","text":"","title":"3.14.0"},{"location":"about/release-notes/#enhancements_6","text":"DateTimePicker : Fixed DateTimePicker strings in Danish Locale #1498 SharePoint Framework v1.17.1 support FieldCollectionData : Adds panelProps property to FieldCollectionData #1525","title":"Enhancements"},{"location":"about/release-notes/#fixes_9","text":"DynamicForm : Fixes DynamicForm trying to load TaxonomyFields with wrong display name #1422 ListItemAttachments : FIX: Cannot download items when it has a ilegal character #1484 FilePicker : FIX: recent tab empty until re-render #1482 Dynamic Form : Adds onListItemLoaded handler to DynamicForm #1472 Dynamic Form : Fix for the DynamicForm when a defaultValue is null and the code try to call the split method on it. #1486 DynamicForm : DynamicForm - Fixing Required Multi Field Saving Problem #1489 FolderExplorer : FolderExplorer doesn't explore folders with ' in the name #1491 DynamicForm : cannot display lookup value when the source field is not Title #1511 FilePicker :Features/1478 filepicker tiles view #1521","title":"Fixes"},{"location":"about/release-notes/#contributors_9","text":"Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Dan Toft , Guido Zambarda , Martin Lingstuyl , Nishkalank Bezawada , Sergio Villalta , Josef Benda , Victor Romanov , wuxiaojun514 , Zied FEHRI .","title":"Contributors"},{"location":"about/release-notes/#3130","text":"","title":"3.13.0"},{"location":"about/release-notes/#new-controls_2","text":"UploadFiles : New Upload Files control #1388","title":"New control(s)"},{"location":"about/release-notes/#enhancements_7","text":"ListItemPicker : use list name as well as GUID to point to list #1355 ListItemPicker : Add Styles property to ListItemPicker and ComboBoxListItemPicker #1407 SitePicker : Pass styles property to Dropdown #1389 FilePicker : Site Tab - Many Document Libraries No Scrolling #1413 DynamicForm : Add respectETag option to DynamicForm #1395 MonacoEditor : Fixed minor typos and misleading instructions #1415 SharePoint Framework v1.16.1 support #1427 RichText : label property is missing #1375 PeoplePicker : PeopleSearch service should also find people by userPrincipalName when group transitive membership check is used. #1446 Update the SPFx source project to add an extension + form customizer #1410 AdaptiveCardDesignerHost : Add Sample Data to Adaptive Card Editor #1425 AdaptiveCardHost : Logic to prevent re-renders (flicker) #1425 ListItemComments : Add new parameter for ListItemComments to highlight comment #1430 ComboBoxListItemPicker : Update ComboBoxListItemPicker.md #1470","title":"Enhancements"},{"location":"about/release-notes/#fixes_10","text":"DateTimePicker : broken link for getErrorMessage property fixed #1277 ProgressStepsIndicator : Fix missing image reference in Progress Steps Indicator #1409 DynamicForm : Dynamicform is hanging on the loading screen if the list has a single value list lookup field #1393 ListView : Update ListView control docs to use a valid field for the icon #1398 Accordion : Fixing Accordion control documentation image issue #1408 DynamicForm : Cannot read properties of undefined (reading 'startsWith') when submitting the form with contentType={undefined] #1431 FilePicker : Fix site breadcrumb navigation #1368 DynamicForm : Initialize changedValue with defaultValue #1454 DynamicForm : Fix image path #1455 DynamicForm : Check empty array and trasform it in set as null #1456 FilePicker : Fix site browser resize #1457 ModernTaxonomyPicker Fix - Show ModernTaxonomyPicker label in correct form #1459 DynamicForm : Update DynamicForm.tsx #1462 FilePicker : Fix breadcrumb nav #1458 DateTimePicker : Date picker locale #1464 DateTimePicker : Date picker locale #1095 RichText : Use theme colors - fix dark mode #669 FilePicker : Use theme colors - fix dark mode #1132","title":"Fixes"},{"location":"about/release-notes/#contributors_10","text":"Special thanks to our contributors (in alphabetical order): araver , Brian Krainer Jacobsen , Edin Kapic , Eduard Paul , Fredrik Ekstr\u00f6m , Guido Zambarda , Harminder Singh , Hugo Bernier , Jo\u00e3o Mendes , mgitta , Micha\u00ebl Maillot , mikezimm , Nikolay Belykh , Patrik Hellgren , Rico van de Ven , Samuele Furnari , sambilfinger , wuxiaojun514 .","title":"Contributors"},{"location":"about/release-notes/#3120","text":"","title":"3.12.0"},{"location":"about/release-notes/#enhancements_8","text":"DynamicForm : support cretion of document sets #1335 SitePicker : add HubId to filter to only sites within a hub #1346 SharePoint Framework v1.16.0 support","title":"Enhancements"},{"location":"about/release-notes/#fixes_11","text":"FilePicker : panel causes SharePoint to Throttle due to infinite loop fetching files #1325 ContentTypePicker : problem importing control #1337 FilePicker : correctly request data from provided webAbsoluteUrl #1340 ModernTaxonomyPicker : Fix infinite loop #1342 ModernTaxonomyPicker : improve display of the term path to align with out of the box control UI #1343 FolderPicker : get folders of other site url instead of the current context/site #1305 FilePicker : browsing Site / Doclibs loops and floods SPO Service with requests and causes http 429 #1350 Remove invalid comma in tsconfig.json #1341 TaxonomyPicker : control allows select deprecated/untaggable terms when typing #1093 SitePicker : prevent infinite loop when fetching sites #1346 DynamicForm : AnchorId of TaxonomyField gets ignored and the whole tree is rendered #1310","title":"Fixes"},{"location":"about/release-notes/#contributors_11","text":"Special thanks to our contributors (in alphabetical order): Carlos Marins Jr , Edin Kapic , Josef Benda , Nello D'Andrea , Nishkalank Bezawada , Nizar Grindi , Paolo Pialorsi , Patrik Hellgren , Peter Paul Kirschner , Victor Romanov .","title":"Contributors"},{"location":"about/release-notes/#3110","text":"","title":"3.11.0"},{"location":"about/release-notes/#new-controls_3","text":"ProgressStepsIndicator : New control that shows a progress of steps. #1322","title":"New control(s)"},{"location":"about/release-notes/#enhancements_9","text":"DynamicForm : Add taxonomy tree to test harness #1269 ModernTaxonomyPicker : ability to disallow selecting children #1279 PeoplePicker : Use webAbsoluteUrl if provided through props to ensure user #1273 DynamicForm : Support for hidden fields #1307 Placeholder : Documentation example to only display in edit mode #1280 DynamicForm : Update documentation regarding onBeforeSubmit #1319 DynamicForm : FirstDayOfWeek in DatePickers from webs regional settings #1317","title":"Enhancements"},{"location":"about/release-notes/#fixes_12","text":"PeoplePicker : fixes where people picker returns no results #1292 FilePicker : Tile view fix #1272 Issues with v1.15.2 #1288 RichText : Fix broken arrow icons #1302 TaxonomyPicker : Does not show term set labels in Version 3.10.0 #1299 TaxonomyPicker : Dynamic form select term not working #1303 DynamicForm : Check if hiddenfields property is undefined #1314 DynamicForm : PeoplePicker preselects wrong user if PrincipalType allows groups #1315","title":"Fixes"},{"location":"about/release-notes/#contributors_12","text":"Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Hilton Giesenow , Jake Stanger , Jasey Waegebaert , Jo\u00e3o Mendes , Josef Benda , Mark Bice , Paolo Pialorsi , Victor Romanov .","title":"Contributors"},{"location":"about/release-notes/#3100","text":"","title":"3.10.0"},{"location":"about/release-notes/#enhancements_10","text":"DynamicForm : possibility to override field rendering for individual fields #1257 ModernTaxonomyPicker : Display the full path of a term #1172 SharePoint Framework v1.15.2 support #1261","title":"Enhancements"},{"location":"about/release-notes/#fixes_13","text":"DateTimePicker : onChange not triggered when clearing date #1277","title":"Fixes"},{"location":"about/release-notes/#contributors_13","text":"Special thanks to our contributors (in alphabetical order): Bart-Jan Dekker , Edin Kapic , Milan Holemans , Steve Beaug\u00e9 .","title":"Contributors"},{"location":"about/release-notes/#390","text":"","title":"3.9.0"},{"location":"about/release-notes/#new-controls_4","text":"EnhancedThemeProvider : Added 'EnhancedThemeProvider' control #1202 FieldPicker : Added FieldPicker control #1219 ContentTypePicler : Added ContentTypePicker control #1220 ModernAudio : Added ModernAudio control #1224 AdaptiveCardDesignerHost : Added AdaptiveCardDesignerHost control #1237","title":"New control(s)"},{"location":"about/release-notes/#enhancements_11","text":"DateTimePicker : Added button to clear date #1217 Toolbar : Allow filters on a Toolbar to be controlled externally #1222 PeoplePicker : add new allowUnvalidated option to allow adding non-tenant users #1232 DynamicForm : Add support for webAbsoluteUrl #1244","title":"Enhancements"},{"location":"about/release-notes/#fixes_14","text":"Localization : Updates to English localizations #1207 Localization : Updates to Dutch localizations #1209 Localization : Updates to Danish localizations #1233 TaxonomyPicker : Check if cultureInfo is valid #1226 FieldCollectionData : Updated docs to fix duplicated property #1236 Changelog : Fix changelog script by setting CHANGELOG.JSON filename extension to lower case #1242 PeoplePicker : PeoplePicker validation on focus out #1221 DynamicForm : Cannot display lookup value when the source field is not Title #1215 FilePicker : the endPoint for webSearch do not work #1256","title":"Fixes"},{"location":"about/release-notes/#contributors_14","text":"Special thanks to our contributors (in alphabetical order): Annie-Johnson , Daniel Watford , Dennis Kuhn , Fabio Franzini , Jake Stanger , Joseph Halvey , Markus M\u00f6ller , Milan Holemans , Morten Andersen , Richard Gigan , Rico van de Ven , ryanexner , Sergio Villalta .","title":"Contributors"},{"location":"about/release-notes/#381","text":"","title":"3.8.1"},{"location":"about/release-notes/#fixes_15","text":"LivePersona : Fix LivePersona not showing card on hover #1241","title":"Fixes"},{"location":"about/release-notes/#380","text":"","title":"3.8.0"},{"location":"about/release-notes/#enhancements_12","text":"PeoplePicker : Allow the use of multiple groupId-s #1163 PeoplePicker : search users in nested security groups #1173 ModenrTaxonomyPicker : Add more complete example of TaxonomyTree usage #1190 AdaptiveCardHost : Add SPFx Context property #1145 AdaptiveCardHost : Remove the isUniqueControlInPage from the control by rebuilding the way to apply AC CSS class names #1154 ListView : Different background color to even and odd rows in ListView #1153 AccessibleAccordion : Support of section variations #1195 TreeView : Support of section variations #1196","title":"Enhancements"},{"location":"about/release-notes/#fixes_16","text":"LocationPicker : Resolve issue when in root site #1162 LocationPicker : Trigger onChange on picker clear action #1165 TreeView : TreeView Control is broken after updating to v3.7.0 #1170 TreeView : collapses on selection of a child node #1182 TreeView : expanded nodes state is getting lost after refresh #1062 NPM Audit Critical Issues #1187 Bump momentjs from 2.29.1 to 2.29.2 #1185 TaxonomyPicker : Sorting the terms in locale language #1160 ComboboxListItemPicker : options are not reloaded after the filter is changed #1180 FieldRendererHelper : Add missing PnPjs import to SPHelper #1140 RichText : Update font style and font size on property pane #1151 Placeholder : Support section variations for themes #1193","title":"Fixes"},{"location":"about/release-notes/#372","text":"","title":"3.7.2"},{"location":"about/release-notes/#370","text":"","title":"3.7.0"},{"location":"about/release-notes/#new-controls_5","text":"VariantThemeProvider : new VariantThemeProvider control #1120 MonacoEditor : new MonacoEditor control #1134","title":"New control(s)"},{"location":"about/release-notes/#enhancements_13","text":"Carousel : Prev and Next Buttons are not labeled, and read as 'Unlabeled button' by screen readers #1137 TreeView : Ability to set keys of items that should be expanded by default #1084 SharePoint Framework v1.14.0 support","title":"Enhancements"},{"location":"about/release-notes/#fixes_17","text":"FilePicker : defaultFolderAbsolutePath doesn't work with webAbsoluteUrl #1129 LocationPicker : Location picker not resolving locations #1149 DynamicForm : RichText Field losing focus on typing #1024 LivePersona : Documentation fix for template type #1147","title":"Fixes"},{"location":"about/release-notes/#360","text":"","title":"3.6.0"},{"location":"about/release-notes/#new-controls_6","text":"AdaptiveCardHost : React control that allows you to render an Adaptive Card as a component #1096","title":"New control(s)"},{"location":"about/release-notes/#enhancements_14","text":"ModernTaxonomyPicker : ability to add action buttons to terms #1058 FilePicker : allow to select files from other sites #907 Localization : Update Swedish translations #1099 FilePicker : ability to allow external link and disable file existance chech commit FilePicker : support for multi-select on additional sources #1047 DateTimePicker : new property for allowTextInput #1094","title":"Enhancements"},{"location":"about/release-notes/#fixes_18","text":"LivePersona : Cannot find module '@pnp/spfx-controls-react/lib/LivePersona' #1069 ListView : documentation spelling mistake 'ColumndName' #1063 Fixes for Norwegian localization #1083 DynamicForm : doesn't load or save correctly when field name starts with a special character #1077 DynamicForm : fields in DynamicForm do not honour regional settings #1075 DynamicForm : Boolean fields do not honour the default value in list settings #1073 TaxonomyPicker : table markdown fix in documentation #1072 WebPartTitle : Fix for styling of WebPartTitle to better match the styling of the oob webpart titles. #1088 LivePersona : fix for documentation typos #1106 LivePersona : remove property for SPFx context #1108 Documentation fix for swedish translations #1100","title":"Fixes"},{"location":"about/release-notes/#contributors_15","text":"Special thanks to our contributors (in alphabetical order): Alexander M , Carlos Marins Jr , Fabio Franzini , Henrik , Jasey Waegebaert , Jo\u00e3o Mendes , Milan Holemans , MonalisaBaltatescu , Patrik Hellgren , Tom G .","title":"Contributors"},{"location":"about/release-notes/#350","text":"","title":"3.5.0"},{"location":"about/release-notes/#enhancements_15","text":"Update mgt package to the latest version #1038 ListView : Add ability to provide CSS class names for list wrapper and list itself #1007 IconPicker : onCancel property is added #1043 SharePoint Framework v1.13.* support DynamicForm : disabledFields property added #987 ListPicker : Add multi numbers support for baseTemplate option #1016 ComboboxListItemPicker : Add option to sort the items in the picker #985 PeoplePicker : Added filter for Microsoft 365 Group #985 Accordion : Added custom icons #1033 Localization: Correction for german localizations #1059 Localization: Corrections for norwegian localizations #1060 PeoplePicker : Added Styles property #1061 Localization: Update pt-pt and pt-br loc files #1066","title":"Enhancements"},{"location":"about/release-notes/#fixes_19","text":"FilePicker : defaultFolderAbsolutePath does not work Out of context #1023 ModernTaxonomyPicker : correctly display with RTL mode #1041 FilePicker : Fixed showing the selection circle on recent tabs #1048 FilePicker : Your organisation tab breadcrumb not working #1056","title":"Fixes"},{"location":"about/release-notes/#contributors_16","text":"Special thanks to our contributors (in alphabetical order): Gautam Sheth , Jouni Pohjolainen , jumpei-yamauchi , Louis Pineau , Michalis Koutroupis , MonalisaBaltatescu , Patrik Hellgren , Xiyitifu , Russell gove , Andreas Omayrat , Abderahman Moujahid , Alexander M , Jo\u00e3o Mendes .","title":"Contributors"},{"location":"about/release-notes/#340","text":"","title":"3.4.0"},{"location":"about/release-notes/#new-controls_7","text":"ModernTaxonomyPicker : New control ModernTaxonomyPicker #1014","title":"New control(s)"},{"location":"about/release-notes/#enhancements_16","text":"Translations: Update translation keys #994 LocationPicker : Update docs #1009 FileTypeIcon : Add support of 20px icons #1013 Pagination : Update import from lodash #1021","title":"Enhancements"},{"location":"about/release-notes/#fixes_20","text":"ChartControl : Charts not updating properly when properties are changed #997 TaxonomyPicker : suggestions language is always English #879 TaxonomyPicker : errorMessage label not being removed #953 FilePicker : Sorting Not Working as Expected in Site Tab #1011 FilePicker : Site Tab - Lots of file types don't have appropriate icons #1012 LocationPicker : Correct documentation #1019 FilePicker : fileNameWithoutExtension not calculated right #1022 FieldUserRenderer : Add missing PnPJS imports #1025","title":"Fixes"},{"location":"about/release-notes/#contributors_17","text":"Special thanks to our contributors (in alphabetical order): Dennis Kuhn , Gautam Sheth , Jean-Luc Richer , hesperanca , Kiryl Shchasny , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy .","title":"Contributors"},{"location":"about/release-notes/#330","text":"","title":"3.3.0"},{"location":"about/release-notes/#new-controls_8","text":"LivePersona : New Control LivePersona #969 ListItemComments : New Control ListItemComments #979","title":"New control(s)"},{"location":"about/release-notes/#enhancements_17","text":"FilePicker : spanish translation for Stock Images labels #946 FilePicker : Add support for a defaultFolderAbsolutePath prop #947 DynamicForm : Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944 DateTimePicker : Add property for minutes dropdown increment #939 ListItemPicker : add property to show all options by default #955 ListItemPicker : Missing translation keys, improved FI, NL translation #957 TaxonomyPicker : Added onNewTerm called when enter is pressed #967 DynamicForm : Principal Types support #956 DateTimePicker : Expose allowTextInput from the underlying date picker #928 Dynamic Form : Show field descriptions #975","title":"Enhancements"},{"location":"about/release-notes/#fixes_21","text":"RichText : Image button is checked when hyperlink is added to the text #948 RichText : impossible to display link with the text equal to the url #949 ComboBoxListItemPicker : defaultSelectedItems not working #954 Dynamic Form : query items in a folder (managed metadata field) #973 PeoplePicker : Default selected items for groups #958 Documentation: corrected Twitter handle for M365PnP #984 Carousel : Carousel is missing import of ICarouselImageProps #986 Documentation fix - DynamicForm example has incorrect syntax #990","title":"Fixes"},{"location":"about/release-notes/#contributors_18","text":"Special thanks to our contributors (in alphabetical order): Alexey Morozov , Daniel Stratton , Dennis Kuhn , Gautam Sheth , Jo\u00e3o Mendes , Ketill Anton\u00edus \u00c1g\u00fastsson , kmrshubham0 , Modern Dev Dude , Ravichandran Krishnasamy , Sergio Ortega Mart\u00edn , Yannick Reekmans .","title":"Contributors"},{"location":"about/release-notes/#321","text":"","title":"3.2.1"},{"location":"about/release-notes/#enhancements_18","text":"ListItemAttachments : Add new label and description properties #943","title":"Enhancements"},{"location":"about/release-notes/#fixes_22","text":"ListPicker : ListPicker stopped working in upgrade from 3.1.0 to 3.2.0 #945 ListItemAttachments : Fixed multiple bugs #943","title":"Fixes"},{"location":"about/release-notes/#320","text":"","title":"3.2.0"},{"location":"about/release-notes/#new-controls_9","text":"DynamicForm : New Control: Dynamic form #878 LocationPicker : New Control - Location Picker #915","title":"New control(s)"},{"location":"about/release-notes/#enhancements_19","text":"fast-serve : Add fast-serve support #916 ComboBoxListItemPicker and ListItemPicker : Add label to control #914 PeoplePicker : new property groupId . #917 ListPicker : add contenttype id to list picker #894 ListPicker : Few more tests with a little better description #906 Translations: Improved Finnish translations #937","title":"Enhancements"},{"location":"about/release-notes/#fixes_23","text":"Documentation for RichText : correct event handler name #898 SitePicker : SitePicker does not display initial sites until you click the dropdown to select #895 DatePicker : Fix Spanish loc strings #923 FilePicker : invalid CSS: relative in quotes. #930 MyTeams : Update MyTeams to use new library mgt-spfx #918 FieldCollectionData : FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929","title":"Fixes"},{"location":"about/release-notes/#contributors_19","text":"Special thanks to our contributors (in alphabetical order): Nikolay Belykh , Eduard Paul , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy , Russell gove , Sergei Sergeev , Jo\u00e3o Mendes , Marcin Wojciechowski , Gautam Sheth .","title":"Contributors"},{"location":"about/release-notes/#310","text":"","title":"3.1.0"},{"location":"about/release-notes/#new-controls_10","text":"TeamPicker : new Team Picker control #846 TeamChannelPicker : new Team Channel Picker control #846 SitePicker : new Site Picker control #868 DocumentLibraryBrowser , SiteFilePickerTab : jest unit tests #866 DragDropFiles : new DragDropFiles control #861 MyTeams : new MyTeams control #874 TeamChannelPicker : new TeamChannelPicker control #874 TeamPicker : new TeamPicker control #874","title":"New control(s)"},{"location":"about/release-notes/#enhancements_20","text":"ListView : Use new DragDropFiles control #861 FilePicker : Use new DragDropFiles control #861 SharePoint Framework v1.12.1 support ListView : Ability to provide custom sorting function #880 FilePicker : Allow panel on FilePicker to be invoked after first load #886 FilePicker : Allow FilePicker button to be hidden #887 FilePicker : Change same function to return an array of objects","title":"Enhancements"},{"location":"about/release-notes/#fixes_24","text":"Documentation for ListView : typos fixes #855 Documentation fix: type on index page #852 PeoplePicker : error message isn't cleared after onGetErrorMessage returns an empty string #841 TreeView : Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870 FilePicker : React crash on large folders #826 ListItemAttachments : updated filename replacement logic #873 RichText : Adding a link does not work #875 FilePicker : Stock images url is getting a 404 server error #882","title":"Fixes"},{"location":"about/release-notes/#contributors_20","text":"Special thanks to our contributors (in alphabetical order): Ari Gunawan , aroraans1512 , cwparsons , joaojmendes , Kunj Balkrishna Sangani , Marcin Wojciechowski , Yannick Reekmans , Andr\u00e9 Lage .","title":"Contributors"},{"location":"about/release-notes/#300","text":"","title":"3.0.0"},{"location":"about/release-notes/#enhancements_21","text":"SharePoint Framework v1.12 support (breaking change) Fluent UI v7 support","title":"Enhancements"},{"location":"about/release-notes/#290","text":"","title":"2.9.0"},{"location":"about/release-notes/#enhancements_22","text":"FilePicker : spanish translation for Stock Images labels #946 FilePicker : Add support for a defaultFolderAbsolutePath prop #947 DynamicForm : Returning PnPJS IItem in onSubmitted event based on returnListItemInstanceOnSubmit property #944 DateTimePicker : Add property for minutes dropdown increment #939 DynamicForm : Principal Types support #956 Dynamic Form : Show field descriptions #975","title":"Enhancements"},{"location":"about/release-notes/#fixes_25","text":"RichText : Image button is checked when hyperlink is added to the text #948 RichText : impossible to display link with the text equal to the url #949 ComboBoxListItemPicker : defaultSelectedItems not working #954 PeoplePicker : Default selected items for groups #958","title":"Fixes"},{"location":"about/release-notes/#contributors_21","text":"Special thanks to our contributors (in alphabetical order): Alexey Morozov , Daniel Stratton , Ketill Anton\u00edus \u00c1g\u00fastsson , Ravichandran Krishnasamy , Sergio Ortega Mart\u00edn .","title":"Contributors"},{"location":"about/release-notes/#280","text":"","title":"2.8.0"},{"location":"about/release-notes/#new-controls_11","text":"DynamicForm : New Control: Dynamic form #878 LocationPicker : New Control - Location Picker #915","title":"New control(s)"},{"location":"about/release-notes/#enhancements_23","text":"ComboBoxListItemPicker and ListItemPicker : Add label to control #910 PeoplePicker : new property groupId . #917","title":"Enhancements"},{"location":"about/release-notes/#fixes_26","text":"SitePicker : SitePicker does not display initial sites until you click the dropdown to select #895 FilePicker : invalid CSS: relative in quotes. #930 FieldCollectionData : FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929","title":"Fixes"},{"location":"about/release-notes/#contributors_22","text":"Special thanks to our contributors (in alphabetical order): Nikolay Belykh , Patrik Hellgren , Peter Paul Kirschner , Ravichandran Krishnasamy .","title":"Contributors"},{"location":"about/release-notes/#270","text":"","title":"2.7.0"},{"location":"about/release-notes/#new-controls_12","text":"DragDropFiles : new DragDropFiles control #856 SitePicker new Site Picker control #867 Controls Add locale strings for pt-br #865","title":"New control(s)"},{"location":"about/release-notes/#enhancements_24","text":"ListView : Use new DragDropFiles control #856 FilePicker : Use new DragDropFiles control #856 ListView : Ability to provide custom sorting function #880 FilePicker : Allow panel on FilePicker to be invoked after first load #886 FilePicker : Allow FilePicker button to be hidden #887 FilePicker : Changed save function to return an array of objects","title":"Enhancements"},{"location":"about/release-notes/#fixes_27","text":"PeoplePicker : error message isn't cleared after onGetErrorMessage returns an empty string #841 TreeView : Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870 FilePicker : React crash on large folders #826 ListItemAttachments : updated filename replacement logic #873 RichText : Adding a link does not work #875 FilePicker : Stock images url is getting a 404 server error #882","title":"Fixes"},{"location":"about/release-notes/#contributors_23","text":"Special thanks to our contributors (in alphabetical order): Andr\u00e9 Lage , cwparsons , Kunj Balkrishna Sangani , Yannick Reekmans .","title":"Contributors"},{"location":"about/release-notes/#260","text":"","title":"2.6.0"},{"location":"about/release-notes/#new-controls_13","text":"AnimatedDialog : new Animated Dialog control #815 Jest unit tests #834","title":"New control(s)"},{"location":"about/release-notes/#enhancements_25","text":"IconPicker : search icons using contains comparison. FilePicker : default alphabet sorting #824 ListItemPicker : ability to provide orderBy #829 Dashboard : Dashboard widget wrapper for styling and error catching #836 FolderExplorer : Update folder explorer documentation #835","title":"Enhancements"},{"location":"about/release-notes/#fixes_28","text":"IconPicker : Fix case sensitive fluent icon search service #814 Carousel : documentation fix - broken table style #817 AccessibleAccordion : documentation link is broken #818 Documentation: Controls link in the menu is broken #821 TreeView : Fix two potential null reference issues #832 RichText : Problem with bullets and number list #795 FolderPicker : Correct FolderPicker link alignment","title":"Fixes"},{"location":"about/release-notes/#contributors_24","text":"Special thanks to our contributors (in alphabetical order): Anoop Tatti , Ari Gunawan , Gautam Sheth , Kunj Balkrishna Sangani , Marcin Wojciechowski , Mark Bice , Nizar Grindi , Yannick Reekmans .","title":"Contributors"},{"location":"about/release-notes/#250","text":"","title":"2.5.0"},{"location":"about/release-notes/#enhancements_26","text":"TreeView : Adding support to clear TreeView selected items by passing an empty array. #787 FilePicker : new property includePageLibraries to optionally display Site Pages library on Site tab #601 ListItemPicker : Support of Calculated columns #805 Progress : Documentation update to have consistency in variables names #811 FolderExplorer : Add support for sorting folder explorer items #812","title":"Enhancements"},{"location":"about/release-notes/#fixes_29","text":"ListView : Selection is reset when putting a ListView inside a React Component that controls its items and selection props #251 Documentation fix for PeoplePicker : Removed unwanted new line in help content. #783 Documentation fix for TreeView : TreeViewSelectionMode added in the import #780 Documentation fix for TreeView : removed unwanted comma #779 IFrameDialog : height unable to resize relative to screen size, even if we provide in % it is taking default value. #636 DateTimePicker : Clear Date functionality #799","title":"Fixes"},{"location":"about/release-notes/#contributors_25","text":"Special thanks to our contributors (in alphabetical order): Ari Gunawan , Joel Rodrigues , Mike Myers , Ravichandran Krishnasamy , San .","title":"Contributors"},{"location":"about/release-notes/#240","text":"","title":"2.4.0"},{"location":"about/release-notes/#new-controls_14","text":"AccessibleAccordion control #770","title":"New control(s)"},{"location":"about/release-notes/#enhancements_27","text":"Placeholder : support of custom rendering for iconText and description PeoplePicker : ability just to display inactive users name (ideally the value fetched from 'Author/Title') #768 TaxonomyPicker : New onPanelSelectionChange property added. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. #761 TaxonomyPicker : selectChildrenIfParentSelected property added. Specifies if the children should be selected when parent item is selected (defaults to false). #765 ListPicker : ability to pick lists from specified site using webAbsoluteUrl property. FilePicker : buttonIconProps to define properties of the button's icon #770","title":"Enhancements"},{"location":"about/release-notes/#fixes_30","text":"DateTimePicker : documentation fix #767 PeoplePicker : documentation fix - Changed isRequired property to new required #769 Documentation fix - missing IFramePanel link on home page #775 Documentation fix for FilePicker : updated onChaged to onChange #776","title":"Fixes"},{"location":"about/release-notes/#contributors_26","text":"Special thanks to our contributors (in alphabetical order): Andr\u00e9 Lage , Christian Metz , Gaurav Goyal , Leif Frederiksen , Ravichandran Krishnasamy , San , Jo\u00e3o Mendes .","title":"Contributors"},{"location":"about/release-notes/#230","text":"","title":"2.3.0"},{"location":"about/release-notes/#new-controls_15","text":"Dashboard control for Microsoft Teams #758 Toobar control for Microsoft Teams #758","title":"New control(s)"},{"location":"about/release-notes/#enhancements_28","text":"TaxonomyPicker : Added useSessionStorage property #759","title":"Enhancements"},{"location":"about/release-notes/#fixes_31","text":"FilePicker : documentation fix: '|' not escaped #756 TaxonomyPicker : Return TermSetId for suggestions #762 WebPartTitle : Fluent UI Updates to SharePoint - WebPartTitle control too thin now #605 ListView : Sticky Header scrolling issue #734 DateTimePicker : hours dropdown not re-rendered when state changed programmatically #757 RichText : controlled mode doesn't work #666","title":"Fixes"},{"location":"about/release-notes/#contributors_27","text":"Special thanks to our contributors (in alphabetical order): Gautam Sheth , Marcin Wojciechowski , Nikolay Belykh , Andr\u00e9 Lage .","title":"Contributors"},{"location":"about/release-notes/#220","text":"","title":"2.2.0"},{"location":"about/release-notes/#enhancements_29","text":"RichText : Add image support #705 FilePicker : Add file size to the Upload tab and IFilePickerResult #706 FieldCollectionData : SearchBox instead of TextBox #719 TaxonomyPicker : control does not show an error message for an invalid/unresolved input #728 Canadian French localization #671 FilePicker : reduce bundle size #732 FilePicker : Custom render callbacks for the 'Upload' and 'Link' tabs #746","title":"Enhancements"},{"location":"about/release-notes/#fixes_32","text":"Localization: Fixing some wrong localizations for the DatePicker short day in Spanish. #702 ListItemPicker : When use defaultSelectedItems, ListItemPicker allows you to select dublicate entries #722 Deprecated stuff is removed #733 DateTimePicker : time portion not re-rendered when state changed programmatically - when time is displayed as dropdown only #713 PeoplePicker : errorMessage not being removed #730 ListItemAttachment : the control is not fully disabled #736 TaxonomyPicker : icons are not being rendered on Classic SharePoint pages #735 FilePicker : Site Tab does not load document if we access SharePoint site in different language than default language of the site #724 Documentation fix for 'attention' block on index page #740 TaxonomyPicker : sessionStorage exceeds max-size when browsing large termsets #739 FolderExplorer and FolderPicker do not seem to work for document libraries #741 FilePicker : onChange event does not exist despite being documented #747 ListItemPicker : Selected values are not getting cleared or reset #659","title":"Fixes"},{"location":"about/release-notes/#contributors_28","text":"Special thanks to our contributors (in alphabetical order): Abderahman Moujahid , avadhootdindorkar , Devang Bhavsar , Gautam Sheth , Konrad K. , Nikolay Belykh , Vertamin .","title":"Contributors"},{"location":"about/release-notes/#210","text":"","title":"2.1.0"},{"location":"about/release-notes/#enhancements_30","text":"Carousel : Ability to display indicators in a dedicated block #681 FilePicker : Org Assets are not displayed for non-admin users #687 ListView : Drag and Drop option #679 FolderExplorerService : support special characters if folder name #691 ListView : Sticky Header #634 IconPicker : get icons from @uifabric/icons/lib/data/AllIconNames.json ListView : Sticky header with className instead of additional components #696 ListView : StickyHeader code consistency #697 TreeView : Added (optional) property 'defaultExpandedChildren' that controls the behavior of the expansion of child elements. #698","title":"Enhancements"},{"location":"about/release-notes/#fixes_33","text":"RichText : Cannot add link in first line #672 TaxonomyPicker : Ability to reset the TaxonomyPicker (Remove all selected Terms) #367 Documentation fix for TaxonomyPicker : the disabled property is a boolean and not a string as currently specified #695 ComboBoxListItemPicker : update options when listId has been changed #683 FilePicker : styles are updated to match OOB control #700","title":"Fixes"},{"location":"about/release-notes/#contributors_29","text":"Special thanks to our contributors (in alphabetical order): Abderahman88 , Andr\u00e9 Lage , Gautam Sheth .","title":"Contributors"},{"location":"about/release-notes/#200","text":"","title":"2.0.0"},{"location":"about/release-notes/#enhancements_31","text":"FilePicker : added additional properties - isPanelOpen and onCancel #668","title":"Enhancements"},{"location":"about/release-notes/#fixes_34","text":"PeoplePicker : Disabled doesn't work #484 Pagination : control not re-rendering when currentPage is updated in state #663","title":"Fixes"},{"location":"about/release-notes/#contributors_30","text":"Special thanks to our contributor: Gautam Sheth .","title":"Contributors"},{"location":"about/release-notes/#1200","text":"","title":"1.20.0"},{"location":"about/release-notes/#new-controls_16","text":"Accordion control #638 FieldCollectionData control #591","title":"New control(s)"},{"location":"about/release-notes/#enhancements_32","text":"FilePicker : Stock images option added #593 TaxonomyPicker : Add the 'required' property #216 TaxonomyPicker : Add errorMessage and onGetErrorMessage props #600 ListItemPicker : ability to use substring search instead of startswith #583 Map : return display name and address details for the location #585 Map : support for draggable and static Bing maps #586 TaxonomyPicker : onLoad validation #602 FieldCollectionData : Add pagining and filtering #617 TaxonomyPicker : Finding terms with labels #288 FileTypeIcon : Added support for additional file type in Image mode #640","title":"Enhancements"},{"location":"about/release-notes/#fixes_35","text":"ComboBoxListItemPicker : fetching only 100 items #569 TaxonomyPicker : browse (tree view) doesn't work with SP 2016 On-Premises #183 FilePicker : default tab when opened shows hidden RecentTab #477 PeoplePicker : The required error message not showing #590 ListItemAttachments : fails in Microsoft Teams Tab SPFx applications #582 Carousel : Changing pages doesn't work #609 TaxonomyPicker : no suggestions are displayed if anchorId is not set TaxonomyPicker : Suggestion/match does not work as expected #604 TaxonomyPicker : Include check for separator while filtering path of terms when anchorId is configured #625 FilePicker : Bing API search issue #633 ListView : Sort fires selection #621 Map : A minor issue in componentWillUpdate method to get the next props rather than the current props. #641 IFrameDialog : dialog size is incorrect when opening the dialog second time #615 FolderPicker : imports don't work #614 FilePicker : Yor Organization tab is not shown #596 FolderPicker , FolderExplorer : Controls don't let you explore sub folders if parent folder has apostrophe (') in its name. #644 PeoplePicker : image for a user picked in PeoplePicker didn't get resolved #646 Documentation fix for IconPicker : renderOption dialog should be lowercased. #649","title":"Fixes"},{"location":"about/release-notes/#contributors_31","text":"Special thanks to our contributors (in alphabetical order): Alexey Sadomov , Anoop Tatti , Devang Bhavsar , Gautam Sheth , geltapatio , Joel Jeffery , juhaalhojoki , Piotr Siatka , Rabia Williams , Ravichandran Krishnasamy , Victor Pollet .","title":"Contributors"},{"location":"about/release-notes/#1190","text":"","title":"1.19.0"},{"location":"about/release-notes/#enhancements_33","text":"ListView : Add clear button to filter text box #549 FolderExplorer : Add clear button to filter text box #553 TreeView : there should be possibility to collapse the first level nodes by default #561 TreeView : Expand to selected #559 DateTimePicker : When using the datetimePicker I would like to have an opportunity to set maximum/minimum date like in Office UI Fabric #497 TaxonomyPicker : Added the selectTerm , hideTerm , and disableTerm actions #578 TaxonomyPicker : Added the functionality to enable/disable term actions on the fly #578 Carousel : indicators, slide animation, auto cycling, easier basic usage #587","title":"Enhancements"},{"location":"about/release-notes/#fixes_36","text":"TaxonomyPicker : Correct the AnchorID getting all TermSet search options #150 Documentation fix for TreeView : Some tables in TreeView documentation are displayed as plain text. #562 ComboBoxListItemPicker , ListItemPicker : Show error span if error is present #557 TreeView : defaultExpanded: true doesn't work #560 IListPicker : typo fix #574 DateTimePicker : DateTime Picker noon/midnight issue with 12 hour format #576","title":"Fixes"},{"location":"about/release-notes/#contributors_32","text":"Special thanks to our contributors (in alphabetical order): Chad Eiserloh , Gautam Sheth , Koen Zomers , Markus Langer , Nanddeep Nachan , Prasad Kasireddy , David Ramalho , Siddharth Vaghasia .","title":"Contributors"},{"location":"about/release-notes/#1180","text":"","title":"1.18.0"},{"location":"about/release-notes/#new-controls_17","text":"Pagination Control #535 TreeView Control #536 FolderPicker Control #525","title":"New control(s)"},{"location":"about/release-notes/#enhancements_34","text":"FolderExplorer updates: allow selection of libraries if site url is used as the root, allow passing items to be passed as a property and added to the breadcrumb, add support for loading folders from a different site, fix breadcrumb names for document libraries #534 IconPicker : renderOption property to render icons list as a panel or dialog #537","title":"Enhancements"},{"location":"about/release-notes/#fixes_37","text":"ComboBoxListItemPicker documentation fix: Updated import statement in docs for ComboBoxListItemPicker #510 Documentation fix: add the new control ComboBoxListItemPicker component to landing page #511 FilePicker : While using the control, if hideOrganisationalAssetTab is set to true, even then an additional HTTP request is made. IconPicker : search fix and updated list of icons #533 ListItemAttachment : when I upload a file that contains an hyphen, the \"-\" char is replaced by an empty string #526 IconPicker shows selected icon only during the first opening #513 ComboBoxListItemPicker : onSelectedItem passing data to callback method but with attributes value as undefined #519 FilePicker : filename is not visible on Upload tab #518 IconPicker : Search doesn't work at all #512 ComboBoxListItemPicker documentation fix: correct onSelectedItem notation #547 Documentation: Fix mistranslation in Japanese #545 FieldUserRenderer : displayName in FieldUserHoverCard is not updated if props of the FIeldUserRenderer have been changed #542","title":"Fixes"},{"location":"about/release-notes/#contributors_33","text":"Special thanks to our contributors (in alphabetical order): David Ramalho , Gautam Sheth , Gregghis , Jo\u00e3o Mendes , Joel Rodrigues , Nanddeep Nachan , Prasad Kasireddy , Siddharth Vaghasia , Takashi Shinohara .","title":"Contributors"},{"location":"about/release-notes/#1170","text":"","title":"1.17.0"},{"location":"about/release-notes/#new-controls_18","text":"ComboBoxListItemPicker component #292 Localization : Project now supports localization of all SharePoint Online languages (auto translation via Cognitive Services) #456 IconPicker : component #485 FolderExplorer component #499","title":"New control(s)"},{"location":"about/release-notes/#enhancements_35","text":"SecurityTrimmedControl : Added the option to show a control when the user doesn't have permissions 307 PnP Telemetry service opt-out support #475 TaxonomyPicker : Possibility to hide deprecated and \"Available for Tagging\"= false terms #421 FilePicker - French translation #449 Slovak localization #457 TaxonomyPicker : Placeholder for Taxonomy Picker #464 ListItemPicker , PeoplePicker : Placeholder for ListItemPicker and PeoplePicker #486 FilePicker : Do not store active tab in url's hash #488 DateTimePicker : Placeholder property option added #503","title":"Enhancements"},{"location":"about/release-notes/#fixes_38","text":"RichText : problem with edit mode #445 ListView documentation: Typo - the first occurrence of maxWidth should be minWidth #400 RichText : Text indent buttons were copy-paste of subscript and superscript buttons. Clicking on the text-indent buttons would call subscript or superscript instead. #454 RichText : Fix of removing text and inserting link instead #455 FilePicker : Read file content in IE11 #444 ListPicker : listPicker always return \"test\" when multiple allowed #458 FilePicker : Button text overflow fix + global classnames and properties FieldUserRenderer : implementation of api/SP.UserProfiles.PeopleManager/GetPropertiesFor is not working on on-prem #468 Placeholder : Placeholder component is not rendering after a string change in it's properties #469 ListView documentation update: minWidth instead of maxWidth #480 DateTimePicker : Minutes and Seconds validation #495 FilePicker : bingAPIKey not working #489","title":"Fixes"},{"location":"about/release-notes/#contributors_34","text":"Special thanks to our contributors (in alphabetical order): Richard Gigan , Reginald Johnson , JonasBjerke89 , Prasad Kasireddy , Alexander Kleshcheov , Konradox , L\u00e9o Maradan , Matej , mgwojciech , Joel Rodrigues , Jason S , Piotr Siatka , Rabia Williams .","title":"Contributors"},{"location":"about/release-notes/#1160","text":"","title":"1.16.0"},{"location":"about/release-notes/#enhancements_36","text":"FilePicker : Fixes for OneDrive CORS issues #407 ListItemPicker : added new control property filter #392 allowing to use context from any type of SPFx extensions: #419 Placeholder : remove unused and vendor specific CSS #426","title":"Enhancements"},{"location":"about/release-notes/#fixes_39","text":"Documentation fix for FilePicker : updated accepts value in props #404 The FilePicker control doesn't work in many languages due to missing localization keys #412 Documentation fix for broken links of Property Controls landing page #388 Documentation fix to include new components from v 1.15.0 #394 DateTimePicker : dropdown for time not handling AM/PM correctly #405 Documentation fix for index page: updated link to Chart controls #417 Documentation update for SPFx On Premises notice: #418 Documentation update for ListItemPicker : valueColumnInternalName should be keyColumnInternalName RichText : Fix \"Align Left\" button #429 Documentation update for FilePicker : misspelling #432 IFramePanel : Fix doubled scroll issue when iframe content is higher than frame height #431 PeoplePicker : errorMessage not showing #420 IFrameDialog : commitPopUp typo causes popups with classic forms to not close after hitting save #433","title":"Fixes"},{"location":"about/release-notes/#contributors_35","text":"Special thanks to our contributors (in alphabetical order): Piotr Siatka , Dani Dom\u00ednguez , Siddharth Vaghasia , Jo\u00e3o Mendes , PrasadKasireddy , Chad Eiserloh , Koen Zomers , Dmitry Rogozhny , Alexander Kleshcheov , Hugo Bernier , Beniamin , Giovani Martini .","title":"Contributors"},{"location":"about/release-notes/#1150","text":"","title":"1.15.0"},{"location":"about/release-notes/#new-controls_19","text":"FilePicker : New control added to the library #366 GridLayout : New control added to the library #350 Carousel : New control added to the library #227","title":"New control(s)"},{"location":"about/release-notes/#enhancements_37","text":"TaxonomyPicker : Localization keys added to the buttons #361 Swedish localization support added #359 Improved German translations #338 DateTimePicker : added options to render time part as mask or dropdown #330 ListItemPicker : option to select a key column #350 , #381 Improved Russian translations #384 RichText : Added the ability to add a third Color Swatch Group called custom. This will allow you to add custom colors to the font color selector. #385","title":"Enhancements"},{"location":"about/release-notes/#fixes_40","text":"TaxonomyPicker : Tags icon styling issue on IE11 #356 DateTimePicker : Does not respect dateLabel and timeLabel #346 PeoplePicker : Get loginName with ensureUser #342 PeoplePicker : Fix missing required field label #371","title":"Fixes"},{"location":"about/release-notes/#contributors_36","text":"Special thanks to our contributors (in alphabetical order): amortsell , Hugo Bernier , Robert Lindstr\u00f6m , pfc2k8 , Piotr Siatka , Alex Terentiev , Luis Robertto Mello , eweintraub .","title":"Contributors"},{"location":"about/release-notes/#1140","text":"","title":"1.14.0"},{"location":"about/release-notes/#enhancements_38","text":"German translations added for attachment and RichText controls #333 SecurityTrimmedControl : Added a wrapper className property for the parent element #325 ListPicker : Add ability to filter the control via OData #319 IFrameDialog : closing dialog on commit #313 WebPartTitle add support for section background color #258","title":"Enhancements"},{"location":"about/release-notes/#fixes_41","text":"Fix in return type of onClick and onDoubleClick events #321 ListPicker : Fix for available dropdown selection after selection was done #315 Fixes to French translations #312 RichText : Issue on rendering the control in view mode #287","title":"Fixes"},{"location":"about/release-notes/#contributors_37","text":"Special thanks to our contributors (in alphabetical order): Amr Fouad , Joel Jeffery , Mark Powney , Dominik Schmieder , Alex Terentiev , Zhephyr .","title":"Contributors"},{"location":"about/release-notes/#1132","text":"","title":"1.13.2"},{"location":"about/release-notes/#enhancements_39","text":"Improvements to the Lithuanian localization #285","title":"Enhancements"},{"location":"about/release-notes/#fixes_42","text":"IFrameDialog : dimensions issue #303 DateTimePicker : IE11 layout issue #301 FileTypeIcon : Only displays PDF's in SPFx 1.8.2 #300 FieldNameRenderer : Fails to encode URI when hasPreview #296 TaxonomyPicker : Cannot find name `TermLabelAction #293 ListItemAttachments : Move deleted attachments to the recycle bin #291 DateTimePicker : Does not respect isMonthPickerVisible prop #283 ListItemAttachments : Render issue fixed + improvements to the attachment API calls #282 RichText : Fixes an issue when hitting enter in the control #277","title":"Fixes"},{"location":"about/release-notes/#contributors_38","text":"Special thanks to our contributors (in alphabetical order): Tautvydas Duda , Thomas Granheim , Robert Lindstr\u00f6m , Alex Terentiev .","title":"Contributors"},{"location":"about/release-notes/#1131","text":"","title":"1.13.1"},{"location":"about/release-notes/#fixes_43","text":"WebPartTitle : Fix for className property which is not defined #281 RichText : Fix issue where control turns drop-downs black #279","title":"Fixes"},{"location":"about/release-notes/#contributors_39","text":"Special thanks to our contributor: Hugo Bernier .","title":"Contributors"},{"location":"about/release-notes/#1130","text":"","title":"1.13.0"},{"location":"about/release-notes/#new-controls_20","text":"Progress : New control added #230 DateTimePicker : New control added #21 RichText : New control added #20","title":"New control(s)"},{"location":"about/release-notes/#enhancements_40","text":"SecurityTrimmedControl : Support for item and folder permission checks added #271 Retrieve the user its profile picture from SharePoint instead of Office 365 / Outlook #248 Added Lithuanian localization #247 FileTypeIcon : Added support for PDF icon file types #260 WebPartTitle : Added the ability to render a see all link or custom component #228","title":"Enhancements"},{"location":"about/release-notes/#fixes_44","text":"PeoplePicker : Fix for single quotes around the ms-peoplepicker class #275 RichText : Fix for toolbar that appears at top of the page #265 ListItemAttachments : Updated import statement reference in the documentation #254 ListView : Updated documentation for the iconFieldName property #245","title":"Fixes"},{"location":"about/release-notes/#contributors_40","text":"Special thanks to our contributors (in alphabetical order): Francis , Fredrik Andreasson , Hugo Bernier , Tautvydas Duda , \u00d6zg\u00fcr Ersoy , Robert Lindstr\u00f6m , Alex Terentiev .","title":"Contributors"},{"location":"about/release-notes/#1120","text":"","title":"1.12.0"},{"location":"about/release-notes/#new-controls_21","text":"ListItemAttachments : New control added #177 IFramePanel : New control added #226","title":"New control(s)"},{"location":"about/release-notes/#enhancements_41","text":"Added Russian localization #214 TaxonomyPicker : Ability to specify term actions #237","title":"Enhancements"},{"location":"about/release-notes/#fixes_45","text":"TaxonomyPicker : Terms are sorted incorrectly under the wrong parent #199 #229 TaxonomyPicker : Issue with custom sort order of items underneath root terms #231 PeoplePicker : Fix for issue where values couldn't be cleared #234","title":"Fixes"},{"location":"about/release-notes/#contributors_41","text":"Special thanks to our contributors (in alphabetical order): Patrik Hellgren , Jo\u00e3o Mendes , David Opdendries , Piotr Siatka , Alex Terentiev , Tse Kit Yam .","title":"Contributors"},{"location":"about/release-notes/#1110","text":"","title":"1.11.0"},{"location":"about/release-notes/#new-controls_22","text":"Map : Newly introduced map control is available #14 ChartControl : Newly introduced control to render charts #15","title":"New control(s)"},{"location":"about/release-notes/#enhancements_42","text":"PeoplePicker : Allow the people picker to search on site level and on tenant level #97 ListView : Added support for filtering #99 PeoplePicker : Make the titleText property not required #184 Placeholder : Added the ability to specify if the button can be hidden #206 Updated the office-ui-fabric-react to the same version as in SPFx 1.7.0","title":"Enhancements"},{"location":"about/release-notes/#fixes_46","text":"IFrameDialog : fix for spinner which keeps appearing on the iframe #154 PeoplePicker : fix SharePoint groups which could not be retrieved #161 TaxonomyPicker : fix sort order with lowercased terms #205","title":"Fixes"},{"location":"about/release-notes/#contributors_42","text":"Special thanks to our contributors (in alphabetical order): Hugo Bernier , joaojmendes , Asish Padhy , Piotr Siatka , Anoop Tatti , Alex Terentiev , Tse Kit Yam .","title":"Contributors"},{"location":"about/release-notes/#1100","text":"","title":"1.10.0"},{"location":"about/release-notes/#new-controls_23","text":"ListItemPicker : New field control #165","title":"New control(s)"},{"location":"about/release-notes/#enhancements_43","text":"Dutch localization added #100 German localization added #101 French localization added #102 PeoplePicker : Move defaultSelectedUsers from ComponentWillMount to ComponentDidUpdate Lifecycle #135 PeoplePicker : Initialize with users from a list item #138 PeoplePicker : Remove Messagebar error handling to match Office UI Fabric field error styling #140 PeoplePicker : REST API filter and nometadata header added to reduce payload #139 PeoplePicker : Allow to set the maximum number of suggestions suggestionsLimit #143 #148 TaxonomyPicker : retreiving the terms in the correct custom sort order #146 PeoplePicker : Documentation format updated to make it easier to check the default values #159","title":"Enhancements"},{"location":"about/release-notes/#contributors_43","text":"Special thanks to our contributors (in alphabetical order): Marc D Anderson , Ole Bergtun , Jo\u00e3o Mendes , Markus M\u00f6ller , Asish Padhy , PooLP , Gautam Sheth , Tse Kit Yam .","title":"Contributors"},{"location":"about/release-notes/#190","text":"","title":"1.9.0"},{"location":"about/release-notes/#enhancements_44","text":"Optimize bundle size for latest SPFx version due to Office UI Fabric specific versioning #136","title":"Enhancements"},{"location":"about/release-notes/#fixes_47","text":"FieldLookupRenderer : Lookup dialog is empty #131 IFrameDialog : Unnecessary horizontal scroll in IFrame dialog #132 PeoplePicker : Suggested People not loading after first selection #134","title":"Fixes"},{"location":"about/release-notes/#contributors_44","text":"Special thanks to our contributors (in alphabetical order): Gautam Sheth , Alex Terentiev .","title":"Contributors"},{"location":"about/release-notes/#180","text":"","title":"1.8.0"},{"location":"about/release-notes/#enhancements_45","text":"PeoplePicker : Specify to hide or show the users/groups which are hidden in the UI #122 WebPartTitle : changing font-sizes on different resolutions #114 WebPartTitle : Added accessibility tags for web part title #121 ListView : Resizable columns - introduced a isResizable property #119 FieldNameRenderer double click support added #116 TaxonomyPicker : table markup changed to DIV #113 PeoplePicker : ability to specify the source site to load users from #110 TaxonomyPicker : Disable the terms which are set as deprecated or unavailable for tagging #109 PeoplePicker : Specify principle type to retrieve (users, groups, ...) #94","title":"Enhancements"},{"location":"about/release-notes/#fixes_48","text":"FieldLookupRenderer : Fixed URL querystring params #126 IFrameDialog : dialog width is not correct in IE11 #118 PeoplePicker : fix freezes when typing in search values #117","title":"Fixes"},{"location":"about/release-notes/#contributors_45","text":"Special thanks to our contributors (in alphabetical order): Thomas Lamb , Joel Rodrigues , Mikael Svenson , Alex Terentiev .","title":"Contributors"},{"location":"about/release-notes/#170","text":"","title":"1.7.0"},{"location":"about/release-notes/#enhancements_46","text":"PeoplePicker : added functionality to initialize the control with person(s) or group(s) #98 PeoplePicker : support for searching on contains #93 PeoplePicker : find user based on email address #95 Bundle size: statically reference Office UI Fabric components in the FieldRenderer controls #107","title":"Enhancements"},{"location":"about/release-notes/#fixes_49","text":"FieldNameRenderer onClick does not suppress default link behavior #103","title":"Fixes"},{"location":"about/release-notes/#contributors_46","text":"Special thanks to our contributors (in alphabetical order): Octavie van Haaften, Asish Padhy, Mikael Svenson, Alex Terentiev.","title":"Contributors"},{"location":"about/release-notes/#160","text":"","title":"1.6.0"},{"location":"about/release-notes/#enhancements_47","text":"Disabled property for PeoplePicker #88","title":"Enhancements"},{"location":"about/release-notes/#fixes_50","text":"New telemetry approach which allows you to use Application Insights #81 PeoplePicker property selectedItems not implemented? #90","title":"Fixes"},{"location":"about/release-notes/#contributors_47","text":"Special thanks to our contributor: Octavie van Haaften.","title":"Contributors"},{"location":"about/release-notes/#150","text":"","title":"1.5.0"},{"location":"about/release-notes/#new-controls_24","text":"New PeoplePicker control added #19","title":"New control(s)"},{"location":"about/release-notes/#enhancements_48","text":"Added properties to the TaxonomyPicker to specify which terms are disabled/not-selectable #82","title":"Enhancements"},{"location":"about/release-notes/#fixes_51","text":"Bug in TaxonomyPicker where values are not updated by an async change #83 FieldUserRenderer uses email prop for GetPropertiesFor #84 Fixed issue in single selection mode when all group items were selected in the ListView when user clicked on the group header #86","title":"Fixes"},{"location":"about/release-notes/#contributors_48","text":"Special thanks to our contributors (in alphabetical order): Asish Padhy, Alex Terentiev.","title":"Contributors"},{"location":"about/release-notes/#140","text":"","title":"1.4.0"},{"location":"about/release-notes/#new-controls_25","text":"SecurityTrimmedControl control got added #74","title":"New control(s)"},{"location":"about/release-notes/#enhancements_49","text":"Allow the TaxonomyPicker to also be used in Application Customizer #77 Add npm postinstall script to automatically add the locale config #78","title":"Enhancements"},{"location":"about/release-notes/#fixes_52","text":"Icon not showing up in the Placeholder control #76","title":"Fixes"},{"location":"about/release-notes/#130","text":"","title":"1.3.0"},{"location":"about/release-notes/#enhancements_50","text":"TaxonomyPicker control got added #22 #63 #64 ListPicker control got added #34","title":"Enhancements"},{"location":"about/release-notes/#fixes_53","text":"Issue fixed when the optional selection property was not provided to the ListView #65","title":"Fixes"},{"location":"about/release-notes/#125","text":"","title":"1.2.5"},{"location":"about/release-notes/#fixes_54","text":"Undo ListView item selection after items array updates #55","title":"Fixes"},{"location":"about/release-notes/#124","text":"","title":"1.2.4"},{"location":"about/release-notes/#enhancements_51","text":"Hiding placeholder title on small zones","title":"Enhancements"},{"location":"about/release-notes/#fixes_55","text":"iFrame dialog reference fix #52","title":"Fixes"},{"location":"about/release-notes/#123","text":"","title":"1.2.3"},{"location":"about/release-notes/#enhancements_52","text":"Optimized telemetry so that it only pushes control data WebPartTitle hide control completely when empty","title":"Enhancements"},{"location":"about/release-notes/#122","text":"","title":"1.2.2"},{"location":"about/release-notes/#fixes_56","text":"Fixes an issue sorting in the ListView control while items were selected. Indexes were not updated.","title":"Fixes"},{"location":"about/release-notes/#121","text":"","title":"1.2.1"},{"location":"about/release-notes/#fixes_57","text":"FieldTaxonomyRenderer got fixed to support single and multiple values","title":"Fixes"},{"location":"about/release-notes/#120","text":"","title":"1.2.0"},{"location":"about/release-notes/#new-controls_26","text":"Field controls are added to the project IFrameDialog was added to the project","title":"New control(s)"},{"location":"about/release-notes/#fixes_58","text":"Fixed theming in the WebPartTitle control","title":"Fixes"},{"location":"about/release-notes/#113","text":"","title":"1.1.3"},{"location":"about/release-notes/#fixes_59","text":"FileTypeIcon icon fixed where it did not render an icon. This control should now works in SPFx extensions.","title":"Fixes"},{"location":"about/release-notes/#112","text":"","title":"1.1.2"},{"location":"about/release-notes/#enhancements_53","text":"Improved telemetry with some object checks","title":"Enhancements"},{"location":"about/release-notes/#fixes_60","text":"Fix for WebPartTitle control to inherit color","title":"Fixes"},{"location":"about/release-notes/#111","text":"","title":"1.1.1"},{"location":"about/release-notes/#enhancements_54","text":"Removed operation name from telemetry","title":"Enhancements"},{"location":"about/release-notes/#110","text":"","title":"1.1.0"},{"location":"about/release-notes/#enhancements_55","text":"Telemetry added","title":"Enhancements"},{"location":"about/release-notes/#100","text":"","title":"1.0.0"},{"location":"about/release-notes/#new-controls_27","text":"WebPartTitle control got added","title":"New control(s)"},{"location":"about/release-notes/#enhancements_56","text":"ListView control got extended with the ability to specify a set of preselected items.","title":"Enhancements"},{"location":"about/release-notes/#beta-100-beta8","text":"","title":"Beta 1.0.0-beta.8"},{"location":"about/release-notes/#fixes_61","text":"Fix for the ListView control when selection is used in combination with setState .","title":"Fixes"},{"location":"about/release-notes/#beta-100-beta7","text":"","title":"Beta 1.0.0-beta.7"},{"location":"about/release-notes/#new-controls_28","text":"Grouping functionality added to the ListView control","title":"New control(s)"},{"location":"about/release-notes/#beta-100-beta6","text":"","title":"Beta 1.0.0-beta.6"},{"location":"about/release-notes/#new-controls_29","text":"Initial release","title":"New control(s)"},{"location":"controls/AccessibleAccordion/","text":"Accessible Accordion \u00b6 This control allows you to render an accordion control. It is an implementation based on React Accessible Accordion Control, that was customized to be more \"Fluent\". Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Accordion control as follows: import { Accordion , AccordionItem , AccordionItemHeading , AccordionItemButton , AccordionItemPanel , } from \"@pnp/spfx-controls-react/lib/AccessibleAccordion\" ; Use the Accordion control in your code as follows: < Accordion > < AccordionItem > < AccordionItemHeading > < AccordionItemButton > What harsh truths do you prefer to ignore ? < /AccordionItemButton> < /AccordionItemHeading> < AccordionItemPanel > < p > Exercitation in fugiat est ut ad ea cupidatat ut in cupidatat occaecat ut occaecat consequat est minim minim esse tempor laborum consequat esse adipisicing eu reprehenderit enim . < /p> < /AccordionItemPanel> < /AccordionItem> < AccordionItem > < AccordionItemHeading > < AccordionItemButton > Is free will real or just an illusion ? < /AccordionItemButton> < /AccordionItemHeading> < AccordionItemPanel > < p > In ad velit in ex nostrud dolore cupidatat consectetur ea in ut nostrud velit in irure cillum tempor laboris sed adipisicing eu esse duis nulla non . < /p> < /AccordionItemPanel> < /AccordionItem> < /Accordion> } Implementation \u00b6 The Accordion control can be configured with the following properties: Accordion \u00b6 Property Type Required Description Default allowMultipleExpanded boolean no Don't autocollapse items when expanding other items. false allowZeroExpanded boolean no Allow the only remaining expanded item to be collapsed. false preExpanded string[] no Accepts an array of strings and any AccordionItem whose uuid prop matches any one of these strings will be expanded on mount. [] className string no Class(es) to apply to element. \"accordion\" onChange (string[]) => void no Callback which is invoked when items are expanded or collapsed. Gets passed uuid s of the currently expanded AccordionItem s. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded. AccordionItem \u00b6 Property Type Required Description Default className string no Class(es) to apply to element. \"accordion__item\" uuid string | number no Recommended for use with onChange . Will be auto-generated if not provided. dangerouslySetExpanded boolean no Enables external control of the expansion. Warning: This may impact accessibility negatively, use at your own risk AccordionItemHeading \u00b6 Property Type Required Description Default className string no Class(es) to apply to the 'heading' element. \"accordion__heading\" aria-level number no Semantics to apply to the 'heading' element. A value of 1 would make your heading element hierarchically equivalent to an

tag, and likewise a value of 6 would make it equivalent to an

tag. 3 AccordionItemButton \u00b6 Property Type Required Description Default className string no Class(es) to apply to the 'button' element. \"accordion__button\" AccordionItemPanel \u00b6 Property Type Required Description Default className string no Class(es) to apply to element. \"accordion__panel\" AccordionItemState \u00b6 Property Type Required Description Default children ({ expanded: boolean, disabled: booleam }): JSX.Element yes item's children. Helpers \u00b6 resetNextUuid \u00b6 resetNextUuid : () => void Resets the internal counter for Accordion items' identifiers (including id attributes). For use in test suites and isomorphic frameworks.","title":"AccessibleAccordion"},{"location":"controls/AccessibleAccordion/#accessible-accordion","text":"This control allows you to render an accordion control. It is an implementation based on React Accessible Accordion Control, that was customized to be more \"Fluent\". Here is an example of the control in action:","title":"Accessible Accordion"},{"location":"controls/AccessibleAccordion/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Accordion control as follows: import { Accordion , AccordionItem , AccordionItemHeading , AccordionItemButton , AccordionItemPanel , } from \"@pnp/spfx-controls-react/lib/AccessibleAccordion\" ; Use the Accordion control in your code as follows: < Accordion > < AccordionItem > < AccordionItemHeading > < AccordionItemButton > What harsh truths do you prefer to ignore ? < /AccordionItemButton> < /AccordionItemHeading> < AccordionItemPanel > < p > Exercitation in fugiat est ut ad ea cupidatat ut in cupidatat occaecat ut occaecat consequat est minim minim esse tempor laborum consequat esse adipisicing eu reprehenderit enim . < /p> < /AccordionItemPanel> < /AccordionItem> < AccordionItem > < AccordionItemHeading > < AccordionItemButton > Is free will real or just an illusion ? < /AccordionItemButton> < /AccordionItemHeading> < AccordionItemPanel > < p > In ad velit in ex nostrud dolore cupidatat consectetur ea in ut nostrud velit in irure cillum tempor laboris sed adipisicing eu esse duis nulla non . < /p> < /AccordionItemPanel> < /AccordionItem> < /Accordion> }","title":"How to use this control in your solutions"},{"location":"controls/AccessibleAccordion/#implementation","text":"The Accordion control can be configured with the following properties:","title":"Implementation"},{"location":"controls/AccessibleAccordion/#accordion","text":"Property Type Required Description Default allowMultipleExpanded boolean no Don't autocollapse items when expanding other items. false allowZeroExpanded boolean no Allow the only remaining expanded item to be collapsed. false preExpanded string[] no Accepts an array of strings and any AccordionItem whose uuid prop matches any one of these strings will be expanded on mount. [] className string no Class(es) to apply to element. \"accordion\" onChange (string[]) => void no Callback which is invoked when items are expanded or collapsed. Gets passed uuid s of the currently expanded AccordionItem s. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.","title":"Accordion"},{"location":"controls/AccessibleAccordion/#accordionitem","text":"Property Type Required Description Default className string no Class(es) to apply to element. \"accordion__item\" uuid string | number no Recommended for use with onChange . Will be auto-generated if not provided. dangerouslySetExpanded boolean no Enables external control of the expansion. Warning: This may impact accessibility negatively, use at your own risk","title":"AccordionItem"},{"location":"controls/AccessibleAccordion/#accordionitemheading","text":"Property Type Required Description Default className string no Class(es) to apply to the 'heading' element. \"accordion__heading\" aria-level number no Semantics to apply to the 'heading' element. A value of 1 would make your heading element hierarchically equivalent to an

tag, and likewise a value of 6 would make it equivalent to an

tag. 3","title":"AccordionItemHeading"},{"location":"controls/AccessibleAccordion/#accordionitembutton","text":"Property Type Required Description Default className string no Class(es) to apply to the 'button' element. \"accordion__button\"","title":"AccordionItemButton"},{"location":"controls/AccessibleAccordion/#accordionitempanel","text":"Property Type Required Description Default className string no Class(es) to apply to element. \"accordion__panel\"","title":"AccordionItemPanel"},{"location":"controls/AccessibleAccordion/#accordionitemstate","text":"Property Type Required Description Default children ({ expanded: boolean, disabled: booleam }): JSX.Element yes item's children.","title":"AccordionItemState"},{"location":"controls/AccessibleAccordion/#helpers","text":"","title":"Helpers"},{"location":"controls/AccessibleAccordion/#resetnextuuid","text":"resetNextUuid : () => void Resets the internal counter for Accordion items' identifiers (including id attributes). For use in test suites and isomorphic frameworks.","title":"resetNextUuid"},{"location":"controls/Accordion/","text":"Accordion \u00b6 This control allows you to render an accordion control. Here is an example of the control in action: Here is an example of the control with custom icons: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Accordion control as follows: import { Accordion } from \"@pnp/spfx-controls-react/lib/Accordion\" ; Use the Accordion control in your code as follows: { sampleItems . map (( item , index ) => ( < Accordion title = { item . Question } defaultCollapsed = { true } className = { \"itemCell\" } key = { index } > < div className = { \"itemContent\" } > < div className = { \"itemResponse\" } > { item . Reponse } < /div> < div className = { \"itemIndex\" } > { `Langue : ${ item . Langue . Nom } ` } < /div> < /div> < /Accordion> )) } For the Accordion control with custom icons: { < Accordion title = { item . Question } defaultCollapsed = { true } className = { \"itemCell\" } key = { index } collapsedIcon = { \"Rocket\" } expandedIcon = { \"InkingTool\" } > } Implementation \u00b6 The Accordion control can be configured with the following properties: Property Type Required Description Default title string yes The title in the accordion to display. defaultCollapsed boolean no Is the accordion by default collapsed? false className string no Additional class name to add to your accordion. collapsedIcon string no Optional custom icon when accordion is collapsed See Fluent UI icons ChevronRight expandedIcon string no Optional custom icon when accordion is expanded See Fluent UI icons ChevronDown","title":"Accordion"},{"location":"controls/Accordion/#accordion","text":"This control allows you to render an accordion control. Here is an example of the control in action: Here is an example of the control with custom icons:","title":"Accordion"},{"location":"controls/Accordion/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Accordion control as follows: import { Accordion } from \"@pnp/spfx-controls-react/lib/Accordion\" ; Use the Accordion control in your code as follows: { sampleItems . map (( item , index ) => ( < Accordion title = { item . Question } defaultCollapsed = { true } className = { \"itemCell\" } key = { index } > < div className = { \"itemContent\" } > < div className = { \"itemResponse\" } > { item . Reponse } < /div> < div className = { \"itemIndex\" } > { `Langue : ${ item . Langue . Nom } ` } < /div> < /div> < /Accordion> )) } For the Accordion control with custom icons: { < Accordion title = { item . Question } defaultCollapsed = { true } className = { \"itemCell\" } key = { index } collapsedIcon = { \"Rocket\" } expandedIcon = { \"InkingTool\" } > }","title":"How to use this control in your solutions"},{"location":"controls/Accordion/#implementation","text":"The Accordion control can be configured with the following properties: Property Type Required Description Default title string yes The title in the accordion to display. defaultCollapsed boolean no Is the accordion by default collapsed? false className string no Additional class name to add to your accordion. collapsedIcon string no Optional custom icon when accordion is collapsed See Fluent UI icons ChevronRight expandedIcon string no Optional custom icon when accordion is expanded See Fluent UI icons ChevronDown","title":"Implementation"},{"location":"controls/AdaptiveCardDesignerHost/","text":"Adaptive Card Designer Host \u00b6 This control allows you to embed the official Adaptive Cards designer inside a React SPFx solution. The control consists of 2 components: AdaptiveCardDesigner : implements all the logic to embed the designer control as a React component; AdaptiveCardDesignerHost : main control to render the designer in a full page Fluent UI panel; Due to the nature in which the original Adaptive Card Designer control was implemented , it is not possible at this time to adapt it to the current theme applied to the site and especially to localize it to give multilingual support. The designer, therefore, is only available in the English language . This control shares a lot of code with another control in this library, the \"AdaptiveCardHost\" control. In this way you have a uniformity of display between the cards created with this designer and those rendered with \"AdaptiveCardHost\". The same thing goes for the various HostContainer objects, so that you can test the cards with the themes available for \"AdaptiveCardHost\". The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0. All Inputs Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, adding and improving features that are not managed in Microsoft's implementation of the \"adaptivecards-fluentui\" library (Theme support for example). Thanks to the \"context\" property that allows you to pass the SPFx context, whether the \"data\" property is passed or not, a new field called @context will be injected into the data object. This allows, using Adaptive Cards templating syntax and binding feature of the Designer, to access to the context informations. For more info please to refear tot he documentation of AdaptiveCardHost control Here is an example of the control in action inside a Web Part: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AdaptiveCardDesignerHost control as follows: import { AdaptiveCardDesignerHost , HostContainer , BindingPreviewMode , Versions } from \"@pnp/spfx-controls-react/lib/AdaptiveCardDesignerHost\" ; Example on use the AdaptiveCardDesignerHost control with only required properties: < AdaptiveCardDesignerHost headerText = \"Adaptive Card Designer\" buttonText = \"Open the Designer\" context = { props . context } onSave = {( payload : object ) => setCard ( payload )} /> Example on use the AdaptiveCardDesignerHost control with all properties: < AdaptiveCardDesignerHost headerText = \"Adaptive Card Designer\" buttonText = \"Open the Designer\" context = { props . context } onSave = {( payload : object ) => setCard ( payload )} addDefaultAdaptiveCardHostContainer = { true } bindingPreviewMode = { BindingPreviewMode . SampleData } theme = { props . theme } card = { card } data = { data } enableDataBindingSupport = { true } hostConfig = { hostConfig } hostContainers = {[]} injectAdaptiveCardHostContextProperty = { true } newCardPayload = { newCard } selectedHostContainerControlsTargetVersion = { false } showCopyToJsonToolbarCommand = { true } showDataStructureToolbox = { true } showFluentBreakpointsPicker = { true } showSampleDataEditorToolbox = { true } showTargetVersionMismatchWarning = { true } showVersionPicker = { true } supportedTargetVersions = {[ Versions . v1_5 ]} snippets = { snippets } /> Implementation \u00b6 The AdaptiveCardDesignerHost control can be configured with the following properties: Property Type Required Description Default Value context BaseComponentContext true Set the context from SPFx component - theme IPartialTheme or ITheme false Set Fluent UI Theme - onSave (payload: object) => void true Callback for saving the card - card object false Set Adaptive Card payload - data { \"$root\": object } false Set Data Source for template rendering - newCardPayload object false Set Adaptive Card payload for the New Card - hostContainers HostContainer[] false Set custom HostContainers [] supportedTargetVersions Version[] false Set the suported Versions [Versions.v1_5] snippets IToolboxSnippet[] false Set the Toolbox Snippets [] bindingPreviewMode BindingPreviewMode false Set the Binding preview mode BindingPreviewMode.GeneratedData enableDataBindingSupport boolean false Enable the support for Data Binding true selectedHostContainerControlsTargetVersion boolean false Enable the support for Data Binding false showTargetVersionMismatchWarning boolean false Show the target version mismatch warning true showVersionPicker boolean false Show the Version Picker false showSampleDataEditorToolbox boolean false Show the Sample Data Editor Toolbox false showDataStructureToolbox boolean false Show the Data Structure Toolbox true showFluentBreakpointsPicker boolean false Show the Fluent UI Breakpoint Picker true showCopyToJsonToolbarCommand boolean false Show the copy to json button false addDefaultAdaptiveCardHostContainer boolean false Add the default Host Containers to the Picker true injectAdaptiveCardHostContextProperty boolean false Inject the SPFx Context Property inside the Adaptive Card data object true headerText boolean false Set the Header text for the Adaptive Card Designer - buttonText boolean false Set the Button text for open the Adaptive Card Designer -","title":"AdaptiveCardDesignerHost"},{"location":"controls/AdaptiveCardDesignerHost/#adaptive-card-designer-host","text":"This control allows you to embed the official Adaptive Cards designer inside a React SPFx solution. The control consists of 2 components: AdaptiveCardDesigner : implements all the logic to embed the designer control as a React component; AdaptiveCardDesignerHost : main control to render the designer in a full page Fluent UI panel; Due to the nature in which the original Adaptive Card Designer control was implemented , it is not possible at this time to adapt it to the current theme applied to the site and especially to localize it to give multilingual support. The designer, therefore, is only available in the English language . This control shares a lot of code with another control in this library, the \"AdaptiveCardHost\" control. In this way you have a uniformity of display between the cards created with this designer and those rendered with \"AdaptiveCardHost\". The same thing goes for the various HostContainer objects, so that you can test the cards with the themes available for \"AdaptiveCardHost\". The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0. All Inputs Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, adding and improving features that are not managed in Microsoft's implementation of the \"adaptivecards-fluentui\" library (Theme support for example). Thanks to the \"context\" property that allows you to pass the SPFx context, whether the \"data\" property is passed or not, a new field called @context will be injected into the data object. This allows, using Adaptive Cards templating syntax and binding feature of the Designer, to access to the context informations. For more info please to refear tot he documentation of AdaptiveCardHost control Here is an example of the control in action inside a Web Part:","title":"Adaptive Card Designer Host"},{"location":"controls/AdaptiveCardDesignerHost/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AdaptiveCardDesignerHost control as follows: import { AdaptiveCardDesignerHost , HostContainer , BindingPreviewMode , Versions } from \"@pnp/spfx-controls-react/lib/AdaptiveCardDesignerHost\" ; Example on use the AdaptiveCardDesignerHost control with only required properties: < AdaptiveCardDesignerHost headerText = \"Adaptive Card Designer\" buttonText = \"Open the Designer\" context = { props . context } onSave = {( payload : object ) => setCard ( payload )} /> Example on use the AdaptiveCardDesignerHost control with all properties: < AdaptiveCardDesignerHost headerText = \"Adaptive Card Designer\" buttonText = \"Open the Designer\" context = { props . context } onSave = {( payload : object ) => setCard ( payload )} addDefaultAdaptiveCardHostContainer = { true } bindingPreviewMode = { BindingPreviewMode . SampleData } theme = { props . theme } card = { card } data = { data } enableDataBindingSupport = { true } hostConfig = { hostConfig } hostContainers = {[]} injectAdaptiveCardHostContextProperty = { true } newCardPayload = { newCard } selectedHostContainerControlsTargetVersion = { false } showCopyToJsonToolbarCommand = { true } showDataStructureToolbox = { true } showFluentBreakpointsPicker = { true } showSampleDataEditorToolbox = { true } showTargetVersionMismatchWarning = { true } showVersionPicker = { true } supportedTargetVersions = {[ Versions . v1_5 ]} snippets = { snippets } />","title":"How to use this control in your solutions"},{"location":"controls/AdaptiveCardDesignerHost/#implementation","text":"The AdaptiveCardDesignerHost control can be configured with the following properties: Property Type Required Description Default Value context BaseComponentContext true Set the context from SPFx component - theme IPartialTheme or ITheme false Set Fluent UI Theme - onSave (payload: object) => void true Callback for saving the card - card object false Set Adaptive Card payload - data { \"$root\": object } false Set Data Source for template rendering - newCardPayload object false Set Adaptive Card payload for the New Card - hostContainers HostContainer[] false Set custom HostContainers [] supportedTargetVersions Version[] false Set the suported Versions [Versions.v1_5] snippets IToolboxSnippet[] false Set the Toolbox Snippets [] bindingPreviewMode BindingPreviewMode false Set the Binding preview mode BindingPreviewMode.GeneratedData enableDataBindingSupport boolean false Enable the support for Data Binding true selectedHostContainerControlsTargetVersion boolean false Enable the support for Data Binding false showTargetVersionMismatchWarning boolean false Show the target version mismatch warning true showVersionPicker boolean false Show the Version Picker false showSampleDataEditorToolbox boolean false Show the Sample Data Editor Toolbox false showDataStructureToolbox boolean false Show the Data Structure Toolbox true showFluentBreakpointsPicker boolean false Show the Fluent UI Breakpoint Picker true showCopyToJsonToolbarCommand boolean false Show the copy to json button false addDefaultAdaptiveCardHostContainer boolean false Add the default Host Containers to the Picker true injectAdaptiveCardHostContextProperty boolean false Inject the SPFx Context Property inside the Adaptive Card data object true headerText boolean false Set the Header text for the Adaptive Card Designer - buttonText boolean false Set the Button text for open the Adaptive Card Designer -","title":"Implementation"},{"location":"controls/AdaptiveCardHost/","text":"Adaptive Card Host \u00b6 The motivation behind this control is to have a React control that facilitates the use of Adaptive Cards in SPFx by adding some features such as: Graphic integration with SharePoint / Microsoft Teams themes, both as regards the color palette and the use of the Fluent UI React controls instead of the classic HTML controls. Automatic use of Adaptive Cards Templating if an object containing data is passed to the control. For graphic integration, in the case of SharePoint the current theme (page or section theme) or a custom theme is used. Three custom themes have been created for Microsoft Teams to emulate the colors of the available themes: Default, Dark and Hight Contrast. All Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, both for SharePoint and Microsoft Teams (in this case the \"Fluent UI Northstar\" library is not used), adding and improving features that are not managed in Microsoft's implementation of the \"adaptivecards-fluentui\" library (Theme support for example). Thanks to the \"context\" property that allows you to pass the SPFx context, whether the \"data\" property is passed or not, a new field called @context will be injected into the data object. This allows, using Adaptive Cards templating syntax, to access to the context informations using the following fields (for more information on these fields, refer to the BaseComponentContext class): - \"theme\": property \"theme\" from the current theme applied to the card. - \"aadInfo\": Azure AD informations retrieved from the SPFx context object. - \"cultureInfo\": Culture informations retrieved from the SPFx context object. - \"userInfo\": User informations retrieved from the SPFx context object. - \"spListInfo\": Current List informations retrieved from the SPFx context object. - \"spListItemInfo\": Current List item informations retrieved from the SPFx context object. - \"spSiteInfo\": Current Site informations retrieved from the SPFx context object. - \"spWebInfo\": Current Web informations retrieved from the SPFx context object. The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0. Here is an example of the control in action inside a Web Part: Here is an example of the previous Web Part (using different Card), hosted as a Tab in Microsoft Teams: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AdaptiveCardHost control as follows: import { AdaptiveCardHost , IAdaptiveCardHostActionResult , AdaptiveCardHostThemeType , Action , CardElement , CardObjectRegistry , HostCapabilities } from \"@pnp/spfx-controls-react/lib/AdaptiveCardHost\" ; Example on use the AdaptiveCardHost control with only required properties: < AdaptiveCardHost card = { card } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with all properties: < AdaptiveCardHost card = { card } data = { data } style = { null } className = { null } theme = { this . props . theme } themeType = { themeType } hostConfig = { null } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} onSetCustomElements = {( registry : CardObjectRegistry < CardElement > ) => { registry . register ( \"CustomElementName\" , CustomElement ); }} onSetCustomActions = {( registry : CardObjectRegistry < Action > ) => { registry . register ( \"CustomActionName\" , CustomAction ); }} onUpdateHostCapabilities = {( hostCapabilities : HostCapabilities ) => { hostCapabilities . setCustomProperty ( \"CustomPropertyName\" , Date . now ); }} context = { this . props . context } /> Example on use the AdaptiveCardHost control with SharePoint Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . SharePoint } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with SharePoint Theme \"Section Variation\" ('this.props.theme' is the theme that come from the Web Part) */): < AdaptiveCardHost card = { card } theme = { this . props . theme } themeType = { AdaptiveCardHostThemeType . SharePoint } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"Default\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . Teams } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"Dark\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . TeamsDark } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"High Contrast\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . TeamsHighContrast } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Implementation \u00b6 The AdaptiveCardHost control can be configured with the following properties: Property Type Required Description card object yes Set Adaptive Card payload. data { \"$root\": object } no Set Data Source for template rendering. style React.CSSProperties no Set CSS Style. className string no Set CSS Class. theme IPartialTheme or ITheme no Set Fluent UI Theme. Used only if the \"themeType\" property is set to 'ThemeType.SharePoint'. If not set or set to null or not defined, the theme passed through context will be searched, or the default theme of the page will be loaded. However, the Theme object will be automatically injected into the data object, so that it can be used by the Adaptive Cards binding engine. themeType ThemeType no Select the Type of Theme you want to use. If it is not set or set to null or undefined, the 'ThemeType.SharePoint' value will be used and the \"theme\" property or the theme passed through the context or default page will be loaded. In other cases, the chosen Microsoft Teams theme will be applied. hostConfig object no Set custom HostConfig. onInvokeAction (action: IAdaptiveCardActionResult) => void yes Invoked every time an Action is performed. onError (error: Error) => void yes Invoked every time an exception occurs in the rendering phase. onSetCustomElements (registry: CardObjectRegistry ) => void no Invoked to manage Elements to the current Adaptive Card instance. onSetCustomActions (registry: CardObjectRegistry ) => void no Invoked to manage Actions to the current Adaptive Card instance. onUpdateHostCapabilities (hostCapabilities: HostCapabilities) => void no Invoked to manage the HostCapabilities object like add custom properties. context BaseComponentContext no Set the context from the SPFx component. If set, some context properties will be automatically injected into the data object, so they can be used by the Adaptive Cards binding engine. Interface IAdaptiveCardHostActionResult Property Type Required Description type string yes Type of the Action. title string no Title of the Action. url string no Url of the Action. data object no Data of the Action. verb string no Verb of the Action. Enum AdaptiveCardHostThemeType Type Description SharePoint Use the SharePoint current Theme or Theme Variation Teams Use the Fluent UI Teams default theme TeamsDark Use the Fluent UI Teams dark theme TeamsHighContrast Use the Fluent UI Teams high contrast theme","title":"AdaptiveCardHost"},{"location":"controls/AdaptiveCardHost/#adaptive-card-host","text":"The motivation behind this control is to have a React control that facilitates the use of Adaptive Cards in SPFx by adding some features such as: Graphic integration with SharePoint / Microsoft Teams themes, both as regards the color palette and the use of the Fluent UI React controls instead of the classic HTML controls. Automatic use of Adaptive Cards Templating if an object containing data is passed to the control. For graphic integration, in the case of SharePoint the current theme (page or section theme) or a custom theme is used. Three custom themes have been created for Microsoft Teams to emulate the colors of the available themes: Default, Dark and Hight Contrast. All Elements and Actions of Adaptive Cards have been redefined using Fluent UI React, both for SharePoint and Microsoft Teams (in this case the \"Fluent UI Northstar\" library is not used), adding and improving features that are not managed in Microsoft's implementation of the \"adaptivecards-fluentui\" library (Theme support for example). Thanks to the \"context\" property that allows you to pass the SPFx context, whether the \"data\" property is passed or not, a new field called @context will be injected into the data object. This allows, using Adaptive Cards templating syntax, to access to the context informations using the following fields (for more information on these fields, refer to the BaseComponentContext class): - \"theme\": property \"theme\" from the current theme applied to the card. - \"aadInfo\": Azure AD informations retrieved from the SPFx context object. - \"cultureInfo\": Culture informations retrieved from the SPFx context object. - \"userInfo\": User informations retrieved from the SPFx context object. - \"spListInfo\": Current List informations retrieved from the SPFx context object. - \"spListItemInfo\": Current List item informations retrieved from the SPFx context object. - \"spSiteInfo\": Current Site informations retrieved from the SPFx context object. - \"spWebInfo\": Current Web informations retrieved from the SPFx context object. The Adaptive Cards version supported is 1.5, by using the 'adaptivecards' npm package version 2.10.0. Here is an example of the control in action inside a Web Part: Here is an example of the previous Web Part (using different Card), hosted as a Tab in Microsoft Teams:","title":"Adaptive Card Host"},{"location":"controls/AdaptiveCardHost/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AdaptiveCardHost control as follows: import { AdaptiveCardHost , IAdaptiveCardHostActionResult , AdaptiveCardHostThemeType , Action , CardElement , CardObjectRegistry , HostCapabilities } from \"@pnp/spfx-controls-react/lib/AdaptiveCardHost\" ; Example on use the AdaptiveCardHost control with only required properties: < AdaptiveCardHost card = { card } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with all properties: < AdaptiveCardHost card = { card } data = { data } style = { null } className = { null } theme = { this . props . theme } themeType = { themeType } hostConfig = { null } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} onSetCustomElements = {( registry : CardObjectRegistry < CardElement > ) => { registry . register ( \"CustomElementName\" , CustomElement ); }} onSetCustomActions = {( registry : CardObjectRegistry < Action > ) => { registry . register ( \"CustomActionName\" , CustomAction ); }} onUpdateHostCapabilities = {( hostCapabilities : HostCapabilities ) => { hostCapabilities . setCustomProperty ( \"CustomPropertyName\" , Date . now ); }} context = { this . props . context } /> Example on use the AdaptiveCardHost control with SharePoint Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . SharePoint } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with SharePoint Theme \"Section Variation\" ('this.props.theme' is the theme that come from the Web Part) */): < AdaptiveCardHost card = { card } theme = { this . props . theme } themeType = { AdaptiveCardHostThemeType . SharePoint } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"Default\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . Teams } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"Dark\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . TeamsDark } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } /> Example on use the AdaptiveCardHost control with Teams \"High Contrast\" Theme: < AdaptiveCardHost card = { card } themeType = { AdaptiveCardHostThemeType . TeamsHighContrast } onInvokeAction = {( action ) => alert ( JSON . stringify ( action ))} onError = {( error ) => alert ( error . message )} context = { this . props . context } />","title":"How to use this control in your solutions"},{"location":"controls/AdaptiveCardHost/#implementation","text":"The AdaptiveCardHost control can be configured with the following properties: Property Type Required Description card object yes Set Adaptive Card payload. data { \"$root\": object } no Set Data Source for template rendering. style React.CSSProperties no Set CSS Style. className string no Set CSS Class. theme IPartialTheme or ITheme no Set Fluent UI Theme. Used only if the \"themeType\" property is set to 'ThemeType.SharePoint'. If not set or set to null or not defined, the theme passed through context will be searched, or the default theme of the page will be loaded. However, the Theme object will be automatically injected into the data object, so that it can be used by the Adaptive Cards binding engine. themeType ThemeType no Select the Type of Theme you want to use. If it is not set or set to null or undefined, the 'ThemeType.SharePoint' value will be used and the \"theme\" property or the theme passed through the context or default page will be loaded. In other cases, the chosen Microsoft Teams theme will be applied. hostConfig object no Set custom HostConfig. onInvokeAction (action: IAdaptiveCardActionResult) => void yes Invoked every time an Action is performed. onError (error: Error) => void yes Invoked every time an exception occurs in the rendering phase. onSetCustomElements (registry: CardObjectRegistry ) => void no Invoked to manage Elements to the current Adaptive Card instance. onSetCustomActions (registry: CardObjectRegistry ) => void no Invoked to manage Actions to the current Adaptive Card instance. onUpdateHostCapabilities (hostCapabilities: HostCapabilities) => void no Invoked to manage the HostCapabilities object like add custom properties. context BaseComponentContext no Set the context from the SPFx component. If set, some context properties will be automatically injected into the data object, so they can be used by the Adaptive Cards binding engine. Interface IAdaptiveCardHostActionResult Property Type Required Description type string yes Type of the Action. title string no Title of the Action. url string no Url of the Action. data object no Data of the Action. verb string no Verb of the Action. Enum AdaptiveCardHostThemeType Type Description SharePoint Use the SharePoint current Theme or Theme Variation Teams Use the Fluent UI Teams default theme TeamsDark Use the Fluent UI Teams dark theme TeamsHighContrast Use the Fluent UI Teams high contrast theme","title":"Implementation"},{"location":"controls/AnimatedDialog/","text":"Animated Dialog \u00b6 Animated Dialog control is an extended version of the Office UI Fabric React Dialog . Animated Dialog control adds the following to the dialog - Entrance and exit animations - Animated icon above the title This control uses Animate.css to add the animations. Here is an example of the control in action: Animate.css and animation names \u00b6 Animate.css is a library that adds css animtions to controls. The website has all the names of the animations and any of them can be used in the Animated Dialog control. The default entrance animation name used in this control is bounceIn and the default exit animaton name is zoomOut . How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AnimatedDialog control as follows: import { AnimatedDialog } from \"@pnp/spfx-controls-react/lib/AnimatedDialog\" ; Different ways of using the control \u00b6 1. Simple way \u00b6 The code below adds a dialog with an entrance animation of bounceIn and exit animation of zoomOut . (These are the default animations) // Initial state this . state = { showAnimatedDialog : false } ... ... // Properties of the dialog const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog' , subText : 'Do you like the animated dialog?' , }; const animatedModalProps : IModalProps = { isDarkOverlay : true }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showAnimatedDialog } onDismiss = {() => { this . setState ({ showAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } > < DialogFooter > < PrimaryButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"Yes\" /> < DefaultButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"No\" /> < /DialogFooter> < /AnimatedDialog> Simple animated dialog \u00b6 2. Adding custom animations \u00b6 The code below adds adds a dialog with an entrance animation of fadeInDown and exit animation of fadeInDown . // Initial state this . state = { showAnimatedDialog : false } ... ... // Properties of the dialog const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog' , subText : 'Do you like the animated dialog?' , }; const animatedModalProps : IModalProps = { isDarkOverlay : true }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showAnimatedDialog } onDismiss = {() => { this . setState ({ showAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } dialogAnimationInType = 'fadeInDown' dialogAnimationOutType = 'fadeOutDown' > < DialogFooter > < PrimaryButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"Yes\" /> < DefaultButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"No\" /> < /DialogFooter> < /AnimatedDialog> Animated dialog with custom animations \u00b6 3. Adding icons and functions \u00b6 The code below does the following: - adds an icon (question mark) above the title - adds Yes and No buttons in the footer as showAnimatedDialogFooter is set to true . - passes 3 functions - onOkClick : The function that gets executed when the Ok/Yes button is clicked. - onSuccess : The function that gets executed on successful operation of the above function. - onError: The function that gets executed when the onOkClick function fails. // Initial state this . state = { showCustomisedAnimatedDialog : false , showSuccessDialog : false , showErrorDialog : false } ... ... const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog with icon' }; const successDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Good answer!' }; const animatedModalProps : IModalProps = { isDarkOverlay : true , containerClassName : ` ${ styles . dialogContainer } ` }; // The operation that does something - e.g. update data const timeout = ( ms : number ) : Promise < void > => { return new Promise (( resolve , reject ) => setTimeout ( resolve , ms )); }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showCustomisedAnimatedDialog } onDismiss = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } iconName = 'UnknownSolid' showAnimatedDialogFooter = { true } okButtonText = \"Yes\" cancelButtonText = \"No\" onOkClick = {() => timeout ( 1500 )} onSuccess = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showSuccessDialog : true }); }} onError = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showErrorDialog : true }); }} > < div className = { styles . dialogContent } > < span > Do you like the animated dialog ?< /span> < /div> < /AnimatedDialog> // Render success animated dialog which will appear after the execution // of onSuccess function in the above animated dialog < AnimatedDialog hidden = { ! this . state . showSuccessDialog } onDismiss = {() => { this . setState ({ showSuccessDialog : false }); }} dialogContentProps = { successDialogContentProps } modalProps = { animatedModalProps } iconName = 'CompletedSolid' > < div className = { styles . dialogContent } >< span > Thank you . < /span> < div className = { styles . resultDialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showSuccessDialog : false }); }} text = \"OK\" > < /PrimaryButton> < /div> < /AnimatedDialog> Animated dialog with icon \u00b6 4. Custom footer \u00b6 If the dialog content and footer buttons need to be controlled by our code and not the animated dialog control then the code below can be used // Initial state this . state = { showCustomisedAnimatedDialog : false , showSuccessDialog : false , showErrorDialog : false , showLoading : false } ... ... const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Custom content and footer' }; const successDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Good answer!' }; const animatedModalProps : IModalProps = { isDarkOverlay : true , containerClassName : ` ${ styles . dialogContainer } ` }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showCustomisedAnimatedDialog } onDismiss = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } iconName = 'UnknownSolid' > < div className = { styles . dialogContent } > < span > Do you like the animated dialog ?< /span> < /div> < div className = { styles . dialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showLoading : true }); setTimeout (() => { this . setState ({ showLoading : true }); this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showSuccessDialog : true }); }, 1500 ); }} disabled = { this . state . showLoading } text = { ! this . state . showLoading && \"Yeah!\" } > { this . state . showLoading && < Spinner size = { SpinnerSize . medium } /> } < /PrimaryButton> < DefaultButton onClick = {() => this . setState ({ showCustomisedAnimatedDialog : false })} text = \"Nope\" disabled = { this . state . showLoading } /> < /div> < /AnimatedDialog> // Render success animated dialog which will appear after the execution // of the onClick function of the Button in the above animated dialog < AnimatedDialog hidden = { ! this . state . showSuccessDialog } onDismiss = {() => { this . setState ({ showSuccessDialog : false }); }} dialogContentProps = { successDialogContentProps } modalProps = { animatedModalProps } iconName = 'CompletedSolid' > < div className = { styles . dialogContent } >< span > Thank you . < /span> < div className = { styles . resultDialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showSuccessDialog : false }); }} text = \"OK\" > < /PrimaryButton> < /div> < /AnimatedDialog> Animated dialog with custom content and footer \u00b6 SCSS used in the above examples \u00b6 $themePrimary : '[theme:themePrimary, default:#0078d7]' ; .dialogContainer { border-top : 4px ; border-top-color : $ themePrimary ; border-top-style : solid ; min-width : 400px ; .dialogContent { text-align : center ; padding-bottom : 10px ; font-size : 1 .125em ; } .dialogFooter { text-align : right ; margin-top : 1 .25em ; button { min-width : 75px ; margin : 0px 10px ; border-radius : 5px ; } .loader { margin-top : 15px ; } } .resultDialogFooter { text-align : center ; margin-top : 1 .25em ; button { min-width : 100px ; margin : 0px 10px ; } } } Implementation \u00b6 In addition to the Office UI Fabric dialog properties , the AnimatedDialog control can be configured with the following properties: Property Type Required Description Default dialogAnimationInType string no The name of the dialog entrace animation. See animate.css for values bounceIn dialogAnimationOutType string no The name of the dialog exit animation. See animate.css for values zoomOut iconName string no The name of the Fabric UI icon that appears above title. iconAnimationType string no The name of the icon entrace animation. See animate.css for values. zoomIn showAnimatedDialogFooter boolean no Should the animated dialog show it's own footer. See example 3 and 4 above for usage. false okButtonText string no The text of the the OK button if showAnimatedDialogFooter is true . See example 3 above for usage. Ok cancelButtonText string no The text of the the Cancel button if showAnimatedDialogFooter is true . See example 3 above for usage. Cancel onOkClick function no The function to be executed when Ok button is clicked. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage. onSuccess function no The function to be executed after successful execution of the OK button function. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage. onError function no The function to be executed after unsuccessful execution of the OK button function. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage.","title":"AnimatedDialog"},{"location":"controls/AnimatedDialog/#animated-dialog","text":"Animated Dialog control is an extended version of the Office UI Fabric React Dialog . Animated Dialog control adds the following to the dialog - Entrance and exit animations - Animated icon above the title This control uses Animate.css to add the animations. Here is an example of the control in action:","title":"Animated Dialog"},{"location":"controls/AnimatedDialog/#animatecss-and-animation-names","text":"Animate.css is a library that adds css animtions to controls. The website has all the names of the animations and any of them can be used in the Animated Dialog control. The default entrance animation name used in this control is bounceIn and the default exit animaton name is zoomOut .","title":"Animate.css and animation names"},{"location":"controls/AnimatedDialog/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the AnimatedDialog control as follows: import { AnimatedDialog } from \"@pnp/spfx-controls-react/lib/AnimatedDialog\" ;","title":"How to use this control in your solutions"},{"location":"controls/AnimatedDialog/#different-ways-of-using-the-control","text":"","title":"Different ways of using the control"},{"location":"controls/AnimatedDialog/#1-simple-way","text":"The code below adds a dialog with an entrance animation of bounceIn and exit animation of zoomOut . (These are the default animations) // Initial state this . state = { showAnimatedDialog : false } ... ... // Properties of the dialog const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog' , subText : 'Do you like the animated dialog?' , }; const animatedModalProps : IModalProps = { isDarkOverlay : true }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showAnimatedDialog } onDismiss = {() => { this . setState ({ showAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } > < DialogFooter > < PrimaryButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"Yes\" /> < DefaultButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"No\" /> < /DialogFooter> < /AnimatedDialog>","title":"1. Simple way"},{"location":"controls/AnimatedDialog/#simple-animated-dialog","text":"","title":"Simple animated dialog"},{"location":"controls/AnimatedDialog/#2-adding-custom-animations","text":"The code below adds adds a dialog with an entrance animation of fadeInDown and exit animation of fadeInDown . // Initial state this . state = { showAnimatedDialog : false } ... ... // Properties of the dialog const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog' , subText : 'Do you like the animated dialog?' , }; const animatedModalProps : IModalProps = { isDarkOverlay : true }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showAnimatedDialog } onDismiss = {() => { this . setState ({ showAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } dialogAnimationInType = 'fadeInDown' dialogAnimationOutType = 'fadeOutDown' > < DialogFooter > < PrimaryButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"Yes\" /> < DefaultButton onClick = {() => { this . setState ({ showAnimatedDialog : false }); }} text = \"No\" /> < /DialogFooter> < /AnimatedDialog>","title":"2. Adding custom animations"},{"location":"controls/AnimatedDialog/#animated-dialog-with-custom-animations","text":"","title":"Animated dialog with custom animations"},{"location":"controls/AnimatedDialog/#3-adding-icons-and-functions","text":"The code below does the following: - adds an icon (question mark) above the title - adds Yes and No buttons in the footer as showAnimatedDialogFooter is set to true . - passes 3 functions - onOkClick : The function that gets executed when the Ok/Yes button is clicked. - onSuccess : The function that gets executed on successful operation of the above function. - onError: The function that gets executed when the onOkClick function fails. // Initial state this . state = { showCustomisedAnimatedDialog : false , showSuccessDialog : false , showErrorDialog : false } ... ... const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Animated Dialog with icon' }; const successDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Good answer!' }; const animatedModalProps : IModalProps = { isDarkOverlay : true , containerClassName : ` ${ styles . dialogContainer } ` }; // The operation that does something - e.g. update data const timeout = ( ms : number ) : Promise < void > => { return new Promise (( resolve , reject ) => setTimeout ( resolve , ms )); }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showCustomisedAnimatedDialog } onDismiss = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } iconName = 'UnknownSolid' showAnimatedDialogFooter = { true } okButtonText = \"Yes\" cancelButtonText = \"No\" onOkClick = {() => timeout ( 1500 )} onSuccess = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showSuccessDialog : true }); }} onError = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showErrorDialog : true }); }} > < div className = { styles . dialogContent } > < span > Do you like the animated dialog ?< /span> < /div> < /AnimatedDialog> // Render success animated dialog which will appear after the execution // of onSuccess function in the above animated dialog < AnimatedDialog hidden = { ! this . state . showSuccessDialog } onDismiss = {() => { this . setState ({ showSuccessDialog : false }); }} dialogContentProps = { successDialogContentProps } modalProps = { animatedModalProps } iconName = 'CompletedSolid' > < div className = { styles . dialogContent } >< span > Thank you . < /span> < div className = { styles . resultDialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showSuccessDialog : false }); }} text = \"OK\" > < /PrimaryButton> < /div> < /AnimatedDialog>","title":"3. Adding icons and functions"},{"location":"controls/AnimatedDialog/#animated-dialog-with-icon","text":"","title":"Animated dialog with icon"},{"location":"controls/AnimatedDialog/#4-custom-footer","text":"If the dialog content and footer buttons need to be controlled by our code and not the animated dialog control then the code below can be used // Initial state this . state = { showCustomisedAnimatedDialog : false , showSuccessDialog : false , showErrorDialog : false , showLoading : false } ... ... const animatedDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Custom content and footer' }; const successDialogContentProps : IDialogContentProps = { type : DialogType . normal , title : 'Good answer!' }; const animatedModalProps : IModalProps = { isDarkOverlay : true , containerClassName : ` ${ styles . dialogContainer } ` }; ... ... // Add a control (like a button) that changes the state showAnimatedDialog to true //Render the animated dialog < AnimatedDialog hidden = { ! this . state . showCustomisedAnimatedDialog } onDismiss = {() => { this . setState ({ showCustomisedAnimatedDialog : false }); }} dialogContentProps = { animatedDialogContentProps } modalProps = { animatedModalProps } iconName = 'UnknownSolid' > < div className = { styles . dialogContent } > < span > Do you like the animated dialog ?< /span> < /div> < div className = { styles . dialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showLoading : true }); setTimeout (() => { this . setState ({ showLoading : true }); this . setState ({ showCustomisedAnimatedDialog : false }); this . setState ({ showSuccessDialog : true }); }, 1500 ); }} disabled = { this . state . showLoading } text = { ! this . state . showLoading && \"Yeah!\" } > { this . state . showLoading && < Spinner size = { SpinnerSize . medium } /> } < /PrimaryButton> < DefaultButton onClick = {() => this . setState ({ showCustomisedAnimatedDialog : false })} text = \"Nope\" disabled = { this . state . showLoading } /> < /div> < /AnimatedDialog> // Render success animated dialog which will appear after the execution // of the onClick function of the Button in the above animated dialog < AnimatedDialog hidden = { ! this . state . showSuccessDialog } onDismiss = {() => { this . setState ({ showSuccessDialog : false }); }} dialogContentProps = { successDialogContentProps } modalProps = { animatedModalProps } iconName = 'CompletedSolid' > < div className = { styles . dialogContent } >< span > Thank you . < /span> < div className = { styles . resultDialogFooter } > < PrimaryButton onClick = {() => { this . setState ({ showSuccessDialog : false }); }} text = \"OK\" > < /PrimaryButton> < /div> < /AnimatedDialog>","title":"4. Custom footer"},{"location":"controls/AnimatedDialog/#animated-dialog-with-custom-content-and-footer","text":"","title":"Animated dialog with custom content and footer"},{"location":"controls/AnimatedDialog/#scss-used-in-the-above-examples","text":"$themePrimary : '[theme:themePrimary, default:#0078d7]' ; .dialogContainer { border-top : 4px ; border-top-color : $ themePrimary ; border-top-style : solid ; min-width : 400px ; .dialogContent { text-align : center ; padding-bottom : 10px ; font-size : 1 .125em ; } .dialogFooter { text-align : right ; margin-top : 1 .25em ; button { min-width : 75px ; margin : 0px 10px ; border-radius : 5px ; } .loader { margin-top : 15px ; } } .resultDialogFooter { text-align : center ; margin-top : 1 .25em ; button { min-width : 100px ; margin : 0px 10px ; } } }","title":"SCSS used in the above examples"},{"location":"controls/AnimatedDialog/#implementation","text":"In addition to the Office UI Fabric dialog properties , the AnimatedDialog control can be configured with the following properties: Property Type Required Description Default dialogAnimationInType string no The name of the dialog entrace animation. See animate.css for values bounceIn dialogAnimationOutType string no The name of the dialog exit animation. See animate.css for values zoomOut iconName string no The name of the Fabric UI icon that appears above title. iconAnimationType string no The name of the icon entrace animation. See animate.css for values. zoomIn showAnimatedDialogFooter boolean no Should the animated dialog show it's own footer. See example 3 and 4 above for usage. false okButtonText string no The text of the the OK button if showAnimatedDialogFooter is true . See example 3 above for usage. Ok cancelButtonText string no The text of the the Cancel button if showAnimatedDialogFooter is true . See example 3 above for usage. Cancel onOkClick function no The function to be executed when Ok button is clicked. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage. onSuccess function no The function to be executed after successful execution of the OK button function. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage. onError function no The function to be executed after unsuccessful execution of the OK button function. Valid only when showAnimatedDialogFooter is true . See example 3 above for usage.","title":"Implementation"},{"location":"controls/Carousel/","text":"Carousel control \u00b6 A slideshow component for cycling through elements\u2014images or slides of text\u2014like a carousel. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Carousel } from \"@pnp/spfx-controls-react/lib/Carousel\" ; Use the Carousel control in your code as follows: Carousel component with provided JSX.Element[] slides < Carousel buttonsLocation = { CarouselButtonsLocation . top } buttonsDisplay = { CarouselButtonsDisplay . block } contentContainerStyles = { styles . carouselContent } containerButtonsStyles = { styles . carouselButtonsContainer } isInfinite = { true } element = { this . carouselElements } onMoveNextClicked = {( index : number ) => { console . log ( `Next button clicked: ${ index } ` ); }} onMovePrevClicked = {( index : number ) => { console . log ( `Prev button clicked: ${ index } ` ); }} /> Carousel component with provided triggerPageEvent < Carousel buttonsLocation = { CarouselButtonsLocation . bottom } buttonsDisplay = { CarouselButtonsDisplay . buttonsOnly } contentContainerStyles = { styles . carouselContent } containerButtonsStyles = { styles . carouselButtonsContainer } canMoveNext = { this . state . canMoveNext } canMovePrev = { this . state . canMovePrev } triggerPageEvent = { this . triggerNextElement } element = { this . state . currentCarouselElement } /> Carousel component with provided ICarouselImageProps[] slides: < Carousel buttonsLocation = { CarouselButtonsLocation . center } buttonsDisplay = { CarouselButtonsDisplay . buttonsOnly } contentContainerStyles = { styles . carouselImageContent } isInfinite = { true } indicatorShape = { CarouselIndicatorShape . circle } pauseOnHover = { true } element = {[ { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover }, { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover }, { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover } ]} onMoveNextClicked = {( index : number ) => { console . log ( `Next button clicked: ${ index } ` ); }} onMovePrevClicked = {( index : number ) => { console . log ( `Prev button clicked: ${ index } ` ); }} /> Implementation \u00b6 The Carousel component can be configured with the following properties: Property Type Required Description startIndex number no Specifies the initial index of the element to be displayed. isInfinite boolean no Indicates if infinite scrolling is enabled. canMoveNext boolean no Property indicates if the next item button can be clicked. If not provided, status of the button is calculated based on the current index. It is mandatory when triggerPageEvent is used. canMovePrev boolean no Property indicates if the previous item button can be clicked. If not provided, status of the button is calculated based on the current index. It is mandatory when triggerPageEvent is used. buttonsLocation CarouselButtonsLocation no Specifies the location of the buttons inside the container. Default: center buttonsDisplay CarouselButtonsDisplay no Specifies the buttons container display mode. Default: block containerStyles ICssInput no Allows to specify own styles for carousel container. loadingComponentContainerStyles ICssInput no Allows to specify own styles for loading component. contentContainerStyles ICssInput no Allows to specify own styles for elements container. containerButtonsStyles ICssInput no Allows to specify own styles for buttons container. prevButtonStyles ICssInput no Allows to specify own styles for previous item button. nextButtonStyles ICssInput no Allows to specify own styles for next item button. prevButtonIconName string no Name of the icon to be used for PreviousItem button. Default 'ChevronLeft'. nextButtonIconName string no Name of the icon to be used for NextItem button. Default 'ChevronRight'. triggerPageEvent (index: number) => void no Triggers parent control to provide new element to be displayed. After the method is executed, carousel control switches to processing mode and loadingComponent is displayed. element JSX.Element | JSX.Element[] yes Fixed array of elemenets to be displayed in carousel - if triggerPageEvent is not used. In case triggerPageEvent is in use, JSX.Element has to be provided. Elements are distinguished based on the 'key' property. loadingComponent JSX.Element no Allows to inject custom component when the carousel is in processing state. If not provided, Spinner is displayed. onMoveNextClicked (currentIndex: number) => void no Callback function called after the next item button is clicked. Not used when triggerPageEvent is specified. onMovePrevClicked (currentIndex: number) => void no Callback function called after the previous item button is clicked. Not used when triggerPageEvent is specified. elementsCount number no In case triggerPageEvent is in use, provides total number of slides in the carousel. onSelect (selectedIndex: number) => void no Callback function called when element has been selected in the carousel slide boolean no Enables animation on the Carousel as it transitions between slides. This property is ignored if triggerPageEvent is in use. interval number | null no The amount of time to delay between automatically cycling an item. If null, carousel will not automatically cycle. pauseOnHover boolean no Specifies if slides cycling should pause when hovering over the content (touchStart on touch devices). indicators boolean no Specifies if set of slide position indicators is shown. indicatorShape CarouselIndicatorShape no Specifies indicators' shape. If onRenderIndicator is provided - this property is ignored indicatorClassName string no Specifies additional class applied to slide position indicators indicatorStyle React.CSSProperties no Specifies additional styles applied to slide position indicators onRenderIndicator (index: number, onClick: (e: React.MouseEvent | React.TouchEvent, selectedIndex: number) => void) => JSX.Element no Function to render indicator element indicatorsDisplay CarouselIndicatorsDisplay no Specifies display mode of the indicators. Default value overlap . rootStyles ICssInput no Allows to specify own styles for root element indicatorsContainerStyles ICssInput no Allows to specify own styles for indicators container when indicatorsDisplay is set to \"block\" prevButtonAriaLabel string no Aria label of the PreviousItem button. Default 'Previous item'. nextButtonAriaLabel string no Aria label of the NextItem button. Default 'Next item'. contentHeight number no Allows to specify the height of the content. Can be used instead of providing styles for the content container ( contentContainerStyles ). enum CarouselButtonsLocation Provides options for carousel buttons location. Value Description top Buttons are going to be placed in the top of the control. center Buttons are going to be placed in the center of the control. bottom Buttons are going to be placed in the bottom of the control. enum CarouselButtonsDisplay Provides options for carousel buttons display mode. Value Description block Reserves space for buttons on both sides of the control. buttonsOnly Only icon buttons are displayed. hidden Buttons are not displayed. They appear onhover event. enum CarouselIndicatorShape Provides options for carousel indicators' shape. Value Description circle Indicators displayed as cirlces square Indicators displayed as squares rectangle Indicators displayed as rectangles enum CarouselIndicatorsDisplay Provides options for carousel indicators display mode. Value Description overlap Indicators are displayed on top of the carousel content block Reserves space for indicators Interface ICarouselImageProps Allows to easily render a set of CarouselImage components in the carousel Property Type Required Description imageSrc string yes Image source imageFit ImageFit no Specifies the method to be used to fit image. Default: ImageFit.none . See Fluent UI Image url string no URL to be opened when clicking on details title string no Title to display in details description string | JSX.Element no Description to show in details. Can be either a string (text) or JSX.Element to show HTML. target \"_blank\" | \"_self\" no Target of the URL to open. Default \"_blank\" showDetailsOnHover boolean no Specifies if the details are shown on hover or constantly className string no Class to apply to the component style React.CSSProperties no Styles to apply to the component imgClassName string no Class to apply to the image control imgStyle React.CSSProperties no Styles to apply to the image control detailsClassName string no Class to apply to the details control detailsStyle React.CSSProperties no Styles to apply to the details control titleClassName string no Class to apply to the title control titleStyle React.CSSProperties no Styles to apply to the title control descriptionClassName string no Class to apply to the description control descriptionStyle React.CSSProperties no Styles to apply to the description control","title":"Carousel"},{"location":"controls/Carousel/#carousel-control","text":"A slideshow component for cycling through elements\u2014images or slides of text\u2014like a carousel. Here is an example of the control in action:","title":"Carousel control"},{"location":"controls/Carousel/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Carousel } from \"@pnp/spfx-controls-react/lib/Carousel\" ; Use the Carousel control in your code as follows: Carousel component with provided JSX.Element[] slides < Carousel buttonsLocation = { CarouselButtonsLocation . top } buttonsDisplay = { CarouselButtonsDisplay . block } contentContainerStyles = { styles . carouselContent } containerButtonsStyles = { styles . carouselButtonsContainer } isInfinite = { true } element = { this . carouselElements } onMoveNextClicked = {( index : number ) => { console . log ( `Next button clicked: ${ index } ` ); }} onMovePrevClicked = {( index : number ) => { console . log ( `Prev button clicked: ${ index } ` ); }} /> Carousel component with provided triggerPageEvent < Carousel buttonsLocation = { CarouselButtonsLocation . bottom } buttonsDisplay = { CarouselButtonsDisplay . buttonsOnly } contentContainerStyles = { styles . carouselContent } containerButtonsStyles = { styles . carouselButtonsContainer } canMoveNext = { this . state . canMoveNext } canMovePrev = { this . state . canMovePrev } triggerPageEvent = { this . triggerNextElement } element = { this . state . currentCarouselElement } /> Carousel component with provided ICarouselImageProps[] slides: < Carousel buttonsLocation = { CarouselButtonsLocation . center } buttonsDisplay = { CarouselButtonsDisplay . buttonsOnly } contentContainerStyles = { styles . carouselImageContent } isInfinite = { true } indicatorShape = { CarouselIndicatorShape . circle } pauseOnHover = { true } element = {[ { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover }, { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover }, { imageSrc : 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80' , title : 'Colosseum' , description : 'This is Colosseum' , url : 'https://en.wikipedia.org/wiki/Colosseum' , showDetailsOnHover : true , imageFit : ImageFit.cover } ]} onMoveNextClicked = {( index : number ) => { console . log ( `Next button clicked: ${ index } ` ); }} onMovePrevClicked = {( index : number ) => { console . log ( `Prev button clicked: ${ index } ` ); }} />","title":"How to use this control in your solutions"},{"location":"controls/Carousel/#implementation","text":"The Carousel component can be configured with the following properties: Property Type Required Description startIndex number no Specifies the initial index of the element to be displayed. isInfinite boolean no Indicates if infinite scrolling is enabled. canMoveNext boolean no Property indicates if the next item button can be clicked. If not provided, status of the button is calculated based on the current index. It is mandatory when triggerPageEvent is used. canMovePrev boolean no Property indicates if the previous item button can be clicked. If not provided, status of the button is calculated based on the current index. It is mandatory when triggerPageEvent is used. buttonsLocation CarouselButtonsLocation no Specifies the location of the buttons inside the container. Default: center buttonsDisplay CarouselButtonsDisplay no Specifies the buttons container display mode. Default: block containerStyles ICssInput no Allows to specify own styles for carousel container. loadingComponentContainerStyles ICssInput no Allows to specify own styles for loading component. contentContainerStyles ICssInput no Allows to specify own styles for elements container. containerButtonsStyles ICssInput no Allows to specify own styles for buttons container. prevButtonStyles ICssInput no Allows to specify own styles for previous item button. nextButtonStyles ICssInput no Allows to specify own styles for next item button. prevButtonIconName string no Name of the icon to be used for PreviousItem button. Default 'ChevronLeft'. nextButtonIconName string no Name of the icon to be used for NextItem button. Default 'ChevronRight'. triggerPageEvent (index: number) => void no Triggers parent control to provide new element to be displayed. After the method is executed, carousel control switches to processing mode and loadingComponent is displayed. element JSX.Element | JSX.Element[] yes Fixed array of elemenets to be displayed in carousel - if triggerPageEvent is not used. In case triggerPageEvent is in use, JSX.Element has to be provided. Elements are distinguished based on the 'key' property. loadingComponent JSX.Element no Allows to inject custom component when the carousel is in processing state. If not provided, Spinner is displayed. onMoveNextClicked (currentIndex: number) => void no Callback function called after the next item button is clicked. Not used when triggerPageEvent is specified. onMovePrevClicked (currentIndex: number) => void no Callback function called after the previous item button is clicked. Not used when triggerPageEvent is specified. elementsCount number no In case triggerPageEvent is in use, provides total number of slides in the carousel. onSelect (selectedIndex: number) => void no Callback function called when element has been selected in the carousel slide boolean no Enables animation on the Carousel as it transitions between slides. This property is ignored if triggerPageEvent is in use. interval number | null no The amount of time to delay between automatically cycling an item. If null, carousel will not automatically cycle. pauseOnHover boolean no Specifies if slides cycling should pause when hovering over the content (touchStart on touch devices). indicators boolean no Specifies if set of slide position indicators is shown. indicatorShape CarouselIndicatorShape no Specifies indicators' shape. If onRenderIndicator is provided - this property is ignored indicatorClassName string no Specifies additional class applied to slide position indicators indicatorStyle React.CSSProperties no Specifies additional styles applied to slide position indicators onRenderIndicator (index: number, onClick: (e: React.MouseEvent | React.TouchEvent, selectedIndex: number) => void) => JSX.Element no Function to render indicator element indicatorsDisplay CarouselIndicatorsDisplay no Specifies display mode of the indicators. Default value overlap . rootStyles ICssInput no Allows to specify own styles for root element indicatorsContainerStyles ICssInput no Allows to specify own styles for indicators container when indicatorsDisplay is set to \"block\" prevButtonAriaLabel string no Aria label of the PreviousItem button. Default 'Previous item'. nextButtonAriaLabel string no Aria label of the NextItem button. Default 'Next item'. contentHeight number no Allows to specify the height of the content. Can be used instead of providing styles for the content container ( contentContainerStyles ). enum CarouselButtonsLocation Provides options for carousel buttons location. Value Description top Buttons are going to be placed in the top of the control. center Buttons are going to be placed in the center of the control. bottom Buttons are going to be placed in the bottom of the control. enum CarouselButtonsDisplay Provides options for carousel buttons display mode. Value Description block Reserves space for buttons on both sides of the control. buttonsOnly Only icon buttons are displayed. hidden Buttons are not displayed. They appear onhover event. enum CarouselIndicatorShape Provides options for carousel indicators' shape. Value Description circle Indicators displayed as cirlces square Indicators displayed as squares rectangle Indicators displayed as rectangles enum CarouselIndicatorsDisplay Provides options for carousel indicators display mode. Value Description overlap Indicators are displayed on top of the carousel content block Reserves space for indicators Interface ICarouselImageProps Allows to easily render a set of CarouselImage components in the carousel Property Type Required Description imageSrc string yes Image source imageFit ImageFit no Specifies the method to be used to fit image. Default: ImageFit.none . See Fluent UI Image url string no URL to be opened when clicking on details title string no Title to display in details description string | JSX.Element no Description to show in details. Can be either a string (text) or JSX.Element to show HTML. target \"_blank\" | \"_self\" no Target of the URL to open. Default \"_blank\" showDetailsOnHover boolean no Specifies if the details are shown on hover or constantly className string no Class to apply to the component style React.CSSProperties no Styles to apply to the component imgClassName string no Class to apply to the image control imgStyle React.CSSProperties no Styles to apply to the image control detailsClassName string no Class to apply to the details control detailsStyle React.CSSProperties no Styles to apply to the details control titleClassName string no Class to apply to the title control titleStyle React.CSSProperties no Styles to apply to the title control descriptionClassName string no Class to apply to the description control descriptionStyle React.CSSProperties no Styles to apply to the description control","title":"Implementation"},{"location":"controls/ChartControl/","text":"ChartControl control \u00b6 This control makes it easy to integrate Chart.js charts into your web parts. It offers most of the functionality available with Chart.js. The control automatically renders responsive charts, uses the environment's theme colors, and renders a hidden table for users with impaired vision. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Use the ChartControl control in your code as follows: < ChartControl type = { ChartType . Bar } data = {{ labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] }] }} /> Compatibility with Chart.js \u00b6 The majority of Chart.js its options like data , options , type , and plugins will work the same way as is -- except that you use TypeScript syntax. To find sample code that you can use, visit the Chart.Js documentation . For example, to reproduce following Javascript code sample from Chart.js : < canvas id = \"myChart\" width = \"400\" height = \"400\" > < script > var ctx = document . getElementById ( \"myChart\" ). getContext ( '2d' ); var myChart = new Chart ( ctx , { type : 'bar' , data : { labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(255, 206, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(255, 159, 64, 0.2)' ], borderColor : [ 'rgba(255,99,132,1)' , 'rgba(54, 162, 235, 1)' , 'rgba(255, 206, 86, 1)' , 'rgba(75, 192, 192, 1)' , 'rgba(153, 102, 255, 1)' , 'rgba(255, 159, 64, 1)' ], borderWidth : 1 }] }, options : { scales : { yAxes : [{ ticks : { beginAtZero : true } }] } } }); You would use the following Typescript code: < ChartControl type = { ChartType . Bar } data = {{ labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(255, 206, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(255, 159, 64, 0.2)' ], borderColor : [ 'rgba(255,99,132,1)' , 'rgba(54, 162, 235, 1)' , 'rgba(255, 206, 86, 1)' , 'rgba(75, 192, 192, 1)' , 'rgba(153, 102, 255, 1)' , 'rgba(255, 159, 64, 1)' ], borderWidth : 1 }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} /> The code above will produce the following chart: Specifying Data \u00b6 The data property typically consist of: labels : (Optional) An array of strings providing the data labels (e.g.: ['January', 'February', 'March', 'April', 'May', 'June', 'July'] ) datasets : At least one dataset, which contains: label : (Optional) A label for the data (e.g.: 'My First Dataset' ) data : An array of numbers (e.g.: [65, 59, 80, 81, 56, 55, 40] ) See below for more information on what types of data are required for each type of chart. Specifying Data Promises \u00b6 The ChartControl makes it easy to retrieve data asynchronously with the datapromise property. To use datapromise , add a function to your web part that returns a Promise as follows: private _loadAsyncData () : Promise < Chart . ChartData > { return new Promise < Chart . ChartData > (( resolve , reject ) => { // Call your own service -- this example returns an array of numbers // but you could call const dataProvider : IChartDataProvider = new MockChartDataProvider (); dataProvider . getNumberArray (). then (( numbers : number []) => { // format your response to ChartData const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ] datasets : [ { label : 'My First dataset' , data : numbers } ] }; // resolve the promise resolve ( data ); }); }); } Then, instead of passing a data property, pass your function to the datapromise property, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} /> If you want, you provide a template to display until the datapromise is resolved, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < div > Please wait ... < /div>} /> You can provide full React controls within the loadingtemplate . For example, to use the Office UI Fabric Spinner control, you would use the following code: import { Spinner , SpinnerSize } from 'office-ui-fabric-react/lib/Spinner' ; ... < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < Spinner size = { SpinnerSize . large } label = \"Loading...\" /> } /> You can also provide another template to display when the datapromise is rejected, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < Spinner size = { SpinnerSize . large } label = \"Loading...\" /> } rejectedtemplate = {( error : string ) => < div > Something went wrong : { error } < /div>} /> Theme Color Support \u00b6 By default, the ChartControl will attempt to use the environment theme colors and fonts for elements such as the chart background color, grid lines, titles, labels, legends, and tooltips. This includes support for dark themes and high contrast themes. If you wish, you can disable the use of themes by setting the useTheme property to false . Doing so will use the standard Chart.js colors and fonts. Office Color Palettes \u00b6 You can also simplify the majority of code samples by omitting the color properties; the ChartControl will automatically reproduce the color palette that you would get if you used Office to create the chart. < ChartControl type = { ChartType . Bar } data = {{ labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ] }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} /> You can also set the palette property to choose one of the Office color palettes. For example, Specifying ChartPalette.OfficeMonochromatic1 will produce the following chart: Responsiveness \u00b6 The ChartControl will automatically expand to fit its container. If you wish to control the size of the chart, set its parent container size, or use the className property to pass your own CSS class and override the dimensions within that class. Accessibility \u00b6 As long as you provide labels for all your data elements, the ChartControl will render a hidden table. Users who are visually impaired and use a screen reader will hear a description of the data in the chart. You can improve the accessible table by adding an alternateText , a caption and a summary . If you do not provide a caption , the control will attempt to use the chart's title. For example: < ChartControl type = { ChartType . Bar } accessible = {{ alternateText : 'Text alternative for this canvas graphic is in the data table below.' , summary : 'This is the text alternative for the canvas graphic.' , caption : 'Votes for favorite pets' }} data = {{ labels : [ \"Dog\" , \"Cat\" , \"Hamster\" , \"Gerbil\" , \"Hedgehog\" , \"Platypus\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ] }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} /> Implementation \u00b6 ChartControl Properties \u00b6 The ChartControl can be configured with the following properties: Property Type Required Description accessibility IChartAccessibility no Optional property to specify the accessibility options. className string no Optional property to specify a custom class that allows you to change the chart's styles. data ChartData no The data you wish to display. datapromise Promise no The promise to load data asynchronously. Use with loadingtemplate and rejectedtemplate loadingtemplate JSX.Element () => JSX.Element no The HTML to display while waiting to resolve the datapromise options ChartOptions no Optional property to set the chart's additional options. palette ChartPalette no Optional property to set the desired Office color paette plugins object[] no Optional property to set an array of objects implementing the IChartPlugin interface rejectedtemplate JSX.Element () => JSX.Element no The HTML to display if the datapromise promise returns an error. useTheme boolean no Optional property to set whether the ChartControl should attempt to use theme colors. Setting it to false will use the startard Chart.js colors and fonts. type ChartType or string yes The type of chart you wish to render. You can also use the string equivalent. onClick (event?: MouseEvent, activeElements?: Array<{}>) => void no Optional callback method that get called when a user clicks on the chart onHover (chart: Chart, event: MouseEvent, activeElements: Array<{}>) => void no Optional callback method that get called when a user hovers the chart onResize (chart: Chart, newSize: ChartSize) => void no Optional callback method that get called when the window containing the ChartXontrol resizes You can call the following methods to interact with the chart after it has been initialized: Method Type Description clear void Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful. getCanvas () => HTMLCanvasElement Return the canvass element that contains the chart getChart () => Chart Returns the Chart.js instance getDatasetAtEvent (e: MouseEvent) => Array<{}> Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting getElementAtEvent (e: MouseEvent) => {} Calling getElementAtEvent(event) passing an argument of an event will return the single element at the event position. For example, you can use with onClick event handlers. getElementsAtEvent (e: MouseEvent) => Array<{}> Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting. Calling getElementsAtEvent(event) passing an argument of an event will return the point elements that are at that the same position of that event. renderChart (config: {}) => void Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use .update() in that case. stop void Use this to stop any current animation loop. This will pause the chart during any current animation frame. toBase64Image () => string Returns a base 64 encoded string of the chart in it's current state. update (config?: number | boolean | string) => void Triggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart. ChartType \u00b6 Defines the type of chart that will be rendered. For more information what data structure is required for each type of chart, review the Chart.js documentation ( links below ). Name Chart.js Equivalent Description Bar bar Vertical bar chart Bubble bubble Bubble chart Doughnut doughnut Doughnut chart HorizontalBar horizontalBar Horizontal bar chart Line line Line chart Pie pie Pie chart PolarArea polarArea Polar area chart Radar radar Radar chart Scatter scatter Scatter graph IChartAccessibility \u00b6 The IChartAccessibility interface implements the following properties: Property Type Required Description alternateText string no Optional property to provide an accessible alternate text for the chart. We recommend that you use this property with summary className string no Optional property to specify a custom CSS class for the accessible table. caption string no Optional property to provide a caption for the accessible table. enable boolean no Optional property to turn on or off the rendering of the accessible table. summary string no Optional property to specify the chart's summary. We recommend that you use this property with alternateText onRenderTable () => JSX.Element no Options callback method that allows you to override the accessible table. ChartPalette \u00b6 Defines one of the possible Office color palette to use in a chart. The color palettes are the same that you find within Office. Name Office Name Description Example OfficeColorful1 Office Colorful Palette 1 Blue, Orange, Grey, Gold, Blue, Green OfficeColorful2 Office Colorful Palette 2 Blue, Grey, Blue, Dark Blue, Dark Grey, Dark Blue OfficeColorful3 Office Colorful Palette 3 Orange, Gold, Green, Brown, Dark Yellow, Dark Green OfficeColorful4 Office Colorful Palette 4 Green, Blue, Gold, Dark Green, Dark Blue, Dark Yellow OfficeMonochromatic1 Monochromatic Palette 1 Blue gradient, dark to light OfficeMonochromatic2 Monochromatic Palette 2 Orange gradient, dark to light OfficeMonochromatic3 Monochromatic Palette 3 Grey gradient, dark to light OfficeMonochromatic4 Monochromatic Palette 4 Gold gradient, dark to light OfficeMonochromatic5 Monochromatic Palette 5 Blue gradient, dark to light OfficeMonochromatic6 Monochromatic Palette 6 Green gradient, dark to light OfficeMonochromatic7 Monochromatic Palette 7 Dark Grey, Light Grey, Grey, Dark Grey, Light Grey, Grey OfficeMonochromatic8 Monochromatic Palette 8 Blue gradient, light to dark OfficeMonochromatic9 Monochromatic Palette 9 Orange gradient, light to dark OfficeMonochromatic10 Monochromatic Palette 10 Grey gradient, light to dark OfficeMonochromatic11 Monochromatic Palette 11 Gold gradient, light to dark OfficeMonochromatic12 Monochromatic Palette 12 Blue gradient, light to dark OfficeMonochromatic13 Monochromatic Palette 13 Green gradient, light to dark IChartPlugin \u00b6 The easiest way to customize a chart is to use the plugin functionality provided by Chart.js . In order to use a plugin, simply pass an array of objects that implement the IChartPlugin interface to the plugins property of the ChartControl. If a hook is listed as cancellable, you can return false to cancel the event. Property Type Required Description afterDatasetsDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called after the datasets are drawn but after scales are drawn. afterDatasetUpdate (chartInstance: Chart, options?: {}) => void no Called after a dataset was updated. afterDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called after an animation frame was drawn. afterEvent (chartInstance: Chart, event: Event, options?: {}) => void no Called after an event occurs on the chart. afterInit (chartInstance: Chart, options?: {}) => void no Called after a chart initializes afterLayout (chartInstance: Chart, options?: {}) => void no Called after the chart layout was rendered. afterRender (chartInstance: Chart, options?: {}) => void no Called after a rander. afterTooltipDraw (chartInstance: Chart, tooltipData?: {}, options?: {}) => void no Called after drawing the tooltip . Note that this hook will not be called if the tooltip drawing has been previously cancelled. afterUpdate (chartInstance: Chart, options?: {}) => void no Called after a chart updates beforeDatasetsDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called before the datasets are drawn but after scales are drawn. Cancellable. beforeDatasetUpdate (chartInstance: Chart, options?: {}) => void no Called before a dataset is updated. Cancellable. beforeDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called before an animation frame is drawn. beforeEvent (chartInstance: Chart, event: Event, options?: {}) => void no Called when an event occurs on the chart. Cancellable. beforeInit (chartInstance: Chart, options?: {}) => void no Called before a chart initializes beforeLayout (chartInstance: Chart, options?: {}) => void no Called before rendering the chart's layout. Cancellable. beforeRender (chartInstance: Chart, options?: {}) => void no Called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw to do something on each animation frame. Cancellable. beforeTooltipDraw (chartInstance: Chart, tooltipData?: {}, options?: {}) => void no Called before drawing the tooltip . Cancellable. If it returns false , tooltip drawing is cancelled until another render is triggered. beforeUpdate (chartInstance: Chart, options?: {}) => void no Called before updating the chart. Cancellable. destroy (chartInstance: Chart) => void no Called when a chart is destroyed. resize (chartInstance: Chart, newChartSize: Chart.ChartSize, options?: {}) => void no Called when a chart resizes. Cancellable.","title":"ChartControl"},{"location":"controls/ChartControl/#chartcontrol-control","text":"This control makes it easy to integrate Chart.js charts into your web parts. It offers most of the functionality available with Chart.js. The control automatically renders responsive charts, uses the environment's theme colors, and renders a hidden table for users with impaired vision. Here is an example of the control in action:","title":"ChartControl control"},{"location":"controls/ChartControl/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Use the ChartControl control in your code as follows: < ChartControl type = { ChartType . Bar } data = {{ labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] }] }} />","title":"How to use this control in your solutions"},{"location":"controls/ChartControl/#compatibility-with-chartjs","text":"The majority of Chart.js its options like data , options , type , and plugins will work the same way as is -- except that you use TypeScript syntax. To find sample code that you can use, visit the Chart.Js documentation . For example, to reproduce following Javascript code sample from Chart.js : < canvas id = \"myChart\" width = \"400\" height = \"400\" > < script > var ctx = document . getElementById ( \"myChart\" ). getContext ( '2d' ); var myChart = new Chart ( ctx , { type : 'bar' , data : { labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(255, 206, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(255, 159, 64, 0.2)' ], borderColor : [ 'rgba(255,99,132,1)' , 'rgba(54, 162, 235, 1)' , 'rgba(255, 206, 86, 1)' , 'rgba(75, 192, 192, 1)' , 'rgba(153, 102, 255, 1)' , 'rgba(255, 159, 64, 1)' ], borderWidth : 1 }] }, options : { scales : { yAxes : [{ ticks : { beginAtZero : true } }] } } }); You would use the following Typescript code: < ChartControl type = { ChartType . Bar } data = {{ labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(255, 206, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(255, 159, 64, 0.2)' ], borderColor : [ 'rgba(255,99,132,1)' , 'rgba(54, 162, 235, 1)' , 'rgba(255, 206, 86, 1)' , 'rgba(75, 192, 192, 1)' , 'rgba(153, 102, 255, 1)' , 'rgba(255, 159, 64, 1)' ], borderWidth : 1 }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} /> The code above will produce the following chart:","title":"Compatibility with Chart.js"},{"location":"controls/ChartControl/#specifying-data","text":"The data property typically consist of: labels : (Optional) An array of strings providing the data labels (e.g.: ['January', 'February', 'March', 'April', 'May', 'June', 'July'] ) datasets : At least one dataset, which contains: label : (Optional) A label for the data (e.g.: 'My First Dataset' ) data : An array of numbers (e.g.: [65, 59, 80, 81, 56, 55, 40] ) See below for more information on what types of data are required for each type of chart.","title":"Specifying Data"},{"location":"controls/ChartControl/#specifying-data-promises","text":"The ChartControl makes it easy to retrieve data asynchronously with the datapromise property. To use datapromise , add a function to your web part that returns a Promise as follows: private _loadAsyncData () : Promise < Chart . ChartData > { return new Promise < Chart . ChartData > (( resolve , reject ) => { // Call your own service -- this example returns an array of numbers // but you could call const dataProvider : IChartDataProvider = new MockChartDataProvider (); dataProvider . getNumberArray (). then (( numbers : number []) => { // format your response to ChartData const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ] datasets : [ { label : 'My First dataset' , data : numbers } ] }; // resolve the promise resolve ( data ); }); }); } Then, instead of passing a data property, pass your function to the datapromise property, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} /> If you want, you provide a template to display until the datapromise is resolved, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < div > Please wait ... < /div>} /> You can provide full React controls within the loadingtemplate . For example, to use the Office UI Fabric Spinner control, you would use the following code: import { Spinner , SpinnerSize } from 'office-ui-fabric-react/lib/Spinner' ; ... < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < Spinner size = { SpinnerSize . large } label = \"Loading...\" /> } /> You can also provide another template to display when the datapromise is rejected, as follows: < ChartControl type = 'bar' datapromise = { this . _loadAsyncData ()} loadingtemplate = {() => < Spinner size = { SpinnerSize . large } label = \"Loading...\" /> } rejectedtemplate = {( error : string ) => < div > Something went wrong : { error } < /div>} />","title":"Specifying Data Promises"},{"location":"controls/ChartControl/#theme-color-support","text":"By default, the ChartControl will attempt to use the environment theme colors and fonts for elements such as the chart background color, grid lines, titles, labels, legends, and tooltips. This includes support for dark themes and high contrast themes. If you wish, you can disable the use of themes by setting the useTheme property to false . Doing so will use the standard Chart.js colors and fonts.","title":"Theme Color Support"},{"location":"controls/ChartControl/#office-color-palettes","text":"You can also simplify the majority of code samples by omitting the color properties; the ChartControl will automatically reproduce the color palette that you would get if you used Office to create the chart. < ChartControl type = { ChartType . Bar } data = {{ labels : [ \"Red\" , \"Blue\" , \"Yellow\" , \"Green\" , \"Purple\" , \"Orange\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ] }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} /> You can also set the palette property to choose one of the Office color palettes. For example, Specifying ChartPalette.OfficeMonochromatic1 will produce the following chart:","title":"Office Color Palettes"},{"location":"controls/ChartControl/#responsiveness","text":"The ChartControl will automatically expand to fit its container. If you wish to control the size of the chart, set its parent container size, or use the className property to pass your own CSS class and override the dimensions within that class.","title":"Responsiveness"},{"location":"controls/ChartControl/#accessibility","text":"As long as you provide labels for all your data elements, the ChartControl will render a hidden table. Users who are visually impaired and use a screen reader will hear a description of the data in the chart. You can improve the accessible table by adding an alternateText , a caption and a summary . If you do not provide a caption , the control will attempt to use the chart's title. For example: < ChartControl type = { ChartType . Bar } accessible = {{ alternateText : 'Text alternative for this canvas graphic is in the data table below.' , summary : 'This is the text alternative for the canvas graphic.' , caption : 'Votes for favorite pets' }} data = {{ labels : [ \"Dog\" , \"Cat\" , \"Hamster\" , \"Gerbil\" , \"Hedgehog\" , \"Platypus\" ], datasets : [{ label : '# of Votes' , data : [ 12 , 19 , 3 , 5 , 2 , 3 ] }] }} options = {{ scales : { yAxes : [{ ticks : { beginAtZero : true } }] } }} />","title":"Accessibility"},{"location":"controls/ChartControl/#implementation","text":"","title":"Implementation"},{"location":"controls/ChartControl/#chartcontrol-properties","text":"The ChartControl can be configured with the following properties: Property Type Required Description accessibility IChartAccessibility no Optional property to specify the accessibility options. className string no Optional property to specify a custom class that allows you to change the chart's styles. data ChartData no The data you wish to display. datapromise Promise no The promise to load data asynchronously. Use with loadingtemplate and rejectedtemplate loadingtemplate JSX.Element () => JSX.Element no The HTML to display while waiting to resolve the datapromise options ChartOptions no Optional property to set the chart's additional options. palette ChartPalette no Optional property to set the desired Office color paette plugins object[] no Optional property to set an array of objects implementing the IChartPlugin interface rejectedtemplate JSX.Element () => JSX.Element no The HTML to display if the datapromise promise returns an error. useTheme boolean no Optional property to set whether the ChartControl should attempt to use theme colors. Setting it to false will use the startard Chart.js colors and fonts. type ChartType or string yes The type of chart you wish to render. You can also use the string equivalent. onClick (event?: MouseEvent, activeElements?: Array<{}>) => void no Optional callback method that get called when a user clicks on the chart onHover (chart: Chart, event: MouseEvent, activeElements: Array<{}>) => void no Optional callback method that get called when a user hovers the chart onResize (chart: Chart, newSize: ChartSize) => void no Optional callback method that get called when the window containing the ChartXontrol resizes You can call the following methods to interact with the chart after it has been initialized: Method Type Description clear void Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful. getCanvas () => HTMLCanvasElement Return the canvass element that contains the chart getChart () => Chart Returns the Chart.js instance getDatasetAtEvent (e: MouseEvent) => Array<{}> Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting getElementAtEvent (e: MouseEvent) => {} Calling getElementAtEvent(event) passing an argument of an event will return the single element at the event position. For example, you can use with onClick event handlers. getElementsAtEvent (e: MouseEvent) => Array<{}> Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting. Calling getElementsAtEvent(event) passing an argument of an event will return the point elements that are at that the same position of that event. renderChart (config: {}) => void Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use .update() in that case. stop void Use this to stop any current animation loop. This will pause the chart during any current animation frame. toBase64Image () => string Returns a base 64 encoded string of the chart in it's current state. update (config?: number | boolean | string) => void Triggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart.","title":"ChartControl Properties"},{"location":"controls/ChartControl/#charttype","text":"Defines the type of chart that will be rendered. For more information what data structure is required for each type of chart, review the Chart.js documentation ( links below ). Name Chart.js Equivalent Description Bar bar Vertical bar chart Bubble bubble Bubble chart Doughnut doughnut Doughnut chart HorizontalBar horizontalBar Horizontal bar chart Line line Line chart Pie pie Pie chart PolarArea polarArea Polar area chart Radar radar Radar chart Scatter scatter Scatter graph","title":"ChartType"},{"location":"controls/ChartControl/#ichartaccessibility","text":"The IChartAccessibility interface implements the following properties: Property Type Required Description alternateText string no Optional property to provide an accessible alternate text for the chart. We recommend that you use this property with summary className string no Optional property to specify a custom CSS class for the accessible table. caption string no Optional property to provide a caption for the accessible table. enable boolean no Optional property to turn on or off the rendering of the accessible table. summary string no Optional property to specify the chart's summary. We recommend that you use this property with alternateText onRenderTable () => JSX.Element no Options callback method that allows you to override the accessible table.","title":"IChartAccessibility"},{"location":"controls/ChartControl/#chartpalette","text":"Defines one of the possible Office color palette to use in a chart. The color palettes are the same that you find within Office. Name Office Name Description Example OfficeColorful1 Office Colorful Palette 1 Blue, Orange, Grey, Gold, Blue, Green OfficeColorful2 Office Colorful Palette 2 Blue, Grey, Blue, Dark Blue, Dark Grey, Dark Blue OfficeColorful3 Office Colorful Palette 3 Orange, Gold, Green, Brown, Dark Yellow, Dark Green OfficeColorful4 Office Colorful Palette 4 Green, Blue, Gold, Dark Green, Dark Blue, Dark Yellow OfficeMonochromatic1 Monochromatic Palette 1 Blue gradient, dark to light OfficeMonochromatic2 Monochromatic Palette 2 Orange gradient, dark to light OfficeMonochromatic3 Monochromatic Palette 3 Grey gradient, dark to light OfficeMonochromatic4 Monochromatic Palette 4 Gold gradient, dark to light OfficeMonochromatic5 Monochromatic Palette 5 Blue gradient, dark to light OfficeMonochromatic6 Monochromatic Palette 6 Green gradient, dark to light OfficeMonochromatic7 Monochromatic Palette 7 Dark Grey, Light Grey, Grey, Dark Grey, Light Grey, Grey OfficeMonochromatic8 Monochromatic Palette 8 Blue gradient, light to dark OfficeMonochromatic9 Monochromatic Palette 9 Orange gradient, light to dark OfficeMonochromatic10 Monochromatic Palette 10 Grey gradient, light to dark OfficeMonochromatic11 Monochromatic Palette 11 Gold gradient, light to dark OfficeMonochromatic12 Monochromatic Palette 12 Blue gradient, light to dark OfficeMonochromatic13 Monochromatic Palette 13 Green gradient, light to dark","title":"ChartPalette"},{"location":"controls/ChartControl/#ichartplugin","text":"The easiest way to customize a chart is to use the plugin functionality provided by Chart.js . In order to use a plugin, simply pass an array of objects that implement the IChartPlugin interface to the plugins property of the ChartControl. If a hook is listed as cancellable, you can return false to cancel the event. Property Type Required Description afterDatasetsDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called after the datasets are drawn but after scales are drawn. afterDatasetUpdate (chartInstance: Chart, options?: {}) => void no Called after a dataset was updated. afterDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called after an animation frame was drawn. afterEvent (chartInstance: Chart, event: Event, options?: {}) => void no Called after an event occurs on the chart. afterInit (chartInstance: Chart, options?: {}) => void no Called after a chart initializes afterLayout (chartInstance: Chart, options?: {}) => void no Called after the chart layout was rendered. afterRender (chartInstance: Chart, options?: {}) => void no Called after a rander. afterTooltipDraw (chartInstance: Chart, tooltipData?: {}, options?: {}) => void no Called after drawing the tooltip . Note that this hook will not be called if the tooltip drawing has been previously cancelled. afterUpdate (chartInstance: Chart, options?: {}) => void no Called after a chart updates beforeDatasetsDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called before the datasets are drawn but after scales are drawn. Cancellable. beforeDatasetUpdate (chartInstance: Chart, options?: {}) => void no Called before a dataset is updated. Cancellable. beforeDraw (chartInstance: Chart, easing: string, options?: {}) => void no Called before an animation frame is drawn. beforeEvent (chartInstance: Chart, event: Event, options?: {}) => void no Called when an event occurs on the chart. Cancellable. beforeInit (chartInstance: Chart, options?: {}) => void no Called before a chart initializes beforeLayout (chartInstance: Chart, options?: {}) => void no Called before rendering the chart's layout. Cancellable. beforeRender (chartInstance: Chart, options?: {}) => void no Called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw to do something on each animation frame. Cancellable. beforeTooltipDraw (chartInstance: Chart, tooltipData?: {}, options?: {}) => void no Called before drawing the tooltip . Cancellable. If it returns false , tooltip drawing is cancelled until another render is triggered. beforeUpdate (chartInstance: Chart, options?: {}) => void no Called before updating the chart. Cancellable. destroy (chartInstance: Chart) => void no Called when a chart is destroyed. resize (chartInstance: Chart, newChartSize: Chart.ChartSize, options?: {}) => void no Called when a chart resizes. Cancellable.","title":"IChartPlugin"},{"location":"controls/ComboBoxListItemPicker/","text":"ComboBoxListItemPicker control \u00b6 This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value. Here is an example of the control: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ComboBoxListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker' ; Use the ComboBoxListItemPicker control in your code as follows: < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' orderBy = 'Title asc' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> Use the ComboBoxListItemPicker with objects passed in defaultSelectedItems < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[{ Id : 2 , Title : \"Test\" }]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> Or only ids < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[ 2 ]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> The onSelectedItem change event returns the list items selected and can be implemented as follows: private onSelectedItem ( items : []) { console . log ( \"selected items:\" , items ); } If you can provide typing details to the implementation based on columnInternalName and keyColumnInternalName . For example above: columnInternalName = 'Title' keyColumnInternalName = 'Id' // ... private onSelectedItem ( items : { Title : string , Id : string }[]) { console . log ( \"selected items:\" , items ); } If you use variables for columnInternalName and keyColumnInternalName the typing will look as follow: const columnInternalName = 'Title' ; const keyColumnInternalName = 'Id' ; < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = { columnInternalName } keyColumnInternalName = { keyColumnInternalName } filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[ 2 ]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> private onSelectedItem ( items : { [ columnInternalName ] : string , [ keyColumnInternalName ] : string }[]) { console . log ( \"selected items:\" , items ); } Implementation \u00b6 The ComboBoxListItemPicker control can be configured with the following properties: Property Type Required Description columnInternalName string yes InternalName of column to search and get values. keyColumnInternalName string no InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id webUrl string yes Url to web hosting list spHttpClient RequestClient yes Any implementation of PnPJS RequestClient listId string yes Guid or title of the list. onSelectedItem (items: any[]) => void yes Callback function which returns the selected items. className string no ClassName for the picker. defaultSelectedItems any[] no Initial items that have already been selected and should appear in the people picker. Support objects and Ids only suggestionsHeaderText string no The text that should appear at the top of the suggestion box. noResultsFoundText string no The text that should appear when no results are returned. disabled boolean no Specifies if the control is disabled or not. filter string no Condition to filter list Item, same as $filter ODATA parameter multiSelect boolean no Allows multiple selection onInitialized () => void no Calls when component is ready itemLimit number no Maximum number of items to be displayed in the combobox. Default: 100 label string no Specifies the text describing the combobox ListItemPicker. orderBy string no Specifies the sequence of the items in the comboBox ,same as $orderBy ODATA parameter","title":"ComboBoxListItemPicker"},{"location":"controls/ComboBoxListItemPicker/#comboboxlistitempicker-control","text":"This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value. Here is an example of the control:","title":"ComboBoxListItemPicker control"},{"location":"controls/ComboBoxListItemPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ComboBoxListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker' ; Use the ComboBoxListItemPicker control in your code as follows: < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' orderBy = 'Title asc' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> Use the ComboBoxListItemPicker with objects passed in defaultSelectedItems < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[{ Id : 2 , Title : \"Test\" }]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> Or only ids < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[ 2 ]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> The onSelectedItem change event returns the list items selected and can be implemented as follows: private onSelectedItem ( items : []) { console . log ( \"selected items:\" , items ); } If you can provide typing details to the implementation based on columnInternalName and keyColumnInternalName . For example above: columnInternalName = 'Title' keyColumnInternalName = 'Id' // ... private onSelectedItem ( items : { Title : string , Id : string }[]) { console . log ( \"selected items:\" , items ); } If you use variables for columnInternalName and keyColumnInternalName the typing will look as follow: const columnInternalName = 'Title' ; const keyColumnInternalName = 'Id' ; < ComboBoxListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = { columnInternalName } keyColumnInternalName = { keyColumnInternalName } filter = \"Title eq 'SPFx'\" defaultSelectedItems = {[ 2 ]} onSelectedItem = { this . onSelectedItem } webUrl = { this . context . pageContext . web . absoluteUrl } spHttpClient = { this . context . spHttpClient } /> private onSelectedItem ( items : { [ columnInternalName ] : string , [ keyColumnInternalName ] : string }[]) { console . log ( \"selected items:\" , items ); }","title":"How to use this control in your solutions"},{"location":"controls/ComboBoxListItemPicker/#implementation","text":"The ComboBoxListItemPicker control can be configured with the following properties: Property Type Required Description columnInternalName string yes InternalName of column to search and get values. keyColumnInternalName string no InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id webUrl string yes Url to web hosting list spHttpClient RequestClient yes Any implementation of PnPJS RequestClient listId string yes Guid or title of the list. onSelectedItem (items: any[]) => void yes Callback function which returns the selected items. className string no ClassName for the picker. defaultSelectedItems any[] no Initial items that have already been selected and should appear in the people picker. Support objects and Ids only suggestionsHeaderText string no The text that should appear at the top of the suggestion box. noResultsFoundText string no The text that should appear when no results are returned. disabled boolean no Specifies if the control is disabled or not. filter string no Condition to filter list Item, same as $filter ODATA parameter multiSelect boolean no Allows multiple selection onInitialized () => void no Calls when component is ready itemLimit number no Maximum number of items to be displayed in the combobox. Default: 100 label string no Specifies the text describing the combobox ListItemPicker. orderBy string no Specifies the sequence of the items in the comboBox ,same as $orderBy ODATA parameter","title":"Implementation"},{"location":"controls/ContentTypePicker/","text":"ContentTypePicker control \u00b6 This control allows you to select one or multiple available site content types or list content types. Here is an example of the control: ContentTypePicker single selection mode: ContentTypePicker multi selection mode: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ContentTypePicker } from \"@pnp/spfx-controls-react/lib/ContentTypePicker\" ; Use the ContentTypePicker control in your code as follows: < ContentTypePicker context = { this . props . context } group = \"Content Feedback\" includeHidden = { false } includeReadOnly = { false } label = \"Select your content type\" multiSelect = { false } orderBy = { ContentTypesOrderBy . Name } listId = \"00000000-0000-0000-0000-000000000000\" onSelectionChanged = { this . onContentTypePickerChanged } showBlankOption = { true } /> The onSelectionChanged change event returns the content type(s) and can be implemented as follows: private onContentTypePickerChanged ( contentTypes : ISPContentType | ISPContentType []) { console . log ( \"Content types:\" , contentTypes ); } Implementation \u00b6 The ContentTypePicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string no The ID of the list or library you wish to select content type(s) from. When not specified, picker will be populated with site content types. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. includeHidden boolean no Whether or not to include hidden content types. Default is true. includeReadOnly boolean no Whether or not to include read-only content types. Default is true. group string no Only show content types of a certain group. filter string no Filter content types from OData query (takes the upperhand of hidden , readOnly and group Filters). orderBy ContentTypesOrderBy no How to order the content types. selectedContentTypes string | string[] no IDs of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Indicates if multi-choice selections is allowed. Default is false. label string no The label to display. placeholder string no Input placeholder text. Displayed until option is selected. onSelectionChanged (newValue: ISPContentType | ISPContentType[]): void no Callback issued when the selected option changes. filterItems (contentTypes: ISPContentType[]): ISPContentType[] no This function is invoked after the filtering has been done. This allows you to add additional custom filtering. webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). showBlankOption boolean no Whether or not to show a blank option. Default is false. Works only when multiSelect is false. Enum ContentTypesOrderBy Value Name Id","title":"ContentTypePicker"},{"location":"controls/ContentTypePicker/#contenttypepicker-control","text":"This control allows you to select one or multiple available site content types or list content types. Here is an example of the control: ContentTypePicker single selection mode: ContentTypePicker multi selection mode:","title":"ContentTypePicker control"},{"location":"controls/ContentTypePicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ContentTypePicker } from \"@pnp/spfx-controls-react/lib/ContentTypePicker\" ; Use the ContentTypePicker control in your code as follows: < ContentTypePicker context = { this . props . context } group = \"Content Feedback\" includeHidden = { false } includeReadOnly = { false } label = \"Select your content type\" multiSelect = { false } orderBy = { ContentTypesOrderBy . Name } listId = \"00000000-0000-0000-0000-000000000000\" onSelectionChanged = { this . onContentTypePickerChanged } showBlankOption = { true } /> The onSelectionChanged change event returns the content type(s) and can be implemented as follows: private onContentTypePickerChanged ( contentTypes : ISPContentType | ISPContentType []) { console . log ( \"Content types:\" , contentTypes ); }","title":"How to use this control in your solutions"},{"location":"controls/ContentTypePicker/#implementation","text":"The ContentTypePicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string no The ID of the list or library you wish to select content type(s) from. When not specified, picker will be populated with site content types. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. includeHidden boolean no Whether or not to include hidden content types. Default is true. includeReadOnly boolean no Whether or not to include read-only content types. Default is true. group string no Only show content types of a certain group. filter string no Filter content types from OData query (takes the upperhand of hidden , readOnly and group Filters). orderBy ContentTypesOrderBy no How to order the content types. selectedContentTypes string | string[] no IDs of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Indicates if multi-choice selections is allowed. Default is false. label string no The label to display. placeholder string no Input placeholder text. Displayed until option is selected. onSelectionChanged (newValue: ISPContentType | ISPContentType[]): void no Callback issued when the selected option changes. filterItems (contentTypes: ISPContentType[]): ISPContentType[] no This function is invoked after the filtering has been done. This allows you to add additional custom filtering. webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). showBlankOption boolean no Whether or not to show a blank option. Default is false. Works only when multiSelect is false. Enum ContentTypesOrderBy Value Name Id","title":"Implementation"},{"location":"controls/Dashboard/","text":"Dashboard control \u00b6 Dashboard component for Microsoft Teams. Note As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { WidgetSize , Dashboard } from '@pnp/spfx-controls-react/lib/Dashboard' ; Use the Dashboard control in your code as follows: const linkExample = { href : \"#\" }; const customizedLinkExample = { href : \"#\" , title : \"This is a customized link!\" , color : \"red\" , target : \"_top\" }; const calloutItemsExample = [ { id : \"action_1\" , title : \"Info\" , icon : < Icon iconName = { 'Edit' } /> , }, { id : \"action_2\" , title : \"Popup\" , icon : < Icon iconName = { 'Add' } /> }, ]; // ... < Dashboard widgets = {[{ title : \"Card 1\" , desc : \"Last updated Monday, April 4 at 11:15 AM (PT)\" , widgetActionGroup : calloutItemsExample , size : WidgetSize.Triple , body : [ { id : \"t1\" , title : \"Tab 1\" , content : ( < Text > Content # 1 < /Text> ), }, { id : \"t2\" , title : \"Tab 2\" , content : ( < Text > Content # 2 < /Text> ), }, { id : \"t3\" , title : \"Tab 3\" , content : ( < Text > Content # 3 < /Text> ), }, ], link : linkExample , }, { title : \"Card 2\" , size : WidgetSize.Single , link : customizedLinkExample , }, { title : \"Card 3\" , size : WidgetSize.Double , link : linkExample , }]} /> Implementation \u00b6 The Dashboard component can be configured with the following properties: Property Type Required Description widgets IWidget[] yes Widgets collection. allowHidingWidget boolean no Specifies if widgets can be hidden from the dashboard. onWidgetHiding (widget: IWidget) => void no Handler of widget hiding event. toolbarProps IToolbarProps no Dashboard toolbar props. See Toolbar . WidgetContentWrapper React.ComponentType\\ > no Optional component which wraps every Widget component. Useful for a custom error handling or styling. Interface IWidget Provides settings of Dashboard's widget Property Type Required Description size WidgetSize yes Size. title string yes Title. desc string no Description. widgetActionGroup IWidgetActionKey[] no Actions. controlOptions IWidgetControlOptions no Component rendering options. body IWidgetBodyContent[] no Widget's content (children) rendered as tabs. link IWidgetLink no Widget's link rendered at the bottom part of the widget. Interface IWidgetActionKey Provides Dashboard Widget Action properties Property Type Required Description id string yes Action id. icon JSX.Element no Action icon. title string yes Action title. onClick () => void no Action handler. Interface IWidgetControlOptions Provides Widget component options Property Type Required Description isHidden boolean no Specifies if current widget is hidden. Interface IWidgetBodyContent Provides Widget content (tab) properties Property Type Required Description id string yes Content (tab) id. title string yes Content (tab) title. content React.ReactNode yes Tab content. Interface IWidgetLink Provides Widget link properties Property Type Required Description href string yes Link to be opened. title string no The text to display for the link, if not provided, the default text will be used. color string no The color of the link, if not provided, the \"default\" color will be used. The available colors can be found on the official Fluent UI documentation of the Text control . target string no The target property value for the generated anchor tag, if not provided, the default target will be _blank . Enum WidgetSize Provides size of the widget Value Description Single Single-sized grid item. Double Double-width grid item. Triple Triple width grid item. Quadruple Quadruple width grid item. Box Double-width, double-height grid item.","title":"Dashboard"},{"location":"controls/Dashboard/#dashboard-control","text":"Dashboard component for Microsoft Teams. Note As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well. Here is an example of the control in action:","title":"Dashboard control"},{"location":"controls/Dashboard/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { WidgetSize , Dashboard } from '@pnp/spfx-controls-react/lib/Dashboard' ; Use the Dashboard control in your code as follows: const linkExample = { href : \"#\" }; const customizedLinkExample = { href : \"#\" , title : \"This is a customized link!\" , color : \"red\" , target : \"_top\" }; const calloutItemsExample = [ { id : \"action_1\" , title : \"Info\" , icon : < Icon iconName = { 'Edit' } /> , }, { id : \"action_2\" , title : \"Popup\" , icon : < Icon iconName = { 'Add' } /> }, ]; // ... < Dashboard widgets = {[{ title : \"Card 1\" , desc : \"Last updated Monday, April 4 at 11:15 AM (PT)\" , widgetActionGroup : calloutItemsExample , size : WidgetSize.Triple , body : [ { id : \"t1\" , title : \"Tab 1\" , content : ( < Text > Content # 1 < /Text> ), }, { id : \"t2\" , title : \"Tab 2\" , content : ( < Text > Content # 2 < /Text> ), }, { id : \"t3\" , title : \"Tab 3\" , content : ( < Text > Content # 3 < /Text> ), }, ], link : linkExample , }, { title : \"Card 2\" , size : WidgetSize.Single , link : customizedLinkExample , }, { title : \"Card 3\" , size : WidgetSize.Double , link : linkExample , }]} />","title":"How to use this control in your solutions"},{"location":"controls/Dashboard/#implementation","text":"The Dashboard component can be configured with the following properties: Property Type Required Description widgets IWidget[] yes Widgets collection. allowHidingWidget boolean no Specifies if widgets can be hidden from the dashboard. onWidgetHiding (widget: IWidget) => void no Handler of widget hiding event. toolbarProps IToolbarProps no Dashboard toolbar props. See Toolbar . WidgetContentWrapper React.ComponentType\\ > no Optional component which wraps every Widget component. Useful for a custom error handling or styling. Interface IWidget Provides settings of Dashboard's widget Property Type Required Description size WidgetSize yes Size. title string yes Title. desc string no Description. widgetActionGroup IWidgetActionKey[] no Actions. controlOptions IWidgetControlOptions no Component rendering options. body IWidgetBodyContent[] no Widget's content (children) rendered as tabs. link IWidgetLink no Widget's link rendered at the bottom part of the widget. Interface IWidgetActionKey Provides Dashboard Widget Action properties Property Type Required Description id string yes Action id. icon JSX.Element no Action icon. title string yes Action title. onClick () => void no Action handler. Interface IWidgetControlOptions Provides Widget component options Property Type Required Description isHidden boolean no Specifies if current widget is hidden. Interface IWidgetBodyContent Provides Widget content (tab) properties Property Type Required Description id string yes Content (tab) id. title string yes Content (tab) title. content React.ReactNode yes Tab content. Interface IWidgetLink Provides Widget link properties Property Type Required Description href string yes Link to be opened. title string no The text to display for the link, if not provided, the default text will be used. color string no The color of the link, if not provided, the \"default\" color will be used. The available colors can be found on the official Fluent UI documentation of the Text control . target string no The target property value for the generated anchor tag, if not provided, the default target will be _blank . Enum WidgetSize Provides size of the widget Value Description Single Single-sized grid item. Double Double-width grid item. Triple Triple width grid item. Quadruple Quadruple width grid item. Box Double-width, double-height grid item.","title":"Implementation"},{"location":"controls/DateTimePicker/","text":"DateTimePicker control \u00b6 This control allows you to select dates from a calendar and optionally the time of day using dropdown controls. You can configure the control to use 12 or 24-hour clock. Here are some examples of the control: DateTime Picker 12-hour clock DateTime Picker 24-hour clock DateTime Picker Date Only DateTime Picker No Seconds DateTime Picker Dropdowns for Time Part How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component. The DateConvention and TimeConvention controls if the time of day controls are shown and the time format used (12 hours/24 hours). import { DateTimePicker , DateConvention , TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker' ; Use the DateTimePicker control in your code as follows, either as an uncontrolled or a controlled component: // Uncontrolled < DateTimePicker label = \"DateTime Picker - 12h\" dateConvention = { DateConvention . DateTime } timeConvention = { TimeConvention . Hours12 } /> // Controlled < DateTimePicker label = \"DateTime Picker - 24h\" dateConvention = { DateConvention . DateTime } timeConvention = { TimeConvention . Hours24 } value = { this . state . date } onChange = { this . handleChange } /> Implementation \u00b6 The DateTimePicker control can be configured with the following properties: Property Type Required Description label string no Property field label displayed on top. disabled boolean no Specifies if the control is disabled or not. formatDate function no Defines a formatDate function that can override the output value in Date picker. parseDateFromString function no Optional method to parse the text input value to date, it is only useful when allowTextInput is set to true dateConvention DateConvention no Defines the date convention to use. The default is date and time. timeConvention TimeConvention no Defines the time convention to use. The default value is the 24-hour clock convention. firstDayOfWeek DayOfWeek no Specify the first day of the week for your locale. firstWeekOfYear FirstWeekOfYear no Defines when the first week of the year should start. key string no A unique key that indicates the identity of this control onGetErrorMessage function no The method is used to get the validation error message and determine whether the input value is valid or not. See this documentation to learn how to use it. showGoToToday boolean no Controls whether the \"Go to today\" link should be shown or not isMonthPickerVisible boolean no Controls whether the month picker is shown beside the day picker or hidden. showMonthPickerAsOverlay boolean no Show month picker on top of date picker when visible. showWeekNumbers boolean no Controls whether the calendar should show the week number (weeks 1 to 53) before each week row allowTextInput boolean no Whether the user is allowed to enter a date as text instead of picking one from the date picker. strings IDatePickerStrings no Localized strings to use in the DateTimePicker value Date no Default value of the DatePicker, if any onChange function no Callback issued when date or time is changed showSeconds boolean no Specifies, if seconds dropdown should be shown, defaults to false. timeDisplayControlType TimeDisplayControlType no Specifies what type of control to use when rendering time part. showLabels boolean no Specifies if labels in front of date and time parts should be rendered. placeholder string no Placeholder text for the DatePicker. initialPickerDate Date no The initially highlighted date in the calendar picker maxDate Date no The maximum allowable date. minDate Date no The minimum allowable date. minutesIncrementStep MinutesIncrement no Specifies minutes' increment step for TimeDisplayControlType.Dropdow showClearDate boolean no Controls whether the clearDate iconbutton must be available when date is selected, default to false showClearDateIcon string no Controls the icon used for clearDate iconbutton. Defaults to 'RemoveEvent' restrictedDates Date[] no If set the Calendar will not allow selection of dates in this array. Enum TimeDisplayControlType Name Description Text Renders Time part as Masked Edit Dropdown Renders Time part as Dropdown Enum DateConvention Name Description DateTime Shows the date and time picker Date Shows only the date picker Enum TimeConvention Name Description Hours12 Specify the hours in 12-hours (AM / PM) time convention. Hours24 Specify the hours in 24-hours time convention. Interface IDateTimePickerStrings extends IDatePickerStrings Property Type Required Description dateLabel string no Label for the date selector. timeLabel string no Label for the time of day selector. timeSeparator string no Separator between time of day components (hours, minutes, seconds). amDesignator string no Used as AM designator when 12-hour clock is used. pmDesignator string no Used as PM designator when 12-hour clock is used. textErrorMessage string no Error message when text is entered in the date picker. Type MinutesIncrement type MinutesIncrement = 1 | 5 | 10 | 15 | 30 ;","title":"DateTimePicker"},{"location":"controls/DateTimePicker/#datetimepicker-control","text":"This control allows you to select dates from a calendar and optionally the time of day using dropdown controls. You can configure the control to use 12 or 24-hour clock. Here are some examples of the control: DateTime Picker 12-hour clock DateTime Picker 24-hour clock DateTime Picker Date Only DateTime Picker No Seconds DateTime Picker Dropdowns for Time Part","title":"DateTimePicker control"},{"location":"controls/DateTimePicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component. The DateConvention and TimeConvention controls if the time of day controls are shown and the time format used (12 hours/24 hours). import { DateTimePicker , DateConvention , TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker' ; Use the DateTimePicker control in your code as follows, either as an uncontrolled or a controlled component: // Uncontrolled < DateTimePicker label = \"DateTime Picker - 12h\" dateConvention = { DateConvention . DateTime } timeConvention = { TimeConvention . Hours12 } /> // Controlled < DateTimePicker label = \"DateTime Picker - 24h\" dateConvention = { DateConvention . DateTime } timeConvention = { TimeConvention . Hours24 } value = { this . state . date } onChange = { this . handleChange } />","title":"How to use this control in your solutions"},{"location":"controls/DateTimePicker/#implementation","text":"The DateTimePicker control can be configured with the following properties: Property Type Required Description label string no Property field label displayed on top. disabled boolean no Specifies if the control is disabled or not. formatDate function no Defines a formatDate function that can override the output value in Date picker. parseDateFromString function no Optional method to parse the text input value to date, it is only useful when allowTextInput is set to true dateConvention DateConvention no Defines the date convention to use. The default is date and time. timeConvention TimeConvention no Defines the time convention to use. The default value is the 24-hour clock convention. firstDayOfWeek DayOfWeek no Specify the first day of the week for your locale. firstWeekOfYear FirstWeekOfYear no Defines when the first week of the year should start. key string no A unique key that indicates the identity of this control onGetErrorMessage function no The method is used to get the validation error message and determine whether the input value is valid or not. See this documentation to learn how to use it. showGoToToday boolean no Controls whether the \"Go to today\" link should be shown or not isMonthPickerVisible boolean no Controls whether the month picker is shown beside the day picker or hidden. showMonthPickerAsOverlay boolean no Show month picker on top of date picker when visible. showWeekNumbers boolean no Controls whether the calendar should show the week number (weeks 1 to 53) before each week row allowTextInput boolean no Whether the user is allowed to enter a date as text instead of picking one from the date picker. strings IDatePickerStrings no Localized strings to use in the DateTimePicker value Date no Default value of the DatePicker, if any onChange function no Callback issued when date or time is changed showSeconds boolean no Specifies, if seconds dropdown should be shown, defaults to false. timeDisplayControlType TimeDisplayControlType no Specifies what type of control to use when rendering time part. showLabels boolean no Specifies if labels in front of date and time parts should be rendered. placeholder string no Placeholder text for the DatePicker. initialPickerDate Date no The initially highlighted date in the calendar picker maxDate Date no The maximum allowable date. minDate Date no The minimum allowable date. minutesIncrementStep MinutesIncrement no Specifies minutes' increment step for TimeDisplayControlType.Dropdow showClearDate boolean no Controls whether the clearDate iconbutton must be available when date is selected, default to false showClearDateIcon string no Controls the icon used for clearDate iconbutton. Defaults to 'RemoveEvent' restrictedDates Date[] no If set the Calendar will not allow selection of dates in this array. Enum TimeDisplayControlType Name Description Text Renders Time part as Masked Edit Dropdown Renders Time part as Dropdown Enum DateConvention Name Description DateTime Shows the date and time picker Date Shows only the date picker Enum TimeConvention Name Description Hours12 Specify the hours in 12-hours (AM / PM) time convention. Hours24 Specify the hours in 24-hours time convention. Interface IDateTimePickerStrings extends IDatePickerStrings Property Type Required Description dateLabel string no Label for the date selector. timeLabel string no Label for the time of day selector. timeSeparator string no Separator between time of day components (hours, minutes, seconds). amDesignator string no Used as AM designator when 12-hour clock is used. pmDesignator string no Used as PM designator when 12-hour clock is used. textErrorMessage string no Error message when text is entered in the date picker. Type MinutesIncrement type MinutesIncrement = 1 | 5 | 10 | 15 | 30 ;","title":"Implementation"},{"location":"controls/DragDropFiles/","text":"DragDropFiles \u00b6 This control allows to drag and drop files in pre defined areas. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { DragDropFiles } from \"@pnp/spfx-controls-react/lib/DragDropFiles\" ; Use the DragDropFiles control in your code as follows: < DragDropFiles dropEffect = \"copy\" enable = { true } onDrop = { this . _getDropFiles } iconName = \"Upload\" labelMessage = \"My custom upload File\" > { /* Specify the components to load where Drag and drop area should work */ } Content with drag and drop applied < DragDropFiles dropEffect = \"copy\" enable = { true } onDrop = { this . _getDropFiles } iconName = \"Upload\" labelMessage = \"My custom upload File\" > Drag and drop here ... ListView with drag and drop applied FilePicker with drag and drop applied With the onDrop handler you can define a method that returns files and files inside folders that where drag and drop by user. PS: New property \"fullPath\" was included in file object to allow identify dropped files based on Folders, this allow users to create associated folder path. private _getDropFiles = ( files ) => { for ( var i = 0 ; i < files . length ; i ++ ) { console . log ( \"Filename: \" + files [ i ]. name ); console . log ( \"Path: \" + files [ i ]. fullPath ); } } Implementation \u00b6 The DragDropFiles can be configured with the following properties: Property Type Required Description dropEffect string no Visual feedback given to user during a drag and drop operation (copy,move,link,none). Default value is copy . enable boolean no Option allow control to be enable or disable. Default value is true labelMessage string no Message displayed in drag drop preview. onDrop any no Method that returns all Files[] from drag and drop file area. iconName string no Icon Name from Office UI Fabric Icons.","title":"DragDropFiles"},{"location":"controls/DragDropFiles/#dragdropfiles","text":"This control allows to drag and drop files in pre defined areas.","title":"DragDropFiles"},{"location":"controls/DragDropFiles/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { DragDropFiles } from \"@pnp/spfx-controls-react/lib/DragDropFiles\" ; Use the DragDropFiles control in your code as follows: < DragDropFiles dropEffect = \"copy\" enable = { true } onDrop = { this . _getDropFiles } iconName = \"Upload\" labelMessage = \"My custom upload File\" > { /* Specify the components to load where Drag and drop area should work */ } Content with drag and drop applied < DragDropFiles dropEffect = \"copy\" enable = { true } onDrop = { this . _getDropFiles } iconName = \"Upload\" labelMessage = \"My custom upload File\" > Drag and drop here ... ListView with drag and drop applied FilePicker with drag and drop applied With the onDrop handler you can define a method that returns files and files inside folders that where drag and drop by user. PS: New property \"fullPath\" was included in file object to allow identify dropped files based on Folders, this allow users to create associated folder path. private _getDropFiles = ( files ) => { for ( var i = 0 ; i < files . length ; i ++ ) { console . log ( \"Filename: \" + files [ i ]. name ); console . log ( \"Path: \" + files [ i ]. fullPath ); } }","title":"How to use this control in your solutions"},{"location":"controls/DragDropFiles/#implementation","text":"The DragDropFiles can be configured with the following properties: Property Type Required Description dropEffect string no Visual feedback given to user during a drag and drop operation (copy,move,link,none). Default value is copy . enable boolean no Option allow control to be enable or disable. Default value is true labelMessage string no Message displayed in drag drop preview. onDrop any no Method that returns all Files[] from drag and drop file area. iconName string no Icon Name from Office UI Fabric Icons.","title":"Implementation"},{"location":"controls/DynamicForm/","text":"Dynamic Form \u00b6 This control can dynamically generate SharePoint list or SharePoint document library form and everything controlled through list setting. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { DynamicForm } from \"@pnp/spfx-controls-react/lib/DynamicForm\" ; Use the DynamicForm control in your code as follows: < DynamicForm context = { this . props . context } listId = { \"3071c058-549f-461d-9d73-8b9a52049a80\" } listItemId = { 1 } onCancelled = {() => { console . log ( 'Cancelled' ) }} onBeforeSubmit = { async ( listItem ) => { return false ; }} onSubmitError = {( listItem , error ) => { alert ( error . message ); }} onSubmitted = { async ( listItemData ) => { console . log ( listItemData ); }}> File selection \u00b6 To upload a file when creating a new document in a document library you need to specify: - enableFileSelection: Set this parameter to true to enable file selection. - contentTypeId: This parameter specifies the target content type ID of the document you are creating. - supportedFileExtensions: This parameter is optional and is used to specify the supported file extensions if they are different from the default ones. Enabling the file selection will display a new button on top of the form that allow the user to select a file from the recent files, browsing OneDrive or select and upload a file from the computer. Implementation \u00b6 The DynamicForm can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string yes Guid of the list. listItemId number no list item ID. contentTypeId string no content type ID disabled boolean no Allows form to be disabled. Default value is false disabledFields string[] no InternalName of fields that should be disabled. Default value is false enableFileSelection boolean no Specify if the form should support the creation of a new list item in a document library attaching a file to it. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document. Default value is false fieldOrder string[] no List of fields internal names. Specifies fields custom sorting. hiddenFields string[] no InternalName of fields that should be hidden. Default value is false onListItemLoaded (listItemData: any) => Promise no List item loaded handler. Allows to access list item information after it's loaded. onBeforeSubmit (listItemData: any) => Promise no Before submit handler. Allows to modify the object to be submitted or cancel the submission. To cancel, return true . onSubmitted (listItemData: any, listItem?: IItem) => void no Method that returns listItem data JSON object and PnPJS list item instance ( IItem ). onSubmitError (listItemData: any, error: Error) => void no Handler of submission error. onCancelled () => void no Handler when form has been cancelled. returnListItemInstanceOnSubmit boolean no Specifies if onSubmitted event should pass PnPJS list item ( IItem ) as a second parameter. Default - true supportedFileExtensions string[] no Specify the supported file extensions for the file picker. Only used when enableFileSelection is true . Default value is [\"docx\", \"doc\", \"pptx\", \"ppt\", \"xlsx\", \"xls\", \"pdf\"] . webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). fieldOverrides {[columnInternalName: string] : {(fieldProperties: IDynamicFieldProps): React.ReactElement\\}} no Key value pair for fields you want to override. Key is the internal field name, value is the function to be called for the custom element to render. respectEtag boolean no Specifies if the form should respect the ETag of the item. Default - true saveDisabled boolean no Specifies if save button is disabled. validationErrorDialogProps IValidationErrorDialogProps no Specifies validation error dialog properties customIcons { [ columnInternalName: string ]: string } no Specifies custom icons for the form. The key of this dictionary is the column internal name, the value is the Fluent UI icon name. storeLastActiveTab boolean no When uploading files: Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default - true folderPath string no Server relative or library relative folder to create the item in. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document or Folder. Defaults to the root folder of the library. Validation Error Dialog Properties IValidationErrorDialogProps \u00b6 Property Type Required Description showDialogOnValidationError boolean no Specifies if the dialog should be shown on validation error. Default - false customTitle string no Specifies a custom title to be shown in the validation dialog. Default - empty customMessage string no Specifies a custom message to be shown in the validation dialog. Default - empty","title":"DynamicForm"},{"location":"controls/DynamicForm/#dynamic-form","text":"This control can dynamically generate SharePoint list or SharePoint document library form and everything controlled through list setting.","title":"Dynamic Form"},{"location":"controls/DynamicForm/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { DynamicForm } from \"@pnp/spfx-controls-react/lib/DynamicForm\" ; Use the DynamicForm control in your code as follows: < DynamicForm context = { this . props . context } listId = { \"3071c058-549f-461d-9d73-8b9a52049a80\" } listItemId = { 1 } onCancelled = {() => { console . log ( 'Cancelled' ) }} onBeforeSubmit = { async ( listItem ) => { return false ; }} onSubmitError = {( listItem , error ) => { alert ( error . message ); }} onSubmitted = { async ( listItemData ) => { console . log ( listItemData ); }}> ","title":"How to use this control in your solutions"},{"location":"controls/DynamicForm/#file-selection","text":"To upload a file when creating a new document in a document library you need to specify: - enableFileSelection: Set this parameter to true to enable file selection. - contentTypeId: This parameter specifies the target content type ID of the document you are creating. - supportedFileExtensions: This parameter is optional and is used to specify the supported file extensions if they are different from the default ones. Enabling the file selection will display a new button on top of the form that allow the user to select a file from the recent files, browsing OneDrive or select and upload a file from the computer.","title":"File selection"},{"location":"controls/DynamicForm/#implementation","text":"The DynamicForm can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string yes Guid of the list. listItemId number no list item ID. contentTypeId string no content type ID disabled boolean no Allows form to be disabled. Default value is false disabledFields string[] no InternalName of fields that should be disabled. Default value is false enableFileSelection boolean no Specify if the form should support the creation of a new list item in a document library attaching a file to it. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document. Default value is false fieldOrder string[] no List of fields internal names. Specifies fields custom sorting. hiddenFields string[] no InternalName of fields that should be hidden. Default value is false onListItemLoaded (listItemData: any) => Promise no List item loaded handler. Allows to access list item information after it's loaded. onBeforeSubmit (listItemData: any) => Promise no Before submit handler. Allows to modify the object to be submitted or cancel the submission. To cancel, return true . onSubmitted (listItemData: any, listItem?: IItem) => void no Method that returns listItem data JSON object and PnPJS list item instance ( IItem ). onSubmitError (listItemData: any, error: Error) => void no Handler of submission error. onCancelled () => void no Handler when form has been cancelled. returnListItemInstanceOnSubmit boolean no Specifies if onSubmitted event should pass PnPJS list item ( IItem ) as a second parameter. Default - true supportedFileExtensions string[] no Specify the supported file extensions for the file picker. Only used when enableFileSelection is true . Default value is [\"docx\", \"doc\", \"pptx\", \"ppt\", \"xlsx\", \"xls\", \"pdf\"] . webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). fieldOverrides {[columnInternalName: string] : {(fieldProperties: IDynamicFieldProps): React.ReactElement\\}} no Key value pair for fields you want to override. Key is the internal field name, value is the function to be called for the custom element to render. respectEtag boolean no Specifies if the form should respect the ETag of the item. Default - true saveDisabled boolean no Specifies if save button is disabled. validationErrorDialogProps IValidationErrorDialogProps no Specifies validation error dialog properties customIcons { [ columnInternalName: string ]: string } no Specifies custom icons for the form. The key of this dictionary is the column internal name, the value is the Fluent UI icon name. storeLastActiveTab boolean no When uploading files: Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default - true folderPath string no Server relative or library relative folder to create the item in. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document or Folder. Defaults to the root folder of the library.","title":"Implementation"},{"location":"controls/DynamicForm/#validation-error-dialog-properties-ivalidationerrordialogprops","text":"Property Type Required Description showDialogOnValidationError boolean no Specifies if the dialog should be shown on validation error. Default - false customTitle string no Specifies a custom title to be shown in the validation dialog. Default - empty customMessage string no Specifies a custom message to be shown in the validation dialog. Default - empty","title":"Validation Error Dialog Properties IValidationErrorDialogProps"},{"location":"controls/EnhancedThemeProvider/","text":"Enhanced Theme Provider \u00b6 The reasons behind this control are many and concern the use of Fluent UI controls currently officially supported by SPFx, that is: Problems with Teams theme support , when hosting a web part like Tab or Personal App and specifically the lack of support by this version of Fluent UI React of the high contrast theme. Lack of basic style , such as fonts, for basic HTML elements when creating web parts hosted in Teams as Tabs or personal App . Lack of basic style, such as fonts, for basic HTML elements when creating web parts in \"isDomainIsolated\" mode , aka the Isolated web parts. Therefore, the control is to be considered as a sort of wrapper for all react and non-react controls that you want to add to the web part. The control extends the functionality of the Fluent UI ThemeProvider control (currently in version 7) by adding some logic thanks to the information contained in the 'context' property, that is: If the web part is hosted inside SharePoint, the theme passed through the 'Theme' property will be used or the default one of the current site will be taken. If the web part is hosted within Teams, the \"Theme\" property will be ignored and using the \"Context\" property checks which theme is currently applied and adds a handler to notify when the theme is changed. This allows you to manage the change of theme in Teams in real-time, without having to reload the Tab or the Personal App. Example of use in SharePoint in a SharePointFullPage - Isolated web parts (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control): As for Teams, given the inconsistency of the theme system of Fluent UI NorthStar (used in Teams) and Fluent UI React (used by SPFx), the themes are \"emulated\". The control contains the refining of Teams' Default , Dark and Hight Contrast themes. The Default and Dark themes were created simply using the Fluent UI Themes designer and the primary colors of their corresponding Teams themes. For the Hight Contrast theme, on the other hand, given the complexity of creating a completely new theme and above all in Hight Contrast mode (neither supported nor gives SharePoint nor gives Fluent UI v7), it was decided to create the theme by hand and support only \"main controls\". This means that this theme is not perfect and above all not all controls will be displayed correctly. This is not a big deal, as the same theme provided by SharePoint has the same problems, it does not support Hight Contrast rendering for all controls. For the Hight Contrast theme (in Teams), only these controls are supported by this control: ChoiceGroup, Checkbox, ComboBox, DatePicker, SpinButton, TextField, Toggle, PrimaryButton, DefaultButton, CompoundButton, IconButton , other fluent controls may have color rendering problems. Example of use in Teams as a TeamsPersonalApp (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control): How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the EnhancedThemeProvider control as follows: import { EnhancedThemeProvider , getDefaultTheme , useTheme , ThemeContext } from \"@pnp/spfx-controls-react/lib/EnhancedThemeProvider\" ; Example on use the EnhancedThemeProvider control with only required properties: < EnhancedThemeProvider context = { this . props . context } > { /* controls to apply the theme to */ } < /EnhancedThemeProvider> Example on use the EnhancedThemeProvider control with the most important properties: < EnhancedThemeProvider applyTo = \"element\" context = { this . props . context } theme = { this . props . themeVariant } > { /* controls to apply the theme to */ } < /EnhancedThemeProvider> The control provides the passage and/or creation of the theme according to what has been said before. In order to access the theme, from child controls, there are two modes, one for function-based controls, one for class-based controls. Access the theme from the child control using a function component: export const ChildFunctionComponent = () => { const theme = useTheme (); return ( < DefaultButton theme = { theme } > Example Child Control < /DefaultButton> ); } Access the theme from the child control using a class component: export class ChildClassComponent extends React . Component { public render () { return ( < ThemeContext . Consumer > { theme => < DefaultButton theme = { theme } > Example Child Control < /DefaultButton> } < /ThemeContext.Consumer> ) } }; Usage example using theme in child controls: < EnhancedThemeProvider applyTo = \"element\" context = { this . props . context } theme = { this . props . themeVariant } > < ChildFunctionComponent /> < ChildClassComponent /> < /EnhancedThemeProvider> Implementation \u00b6 The EnhancedThemeProvider control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Sets the context from the SPFx component (a web part, an application customizer or a form customizer). as React.ElementType no A component that should be used as the root element of the ThemeProvider component. ref React.Ref no Optional ref to the root element. theme PartialTheme | Theme no Defines the theme provided by the user. renderer StyleRenderer no Optional interface for registering dynamic styles. Defaults to using merge-styles . Use this to opt into a particular rendering implementation, such as emotion , styled-components , or jss . Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation. applyTo 'element' | 'body' | 'none' no Defines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of ThemeProvider. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body.","title":"EnhancedThemeProvider"},{"location":"controls/EnhancedThemeProvider/#enhanced-theme-provider","text":"The reasons behind this control are many and concern the use of Fluent UI controls currently officially supported by SPFx, that is: Problems with Teams theme support , when hosting a web part like Tab or Personal App and specifically the lack of support by this version of Fluent UI React of the high contrast theme. Lack of basic style , such as fonts, for basic HTML elements when creating web parts hosted in Teams as Tabs or personal App . Lack of basic style, such as fonts, for basic HTML elements when creating web parts in \"isDomainIsolated\" mode , aka the Isolated web parts. Therefore, the control is to be considered as a sort of wrapper for all react and non-react controls that you want to add to the web part. The control extends the functionality of the Fluent UI ThemeProvider control (currently in version 7) by adding some logic thanks to the information contained in the 'context' property, that is: If the web part is hosted inside SharePoint, the theme passed through the 'Theme' property will be used or the default one of the current site will be taken. If the web part is hosted within Teams, the \"Theme\" property will be ignored and using the \"Context\" property checks which theme is currently applied and adds a handler to notify when the theme is changed. This allows you to manage the change of theme in Teams in real-time, without having to reload the Tab or the Personal App. Example of use in SharePoint in a SharePointFullPage - Isolated web parts (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control): As for Teams, given the inconsistency of the theme system of Fluent UI NorthStar (used in Teams) and Fluent UI React (used by SPFx), the themes are \"emulated\". The control contains the refining of Teams' Default , Dark and Hight Contrast themes. The Default and Dark themes were created simply using the Fluent UI Themes designer and the primary colors of their corresponding Teams themes. For the Hight Contrast theme, on the other hand, given the complexity of creating a completely new theme and above all in Hight Contrast mode (neither supported nor gives SharePoint nor gives Fluent UI v7), it was decided to create the theme by hand and support only \"main controls\". This means that this theme is not perfect and above all not all controls will be displayed correctly. This is not a big deal, as the same theme provided by SharePoint has the same problems, it does not support Hight Contrast rendering for all controls. For the Hight Contrast theme (in Teams), only these controls are supported by this control: ChoiceGroup, Checkbox, ComboBox, DatePicker, SpinButton, TextField, Toggle, PrimaryButton, DefaultButton, CompoundButton, IconButton , other fluent controls may have color rendering problems. Example of use in Teams as a TeamsPersonalApp (note that the titles H1, H2, H3 and the paragraph are normal html tags that automatically take the font and color style from the control):","title":"Enhanced Theme Provider"},{"location":"controls/EnhancedThemeProvider/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the EnhancedThemeProvider control as follows: import { EnhancedThemeProvider , getDefaultTheme , useTheme , ThemeContext } from \"@pnp/spfx-controls-react/lib/EnhancedThemeProvider\" ; Example on use the EnhancedThemeProvider control with only required properties: < EnhancedThemeProvider context = { this . props . context } > { /* controls to apply the theme to */ } < /EnhancedThemeProvider> Example on use the EnhancedThemeProvider control with the most important properties: < EnhancedThemeProvider applyTo = \"element\" context = { this . props . context } theme = { this . props . themeVariant } > { /* controls to apply the theme to */ } < /EnhancedThemeProvider> The control provides the passage and/or creation of the theme according to what has been said before. In order to access the theme, from child controls, there are two modes, one for function-based controls, one for class-based controls. Access the theme from the child control using a function component: export const ChildFunctionComponent = () => { const theme = useTheme (); return ( < DefaultButton theme = { theme } > Example Child Control < /DefaultButton> ); } Access the theme from the child control using a class component: export class ChildClassComponent extends React . Component { public render () { return ( < ThemeContext . Consumer > { theme => < DefaultButton theme = { theme } > Example Child Control < /DefaultButton> } < /ThemeContext.Consumer> ) } }; Usage example using theme in child controls: < EnhancedThemeProvider applyTo = \"element\" context = { this . props . context } theme = { this . props . themeVariant } > < ChildFunctionComponent /> < ChildClassComponent /> < /EnhancedThemeProvider>","title":"How to use this control in your solutions"},{"location":"controls/EnhancedThemeProvider/#implementation","text":"The EnhancedThemeProvider control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Sets the context from the SPFx component (a web part, an application customizer or a form customizer). as React.ElementType no A component that should be used as the root element of the ThemeProvider component. ref React.Ref no Optional ref to the root element. theme PartialTheme | Theme no Defines the theme provided by the user. renderer StyleRenderer no Optional interface for registering dynamic styles. Defaults to using merge-styles . Use this to opt into a particular rendering implementation, such as emotion , styled-components , or jss . Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation. applyTo 'element' | 'body' | 'none' no Defines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of ThemeProvider. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body.","title":"Implementation"},{"location":"controls/FieldCollectionData/","text":"FieldCollectionData control \u00b6 This control gives you the ability to insert a list / collection data which can be used in your web part / application customizer. For example: you want to specify multiple locations for showing a weather information. The control allows you to specify multiple data types like: string, number, boolean, or dropdown. It also provides the possibility to render custom field. FieldCollectionData The type of data you get returned depends on the fields you defined. For the example above, the data looks like this: [ { \"Field1\" : \"String value\" , \"Field2\" : \"123\" , \"Field3\" : \"https://pnp.github.io/\" , \"Field4\" : true } ] How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out The getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldCollectionData , CustomCollectionFieldType } from '@pnp/spfx-controls-react/lib/FieldCollectionData' ; Add the control to the render method: < FieldCollectionData key = { \"FieldCollectionData\" } label = { \"Fields Collection\" } manageBtnLabel = { \"Manage\" } onChanged = {( value ) => { console . log ( value ); }} panelHeader = { \"Manage values\" } executeFiltering = {( searchFilter : string , item : any ) => { return item [ \"Field2\" ] === + searchFilter ; }} itemsPerPage = { 3 } fields = {[ { id : \"Field1\" , title : \"String field\" , type : CustomCollectionFieldType . string , required : true }, { id : \"Field2\" , title : \"Number field\" , type : CustomCollectionFieldType . number }, { id : \"Field3\" , title : \"URL field\" , type : CustomCollectionFieldType . url }, { id : \"Field4\" , title : \"Boolean field\" , type : CustomCollectionFieldType . boolean } ]} value = {[ { \"Field1\" : \"String value\" , \"Field2\" : \"123\" , \"Field3\" : \"https://pnp.github.io/\" , \"Field4\" : true } ]} /> Sample of custom field rendering \u00b6 Here is an example of how you can render your own controls in the FieldCollectionData control: { id : \"customFieldId\" , title : \"Custom Field\" , type : CustomCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item , itemId , onError ) => { return ( React . createElement ( \"div\" , null , React . createElement ( \"input\" , { key : itemId , value : value , onChange : ( event : React.FormEvent < HTMLInputElement > ) => { if ( event . currentTarget . value === \"error\" ) { onError ( field . id , \"Value shouldn't be equal to error\" ); } else { onError ( field . id , \"\" ); } onUpdate ( field . id , event . currentTarget . value ); }}), \" \ud83c\udf89\" ) ); } } Implementation \u00b6 The FieldCollectionData control can be configured with the following properties: Property Type Required Description Default Value key string yes An unique key that indicates the identity of this control. label string no Property field label displayed on top. panelHeader string yes Label to be used as the header in the panel. panelDescription string no Property that allows you to specify a description in the collection panel. manageBtnLabel string yes Label of the button to open the panel. saveBtnLabel string no Label of the save button. saveAndAddBtnLabel string yes Label of the save and add button. cancelBtnLabel string yes Label of the cancel button. fields ICustomCollectionField[] yes The fields to be used for the list of collection data. value any[] yes The collection data value. enableSorting boolean no Specify if you want to be able to sort the items in the collection. false disabled boolean no Specify if the control is disabled. false disableItemCreation boolean no Allows you to specify if user can create new items. false disableItemDeletion boolean no Allows you to specify if users can delete already inserted items. false panelClassName string no Allows you to specify a custom CSS class name for the collection data panel. tableClassName string no Allows you to specify a custom CSS class name for the collection data table inside the panel. itemsPerPage number no Allows you to specify the amount of items displayed per page. Paging control is added automatically. executeFiltering (searchFilter: string, item: any) => boolean no Allows you to show Search Box and specify own filtering logic. panelProps IPanelProps no Allows you to pass in props of the panel such as type and customWidth to control the underlying panel. context BaseComponentContext no Needed if peoplepicker field type is used usePanel boolean no Specify if you want the control to opened in a panel or directly on the page (only useful within webpart) true noDataMessage string no Specify the message when no items are added to the collection Interface ICustomCollectionField Property Type Required Description id string yes ID of the field. title string yes Title of the field. This will be used for the label in the table. type CustomCollectionFieldType yes Specifies the type of field to render. disableEdit boolean no Allows you to specify if a field is disabled for editing. required boolean no Specify if the field is required. options IDropdownOption[] IComboboxOption[] no Dropdown options. Only necessary when dropdown or combobox type is used. onRenderOption IRenderFunction no Dropdown custom options render method. Only for the dropdown field type. placeholder string no Placehoder text which will be used for the input field. If not provided the input title will be used. defaultValue any no Specify a default value for the input field. deferredValidationTime number no Field will start to validate after users stop typing for deferredValidationTime milliseconds. Default: 200ms. onGetErrorMessage (value: any, index: number, crntItem: any): string | Promise no The method is used to get the validation error message and determine whether the input value is valid or not. It provides you the current row index and the item you are currently editing. onCustomRender (field: ICustomCollectionField, value: any, onUpdate: (fieldId: string, value: any) => void, item: any, itemUniqueId: string, onCustomFieldValidation: (fieldId: string, errorMessage: string) => void) => JSX.Element no This property is only required if you are using the custom field type and it can be used to specify the custom rendering of your control in the collection data. multiSelect boolean no Specifies multiple options can be selected ( combobox ) or mutliple users can be selected ( peoplepicker ) allowFreeform boolean no Specifies that own options can be entered. Only for combobox field type minimumUsers number no Specifies the minimum number of users to be entered for peoplepicker field type minimumUsersMessage string no Specifies the message to be displayed if minimumUsers are not entered for peoplepicker field type maximumUsers number no Specifies the maximum number of users to be entered for peoplepicker field type Enum CustomCollectionFieldType Type Description string Text field number Number field boolean Checkbox dropdown Dropdown field. You will have to specify the options property when using this field type combobox Combobox field. You wil have to specify the options property, optional specify allowFreeform and multiSelect fabricIcon Name of the Office UI Fabric icon url URL field peoplepicker Peoplepicker control custom This gives you control over the whole field rendering. Be sure to provide the onCustomRender method to render your control in the collection data.","title":"FieldCollectionData"},{"location":"controls/FieldCollectionData/#fieldcollectiondata-control","text":"This control gives you the ability to insert a list / collection data which can be used in your web part / application customizer. For example: you want to specify multiple locations for showing a weather information. The control allows you to specify multiple data types like: string, number, boolean, or dropdown. It also provides the possibility to render custom field. FieldCollectionData The type of data you get returned depends on the fields you defined. For the example above, the data looks like this: [ { \"Field1\" : \"String value\" , \"Field2\" : \"123\" , \"Field3\" : \"https://pnp.github.io/\" , \"Field4\" : true } ]","title":"FieldCollectionData control"},{"location":"controls/FieldCollectionData/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out The getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldCollectionData , CustomCollectionFieldType } from '@pnp/spfx-controls-react/lib/FieldCollectionData' ; Add the control to the render method: < FieldCollectionData key = { \"FieldCollectionData\" } label = { \"Fields Collection\" } manageBtnLabel = { \"Manage\" } onChanged = {( value ) => { console . log ( value ); }} panelHeader = { \"Manage values\" } executeFiltering = {( searchFilter : string , item : any ) => { return item [ \"Field2\" ] === + searchFilter ; }} itemsPerPage = { 3 } fields = {[ { id : \"Field1\" , title : \"String field\" , type : CustomCollectionFieldType . string , required : true }, { id : \"Field2\" , title : \"Number field\" , type : CustomCollectionFieldType . number }, { id : \"Field3\" , title : \"URL field\" , type : CustomCollectionFieldType . url }, { id : \"Field4\" , title : \"Boolean field\" , type : CustomCollectionFieldType . boolean } ]} value = {[ { \"Field1\" : \"String value\" , \"Field2\" : \"123\" , \"Field3\" : \"https://pnp.github.io/\" , \"Field4\" : true } ]} />","title":"How to use this control in your solutions"},{"location":"controls/FieldCollectionData/#sample-of-custom-field-rendering","text":"Here is an example of how you can render your own controls in the FieldCollectionData control: { id : \"customFieldId\" , title : \"Custom Field\" , type : CustomCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item , itemId , onError ) => { return ( React . createElement ( \"div\" , null , React . createElement ( \"input\" , { key : itemId , value : value , onChange : ( event : React.FormEvent < HTMLInputElement > ) => { if ( event . currentTarget . value === \"error\" ) { onError ( field . id , \"Value shouldn't be equal to error\" ); } else { onError ( field . id , \"\" ); } onUpdate ( field . id , event . currentTarget . value ); }}), \" \ud83c\udf89\" ) ); } }","title":"Sample of custom field rendering"},{"location":"controls/FieldCollectionData/#implementation","text":"The FieldCollectionData control can be configured with the following properties: Property Type Required Description Default Value key string yes An unique key that indicates the identity of this control. label string no Property field label displayed on top. panelHeader string yes Label to be used as the header in the panel. panelDescription string no Property that allows you to specify a description in the collection panel. manageBtnLabel string yes Label of the button to open the panel. saveBtnLabel string no Label of the save button. saveAndAddBtnLabel string yes Label of the save and add button. cancelBtnLabel string yes Label of the cancel button. fields ICustomCollectionField[] yes The fields to be used for the list of collection data. value any[] yes The collection data value. enableSorting boolean no Specify if you want to be able to sort the items in the collection. false disabled boolean no Specify if the control is disabled. false disableItemCreation boolean no Allows you to specify if user can create new items. false disableItemDeletion boolean no Allows you to specify if users can delete already inserted items. false panelClassName string no Allows you to specify a custom CSS class name for the collection data panel. tableClassName string no Allows you to specify a custom CSS class name for the collection data table inside the panel. itemsPerPage number no Allows you to specify the amount of items displayed per page. Paging control is added automatically. executeFiltering (searchFilter: string, item: any) => boolean no Allows you to show Search Box and specify own filtering logic. panelProps IPanelProps no Allows you to pass in props of the panel such as type and customWidth to control the underlying panel. context BaseComponentContext no Needed if peoplepicker field type is used usePanel boolean no Specify if you want the control to opened in a panel or directly on the page (only useful within webpart) true noDataMessage string no Specify the message when no items are added to the collection Interface ICustomCollectionField Property Type Required Description id string yes ID of the field. title string yes Title of the field. This will be used for the label in the table. type CustomCollectionFieldType yes Specifies the type of field to render. disableEdit boolean no Allows you to specify if a field is disabled for editing. required boolean no Specify if the field is required. options IDropdownOption[] IComboboxOption[] no Dropdown options. Only necessary when dropdown or combobox type is used. onRenderOption IRenderFunction no Dropdown custom options render method. Only for the dropdown field type. placeholder string no Placehoder text which will be used for the input field. If not provided the input title will be used. defaultValue any no Specify a default value for the input field. deferredValidationTime number no Field will start to validate after users stop typing for deferredValidationTime milliseconds. Default: 200ms. onGetErrorMessage (value: any, index: number, crntItem: any): string | Promise no The method is used to get the validation error message and determine whether the input value is valid or not. It provides you the current row index and the item you are currently editing. onCustomRender (field: ICustomCollectionField, value: any, onUpdate: (fieldId: string, value: any) => void, item: any, itemUniqueId: string, onCustomFieldValidation: (fieldId: string, errorMessage: string) => void) => JSX.Element no This property is only required if you are using the custom field type and it can be used to specify the custom rendering of your control in the collection data. multiSelect boolean no Specifies multiple options can be selected ( combobox ) or mutliple users can be selected ( peoplepicker ) allowFreeform boolean no Specifies that own options can be entered. Only for combobox field type minimumUsers number no Specifies the minimum number of users to be entered for peoplepicker field type minimumUsersMessage string no Specifies the message to be displayed if minimumUsers are not entered for peoplepicker field type maximumUsers number no Specifies the maximum number of users to be entered for peoplepicker field type Enum CustomCollectionFieldType Type Description string Text field number Number field boolean Checkbox dropdown Dropdown field. You will have to specify the options property when using this field type combobox Combobox field. You wil have to specify the options property, optional specify allowFreeform and multiSelect fabricIcon Name of the Office UI Fabric icon url URL field peoplepicker Peoplepicker control custom This gives you control over the whole field rendering. Be sure to provide the onCustomRender method to render your control in the collection data.","title":"Implementation"},{"location":"controls/FieldPicker/","text":"FieldPicker control \u00b6 This control allows you to select one or multiple available site fields or list fields. Here is an example of the control: FieldPicker single selection mode: FieldPicker multi selection mode: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FieldPicker } from \"@pnp/spfx-controls-react/lib/FieldPicker\" ; Use the FieldPicker control in your code as follows: < FieldPicker context = { this . props . context } group = \"Content Feedback\" includeHidden = { false } includeReadOnly = { false } label = \"Select your field(s)\" multiSelect = { false } orderBy = { FieldsOrderBy . Title } listId = \"00000000-0000-0000-0000-000000000000\" onSelectionChanged = { this . onFieldPickerChanged } showBlankOption = { true } /> The onSelectionChanged change event returns the field(s) and can be implemented as follows: private onFieldPickerChanged ( fields : ISPField | ISPField []) { console . log ( \"Fields:\" , fields ); } Implementation \u00b6 The FieldPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string no The ID of the list or library you wish to select a column(s) from. When not specified, picker will be populated with site columns. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. includeHidden boolean no Whether or not to include hidden fields. Default is true. includeReadOnly boolean no Whether or not to include read-only fields. Default is true. group string no Only show fields of a certain group. filter string no Filter fields from OData query (takes the upperhand of hidden , readOnly and group Filters). orderBy FieldsOrderBy no How to order the fields. selectedFields string | string[] no Internal names of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Indicates if multi-choice selections is allowed. Default is false. label string no The label to display. placeholder string no Input placeholder text. Displayed until option is selected. onSelectionChanged (newValue: ISPField | ISPField[]): void no Callback issued when the selected option changes. filterItems (fields: ISPField[]): ISPField[] no This function is invoked after the filtering has been done. This allows you to add additional custom filtering. webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). showBlankOption boolean no Whether or not to show a blank option. Default is false. Works only when multiSelect is false. Enum FieldsOrderBy Value Title InternalName","title":"FieldPicker"},{"location":"controls/FieldPicker/#fieldpicker-control","text":"This control allows you to select one or multiple available site fields or list fields. Here is an example of the control: FieldPicker single selection mode: FieldPicker multi selection mode:","title":"FieldPicker control"},{"location":"controls/FieldPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FieldPicker } from \"@pnp/spfx-controls-react/lib/FieldPicker\" ; Use the FieldPicker control in your code as follows: < FieldPicker context = { this . props . context } group = \"Content Feedback\" includeHidden = { false } includeReadOnly = { false } label = \"Select your field(s)\" multiSelect = { false } orderBy = { FieldsOrderBy . Title } listId = \"00000000-0000-0000-0000-000000000000\" onSelectionChanged = { this . onFieldPickerChanged } showBlankOption = { true } /> The onSelectionChanged change event returns the field(s) and can be implemented as follows: private onFieldPickerChanged ( fields : ISPField | ISPField []) { console . log ( \"Fields:\" , fields ); }","title":"How to use this control in your solutions"},{"location":"controls/FieldPicker/#implementation","text":"The FieldPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. listId string no The ID of the list or library you wish to select a column(s) from. When not specified, picker will be populated with site columns. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. includeHidden boolean no Whether or not to include hidden fields. Default is true. includeReadOnly boolean no Whether or not to include read-only fields. Default is true. group string no Only show fields of a certain group. filter string no Filter fields from OData query (takes the upperhand of hidden , readOnly and group Filters). orderBy FieldsOrderBy no How to order the fields. selectedFields string | string[] no Internal names of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Indicates if multi-choice selections is allowed. Default is false. label string no The label to display. placeholder string no Input placeholder text. Displayed until option is selected. onSelectionChanged (newValue: ISPField | ISPField[]): void no Callback issued when the selected option changes. filterItems (fields: ISPField[]): ISPField[] no This function is invoked after the filtering has been done. This allows you to add additional custom filtering. webAbsoluteUrl string no Absolute Web Url of target site (user requires permissions). showBlankOption boolean no Whether or not to show a blank option. Default is false. Works only when multiSelect is false. Enum FieldsOrderBy Value Title InternalName","title":"Implementation"},{"location":"controls/FilePicker/","text":"FilePicker control \u00b6 File picker control allows to browse and select a file from various places. Currently supported locations - Recent files - tab allows to select a file from recently modified files based on the search results. - Web search - tab uses Bing cognitive services to look for a file. (Only images) - OneDrive - tab allows to select a file from the user's One Drive. - Site document libraries - tab allows to select a file from the existing site document libraries. - Upload - tab allows to upload a file from local drive. - Multi-Upload - tab allows to upload multiple files from local drive. - From a link - tab allows to paste a link to the document. Overview \u00b6 The control supports all types of file, however it also allows to specify list of extensions for the files that are going to be looked displayed. Currently, only single file selection is supported. Different display types \u00b6 File picker support 3 types of views : List, Compact list and Tiles. In case Tiles view is selected, the control shows the thumbnail of the file. Breadcrumb support \u00b6 The control displays breadcrumb navigation that allows to easily switch folders or document libraries. Paged data load \u00b6 File picker doesn't load all the files that exist in the folder. Instead, it allows to specify how many results are loaded in a batch, and executes paged requests when new data is required. How to use this control \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { FilePicker , IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker' ; Use the FilePicker control in your code as follows: < FilePicker bingAPIKey = \"\" accepts = {[ \".gif\" , \".jpg\" , \".jpeg\" , \".bmp\" , \".dib\" , \".tif\" , \".tiff\" , \".ico\" , \".png\" , \".jxr\" , \".svg\" ]} buttonIcon = \"FileImage\" onSave = {( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult }) }} onChange = {( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult }) }} context = { this . props . context } /> Sample onSave handler: private _onFilePickerSave = async ( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult : filePickerResult }); if ( filePickerResult && filePickerResult . length > 0 ) { for ( var i = 0 ; i < filePickerResult . length ; i ++ ) { const item = filePickerResult [ i ]; const fileResultContent = await item . downloadFileContent (); console . log ( fileResultContent ); } } } Implementation \u00b6 The FilePicker component can be configured with the following properties: Property Type Required Description label string no Specifies the text describing the file picker. buttonLabel string no Specifies the label of the file picker button. buttonIcon string no In case it is provided the file picker will be rendered as an action button. buttonIconProps IIconProps no In case it is provided the file picker will be rendered as an Icon the and all can define Properties for Icon defaultFolderAbsolutePath string no Optional string parameter to set a default active folder/library for the SiteFilesTab. E.g. \"https://contoso.sharepoint.com/teams/siteName/documentLibrary/Folder 1/SubFolder 1\" onSave (filePickerResult: IFilePickerResult[]) => void yes Handler when the file has been selected and picker has been closed. onChange (filePickerResult: IFilePickerResult[]) => void no Handler when the file selection has been changed. onCancel () => void no Handler when file picker has been cancelled. context BaseComponentContext yes Current context. accepts string[] no Array of strings containing allowed files extensions. E.g. [\".gif\", \".jpg\", \".jpeg\", \".bmp\", \".dib\", \".tif\", \".tiff\", \".ico\", \".png\", \".jxr\", \".svg\"] required boolean no Sets the label to inform that the value is required. bingAPIKey string no Used to execute WebSearch. If not provided SearchTab will not be available. The API key can be created on a Azure account ( Bing image search API ), a free version exist for 1000 query per month ( Pricing ) disabled boolean no Specifies if the picker button is disabled hidden boolean no Specifies if the picker button is hidden (if hidden, panel visibility can still be controlled with isPanelOpen) itemsCountQueryLimit number no Number of items to obtain when executing REST queries. Default 100. hideRecentTab boolean no Specifies if RecentTab should be hidden. hideWebSearchTab boolean no Specifies if WebSearchTab should be hidden. hideStockImages boolean no Specifies if StockImagesTab should be hidden. hideOrganisationalAssetTab boolean no Specifies if OrganisationalAssetTab should be hidden. hideOneDriveTab boolean no Specifies if OneDriveTab should be hidden. hideSiteFilesTab boolean no Specifies if SiteFilesTab should be hidden. hideLocalUploadTab boolean no Specifies if LocalUploadTab should be hidden. hideLocalMultipleUploadTab boolean no Specifies if LocalMultipleUploadTab should be hidden. hideLinkUploadTab boolean no Specifies if LinkUploadTab should be hidden. storeLastActiveTab boolean no Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default true isPanelOpen boolean no Specifies if the file picker panel is open by default or not renderCustomUploadTabContent (filePickerResult: IFilePickerResult) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Upload\" tab renderCustomMultipleUploadTabContent (filePickerResult: IFilePickerResult[]) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Multi-Upload\" tab renderCustomLinkTabContent (filePickerResult: IFilePickerResult) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Link\" tab includePageLibraries boolean no Specifies if Site Pages library to be visible on Sites tab allowExternalLinks boolean no Specifies if external links should be allowed. checkIfFileExists boolean no When using file links, this property allows the user to choose if the control should check if the link point to a file that exists or not. interface IFilePickerResult Provides options for carousel buttons location. Value Type Description fileName string File name of the result with the extension. fileNameWithoutExtension string File name of the result without the extension. fileAbsoluteUrl string Absolute URL of the file. Null in case of file upload. fileSize number Size of the result (in bytes). Set only for file upload downloadFileContent () => Promise Function allows to download file content. Returns File object.","title":"FilePicker"},{"location":"controls/FilePicker/#filepicker-control","text":"File picker control allows to browse and select a file from various places. Currently supported locations - Recent files - tab allows to select a file from recently modified files based on the search results. - Web search - tab uses Bing cognitive services to look for a file. (Only images) - OneDrive - tab allows to select a file from the user's One Drive. - Site document libraries - tab allows to select a file from the existing site document libraries. - Upload - tab allows to upload a file from local drive. - Multi-Upload - tab allows to upload multiple files from local drive. - From a link - tab allows to paste a link to the document.","title":"FilePicker control"},{"location":"controls/FilePicker/#overview","text":"The control supports all types of file, however it also allows to specify list of extensions for the files that are going to be looked displayed. Currently, only single file selection is supported.","title":"Overview"},{"location":"controls/FilePicker/#different-display-types","text":"File picker support 3 types of views : List, Compact list and Tiles. In case Tiles view is selected, the control shows the thumbnail of the file.","title":"Different display types"},{"location":"controls/FilePicker/#breadcrumb-support","text":"The control displays breadcrumb navigation that allows to easily switch folders or document libraries.","title":"Breadcrumb support"},{"location":"controls/FilePicker/#paged-data-load","text":"File picker doesn't load all the files that exist in the folder. Instead, it allows to specify how many results are loaded in a batch, and executes paged requests when new data is required.","title":"Paged data load"},{"location":"controls/FilePicker/#how-to-use-this-control","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { FilePicker , IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker' ; Use the FilePicker control in your code as follows: < FilePicker bingAPIKey = \"\" accepts = {[ \".gif\" , \".jpg\" , \".jpeg\" , \".bmp\" , \".dib\" , \".tif\" , \".tiff\" , \".ico\" , \".png\" , \".jxr\" , \".svg\" ]} buttonIcon = \"FileImage\" onSave = {( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult }) }} onChange = {( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult }) }} context = { this . props . context } /> Sample onSave handler: private _onFilePickerSave = async ( filePickerResult : IFilePickerResult []) => { this . setState ({ filePickerResult : filePickerResult }); if ( filePickerResult && filePickerResult . length > 0 ) { for ( var i = 0 ; i < filePickerResult . length ; i ++ ) { const item = filePickerResult [ i ]; const fileResultContent = await item . downloadFileContent (); console . log ( fileResultContent ); } } }","title":"How to use this control"},{"location":"controls/FilePicker/#implementation","text":"The FilePicker component can be configured with the following properties: Property Type Required Description label string no Specifies the text describing the file picker. buttonLabel string no Specifies the label of the file picker button. buttonIcon string no In case it is provided the file picker will be rendered as an action button. buttonIconProps IIconProps no In case it is provided the file picker will be rendered as an Icon the and all can define Properties for Icon defaultFolderAbsolutePath string no Optional string parameter to set a default active folder/library for the SiteFilesTab. E.g. \"https://contoso.sharepoint.com/teams/siteName/documentLibrary/Folder 1/SubFolder 1\" onSave (filePickerResult: IFilePickerResult[]) => void yes Handler when the file has been selected and picker has been closed. onChange (filePickerResult: IFilePickerResult[]) => void no Handler when the file selection has been changed. onCancel () => void no Handler when file picker has been cancelled. context BaseComponentContext yes Current context. accepts string[] no Array of strings containing allowed files extensions. E.g. [\".gif\", \".jpg\", \".jpeg\", \".bmp\", \".dib\", \".tif\", \".tiff\", \".ico\", \".png\", \".jxr\", \".svg\"] required boolean no Sets the label to inform that the value is required. bingAPIKey string no Used to execute WebSearch. If not provided SearchTab will not be available. The API key can be created on a Azure account ( Bing image search API ), a free version exist for 1000 query per month ( Pricing ) disabled boolean no Specifies if the picker button is disabled hidden boolean no Specifies if the picker button is hidden (if hidden, panel visibility can still be controlled with isPanelOpen) itemsCountQueryLimit number no Number of items to obtain when executing REST queries. Default 100. hideRecentTab boolean no Specifies if RecentTab should be hidden. hideWebSearchTab boolean no Specifies if WebSearchTab should be hidden. hideStockImages boolean no Specifies if StockImagesTab should be hidden. hideOrganisationalAssetTab boolean no Specifies if OrganisationalAssetTab should be hidden. hideOneDriveTab boolean no Specifies if OneDriveTab should be hidden. hideSiteFilesTab boolean no Specifies if SiteFilesTab should be hidden. hideLocalUploadTab boolean no Specifies if LocalUploadTab should be hidden. hideLocalMultipleUploadTab boolean no Specifies if LocalMultipleUploadTab should be hidden. hideLinkUploadTab boolean no Specifies if LinkUploadTab should be hidden. storeLastActiveTab boolean no Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default true isPanelOpen boolean no Specifies if the file picker panel is open by default or not renderCustomUploadTabContent (filePickerResult: IFilePickerResult) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Upload\" tab renderCustomMultipleUploadTabContent (filePickerResult: IFilePickerResult[]) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Multi-Upload\" tab renderCustomLinkTabContent (filePickerResult: IFilePickerResult) => JSX.Element | null no Optional renderer to add custom user-defined fields to \"Link\" tab includePageLibraries boolean no Specifies if Site Pages library to be visible on Sites tab allowExternalLinks boolean no Specifies if external links should be allowed. checkIfFileExists boolean no When using file links, this property allows the user to choose if the control should check if the link point to a file that exists or not. interface IFilePickerResult Provides options for carousel buttons location. Value Type Description fileName string File name of the result with the extension. fileNameWithoutExtension string File name of the result without the extension. fileAbsoluteUrl string Absolute URL of the file. Null in case of file upload. fileSize number Size of the result (in bytes). Set only for file upload downloadFileContent () => Promise Function allows to download file content. Returns File object.","title":"Implementation"},{"location":"controls/FileTypeIcon/","text":"FileTypeIcon control \u00b6 This control returns the file type icon based on a specified file path or application. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FileTypeIcon , ApplicationType , IconType , ImageSize } from \"@pnp/spfx-controls-react/lib/FileTypeIcon\" ; Use the FileTypeIcon control in your code as follows: /* Showing the icons font */ < FileTypeIcon type = { IconType . font } application = { ApplicationType . Word } /> < FileTypeIcon type = { IconType . font } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . font } path = \"https://contoso.sharepoint.com/documents/filename.docx\" /> < FileTypeIcon type = { IconType . font } path = \"https://contoso.sharepoint.com/documents/filename.xslx\" /> /* Showing the icon image */ < FileTypeIcon type = { IconType . image } application = { ApplicationType . Word } /> < FileTypeIcon type = { IconType . image } path = \"https://contoso.sharepoint.com/documents/filename.docx\" /> /* Icon image allows three different sizes */ < FileTypeIcon type = { IconType . image } size = { ImageSize . small } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . image } size = { ImageSize . medium } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . image } size = { ImageSize . large } application = { ApplicationType . Excel } /> Implementation \u00b6 The FileTypeIcon component can be configured with the following properties: Property Type Required Description application ApplicationType no Type of the application for which you want to show the icon. Use the ApplicationType enum to get the list of available applications. path string no Path to the document. If this is provided, the control will use the file extension to display the corresponding icon. size ImageSize no This is a property that only needs to be used when the type is set to image. It allows you to specify the image size. small (16px), normal (20px), medium (48px) and large (96px) are possible. Use the ImageSize enum to get the list of available images sizes. type IconType yes This property specifies is you want to use the icon font or image. Use the IconType enum to get the list of available icon types. onClick React.MouseEvent no Event triggered when the icon is clicked. onDoubleClick React.MouseEvent no Event triggered when the icon is double clicked. onMouseEnter React.MouseEvent no Event triggered when the mouse cursor enters the icon (without event bubbling). onMouseLeave React.MouseEvent no Event triggered when the mouse cursor leaves the icon. onMouseOver React.MouseEvent no Event triggered when the mouse cursor enters the icon (with event bubbling). onMouseUp React.MouseEvent no Event triggered when the mouse button is released after clicked on the icon.","title":"FileTypeIcon"},{"location":"controls/FileTypeIcon/#filetypeicon-control","text":"This control returns the file type icon based on a specified file path or application.","title":"FileTypeIcon control"},{"location":"controls/FileTypeIcon/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FileTypeIcon , ApplicationType , IconType , ImageSize } from \"@pnp/spfx-controls-react/lib/FileTypeIcon\" ; Use the FileTypeIcon control in your code as follows: /* Showing the icons font */ < FileTypeIcon type = { IconType . font } application = { ApplicationType . Word } /> < FileTypeIcon type = { IconType . font } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . font } path = \"https://contoso.sharepoint.com/documents/filename.docx\" /> < FileTypeIcon type = { IconType . font } path = \"https://contoso.sharepoint.com/documents/filename.xslx\" /> /* Showing the icon image */ < FileTypeIcon type = { IconType . image } application = { ApplicationType . Word } /> < FileTypeIcon type = { IconType . image } path = \"https://contoso.sharepoint.com/documents/filename.docx\" /> /* Icon image allows three different sizes */ < FileTypeIcon type = { IconType . image } size = { ImageSize . small } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . image } size = { ImageSize . medium } application = { ApplicationType . Excel } /> < FileTypeIcon type = { IconType . image } size = { ImageSize . large } application = { ApplicationType . Excel } />","title":"How to use this control in your solutions"},{"location":"controls/FileTypeIcon/#implementation","text":"The FileTypeIcon component can be configured with the following properties: Property Type Required Description application ApplicationType no Type of the application for which you want to show the icon. Use the ApplicationType enum to get the list of available applications. path string no Path to the document. If this is provided, the control will use the file extension to display the corresponding icon. size ImageSize no This is a property that only needs to be used when the type is set to image. It allows you to specify the image size. small (16px), normal (20px), medium (48px) and large (96px) are possible. Use the ImageSize enum to get the list of available images sizes. type IconType yes This property specifies is you want to use the icon font or image. Use the IconType enum to get the list of available icon types. onClick React.MouseEvent no Event triggered when the icon is clicked. onDoubleClick React.MouseEvent no Event triggered when the icon is double clicked. onMouseEnter React.MouseEvent no Event triggered when the mouse cursor enters the icon (without event bubbling). onMouseLeave React.MouseEvent no Event triggered when the mouse cursor leaves the icon. onMouseOver React.MouseEvent no Event triggered when the mouse cursor enters the icon (with event bubbling). onMouseUp React.MouseEvent no Event triggered when the mouse button is released after clicked on the icon.","title":"Implementation"},{"location":"controls/FolderExplorer/","text":"FolderExplorer control \u00b6 This control allows you to explore a folder structure by clinking on a folder to load it's sub-folders and using a breadcrumb navigation to navigate back to a previous level. It also allows the user to create a new folder at the current level being explored. Here is an example of the control: FolderExplorer folder creation: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FolderExplorer , IFolder } from \"@pnp/spfx-controls-react/lib/FolderExplorer\" ; Use the FolderExplorer control in your code as follows: < FolderExplorer context = { this . props . context } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} defaultFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } /> The onSelect change event returns the selected folder and can be implemented as follows: private _onFolderSelect = ( folder : IFolder ) : void => { console . log ( 'selected folder' , folder ); } Implementation \u00b6 The FolderExplorer control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. siteAbsoluteUrl string no The absolute url of the target site. Only required if not the current site. rootFolder IFolder yes The lowest level folder that can be explored. This can be the root folder of a library. If site url is provided, it will allow the user to select a document library defaultFolder IFolder yes The default folder to be explored. canCreateFolders boolean no Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions. hiddenBreadcrumb boolean no Hide the breadcrumb control. initialBreadcrumbItems IBreadcrumbItem no Additional items to be added to the beginning of the breadcrumb. hiddenFilterBox boolean no Hide the filter box onSelect (folder: IFolder): void no Callback function called after a folder is selected. orderby string no The name of the folder field on which to sort. Name will be used as default. Other examples: Name, TimeCreated, TimeLastModified orderAscending boolean no If set to true, results will be sorted in ascending order. Otherwise, descending will be used as default","title":"FolderExplorer"},{"location":"controls/FolderExplorer/#folderexplorer-control","text":"This control allows you to explore a folder structure by clinking on a folder to load it's sub-folders and using a breadcrumb navigation to navigate back to a previous level. It also allows the user to create a new folder at the current level being explored. Here is an example of the control: FolderExplorer folder creation:","title":"FolderExplorer control"},{"location":"controls/FolderExplorer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FolderExplorer , IFolder } from \"@pnp/spfx-controls-react/lib/FolderExplorer\" ; Use the FolderExplorer control in your code as follows: < FolderExplorer context = { this . props . context } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} defaultFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } /> The onSelect change event returns the selected folder and can be implemented as follows: private _onFolderSelect = ( folder : IFolder ) : void => { console . log ( 'selected folder' , folder ); }","title":"How to use this control in your solutions"},{"location":"controls/FolderExplorer/#implementation","text":"The FolderExplorer control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. siteAbsoluteUrl string no The absolute url of the target site. Only required if not the current site. rootFolder IFolder yes The lowest level folder that can be explored. This can be the root folder of a library. If site url is provided, it will allow the user to select a document library defaultFolder IFolder yes The default folder to be explored. canCreateFolders boolean no Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions. hiddenBreadcrumb boolean no Hide the breadcrumb control. initialBreadcrumbItems IBreadcrumbItem no Additional items to be added to the beginning of the breadcrumb. hiddenFilterBox boolean no Hide the filter box onSelect (folder: IFolder): void no Callback function called after a folder is selected. orderby string no The name of the folder field on which to sort. Name will be used as default. Other examples: Name, TimeCreated, TimeLastModified orderAscending boolean no If set to true, results will be sorted in ascending order. Otherwise, descending will be used as default","title":"Implementation"},{"location":"controls/FolderPicker/","text":"FolderPicker control \u00b6 This control allows you to explore and select a folder. It also allows the user to create a new folder at the current level being explored. Here is an example of the control: FolderPicker no selection: FolderPicker selection: FolderPicker selected: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FolderPicker , IFolder } from \"@pnp/spfx-controls-react/lib/FolderPicker\" ; Use the FolderPicker control in your code as follows: < FolderPicker context = { this . props . context } label = 'Folder Picker' required = { true } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } /> To use the FolderExplorer control to fetch folders from different sitecollection in your code as follows: < FolderExplorer context = { this . props . context } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite2/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } siteAbsoluteUrl = \"https://xxxx.sharepoint.com/sites/TestSite2\" /> The onSelect change event returns the selected folder and can be implemented as follows: private _onFolderSelect = ( folder : IFolder ) : void => { console . log ( 'selected folder' , folder ); } If you want to pick a folder outside the current site collection (not the one targeted by the SPFx context), you have to specify which site collection owns the folder. You can do this by setting the siteAbsoluteUrl property to the URL of the site collection that owns the folder. < FolderPicker context = { this . props . context } label = 'Folder Picker' rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : '/sites/anotherSite/Shared Documents' }} siteAbsoluteUrl = \"https://contoso.sharepoint.com/sites/anotherSite\" onSelect = { this . _onFolderSelect } /> Implementation \u00b6 The FolderPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. label string yes The label for the control. rootFolder IFolder yes The lowest level folder that can be explored. This can be the root folder of a library. siteAbsoluteUrl string no The absolute url of the target site. Only required if rootFolder does not belongs to the current site defaultFolder IFolder no The default folder to be selected or explored. required boolean no Is selection required. disabled boolean no Is the control disabled. canCreateFolders boolean no Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions. onSelect (folder: IFolder): void no Callback function called after a folder is selected.","title":"FolderPicker"},{"location":"controls/FolderPicker/#folderpicker-control","text":"This control allows you to explore and select a folder. It also allows the user to create a new folder at the current level being explored. Here is an example of the control: FolderPicker no selection: FolderPicker selection: FolderPicker selected:","title":"FolderPicker control"},{"location":"controls/FolderPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { FolderPicker , IFolder } from \"@pnp/spfx-controls-react/lib/FolderPicker\" ; Use the FolderPicker control in your code as follows: < FolderPicker context = { this . props . context } label = 'Folder Picker' required = { true } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } /> To use the FolderExplorer control to fetch folders from different sitecollection in your code as follows: < FolderExplorer context = { this . props . context } rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : `/sites/TestSite2/Shared Documents` }} onSelect = { this . _onFolderSelect } canCreateFolders = { true } siteAbsoluteUrl = \"https://xxxx.sharepoint.com/sites/TestSite2\" /> The onSelect change event returns the selected folder and can be implemented as follows: private _onFolderSelect = ( folder : IFolder ) : void => { console . log ( 'selected folder' , folder ); } If you want to pick a folder outside the current site collection (not the one targeted by the SPFx context), you have to specify which site collection owns the folder. You can do this by setting the siteAbsoluteUrl property to the URL of the site collection that owns the folder. < FolderPicker context = { this . props . context } label = 'Folder Picker' rootFolder = {{ Name : 'Documents' , ServerRelativeUrl : '/sites/anotherSite/Shared Documents' }} siteAbsoluteUrl = \"https://contoso.sharepoint.com/sites/anotherSite\" onSelect = { this . _onFolderSelect } />","title":"How to use this control in your solutions"},{"location":"controls/FolderPicker/#implementation","text":"The FolderPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. label string yes The label for the control. rootFolder IFolder yes The lowest level folder that can be explored. This can be the root folder of a library. siteAbsoluteUrl string no The absolute url of the target site. Only required if rootFolder does not belongs to the current site defaultFolder IFolder no The default folder to be selected or explored. required boolean no Is selection required. disabled boolean no Is the control disabled. canCreateFolders boolean no Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions. onSelect (folder: IFolder): void no Callback function called after a folder is selected.","title":"Implementation"},{"location":"controls/GridLayout/","text":"Grid Layout control \u00b6 This control renders a responsive grid layout for your web parts. The grid layout behaves according to the SharePoint web part layouts design pattern . The grid layout will automatically reflow grid items according to the space available for the control. On mobile devices and 1/3 column layouts, it will render a compact layout. Although it is best used with the Fabric UI DocumentCard control , it will render any rectangular content you wish to display. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { GridLayout } from \"@pnp/spfx-controls-react/lib/GridLayout\" ; Retrieve the items you wish to display in your grid control. For example, you can place them in your component's state : // This sample places loads items in the constructor. You may wish to load // your items in the componentDidUpdate constructor ( props : IMyWebPartProps ) { super ( props ); this . state = { items : [{ thumbnail : \"https://pixabay.com/get/57e9dd474952a414f1dc8460825668204022dfe05555754d742e7bd6/hot-air-balloons-1984308_640.jpg\" , title : \"Adventures in SPFx\" , name : \"Perry Losselyong\" , profileImageSrc : \"https://robohash.org/blanditiisadlabore.png?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"3/13/2019\" }, { thumbnail : \"https://pixabay.com/get/55e8d5474a52ad14f1dc8460825668204022dfe05555754d742d79d0/autumn-3804001_640.jpg\" , title : \"The Wild, Untold Story of SharePoint!\" , name : \"Ebonee Gallyhaock\" , profileImageSrc : \"https://robohash.org/delectusetcorporis.bmp?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"6/29/2019\" }, { thumbnail : \"https://pixabay.com/get/57e8dd454c50ac14f1dc8460825668204022dfe05555754d742c72d7/log-cabin-1886620_640.jpg\" , title : \"Low Code Solutions: PowerApps\" , name : \"Seward Keith\" , profileImageSrc : \"https://robohash.org/asperioresautquasi.jpg?size=50x50&set=set1\" , location : \"PowerApps\" , activity : \"12/31/2018\" }, { thumbnail : \"https://pixabay.com/get/55e3d445495aa514f1dc8460825668204022dfe05555754d742b7dd5/portrait-3316389_640.jpg\" , title : \"Not Your Grandpa's SharePoint\" , name : \"Sharona Selkirk\" , profileImageSrc : \"https://robohash.org/velnammolestiae.png?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"11/20/2018\" }, { thumbnail : \"https://pixabay.com/get/57e6dd474352ae14f1dc8460825668204022dfe05555754d742a7ed1/faucet-1684902_640.jpg\" , title : \"Get with the Flow\" , name : \"Boyce Batstone\" , profileImageSrc : \"https://robohash.org/nulladistinctiomollitia.jpg?size=50x50&set=set1\" , location : \"Flow\" , activity : \"5/26/2019\" }] }; } Because you will implement the method to render each item in your web part, your items can be anything you'd like. Our sample data defines a thumbnail , title , name , profileImageSrc , location and activity to coincide with the Fabric UI DocumentCard elements, but you can use any properties you need. In the component that will call the GridLayout control, create callback function to render every item in the grid. You can return any rectangular element you want. For example, this code uses the Fabric UI DocumentCard control. import { DocumentCard , DocumentCardActivity , DocumentCardPreview , DocumentCardDetails , DocumentCardTitle , IDocumentCardPreviewProps , DocumentCardLocation , DocumentCardType } from 'office-ui-fabric-react/lib/DocumentCard' ; import { ImageFit } from 'office-ui-fabric-react/lib/Image' ; import { ISize } from 'office-ui-fabric-react/lib/Utilities' ; ... private _onRenderGridItem = ( item : any , finalSize : ISize , isCompact : boolean ) : JSX . Element => { const previewProps : IDocumentCardPreviewProps = { previewImages : [ { previewImageSrc : item.thumbnail , imageFit : ImageFit.cover , height : 130 } ] }; return < div data - is - focusable = { true } role = \"listitem\" aria - label = { item . title } > < DocumentCard type = { isCompact ? DocumentCardType.compact : DocumentCardType.normal } onClick = {( ev : React.SyntheticEvent < HTMLElement > ) => alert ( \"You clicked on a grid item\" )} > < DocumentCardPreview {... previewProps } /> { ! isCompact && < DocumentCardLocation location = { item . location } /> } < DocumentCardDetails > < DocumentCardTitle title = { item . title } shouldTruncate = { true } /> < DocumentCardActivity activity = { item . activity } people = {[{ name : item.name , profileImageSrc : item.profileImageSrc }]} /> < /DocumentCardDetails> < /DocumentCard> < /div>; } Note that the sample code above uses the isCompact parameter to remove DocumentCard elements and to render a compact layout. You may choose to ignore the isCompact parameter if you do not wish to handle compact layouts. Use the GridLayout control in your code as follows: < GridLayout ariaLabel = \"List of content, use right and left arrow keys to navigate, arrow down to access details.\" items = { this . state . items } onRenderGridItem = {( item : any , finalSize : ISize , isCompact : boolean ) => this . _onRenderGridItem ( item , finalSize , isCompact )} /> Implementation \u00b6 The grid layout control can be configured with the following properties: Property Type Required Description ariaLabel string no The accessible text you wish to display for the grid control. We recommend that you use \"List of content, use right and left arrow keys to navigate, arrow down to access details.\" . items any[] yes The array of items you wish to display. listProps IListProps no Provides additional list properties to customize the underlaying list. onRenderGridItem function yes onRenderGridItem handler for the grid layout. Use this handler to specify how you wish to render each grid item","title":"GridLayout"},{"location":"controls/GridLayout/#grid-layout-control","text":"This control renders a responsive grid layout for your web parts. The grid layout behaves according to the SharePoint web part layouts design pattern . The grid layout will automatically reflow grid items according to the space available for the control. On mobile devices and 1/3 column layouts, it will render a compact layout. Although it is best used with the Fabric UI DocumentCard control , it will render any rectangular content you wish to display.","title":"Grid Layout control"},{"location":"controls/GridLayout/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { GridLayout } from \"@pnp/spfx-controls-react/lib/GridLayout\" ; Retrieve the items you wish to display in your grid control. For example, you can place them in your component's state : // This sample places loads items in the constructor. You may wish to load // your items in the componentDidUpdate constructor ( props : IMyWebPartProps ) { super ( props ); this . state = { items : [{ thumbnail : \"https://pixabay.com/get/57e9dd474952a414f1dc8460825668204022dfe05555754d742e7bd6/hot-air-balloons-1984308_640.jpg\" , title : \"Adventures in SPFx\" , name : \"Perry Losselyong\" , profileImageSrc : \"https://robohash.org/blanditiisadlabore.png?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"3/13/2019\" }, { thumbnail : \"https://pixabay.com/get/55e8d5474a52ad14f1dc8460825668204022dfe05555754d742d79d0/autumn-3804001_640.jpg\" , title : \"The Wild, Untold Story of SharePoint!\" , name : \"Ebonee Gallyhaock\" , profileImageSrc : \"https://robohash.org/delectusetcorporis.bmp?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"6/29/2019\" }, { thumbnail : \"https://pixabay.com/get/57e8dd454c50ac14f1dc8460825668204022dfe05555754d742c72d7/log-cabin-1886620_640.jpg\" , title : \"Low Code Solutions: PowerApps\" , name : \"Seward Keith\" , profileImageSrc : \"https://robohash.org/asperioresautquasi.jpg?size=50x50&set=set1\" , location : \"PowerApps\" , activity : \"12/31/2018\" }, { thumbnail : \"https://pixabay.com/get/55e3d445495aa514f1dc8460825668204022dfe05555754d742b7dd5/portrait-3316389_640.jpg\" , title : \"Not Your Grandpa's SharePoint\" , name : \"Sharona Selkirk\" , profileImageSrc : \"https://robohash.org/velnammolestiae.png?size=50x50&set=set1\" , location : \"SharePoint\" , activity : \"11/20/2018\" }, { thumbnail : \"https://pixabay.com/get/57e6dd474352ae14f1dc8460825668204022dfe05555754d742a7ed1/faucet-1684902_640.jpg\" , title : \"Get with the Flow\" , name : \"Boyce Batstone\" , profileImageSrc : \"https://robohash.org/nulladistinctiomollitia.jpg?size=50x50&set=set1\" , location : \"Flow\" , activity : \"5/26/2019\" }] }; } Because you will implement the method to render each item in your web part, your items can be anything you'd like. Our sample data defines a thumbnail , title , name , profileImageSrc , location and activity to coincide with the Fabric UI DocumentCard elements, but you can use any properties you need. In the component that will call the GridLayout control, create callback function to render every item in the grid. You can return any rectangular element you want. For example, this code uses the Fabric UI DocumentCard control. import { DocumentCard , DocumentCardActivity , DocumentCardPreview , DocumentCardDetails , DocumentCardTitle , IDocumentCardPreviewProps , DocumentCardLocation , DocumentCardType } from 'office-ui-fabric-react/lib/DocumentCard' ; import { ImageFit } from 'office-ui-fabric-react/lib/Image' ; import { ISize } from 'office-ui-fabric-react/lib/Utilities' ; ... private _onRenderGridItem = ( item : any , finalSize : ISize , isCompact : boolean ) : JSX . Element => { const previewProps : IDocumentCardPreviewProps = { previewImages : [ { previewImageSrc : item.thumbnail , imageFit : ImageFit.cover , height : 130 } ] }; return < div data - is - focusable = { true } role = \"listitem\" aria - label = { item . title } > < DocumentCard type = { isCompact ? DocumentCardType.compact : DocumentCardType.normal } onClick = {( ev : React.SyntheticEvent < HTMLElement > ) => alert ( \"You clicked on a grid item\" )} > < DocumentCardPreview {... previewProps } /> { ! isCompact && < DocumentCardLocation location = { item . location } /> } < DocumentCardDetails > < DocumentCardTitle title = { item . title } shouldTruncate = { true } /> < DocumentCardActivity activity = { item . activity } people = {[{ name : item.name , profileImageSrc : item.profileImageSrc }]} /> < /DocumentCardDetails> < /DocumentCard> < /div>; } Note that the sample code above uses the isCompact parameter to remove DocumentCard elements and to render a compact layout. You may choose to ignore the isCompact parameter if you do not wish to handle compact layouts. Use the GridLayout control in your code as follows: < GridLayout ariaLabel = \"List of content, use right and left arrow keys to navigate, arrow down to access details.\" items = { this . state . items } onRenderGridItem = {( item : any , finalSize : ISize , isCompact : boolean ) => this . _onRenderGridItem ( item , finalSize , isCompact )} />","title":"How to use this control in your solutions"},{"location":"controls/GridLayout/#implementation","text":"The grid layout control can be configured with the following properties: Property Type Required Description ariaLabel string no The accessible text you wish to display for the grid control. We recommend that you use \"List of content, use right and left arrow keys to navigate, arrow down to access details.\" . items any[] yes The array of items you wish to display. listProps IListProps no Provides additional list properties to customize the underlaying list. onRenderGridItem function yes onRenderGridItem handler for the grid layout. Use this handler to specify how you wish to render each grid item","title":"Implementation"},{"location":"controls/HoverReactionsBar/","text":"HoverReactionsBar \u00b6 This control allows you to select an emoji from emoji bar or select from picker. HoverReactionsBar How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { HoverReactionsBar } from '@pnp/spfx-controls-react/lib/HoverReactionsBar' ; Use the HoverReactionsBar control in your code as follows: < HoverReactionsBar isOpen = { isOpenHoverReactionBar } onSelect = { onSelectEmoji } onDismiss = {() : void => { setIsOpenHoverReactionBar ( false ); }} target = { divRefAddReaction . current as HTMLDivElement } /> With the onSelect property you can get the selected emoji: const onSelectEmoji = React . useCallback ( async ( emoji : string , emojiInfo : IEmojiInfo ) => { console . log ( 'emoji' , emoji ); console . log ( 'emojiInfo object' , emojiInfo ); setIsOpenHoverReactionBar ( false ); }, []); onSelect : ( emoji : string | undefined , emojiInfo? : IEmojiInfo ) => void ; isOpen : boolean ; onDismiss : () => void ; top4Reactions? : string []; target : HTMLDivElement ; themeV8? : Theme ; Implementation \u00b6 The HoverReactionsBar control can be configured with the following properties: Property Type Required Description isOpen boolean yes show hoverReactionsBar onSelected onSelect: (emoji: string, emojiInfo?: IEmojiInfo) => void; yes selected Emoji top4Reactions string[] no name of emojis to show on the bar target HTMLDivElement yes container of controls who fire the HoverReactionsBar onDismis onDismiss: () => void; yes function to call to dismiss HoverReactionsBar themeV8 Theme No Set Fluent UI Theme","title":"HoverReactionsBar"},{"location":"controls/HoverReactionsBar/#hoverreactionsbar","text":"This control allows you to select an emoji from emoji bar or select from picker. HoverReactionsBar","title":"HoverReactionsBar"},{"location":"controls/HoverReactionsBar/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { HoverReactionsBar } from '@pnp/spfx-controls-react/lib/HoverReactionsBar' ; Use the HoverReactionsBar control in your code as follows: < HoverReactionsBar isOpen = { isOpenHoverReactionBar } onSelect = { onSelectEmoji } onDismiss = {() : void => { setIsOpenHoverReactionBar ( false ); }} target = { divRefAddReaction . current as HTMLDivElement } /> With the onSelect property you can get the selected emoji: const onSelectEmoji = React . useCallback ( async ( emoji : string , emojiInfo : IEmojiInfo ) => { console . log ( 'emoji' , emoji ); console . log ( 'emojiInfo object' , emojiInfo ); setIsOpenHoverReactionBar ( false ); }, []); onSelect : ( emoji : string | undefined , emojiInfo? : IEmojiInfo ) => void ; isOpen : boolean ; onDismiss : () => void ; top4Reactions? : string []; target : HTMLDivElement ; themeV8? : Theme ;","title":"How to use this control in your solutions"},{"location":"controls/HoverReactionsBar/#implementation","text":"The HoverReactionsBar control can be configured with the following properties: Property Type Required Description isOpen boolean yes show hoverReactionsBar onSelected onSelect: (emoji: string, emojiInfo?: IEmojiInfo) => void; yes selected Emoji top4Reactions string[] no name of emojis to show on the bar target HTMLDivElement yes container of controls who fire the HoverReactionsBar onDismis onDismiss: () => void; yes function to call to dismiss HoverReactionsBar themeV8 Theme No Set Fluent UI Theme","title":"Implementation"},{"location":"controls/IFrameDialog/","text":"IFrameDialog control \u00b6 This control renders a Dialog with an iframe as content. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IFrameDialog } from \"@pnp/spfx-controls-react/lib/IFrameDialog\" ; Use the IFrameDialog control in your code as follows ( this._onIframeLoaded and this._onDialogDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively): < IFrameDialog url = { this . state . lookupDispFormUrl } iframeOnLoad = { this . _onIframeLoaded . bind ( this )} hidden = { this . state . hideDialog } onDismiss = { this . _onDialogDismiss . bind ( this )} modalProps = {{ isBlocking : true , containerClassName : styles.dialogContainer }} dialogContentProps = {{ type : DialogType . close , showCloseButton : true }} width = { '570px' } height = { '315px' } /> Implementation \u00b6 The IFrameDialog component can be configured with the following properties: Property Type Required Description dialogContentProps IDialogContentProps no Props to be passed through to Dialog Content. hidden boolean no Whether the dialog is hidden. modalProps IModalProps no Props to be passed through to Modal. onDismiss (ev?: React.MouseEvent ) => any no A callback function for when the Dialog is dismissed from the close button or light dismiss. Can also be specified separately in content and modal. url string yes iframe Url iframeOnload iframeOnLoad?: (iframe: any) => {} no iframe's onload event handler width string yes iframe's width heigth string yes iframe's height allowFullScreen boolean no Specifies if iframe content can be displayed in a full screen allowTransparency boolean no Specifies if transparency is allowed in iframe marginHeight number no Specifies the top and bottom margins of the content of an iframe marginWidth number no Specifies the left and right margins of the content of an iframe name string no Specifies the name of an iframe sandbox string no Enables an extra set of restrictions for the content in an iframe scrolling string no Specifies whether or not to display scrollbars in an iframe seamless string no When present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)","title":"IFrameDialog"},{"location":"controls/IFrameDialog/#iframedialog-control","text":"This control renders a Dialog with an iframe as content. Here is an example of the control in action:","title":"IFrameDialog control"},{"location":"controls/IFrameDialog/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IFrameDialog } from \"@pnp/spfx-controls-react/lib/IFrameDialog\" ; Use the IFrameDialog control in your code as follows ( this._onIframeLoaded and this._onDialogDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively): < IFrameDialog url = { this . state . lookupDispFormUrl } iframeOnLoad = { this . _onIframeLoaded . bind ( this )} hidden = { this . state . hideDialog } onDismiss = { this . _onDialogDismiss . bind ( this )} modalProps = {{ isBlocking : true , containerClassName : styles.dialogContainer }} dialogContentProps = {{ type : DialogType . close , showCloseButton : true }} width = { '570px' } height = { '315px' } />","title":"How to use this control in your solutions"},{"location":"controls/IFrameDialog/#implementation","text":"The IFrameDialog component can be configured with the following properties: Property Type Required Description dialogContentProps IDialogContentProps no Props to be passed through to Dialog Content. hidden boolean no Whether the dialog is hidden. modalProps IModalProps no Props to be passed through to Modal. onDismiss (ev?: React.MouseEvent ) => any no A callback function for when the Dialog is dismissed from the close button or light dismiss. Can also be specified separately in content and modal. url string yes iframe Url iframeOnload iframeOnLoad?: (iframe: any) => {} no iframe's onload event handler width string yes iframe's width heigth string yes iframe's height allowFullScreen boolean no Specifies if iframe content can be displayed in a full screen allowTransparency boolean no Specifies if transparency is allowed in iframe marginHeight number no Specifies the top and bottom margins of the content of an iframe marginWidth number no Specifies the left and right margins of the content of an iframe name string no Specifies the name of an iframe sandbox string no Enables an extra set of restrictions for the content in an iframe scrolling string no Specifies whether or not to display scrollbars in an iframe seamless string no When present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)","title":"Implementation"},{"location":"controls/IFramePanel/","text":"IFramePanel control \u00b6 This control renders a Panel with an iframe as content. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IFramePanel } from \"@pnp/spfx-controls-react/lib/IFramePanel\" ; The IFramePanel uses the Office Fabric UI implemenation of the panel . The properties of this control inherit the panel properties. Use the IFramePanel control in your code as follows ( this._onIframeLoaded and this._onDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively.) < IFramePanel url = { this . state . iFrameUrl } type = { PanelType . medium } headerText = \"Panel Title\" closeButtonAriaLabel = \"Close\" isOpen = { this . state . iFramePanelOpened } onDismiss = { this . _onDismiss . bind ( this )} iframeOnLoad = { this . _onIframeLoaded . bind ( this )} /> Implementation \u00b6 The IFramePanel component extends the properties from the Fabric UI IPanelProps along with the additional following properties: Property Type Required Description url string yes iframe Url heigth string yes iframe's height, if empty it will be dynamically set to the full height available in the panel's content area iframeOnload iframeOnLoad?: (iframe: any) => {} no iframe's onload event handler name string no Specifies the name of an iframe allowFullScreen boolean no Specifies if iframe content can be displayed in a full screen allowTransparency boolean no Specifies if transparency is allowed in iframe sandbox string no Enables an extra set of restrictions for the content in an iframe scrolling string no Specifies whether or not to display scrollbars in an iframe seamless string no When present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)","title":"IFramePanel"},{"location":"controls/IFramePanel/#iframepanel-control","text":"This control renders a Panel with an iframe as content. Here is an example of the control in action:","title":"IFramePanel control"},{"location":"controls/IFramePanel/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IFramePanel } from \"@pnp/spfx-controls-react/lib/IFramePanel\" ; The IFramePanel uses the Office Fabric UI implemenation of the panel . The properties of this control inherit the panel properties. Use the IFramePanel control in your code as follows ( this._onIframeLoaded and this._onDismiss are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively.) < IFramePanel url = { this . state . iFrameUrl } type = { PanelType . medium } headerText = \"Panel Title\" closeButtonAriaLabel = \"Close\" isOpen = { this . state . iFramePanelOpened } onDismiss = { this . _onDismiss . bind ( this )} iframeOnLoad = { this . _onIframeLoaded . bind ( this )} />","title":"How to use this control in your solutions"},{"location":"controls/IFramePanel/#implementation","text":"The IFramePanel component extends the properties from the Fabric UI IPanelProps along with the additional following properties: Property Type Required Description url string yes iframe Url heigth string yes iframe's height, if empty it will be dynamically set to the full height available in the panel's content area iframeOnload iframeOnLoad?: (iframe: any) => {} no iframe's onload event handler name string no Specifies the name of an iframe allowFullScreen boolean no Specifies if iframe content can be displayed in a full screen allowTransparency boolean no Specifies if transparency is allowed in iframe sandbox string no Enables an extra set of restrictions for the content in an iframe scrolling string no Specifies whether or not to display scrollbars in an iframe seamless string no When present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars)","title":"Implementation"},{"location":"controls/IconPicker/","text":"IconPicker control \u00b6 Control that allows to search and select an icon from office-ui-fabric-react icons. Overview \u00b6 The control allows selecting an icon from the list of icons available in the office-ui-fabric-react library. Icon list is a static copy of available icons. Currently, only one icon selection is supported. Displayed in the panel \u00b6 Icon picker always opens a new panel where you can pick an icon. The panel displays all the icons and maintains readability. Picker does not displays selected icon outside the panel. Displayed in the dialog \u00b6 Icon picker always opens a new dialog where you can pick an icon. The dialog displays all the icons and maintains readability. Picker does not displays selected icon outside the dialog. How to use this control \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker' ; Use the IconPicker control in your code as follows: < IconPicker buttonLabel = { 'Icon' } onChange = {( iconName : string ) => { this . setState ({ icon : iconName }); }} onSave = {( iconName : string ) => { this . setState ({ icon : iconName }); }} /> < IconPicker buttonLabel = { 'Icon' } renderOption = { 'dialog' } onChange = {( iconName : string ) => { this . setState ({ icon : iconName }); }} onSave = {( iconName : string ) => { this . setState ({ icon : iconName }); }} /> Implementation \u00b6 The IconPicker component can be configured with the following properties: Property Type Required Description buttonLabel string no Specifies the label of the icon picker button. onSave (iconName: string) => void yes Handler when the icon has been selected and picker has been closed. onCancel () => void no Handler when the panel is closed. onChange (iconName: string) => void no Handler when the icon selection has been changed. disabled boolean no Specifies if the picker button is disabled buttonClassName boolean no If provided, additional class name will be added to the picker button panelClassName boolean no If provided, additional class name will be added to the picker panel currentIcon string no Specifies default selected icon renderOption dialog , panel no Specifies how to render list of Icons, Values : 'Panel' or 'Dialog' defualt value 'Panel' useStartsWithSearch boolean no Specifies if we need to use startsWith when searching for the icons.","title":"IconPicker"},{"location":"controls/IconPicker/#iconpicker-control","text":"Control that allows to search and select an icon from office-ui-fabric-react icons.","title":"IconPicker control"},{"location":"controls/IconPicker/#overview","text":"The control allows selecting an icon from the list of icons available in the office-ui-fabric-react library. Icon list is a static copy of available icons. Currently, only one icon selection is supported.","title":"Overview"},{"location":"controls/IconPicker/#displayed-in-the-panel","text":"Icon picker always opens a new panel where you can pick an icon. The panel displays all the icons and maintains readability. Picker does not displays selected icon outside the panel.","title":"Displayed in the panel"},{"location":"controls/IconPicker/#displayed-in-the-dialog","text":"Icon picker always opens a new dialog where you can pick an icon. The dialog displays all the icons and maintains readability. Picker does not displays selected icon outside the dialog.","title":"Displayed in the dialog"},{"location":"controls/IconPicker/#how-to-use-this-control","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following module to your component: import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker' ; Use the IconPicker control in your code as follows: < IconPicker buttonLabel = { 'Icon' } onChange = {( iconName : string ) => { this . setState ({ icon : iconName }); }} onSave = {( iconName : string ) => { this . setState ({ icon : iconName }); }} /> < IconPicker buttonLabel = { 'Icon' } renderOption = { 'dialog' } onChange = {( iconName : string ) => { this . setState ({ icon : iconName }); }} onSave = {( iconName : string ) => { this . setState ({ icon : iconName }); }} />","title":"How to use this control"},{"location":"controls/IconPicker/#implementation","text":"The IconPicker component can be configured with the following properties: Property Type Required Description buttonLabel string no Specifies the label of the icon picker button. onSave (iconName: string) => void yes Handler when the icon has been selected and picker has been closed. onCancel () => void no Handler when the panel is closed. onChange (iconName: string) => void no Handler when the icon selection has been changed. disabled boolean no Specifies if the picker button is disabled buttonClassName boolean no If provided, additional class name will be added to the picker button panelClassName boolean no If provided, additional class name will be added to the picker panel currentIcon string no Specifies default selected icon renderOption dialog , panel no Specifies how to render list of Icons, Values : 'Panel' or 'Dialog' defualt value 'Panel' useStartsWithSearch boolean no Specifies if we need to use startsWith when searching for the icons.","title":"Implementation"},{"location":"controls/ImagePicker/","text":"HoverReactionsBar \u00b6 This control allows you to select or Upload Image from SharePoint, Ondrive or Stock Images. ImagePicker \u00b6 How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ImagePicker } from '@pnp/spfx-controls-react/lib/ImagePicker' ; Use the ImagePicker control in your code as follows: < ImagePicker onFileSelected = { handleFileSelected } onDeleteFile = { handleDeleteFile } selectedFileUrl = { selectedImageUrl } context = { appContext } > With the onFileSelect property you can get the selected image: typescript const handleFileSelected = React.useCallback(async (file: IFilePickerResult) => { console.log(\"file\", file); }, []); With the onDelete property you can execute a callback after delete the image: const onDeleteFile = React . useCallback ( async () => { console . log ( \"onDeleteFile\" ); }, []); Implementation \u00b6 The HoverReactionsBar control can be configured with the following properties: Property Type Required Description onFileSelected onFileSelect: (file: IFilePickerResult ) => void; yes OnSelectedFile Callback onDeleteFile onDeleteFile: () => void no onDeleteFile CallBack selectedFileUrl string no Default Selected Image context BaseComponentContext yes Context","title":"HoverReactionsBar"},{"location":"controls/ImagePicker/#hoverreactionsbar","text":"This control allows you to select or Upload Image from SharePoint, Ondrive or Stock Images.","title":"HoverReactionsBar"},{"location":"controls/ImagePicker/#imagepicker","text":"","title":"ImagePicker"},{"location":"controls/ImagePicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ImagePicker } from '@pnp/spfx-controls-react/lib/ImagePicker' ; Use the ImagePicker control in your code as follows: < ImagePicker onFileSelected = { handleFileSelected } onDeleteFile = { handleDeleteFile } selectedFileUrl = { selectedImageUrl } context = { appContext } > With the onFileSelect property you can get the selected image: typescript const handleFileSelected = React.useCallback(async (file: IFilePickerResult) => { console.log(\"file\", file); }, []); With the onDelete property you can execute a callback after delete the image: const onDeleteFile = React . useCallback ( async () => { console . log ( \"onDeleteFile\" ); }, []);","title":"How to use this control in your solutions"},{"location":"controls/ImagePicker/#implementation","text":"The HoverReactionsBar control can be configured with the following properties: Property Type Required Description onFileSelected onFileSelect: (file: IFilePickerResult ) => void; yes OnSelectedFile Callback onDeleteFile onDeleteFile: () => void no onDeleteFile CallBack selectedFileUrl string no Default Selected Image context BaseComponentContext yes Context","title":"Implementation"},{"location":"controls/ListItemAttachments/","text":"ListItemAttachments control \u00b6 This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments are listed in tile view. Here is an example of the control: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttachments' ; Use the ListItemAttachments control in your code as follows: < ListItemAttachments listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } context = { this . props . context } disabled = { false } /> If You want to use ListItemAttachments controls with new form You have to use React.createRef. Following example will add selected attachments to list item with id = 1 let listItemAttachmentsComponentReference = React . createRef < ListItemAttachments > (); ... < ListItemAttachments ref = { listItemAttachmentsComponentReference } context = { this . props . context } listId = \"dfcfdb95-2488-4757-b55b-14d94166ad87\" itemId = { 0 } /> ... < PrimaryButton text = \"Save to Item with id 1\" onClick = {()=>{ //@ts-ignore listItemAttachmentsComponentReference . current . uploadAttachments ( 1 ); }} /> Implementation \u00b6 The ListItemAttachments control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes SPFx web part or extention context itemId number no List Item Id listId string yes Guid of the list. webUrl string no URL of the site. By default it uses the current site URL. label string no Main text to display on the placeholder, next to the icon. description string no Description text to display on the placeholder, below the main text and icon. disabled boolean no Specifies if the control is disabled or not. openAttachmentsInNewWindow boolean no Specifies if the attachment should be openend in a separate browser tab. Use this property set to true if you plan to use the component in Microsoft Teams.","title":"ListItemAttachments"},{"location":"controls/ListItemAttachments/#listitemattachments-control","text":"This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments are listed in tile view. Here is an example of the control:","title":"ListItemAttachments control"},{"location":"controls/ListItemAttachments/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttachments' ; Use the ListItemAttachments control in your code as follows: < ListItemAttachments listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } context = { this . props . context } disabled = { false } /> If You want to use ListItemAttachments controls with new form You have to use React.createRef. Following example will add selected attachments to list item with id = 1 let listItemAttachmentsComponentReference = React . createRef < ListItemAttachments > (); ... < ListItemAttachments ref = { listItemAttachmentsComponentReference } context = { this . props . context } listId = \"dfcfdb95-2488-4757-b55b-14d94166ad87\" itemId = { 0 } /> ... < PrimaryButton text = \"Save to Item with id 1\" onClick = {()=>{ //@ts-ignore listItemAttachmentsComponentReference . current . uploadAttachments ( 1 ); }} />","title":"How to use this control in your solutions"},{"location":"controls/ListItemAttachments/#implementation","text":"The ListItemAttachments control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes SPFx web part or extention context itemId number no List Item Id listId string yes Guid of the list. webUrl string no URL of the site. By default it uses the current site URL. label string no Main text to display on the placeholder, next to the icon. description string no Description text to display on the placeholder, below the main text and icon. disabled boolean no Specifies if the control is disabled or not. openAttachmentsInNewWindow boolean no Specifies if the attachment should be openend in a separate browser tab. Use this property set to true if you plan to use the component in Microsoft Teams.","title":"Implementation"},{"location":"controls/ListItemComments/","text":"ListItemComments control \u00b6 This control allows you to manage list item comments, you can add or delete comments to an item. The comments are listed in tile view. user can scroll to load more comments if they exist (infinite scroll); Here is an example of the control: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemComments } from '@pnp/spfx-controls-react/lib/ListItemComments' ; Use the ListItemComments control in your code as follows: < ListItemComments webUrl = '{\"https://contoso.sharepoint.com/sites/ThePerspective\"}' listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } serviceScope = { serviceScope } numberCommentsPerPage = { 10 } label = \"ListItem Comments\" /> Use \"highlightedCommentId\" parameter to support Comment Notification Link \u00b6 SharePoint will send a comment notification if someone has been \"@\" in the comment. This comment notification mail contains a Go to comment button. The \"Go to Comment\" link is like https://xxx.sharepoint.com/sites/xxxx/Lists/MyList/DispForm.aspx?ID=1&commentId=1&e=LURoEsg5Zki4cS4SgcIG7w&at=15&CT=1674882847351&OR=OWA-NT&CID=c3a04ee0-40b5-9591-e6a4-3fac33046a64 , which contains commentId in url parameter. The comment whose id is commentId will be highlighted in the OOTB SharePoint List Item page. You can use highlightedCommentId to specify the comment you want to highlight in ListItemComments control. < ListItemComments webUrl = '{\"https://contoso.sharepoint.com/sites/ThePerspective\"}' listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } serviceScope = { serviceScope } numberCommentsPerPage = { 10 } highlightedCommentId = { \"1\" } label = \"ListItem Comments\" /> The specified comment will be highlighted with different border and background color (Use theme color). Implementation \u00b6 The ListItemComments control can be configured with the following properties: Property Type Required Description serviceScope ServiceScope yes SPFx Service Scope itemId number yes List Item Id listId string yes Guid of the list. webUrl string no URL of the site. By default it uses the current site URL. label string no Label for control numberCommentsPerPage number no number of comments per page possible values 5 highlightedCommentId string no The commend Id (e.g. \"1\") you want to highlight. This selected comment will show with different border and background color based on site theme MSGraph Permissions required \u00b6 This control requires at least the flowing scopes: People.Read , User.ReadBasic.All","title":"ListItemComments"},{"location":"controls/ListItemComments/#listitemcomments-control","text":"This control allows you to manage list item comments, you can add or delete comments to an item. The comments are listed in tile view. user can scroll to load more comments if they exist (infinite scroll); Here is an example of the control:","title":"ListItemComments control"},{"location":"controls/ListItemComments/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemComments } from '@pnp/spfx-controls-react/lib/ListItemComments' ; Use the ListItemComments control in your code as follows: < ListItemComments webUrl = '{\"https://contoso.sharepoint.com/sites/ThePerspective\"}' listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } serviceScope = { serviceScope } numberCommentsPerPage = { 10 } label = \"ListItem Comments\" />","title":"How to use this control in your solutions"},{"location":"controls/ListItemComments/#use-highlightedcommentid-parameter-to-support-comment-notification-link","text":"SharePoint will send a comment notification if someone has been \"@\" in the comment. This comment notification mail contains a Go to comment button. The \"Go to Comment\" link is like https://xxx.sharepoint.com/sites/xxxx/Lists/MyList/DispForm.aspx?ID=1&commentId=1&e=LURoEsg5Zki4cS4SgcIG7w&at=15&CT=1674882847351&OR=OWA-NT&CID=c3a04ee0-40b5-9591-e6a4-3fac33046a64 , which contains commentId in url parameter. The comment whose id is commentId will be highlighted in the OOTB SharePoint List Item page. You can use highlightedCommentId to specify the comment you want to highlight in ListItemComments control. < ListItemComments webUrl = '{\"https://contoso.sharepoint.com/sites/ThePerspective\"}' listId = 'dfa283f4-5faf-4d54-b6b8-5bcaf2725af5' itemId = { 1 } serviceScope = { serviceScope } numberCommentsPerPage = { 10 } highlightedCommentId = { \"1\" } label = \"ListItem Comments\" /> The specified comment will be highlighted with different border and background color (Use theme color).","title":"Use \"highlightedCommentId\" parameter to support Comment Notification Link"},{"location":"controls/ListItemComments/#implementation","text":"The ListItemComments control can be configured with the following properties: Property Type Required Description serviceScope ServiceScope yes SPFx Service Scope itemId number yes List Item Id listId string yes Guid of the list. webUrl string no URL of the site. By default it uses the current site URL. label string no Label for control numberCommentsPerPage number no number of comments per page possible values 5 highlightedCommentId string no The commend Id (e.g. \"1\") you want to highlight. This selected comment will show with different border and background color based on site theme","title":"Implementation"},{"location":"controls/ListItemComments/#msgraph-permissions-required","text":"This control requires at least the flowing scopes: People.Read , User.ReadBasic.All","title":"MSGraph Permissions required"},{"location":"controls/ListItemPicker/","text":"ListItemPicker control \u00b6 This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value. Here is an example of the control: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker' ; Use the ListItemPicker control in your code as follows: < ListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" orderBy = { \"Id desc\" } itemLimit = { 2 } onSelectedItem = { this . onSelectedItem } context = { this . props . context } /> The onSelectedItem change event returns the list items selected and can be implemented as follows: private onSelectedItem ( data : { key : string ; name : string }[]) { for ( const item of data ) { console . log ( `Item value: ${ item . key } ` ); console . log ( `Item text: ${ item . name } ` ); } } Implementation \u00b6 The ListItemPicker control can be configured with the following properties: Property Type Required Description columnInternalName string yes InternalName of column to search and get values. keyColumnInternalName string no InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id context BaseComponentContext yes SPFx web part or extention context listId string yes Guid or title of the list. itemLimit number yes Number of items which can be selected onSelectedItem (items: any[]) => void yes Callback function which returns the selected items. className string no ClassName for the picker. webUrl string no URL of the site. By default it uses the current site URL. defaultSelectedItems any[] no Initial items that have already been selected and should appear in the people picker. suggestionsHeaderText string no The text that should appear at the top of the suggestion box. noResultsFoundText string no The text that should appear when no results are returned. disabled boolean no Specifies if the control is disabled or not. filter string no condition to filter list Item, same as $filter ODATA parameter orderBy string no condition to order by list Item, same as $orderby ODATA parameter placeholder string no Short text hint to display in empty picker substringSearch boolean no Specifies if substring search should be used label string no Specifies the text describing the ListItemPicker. enableDefaultSuggestions boolean no Enable default suggestions. All options are displayed by default when clicking on the control. itemsQueryCountLimit number no Number of items to display in a lookup field","title":"ListItemPicker"},{"location":"controls/ListItemPicker/#listitempicker-control","text":"This control allows you to select one or more items from a list. The List can be filtered to allow select items from a subset of items The item selection is based from a column value. The control will suggest items based on the inserted value. Here is an example of the control:","title":"ListItemPicker control"},{"location":"controls/ListItemPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker' ; Use the ListItemPicker control in your code as follows: < ListItemPicker listId = 'da8daf15-d84f-4ab1-9800-7568f82fed3f' columnInternalName = 'Title' keyColumnInternalName = 'Id' filter = \"Title eq 'SPFx'\" orderBy = { \"Id desc\" } itemLimit = { 2 } onSelectedItem = { this . onSelectedItem } context = { this . props . context } /> The onSelectedItem change event returns the list items selected and can be implemented as follows: private onSelectedItem ( data : { key : string ; name : string }[]) { for ( const item of data ) { console . log ( `Item value: ${ item . key } ` ); console . log ( `Item text: ${ item . name } ` ); } }","title":"How to use this control in your solutions"},{"location":"controls/ListItemPicker/#implementation","text":"The ListItemPicker control can be configured with the following properties: Property Type Required Description columnInternalName string yes InternalName of column to search and get values. keyColumnInternalName string no InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id context BaseComponentContext yes SPFx web part or extention context listId string yes Guid or title of the list. itemLimit number yes Number of items which can be selected onSelectedItem (items: any[]) => void yes Callback function which returns the selected items. className string no ClassName for the picker. webUrl string no URL of the site. By default it uses the current site URL. defaultSelectedItems any[] no Initial items that have already been selected and should appear in the people picker. suggestionsHeaderText string no The text that should appear at the top of the suggestion box. noResultsFoundText string no The text that should appear when no results are returned. disabled boolean no Specifies if the control is disabled or not. filter string no condition to filter list Item, same as $filter ODATA parameter orderBy string no condition to order by list Item, same as $orderby ODATA parameter placeholder string no Short text hint to display in empty picker substringSearch boolean no Specifies if substring search should be used label string no Specifies the text describing the ListItemPicker. enableDefaultSuggestions boolean no Enable default suggestions. All options are displayed by default when clicking on the control. itemsQueryCountLimit number no Number of items to display in a lookup field","title":"Implementation"},{"location":"controls/ListPicker/","text":"ListPicker control \u00b6 This control allows you to select one or multiple available lists/libraries of the current site. Here is an example of the control: ListPicker single selection mode: ListPicker multi-selection mode How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListPicker } from \"@pnp/spfx-controls-react/lib/ListPicker\" ; Use the ListPicker control in your code as follows: < ListPicker context = { this . props . context } label = \"Select your list(s)\" placeHolder = \"Select your list(s)\" baseTemplate = { 100 } contentTypeId = \"0x0101\" includeHidden = { false } multiSelect = { false } onSelectionChanged = { this . onListPickerChange } /> The onSelectionChanged change event returns the list(s) and can be implemented as follows: private onListPickerChange ( lists : string | string []) { console . log ( \"Lists:\" , lists ); } Implementation \u00b6 The ListPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. baseTemplate number | number[] no The SharePoint BaseTemplate ID to filter the list options by. filter string no Filter list from OData query (takes precendents over Hidden and BaseTemplate Filters). includeHidden boolean no Whether or not to include hidden lists. Default is true . orderBy LibsOrderBy no How to order the lists retrieved from SharePoint. selectedList string OR string[] no Keys(list Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default to false . label string no Label to use for the control. placeHolder string no Placeholder label to show in the dropdown. Deprecated. Use placeholder instead. placeholder string no Placeholder label to show in the dropdown. onSelectionChanged (newValue: string OR string[]): void no Callback function when the selected option changes. webAbsoulteUrl string no Absolute Web Url of target site (user requires permissions) contentTypeId string no The Id if a content type which must be present in a list in order for the list to appear in the picker. refreshToggle boolean no If present can be used to force the control to refresh the list of lists by toggling its value Enum LibsOrderBy Value Id Title","title":"ListPicker"},{"location":"controls/ListPicker/#listpicker-control","text":"This control allows you to select one or multiple available lists/libraries of the current site. Here is an example of the control: ListPicker single selection mode: ListPicker multi-selection mode","title":"ListPicker control"},{"location":"controls/ListPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ListPicker } from \"@pnp/spfx-controls-react/lib/ListPicker\" ; Use the ListPicker control in your code as follows: < ListPicker context = { this . props . context } label = \"Select your list(s)\" placeHolder = \"Select your list(s)\" baseTemplate = { 100 } contentTypeId = \"0x0101\" includeHidden = { false } multiSelect = { false } onSelectionChanged = { this . onListPickerChange } /> The onSelectionChanged change event returns the list(s) and can be implemented as follows: private onListPickerChange ( lists : string | string []) { console . log ( \"Lists:\" , lists ); }","title":"How to use this control in your solutions"},{"location":"controls/ListPicker/#implementation","text":"The ListPicker control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. baseTemplate number | number[] no The SharePoint BaseTemplate ID to filter the list options by. filter string no Filter list from OData query (takes precendents over Hidden and BaseTemplate Filters). includeHidden boolean no Whether or not to include hidden lists. Default is true . orderBy LibsOrderBy no How to order the lists retrieved from SharePoint. selectedList string OR string[] no Keys(list Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default to false . label string no Label to use for the control. placeHolder string no Placeholder label to show in the dropdown. Deprecated. Use placeholder instead. placeholder string no Placeholder label to show in the dropdown. onSelectionChanged (newValue: string OR string[]): void no Callback function when the selected option changes. webAbsoulteUrl string no Absolute Web Url of target site (user requires permissions) contentTypeId string no The Id if a content type which must be present in a list in order for the list to appear in the picker. refreshToggle boolean no If present can be used to force the control to refresh the list of lists by toggling its value Enum LibsOrderBy Value Id Title","title":"Implementation"},{"location":"controls/ListView.ContextualMenu/","text":"ListView: Add a contextual menu \u00b6 The ContextualMenu component \u00b6 In order to create a contextual menu for your list view, you first need to create a new component which will use a combination of an IconButton and ContextualMenu controls from the Office UI Fabric React. Here is some sample code: import * as React from 'react' ; import { Layer , IconButton , IButtonProps } from 'office-ui-fabric-react' ; import { ContextualMenuItemType } from 'office-ui-fabric-react/lib/ContextualMenu' ; // The following are project specific components import { IECBProps } from './IECBProps' ; import styles from './ECB.module.scss' ; import { IListitem } from '../../model/IListitem' ; export class ECB extends React . Component < IECBProps , {} > { public constructor ( props : IECBProps ) { super ( props ); this . state = { panelOpen : false }; } public render () { return ( < div className = { styles . ecb } > < IconButton id = 'ContextualMenuButton1' className = { styles . ecbbutton } text = '' width = '30' split = { false } iconProps = { { iconName : 'MoreVertical' } } menuIconProps = { { iconName : '' } } menuProps = {{ shouldFocusOnMount : true , items : [ { key : 'action1' , name : 'Action 1' , onClick : this.handleClick.bind ( this , this . props . item . Firstname + ' Action 1' ) }, { key : 'divider_1' , itemType : ContextualMenuItemType.Divider }, { key : 'action2' , name : 'Action 2' , onClick : this.handleClick.bind ( this , this . props . item . Firstname + ' Action 2' ) }, { key : 'action3' , name : 'Action 3' , onClick : this.handleClick.bind ( this , this . props . item . Lastname + ' Action 3' ) }, { key : 'disabled' , name : 'Disabled action' , disabled : true , onClick : () => console . error ( 'Disabled action should not be clickable.' ) } ] }} /> < /div> ); } private handleClick ( source : string , event ) { alert ( ` ${ source } clicked` ); } } The ListView column \u00b6 Once the ECB component is created, you can add the contextual menu to the ListView control. In order to do this, you have to insert another Viewfield in code at the position of our choice. For instance after the Lastname : { name : \"\" , sorting : false , maxWidth : 40 , render : ( rowitem : IListitem ) => { const element : React.ReactElement < IECBProps > = React . createElement ( ECB , { item : rowitem } ); return element ; } } Inside the render method of the IViewField , the ECB component gets created and the current item will be used as a reference for the clicked row. The result \u00b6 The result will look like the following: Once you click on an action, you will see the alert:","title":"ListView: add a contextual menu"},{"location":"controls/ListView.ContextualMenu/#listview-add-a-contextual-menu","text":"","title":"ListView: Add a contextual menu"},{"location":"controls/ListView.ContextualMenu/#the-contextualmenu-component","text":"In order to create a contextual menu for your list view, you first need to create a new component which will use a combination of an IconButton and ContextualMenu controls from the Office UI Fabric React. Here is some sample code: import * as React from 'react' ; import { Layer , IconButton , IButtonProps } from 'office-ui-fabric-react' ; import { ContextualMenuItemType } from 'office-ui-fabric-react/lib/ContextualMenu' ; // The following are project specific components import { IECBProps } from './IECBProps' ; import styles from './ECB.module.scss' ; import { IListitem } from '../../model/IListitem' ; export class ECB extends React . Component < IECBProps , {} > { public constructor ( props : IECBProps ) { super ( props ); this . state = { panelOpen : false }; } public render () { return ( < div className = { styles . ecb } > < IconButton id = 'ContextualMenuButton1' className = { styles . ecbbutton } text = '' width = '30' split = { false } iconProps = { { iconName : 'MoreVertical' } } menuIconProps = { { iconName : '' } } menuProps = {{ shouldFocusOnMount : true , items : [ { key : 'action1' , name : 'Action 1' , onClick : this.handleClick.bind ( this , this . props . item . Firstname + ' Action 1' ) }, { key : 'divider_1' , itemType : ContextualMenuItemType.Divider }, { key : 'action2' , name : 'Action 2' , onClick : this.handleClick.bind ( this , this . props . item . Firstname + ' Action 2' ) }, { key : 'action3' , name : 'Action 3' , onClick : this.handleClick.bind ( this , this . props . item . Lastname + ' Action 3' ) }, { key : 'disabled' , name : 'Disabled action' , disabled : true , onClick : () => console . error ( 'Disabled action should not be clickable.' ) } ] }} /> < /div> ); } private handleClick ( source : string , event ) { alert ( ` ${ source } clicked` ); } }","title":"The ContextualMenu component"},{"location":"controls/ListView.ContextualMenu/#the-listview-column","text":"Once the ECB component is created, you can add the contextual menu to the ListView control. In order to do this, you have to insert another Viewfield in code at the position of our choice. For instance after the Lastname : { name : \"\" , sorting : false , maxWidth : 40 , render : ( rowitem : IListitem ) => { const element : React.ReactElement < IECBProps > = React . createElement ( ECB , { item : rowitem } ); return element ; } } Inside the render method of the IViewField , the ECB component gets created and the current item will be used as a reference for the clicked row.","title":"The ListView column"},{"location":"controls/ListView.ContextualMenu/#the-result","text":"The result will look like the following: Once you click on an action, you will see the alert:","title":"The result"},{"location":"controls/ListView/","text":"ListView control \u00b6 This control renders a list view for the given set of items. List view control with grouping applied List view control with drag and drop applied How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ListView , IViewField , SelectionMode , GroupOrder , IGrouping } from \"@pnp/spfx-controls-react/lib/ListView\" ; Use the ListView control in your code as follows: < ListView items = { items } viewFields = { viewFields } iconFieldName = \"FileRef\" compact = { true } selectionMode = { SelectionMode . multiple } selection = { this . _getSelection } showFilter = { true } defaultFilter = \"John\" filterPlaceHolder = \"Search...\" groupByFields = { groupByFields } dragDropFiles = { true } onDrop = { this . _getDropFiles } stickyHeader = { true } className = { styles . listWrapper } listClassName = { styles . list } /> The control provides full text filtering through all the columns. If you want to execute filtering on the specified columns, you can use syntax : : . Use ':' as a separator between column name and value. Control support both 'fieldName' and 'name' properties of IColumn interface. With the selection property you can define a method that which gets called when the user selects one or more items in the list view: private _getSelection ( items : any []) { console . log ( 'Selected items:' , items ); } With the groupByFields property you can define an array of field objects which will be used for grouping. Important : the same order of the fields defines how grouping will be applied. In the snippet the ListView control will first group by the Extension and after that by the Author field. const groupByFields : IGrouping [] = [ { name : \"Extension\" , order : GroupOrder.ascending }, { name : \"Author\" , order : GroupOrder.descending } ]; Extend ListView with a ContextualMenu To extend the ListView control with a ContextualMenu refer to ListView.ContextualMenu . With the onDrop handler you can define a method that returns files that where drag and drop by user in the list view: private _getDropFiles = ( files ) => { for ( var i = 0 ; i < files . length ; i ++ ) { console . log ( files [ i ]. name ); } } Implementation \u00b6 The ListView control can be configured with the following properties: Property Type Required Description iconFieldName string no Specify the items' property name that defines the file URL path which will be used to show the file icon. This automatically creates a column and renders the file icon. items any[] no Items to render in the list view. viewFields IViewField[] no The fields you want to render in the list view. Check the IViewField implementation to see which properties you can define. compact boolean no Boolean value to indicate if the control should render in compact mode. By default this is set to false . selectionMode SelectionMode no Specify if the items in the list view can be selected and how. Options are: none, single, multi. selection function no Selection event that passes the selected item(s) from the list view. groupByFields IGrouping[] no Defines the field on which you want to group the items in the list view. defaultSelection number[] no The index of the items to be select by default filterPlaceHolder string no Specify the placeholder for the filter text box. Default 'Search' showFilter boolean no Specify if the filter text box should be rendered. defaultFilter string no Specify the initial filter to be applied to the list. dragDropFiles boolean no Specify the drag and drop files area option. Default false. onDrop file no Event handler returns files from drag and drop. stickyHeader boolean no Specifies if the header of the ListView , including search box, is sticky onRenderRow (props: IDetailsRowProps) => JSX.Element | null no Callback to override the default row rendering. sortItems (items: any[], columnName: string, descending: boolean) => any[] no Custom sorting function to handle sorting by column className string no Class name to apply additional styles on list view wrapper listClassName string no Class name to apply additional styles on list view The IViewField has the following implementation: Property Type Required Description name string yes Name of the field. displayName string no Name that will be used as the column title. If not defined, the name property will be used. linkPropertyName string no Specify the field name that needs to be used to render a link for the current field. sorting boolean no Specify if you want to enable sorting for the current field. minWidth number no Specify the minimum width of the column. maxWidth number no Specify the maximum width of the column. isResizable boolean no Determines if the column can be resized. render function no Override how the field has to get rendered. The IGrouping has the following implementation: Property Type Required Description name string yes Name of the field order GroupOrder yes Specify how the group needs to be ordered. enum GroupOrder Value Description ascending Order the group in ascending order. descending Order the group in descending order.","title":"ListView"},{"location":"controls/ListView/#listview-control","text":"This control renders a list view for the given set of items. List view control with grouping applied List view control with drag and drop applied","title":"ListView control"},{"location":"controls/ListView/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ListView , IViewField , SelectionMode , GroupOrder , IGrouping } from \"@pnp/spfx-controls-react/lib/ListView\" ; Use the ListView control in your code as follows: < ListView items = { items } viewFields = { viewFields } iconFieldName = \"FileRef\" compact = { true } selectionMode = { SelectionMode . multiple } selection = { this . _getSelection } showFilter = { true } defaultFilter = \"John\" filterPlaceHolder = \"Search...\" groupByFields = { groupByFields } dragDropFiles = { true } onDrop = { this . _getDropFiles } stickyHeader = { true } className = { styles . listWrapper } listClassName = { styles . list } /> The control provides full text filtering through all the columns. If you want to execute filtering on the specified columns, you can use syntax : : . Use ':' as a separator between column name and value. Control support both 'fieldName' and 'name' properties of IColumn interface. With the selection property you can define a method that which gets called when the user selects one or more items in the list view: private _getSelection ( items : any []) { console . log ( 'Selected items:' , items ); } With the groupByFields property you can define an array of field objects which will be used for grouping. Important : the same order of the fields defines how grouping will be applied. In the snippet the ListView control will first group by the Extension and after that by the Author field. const groupByFields : IGrouping [] = [ { name : \"Extension\" , order : GroupOrder.ascending }, { name : \"Author\" , order : GroupOrder.descending } ]; Extend ListView with a ContextualMenu To extend the ListView control with a ContextualMenu refer to ListView.ContextualMenu . With the onDrop handler you can define a method that returns files that where drag and drop by user in the list view: private _getDropFiles = ( files ) => { for ( var i = 0 ; i < files . length ; i ++ ) { console . log ( files [ i ]. name ); } }","title":"How to use this control in your solutions"},{"location":"controls/ListView/#implementation","text":"The ListView control can be configured with the following properties: Property Type Required Description iconFieldName string no Specify the items' property name that defines the file URL path which will be used to show the file icon. This automatically creates a column and renders the file icon. items any[] no Items to render in the list view. viewFields IViewField[] no The fields you want to render in the list view. Check the IViewField implementation to see which properties you can define. compact boolean no Boolean value to indicate if the control should render in compact mode. By default this is set to false . selectionMode SelectionMode no Specify if the items in the list view can be selected and how. Options are: none, single, multi. selection function no Selection event that passes the selected item(s) from the list view. groupByFields IGrouping[] no Defines the field on which you want to group the items in the list view. defaultSelection number[] no The index of the items to be select by default filterPlaceHolder string no Specify the placeholder for the filter text box. Default 'Search' showFilter boolean no Specify if the filter text box should be rendered. defaultFilter string no Specify the initial filter to be applied to the list. dragDropFiles boolean no Specify the drag and drop files area option. Default false. onDrop file no Event handler returns files from drag and drop. stickyHeader boolean no Specifies if the header of the ListView , including search box, is sticky onRenderRow (props: IDetailsRowProps) => JSX.Element | null no Callback to override the default row rendering. sortItems (items: any[], columnName: string, descending: boolean) => any[] no Custom sorting function to handle sorting by column className string no Class name to apply additional styles on list view wrapper listClassName string no Class name to apply additional styles on list view The IViewField has the following implementation: Property Type Required Description name string yes Name of the field. displayName string no Name that will be used as the column title. If not defined, the name property will be used. linkPropertyName string no Specify the field name that needs to be used to render a link for the current field. sorting boolean no Specify if you want to enable sorting for the current field. minWidth number no Specify the minimum width of the column. maxWidth number no Specify the maximum width of the column. isResizable boolean no Determines if the column can be resized. render function no Override how the field has to get rendered. The IGrouping has the following implementation: Property Type Required Description name string yes Name of the field order GroupOrder yes Specify how the group needs to be ordered. enum GroupOrder Value Description ascending Order the group in ascending order. descending Order the group in descending order.","title":"Implementation"},{"location":"controls/LivePersona/","text":"LivePersona control \u00b6 This control allows you to use LivePersona Card available on SharePoint Online. Considerations/Disclaimer \u00b6 The LivePersona Card uses an internal SharePoint Component and it can be changed in the future. Use at your own risk and be conscious that it's behaviour can be changed Example \u00b6 Here is an example of the control: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { LivePersona } from \"@pnp/spfx-controls-react/lib/LivePersona\" ; Use the LivePersona control in your code as follows: < LivePersona upn = \"joao.j.mendes@spteck.com\" template = { <> < Persona text = \"Jo\u00e3o Mendes\" secondaryText = \"joao.j.mendes@sapteck.com\" coinSize = { 48 } /> < /> } serviceScope = { this . context . serviceScope } /> Implementation \u00b6 The LivePersona control can be configured with the following properties: Property Type Required Description serviceScope ServiceScope yes The SPFx ServiceScope object loaded from context of web part or extension. upn string yes User UPN. disableHover boolean no If info should not appear on hover. template string | JSX.Element yes The content to wrap with persona info.","title":"LivePersona"},{"location":"controls/LivePersona/#livepersona-control","text":"This control allows you to use LivePersona Card available on SharePoint Online.","title":"LivePersona control"},{"location":"controls/LivePersona/#considerationsdisclaimer","text":"The LivePersona Card uses an internal SharePoint Component and it can be changed in the future. Use at your own risk and be conscious that it's behaviour can be changed","title":"Considerations/Disclaimer"},{"location":"controls/LivePersona/#example","text":"Here is an example of the control:","title":"Example"},{"location":"controls/LivePersona/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { LivePersona } from \"@pnp/spfx-controls-react/lib/LivePersona\" ; Use the LivePersona control in your code as follows: < LivePersona upn = \"joao.j.mendes@spteck.com\" template = { <> < Persona text = \"Jo\u00e3o Mendes\" secondaryText = \"joao.j.mendes@sapteck.com\" coinSize = { 48 } /> < /> } serviceScope = { this . context . serviceScope } />","title":"How to use this control in your solutions"},{"location":"controls/LivePersona/#implementation","text":"The LivePersona control can be configured with the following properties: Property Type Required Description serviceScope ServiceScope yes The SPFx ServiceScope object loaded from context of web part or extension. upn string yes User UPN. disableHover boolean no If info should not appear on hover. template string | JSX.Element yes The content to wrap with persona info.","title":"Implementation"},{"location":"controls/LocationPicker/","text":"Location Picker \u00b6 This control allows you to search and select the Location, also allows enter a custom location. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { LocationPicker , ILocationPickerItem } from \"@pnp/spfx-controls-react/lib/LocationPicker\" ; Use the LocationPicker control in your code as follows: < LocationPicker context = { this . props . context } label = \"Location\" onChange = {( locValue : ILocationPickerItem ) => { console . log ( locValue . DisplayName + \", \" + locValue . Address . Street ) } }/> Location searching mode Entering into edit mode Readonly mode Implementation \u00b6 The LocationPicker can be configured with the following properties: Property Type Required Description context WebPartContext or ExtensionContext yes The context object of the SPFx loaded webpart or customizer. disabled boolean no Option allows to be enable or disable. Default value is false defaultValue ILocationPickerItem no Option allows set default value errorMessage string no Static error message displayed below the picker. className string no Applies custom styling label string no Label to use for the control. placeholder string no Placeholder label to show in the dropdown. onChange (locItem: ILocationPickerItem) => void no The method that returns location data JSON object.","title":"LocationPicker"},{"location":"controls/LocationPicker/#location-picker","text":"This control allows you to search and select the Location, also allows enter a custom location.","title":"Location Picker"},{"location":"controls/LocationPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { LocationPicker , ILocationPickerItem } from \"@pnp/spfx-controls-react/lib/LocationPicker\" ; Use the LocationPicker control in your code as follows: < LocationPicker context = { this . props . context } label = \"Location\" onChange = {( locValue : ILocationPickerItem ) => { console . log ( locValue . DisplayName + \", \" + locValue . Address . Street ) } }/> Location searching mode Entering into edit mode Readonly mode","title":"How to use this control in your solutions"},{"location":"controls/LocationPicker/#implementation","text":"The LocationPicker can be configured with the following properties: Property Type Required Description context WebPartContext or ExtensionContext yes The context object of the SPFx loaded webpart or customizer. disabled boolean no Option allows to be enable or disable. Default value is false defaultValue ILocationPickerItem no Option allows set default value errorMessage string no Static error message displayed below the picker. className string no Applies custom styling label string no Label to use for the control. placeholder string no Placeholder label to show in the dropdown. onChange (locItem: ILocationPickerItem) => void no The method that returns location data JSON object.","title":"Implementation"},{"location":"controls/Map/","text":"Map control \u00b6 This control renders a map in your solution. The control has also the ability to search for new locations. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Map control as follows: import { Map , ICoordinates , MapType } from \"@pnp/spfx-controls-react/lib/Map\" ; Use the Map control in your code as follows: < Map titleText = \"New of London\" coordinates = {{ latitude : 51.507351 , longitude : - 0.127758 }} enableSearch = { true } /> Implementation \u00b6 The Map control can be configured with the following properties: Property Type Required Description Default titleText string no Title label to show above the control. coordinates ICoordinates yes Coordinates required for rendering the control. enableSearch boolean no Allow the user to search for new locations. zoom number no Zoom level for the maps on display (range 1-15). 10 width number no Width of the maps area in percentage. 100% height number no Height of the maps area. 300px mapType MapType no Type of the map to render. standard loadingMessage string no Custom loading message. errorMessage string no Custom error message. mapsClassName string no Custom CSS class name. errorMessageClassName string no Custom CSS error class name. onUpdateCoordinates (coordinates: ICoordinates) => void no Callback to let your solution knows the new coordinates when a search was performed. ICoordinates interface: Property Type Required Description Default latitude number yes Latitude of the map to display. longitude number yes Longitude of the map to display. displayName string no Display Name of the location. address any no Address of the location. MapType enum: Name standard cycle normal transport","title":"Map"},{"location":"controls/Map/#map-control","text":"This control renders a map in your solution. The control has also the ability to search for new locations. Here is an example of the control in action:","title":"Map control"},{"location":"controls/Map/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the Map control as follows: import { Map , ICoordinates , MapType } from \"@pnp/spfx-controls-react/lib/Map\" ; Use the Map control in your code as follows: < Map titleText = \"New of London\" coordinates = {{ latitude : 51.507351 , longitude : - 0.127758 }} enableSearch = { true } />","title":"How to use this control in your solutions"},{"location":"controls/Map/#implementation","text":"The Map control can be configured with the following properties: Property Type Required Description Default titleText string no Title label to show above the control. coordinates ICoordinates yes Coordinates required for rendering the control. enableSearch boolean no Allow the user to search for new locations. zoom number no Zoom level for the maps on display (range 1-15). 10 width number no Width of the maps area in percentage. 100% height number no Height of the maps area. 300px mapType MapType no Type of the map to render. standard loadingMessage string no Custom loading message. errorMessage string no Custom error message. mapsClassName string no Custom CSS class name. errorMessageClassName string no Custom CSS error class name. onUpdateCoordinates (coordinates: ICoordinates) => void no Callback to let your solution knows the new coordinates when a search was performed. ICoordinates interface: Property Type Required Description Default latitude number yes Latitude of the map to display. longitude number yes Longitude of the map to display. displayName string no Display Name of the location. address any no Address of the location. MapType enum: Name standard cycle normal transport","title":"Implementation"},{"location":"controls/ModernAudio/","text":"Modern Audio \u00b6 This control renders an Audio Control in a modern and themable way. It is controllable with Fluent UI icons instead of old-fashioned standard HTML5 Audio control. Note Originally it's coming from the following community Teams app sample . Modern Audio control rendered with label and default label positioning Modern Audio control rendered with dark (lime) theme and label positioned BottomLeft Modern Audio control in action with label positioned at BottomCenter How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ModernAudio , ModernAudioLabelPosition } from \"@pnp/spfx-controls-react/lib/ModernAudio\" ; Use the ModernAudio control in your code as follows: < ModernAudio audioUrl = 'https://www.winhistory.de/more/winstart/mp3/vista.mp3' label = \"Audio Control\" labelPosition = { ModernAudioLabelPosition . TopCenter } /> Implementation \u00b6 The Modern Audio control can be configured with the following properties: Property Type Required Description Default audioUrl string yes Url to the audio src label string no Label to use for the control. blank labelPosition ModernAudioLabelPosition no Define position of label: TopLeft, TopCenter, BottomLeft, BottomCenter. TopLeft Enum ModernAudioLabelPosition The ModernAudioLabelPosition enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups. Name Value Position TopLeft 1 On top, left aligned TopCenter 2 On top, centered BottomLeft 3 At bottom, left aligned BottomCenter 4 At bottom, centered","title":"ModernAudio"},{"location":"controls/ModernAudio/#modern-audio","text":"This control renders an Audio Control in a modern and themable way. It is controllable with Fluent UI icons instead of old-fashioned standard HTML5 Audio control. Note Originally it's coming from the following community Teams app sample . Modern Audio control rendered with label and default label positioning Modern Audio control rendered with dark (lime) theme and label positioned BottomLeft Modern Audio control in action with label positioned at BottomCenter","title":"Modern Audio"},{"location":"controls/ModernAudio/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ModernAudio , ModernAudioLabelPosition } from \"@pnp/spfx-controls-react/lib/ModernAudio\" ; Use the ModernAudio control in your code as follows: < ModernAudio audioUrl = 'https://www.winhistory.de/more/winstart/mp3/vista.mp3' label = \"Audio Control\" labelPosition = { ModernAudioLabelPosition . TopCenter } />","title":"How to use this control in your solutions"},{"location":"controls/ModernAudio/#implementation","text":"The Modern Audio control can be configured with the following properties: Property Type Required Description Default audioUrl string yes Url to the audio src label string no Label to use for the control. blank labelPosition ModernAudioLabelPosition no Define position of label: TopLeft, TopCenter, BottomLeft, BottomCenter. TopLeft Enum ModernAudioLabelPosition The ModernAudioLabelPosition enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups. Name Value Position TopLeft 1 On top, left aligned TopCenter 2 On top, centered BottomLeft 3 At bottom, left aligned BottomCenter 4 At bottom, centered","title":"Implementation"},{"location":"controls/ModernTaxonomyPicker/","text":"Modern Taxonomy Picker \u00b6 This control allows you to select one or more Terms from a TermSet via its TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the anchorTermId. This is the modern version of the taxonomy picker that uses the REST API and makes use of some load on demand features which makes it well suited for large term sets. Disclaimer Since this control is meant to look as and work in the same way as the out-of-the-box control it lacks some of the features from the legacy TaxonomyPicker control. If you need some of those features please continue using the legacy version. Empty term picker Selecting terms Selected terms in picker Term picker: Auto Complete How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ModernTaxonomyPicker } from \"@pnp/spfx-controls-react/lib/ModernTaxonomyPicker\" ; Use the ModernTaxonomyPicker control in your code as follows: < ModernTaxonomyPicker allowMultipleSelections = { true } termSetId = \"f233d4b7-68fb-41ef-8b58-2af0bafc0d38\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onTaxPickerChange } /> With the onChange property you can capture the event of when the terms in the picker has changed: private onTaxPickerChange ( terms : ITermInfo []) { console . log ( \"Terms\" , terms ); } Advanced example \u00b6 Custom rendering of a More actions button that displays a context menu for each term in the term set and the term set itself and with different options for the terms and the term set. This could for example be used to add terms to an open term set. It also shows how to set the initialsValues property when just knowing the name and the id of the term. const termSetId = \"36d21c3f-b83b-4acc-a223-4df6fa8e946d\" ; const [ clickedActionTerm , setClickedActionTerm ] = React . useState < ITermInfo > (); const addChildTerm = ( parentTermId , updateTaxonomyTreeViewCallback ) : void => { spPost ( sp . termStore . sets . getById ( termSetId ). terms . getById ( parentTermId ). children , { body : JSON.stringify ({ \"labels\" : [ { \"languageTag\" : \"en-US\" , \"name\" : \"Test\" , \"isDefault\" : true } ] }), }) . then ( addedTerm => { return sp . termStore . sets . getById ( termSetId ). terms . getById ( addedTerm . id ). expand ( \"parent\" )(); }) . then ( term => { updateTaxonomyTreeViewCallback ([ term ], null , null ); }); } ... < ModernTaxonomyPicker allowMultipleSelections = { true } termSetId = { termSetId } panelTitle = \"Panel title\" label = { \"Field title\" } context = { this . props . context } required = { false } initialValues = {[{ labels : [{ name : \"Subprocess A1\" , isDefault : true , languageTag : \"en-US\" }], id : \"29eced8f-cf08-454b-bd9e-6443bc0a0f5e\" }]} onChange = { this . onTaxPickerChange } disabled = { false } customPanelWidth = { 700 } isLightDismiss = { false } isBlocking = { false } onRenderActionButton = {( termStoreInfo : ITermStoreInfo , termSetInfo : ITermSetInfo , termInfo : ITermInfo updateTaxonomyTreeViewCallback ?: ( newTermItems? : ITermInfo [], updatedTermItems? : ITermInfo [], deletedTermItems? : ITermInfo []) => void ) : JSX . Element => { const menuIcon : IIconProps = { iconName : 'MoreVertical' , \"aria-label\" : \"More actions\" , style : { fontSize : \"medium\" } }; if ( termInfo ) { const menuProps : IContextualMenuProps = { items : [ { key : 'addTerm' , text : 'Add Term' , iconProps : { iconName : 'Tag' }, onClick : () => addChildTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, { key : 'deleteTerm' , text : 'Delete term' , iconProps : { iconName : 'Untag' }, onClick : () => deleteTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, ], }; return ( < IconButton menuProps = { menuProps } menuIconProps = { menuIcon } style = { clickedActionTerm && clickedActionTerm . id === termInfo . id ? { opacity : 1 } : null } onMenuClick = {( ev? : React.MouseEvent < HTMLElement , MouseEvent > | React . KeyboardEvent < HTMLElement > , button? : IButtonProps ) => { setClickedActionTerm ( termInfo )); }} onAfterMenuDismiss = {() => setClickedActionTerm ( null )} /> ); } else { const menuProps : IContextualMenuProps = { items : [ { key : 'addTerm' , text : 'Add term' , iconProps : { iconName : 'Tag' }, onClick : () => addTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, ], }; return ( < IconButton menuProps = { menuProps } menuIconProps = { menuIcon } style = {{ opacity : 1 }} /> ); } }} /> Implementation \u00b6 The ModernTaxonomyPicker control can be configured with the following properties: Property Type Required Description panelTitle string yes TermSet Picker Panel title. label string yes Text displayed above the Taxonomy Picker. disabled boolean no Specify if the control should be disabled. Default value is false. context BaseComponentContext yes Context of the current web part or extension. initialValues ITermInfo[] no Defines the terms selected by default. This will only set the initial values and cannot be used to use the control in a controlled way. ITermInfo comes from PnP/PnPjs and can be imported with import { ITermInfo } from '@pnp/sp/taxonomy'; allowMultipleSelections boolean no Defines if the user can select only one or multiple terms. Default value is false. termSetId string yes The Id of the TermSet that you would like the Taxonomy Picker to select terms from. onChange function no Captures the event of when the terms in the picker has changed. anchorTermId string no Set the id of a child term in the TermSet to be able to select terms from that level and below. placeHolder string no Short text hint to display in picker. required boolean no Specifies if to display an asterisk near the label. Default value is false. customPanelWidth number no Custom panel width in pixels. termPickerProps IModernTermPickerProps no Custom properties for the term picker (More info: IBasePickerProps interface ). themeVariant IReadonlyTheme no The current loaded SharePoint theme/section background (More info: Supporting section backgrounds ). isLightDismiss boolean no Whether the panel can be light dismissed. isBlocking boolean no Whether the panel uses a modal overlay or not. onRenderActionButton function no Optional custom renderer for adding e.g. a button with additional actions to the terms in the tree view. isPathRendered boolean no Whether the terms will be rendered with the term label or the full path up to the root. allowSelectingChildren boolean no Whether child terms can be selected. Default value is true. Standalone TaxonomyTree control \u00b6 You can also use the TaxonomyTree control separately to just render a stand-alone tree-view of a term set with action buttons. Use the TaxonomyTree control in your code as follows: Initialize the taxonomy service and state, load basic info from term store and display the TaxonomyTree component. import * as React from \"react\" ; import { Guid } from \"@microsoft/sp-core-library\" ; import { WebPartContext } from \"@microsoft/sp-webpart-base\" ; import { sp } from \"@pnp/sp\" ; import { ITermInfo , ITermSetInfo , ITermStoreInfo } from \"@pnp/sp/taxonomy\" ; import { SPTaxonomyService , TaxonomyTree } from \"@pnp/spfx-controls-react\" ; export interface ITestTaxonomyTreeReactHooksProps { context : WebPartContext ; termSetId : string ; onRenderActionButton ?: ( termStoreInfo : ITermStoreInfo , termSetInfo : ITermSetInfo , termInfo : ITermInfo , updateTaxonomyTreeViewCallback ?: ( newTermItems? : ITermInfo [], updatedTermItems? : ITermInfo [], deletedTermItems? : ITermInfo []) => void ) => JSX . Element ; } export function TestTaxonomyTreeReactHooks ( props : ITestTaxonomyTreeReactHooksProps ) : React . ReactElement < ITestTaxonomyTreeReactHooksProps > { const taxonomyService = new SPTaxonomyService ( props . context ); const [ terms , setTerms ] = React . useState < ITermInfo [] > ([]); const [ currentTermStoreInfo , setCurrentTermStoreInfo ] = React . useState < ITermStoreInfo > (); const [ currentTermSetInfo , setCurrentTermSetInfo ] = React . useState < ITermSetInfo > (); const [ currentLanguageTag , setCurrentLanguageTag ] = React . useState < string > ( \"\" ); React . useEffect (() => { sp . setup ( props . context ); taxonomyService . getTermStoreInfo () . then (( termStoreInfo ) => { setCurrentTermStoreInfo ( termStoreInfo ); setCurrentLanguageTag ( props . context . pageContext . cultureInfo . currentUICultureName !== '' ? props.context.pageContext.cultureInfo.currentUICultureName : currentTermStoreInfo.defaultLanguageTag ); }); taxonomyService . getTermSetInfo ( Guid . parse ( props . termSetId )) . then (( termSetInfo ) => { setCurrentTermSetInfo ( termSetInfo ); }); }, []); return ( currentTermStoreInfo && currentTermSetInfo && currentLanguageTag && ( < TaxonomyTree languageTag = { currentLanguageTag } onLoadMoreData = { taxonomyService . getTerms } pageSize = { 50 } setTerms = { setTerms } termSetInfo = { currentTermSetInfo } termStoreInfo = { currentTermStoreInfo } terms = { terms } onRenderActionButton = { props . onRenderActionButton } hideDeprecatedTerms = { false } showIcons = { true } /> ) || null ); }","title":"ModernTaxonomyPicker"},{"location":"controls/ModernTaxonomyPicker/#modern-taxonomy-picker","text":"This control allows you to select one or more Terms from a TermSet via its TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the anchorTermId. This is the modern version of the taxonomy picker that uses the REST API and makes use of some load on demand features which makes it well suited for large term sets. Disclaimer Since this control is meant to look as and work in the same way as the out-of-the-box control it lacks some of the features from the legacy TaxonomyPicker control. If you need some of those features please continue using the legacy version. Empty term picker Selecting terms Selected terms in picker Term picker: Auto Complete","title":"Modern Taxonomy Picker"},{"location":"controls/ModernTaxonomyPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { ModernTaxonomyPicker } from \"@pnp/spfx-controls-react/lib/ModernTaxonomyPicker\" ; Use the ModernTaxonomyPicker control in your code as follows: < ModernTaxonomyPicker allowMultipleSelections = { true } termSetId = \"f233d4b7-68fb-41ef-8b58-2af0bafc0d38\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onTaxPickerChange } /> With the onChange property you can capture the event of when the terms in the picker has changed: private onTaxPickerChange ( terms : ITermInfo []) { console . log ( \"Terms\" , terms ); }","title":"How to use this control in your solutions"},{"location":"controls/ModernTaxonomyPicker/#advanced-example","text":"Custom rendering of a More actions button that displays a context menu for each term in the term set and the term set itself and with different options for the terms and the term set. This could for example be used to add terms to an open term set. It also shows how to set the initialsValues property when just knowing the name and the id of the term. const termSetId = \"36d21c3f-b83b-4acc-a223-4df6fa8e946d\" ; const [ clickedActionTerm , setClickedActionTerm ] = React . useState < ITermInfo > (); const addChildTerm = ( parentTermId , updateTaxonomyTreeViewCallback ) : void => { spPost ( sp . termStore . sets . getById ( termSetId ). terms . getById ( parentTermId ). children , { body : JSON.stringify ({ \"labels\" : [ { \"languageTag\" : \"en-US\" , \"name\" : \"Test\" , \"isDefault\" : true } ] }), }) . then ( addedTerm => { return sp . termStore . sets . getById ( termSetId ). terms . getById ( addedTerm . id ). expand ( \"parent\" )(); }) . then ( term => { updateTaxonomyTreeViewCallback ([ term ], null , null ); }); } ... < ModernTaxonomyPicker allowMultipleSelections = { true } termSetId = { termSetId } panelTitle = \"Panel title\" label = { \"Field title\" } context = { this . props . context } required = { false } initialValues = {[{ labels : [{ name : \"Subprocess A1\" , isDefault : true , languageTag : \"en-US\" }], id : \"29eced8f-cf08-454b-bd9e-6443bc0a0f5e\" }]} onChange = { this . onTaxPickerChange } disabled = { false } customPanelWidth = { 700 } isLightDismiss = { false } isBlocking = { false } onRenderActionButton = {( termStoreInfo : ITermStoreInfo , termSetInfo : ITermSetInfo , termInfo : ITermInfo updateTaxonomyTreeViewCallback ?: ( newTermItems? : ITermInfo [], updatedTermItems? : ITermInfo [], deletedTermItems? : ITermInfo []) => void ) : JSX . Element => { const menuIcon : IIconProps = { iconName : 'MoreVertical' , \"aria-label\" : \"More actions\" , style : { fontSize : \"medium\" } }; if ( termInfo ) { const menuProps : IContextualMenuProps = { items : [ { key : 'addTerm' , text : 'Add Term' , iconProps : { iconName : 'Tag' }, onClick : () => addChildTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, { key : 'deleteTerm' , text : 'Delete term' , iconProps : { iconName : 'Untag' }, onClick : () => deleteTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, ], }; return ( < IconButton menuProps = { menuProps } menuIconProps = { menuIcon } style = { clickedActionTerm && clickedActionTerm . id === termInfo . id ? { opacity : 1 } : null } onMenuClick = {( ev? : React.MouseEvent < HTMLElement , MouseEvent > | React . KeyboardEvent < HTMLElement > , button? : IButtonProps ) => { setClickedActionTerm ( termInfo )); }} onAfterMenuDismiss = {() => setClickedActionTerm ( null )} /> ); } else { const menuProps : IContextualMenuProps = { items : [ { key : 'addTerm' , text : 'Add term' , iconProps : { iconName : 'Tag' }, onClick : () => addTerm ( termInfo . id , updateTaxonomyTreeViewCallback ) }, ], }; return ( < IconButton menuProps = { menuProps } menuIconProps = { menuIcon } style = {{ opacity : 1 }} /> ); } }} />","title":"Advanced example"},{"location":"controls/ModernTaxonomyPicker/#implementation","text":"The ModernTaxonomyPicker control can be configured with the following properties: Property Type Required Description panelTitle string yes TermSet Picker Panel title. label string yes Text displayed above the Taxonomy Picker. disabled boolean no Specify if the control should be disabled. Default value is false. context BaseComponentContext yes Context of the current web part or extension. initialValues ITermInfo[] no Defines the terms selected by default. This will only set the initial values and cannot be used to use the control in a controlled way. ITermInfo comes from PnP/PnPjs and can be imported with import { ITermInfo } from '@pnp/sp/taxonomy'; allowMultipleSelections boolean no Defines if the user can select only one or multiple terms. Default value is false. termSetId string yes The Id of the TermSet that you would like the Taxonomy Picker to select terms from. onChange function no Captures the event of when the terms in the picker has changed. anchorTermId string no Set the id of a child term in the TermSet to be able to select terms from that level and below. placeHolder string no Short text hint to display in picker. required boolean no Specifies if to display an asterisk near the label. Default value is false. customPanelWidth number no Custom panel width in pixels. termPickerProps IModernTermPickerProps no Custom properties for the term picker (More info: IBasePickerProps interface ). themeVariant IReadonlyTheme no The current loaded SharePoint theme/section background (More info: Supporting section backgrounds ). isLightDismiss boolean no Whether the panel can be light dismissed. isBlocking boolean no Whether the panel uses a modal overlay or not. onRenderActionButton function no Optional custom renderer for adding e.g. a button with additional actions to the terms in the tree view. isPathRendered boolean no Whether the terms will be rendered with the term label or the full path up to the root. allowSelectingChildren boolean no Whether child terms can be selected. Default value is true.","title":"Implementation"},{"location":"controls/ModernTaxonomyPicker/#standalone-taxonomytree-control","text":"You can also use the TaxonomyTree control separately to just render a stand-alone tree-view of a term set with action buttons. Use the TaxonomyTree control in your code as follows: Initialize the taxonomy service and state, load basic info from term store and display the TaxonomyTree component. import * as React from \"react\" ; import { Guid } from \"@microsoft/sp-core-library\" ; import { WebPartContext } from \"@microsoft/sp-webpart-base\" ; import { sp } from \"@pnp/sp\" ; import { ITermInfo , ITermSetInfo , ITermStoreInfo } from \"@pnp/sp/taxonomy\" ; import { SPTaxonomyService , TaxonomyTree } from \"@pnp/spfx-controls-react\" ; export interface ITestTaxonomyTreeReactHooksProps { context : WebPartContext ; termSetId : string ; onRenderActionButton ?: ( termStoreInfo : ITermStoreInfo , termSetInfo : ITermSetInfo , termInfo : ITermInfo , updateTaxonomyTreeViewCallback ?: ( newTermItems? : ITermInfo [], updatedTermItems? : ITermInfo [], deletedTermItems? : ITermInfo []) => void ) => JSX . Element ; } export function TestTaxonomyTreeReactHooks ( props : ITestTaxonomyTreeReactHooksProps ) : React . ReactElement < ITestTaxonomyTreeReactHooksProps > { const taxonomyService = new SPTaxonomyService ( props . context ); const [ terms , setTerms ] = React . useState < ITermInfo [] > ([]); const [ currentTermStoreInfo , setCurrentTermStoreInfo ] = React . useState < ITermStoreInfo > (); const [ currentTermSetInfo , setCurrentTermSetInfo ] = React . useState < ITermSetInfo > (); const [ currentLanguageTag , setCurrentLanguageTag ] = React . useState < string > ( \"\" ); React . useEffect (() => { sp . setup ( props . context ); taxonomyService . getTermStoreInfo () . then (( termStoreInfo ) => { setCurrentTermStoreInfo ( termStoreInfo ); setCurrentLanguageTag ( props . context . pageContext . cultureInfo . currentUICultureName !== '' ? props.context.pageContext.cultureInfo.currentUICultureName : currentTermStoreInfo.defaultLanguageTag ); }); taxonomyService . getTermSetInfo ( Guid . parse ( props . termSetId )) . then (( termSetInfo ) => { setCurrentTermSetInfo ( termSetInfo ); }); }, []); return ( currentTermStoreInfo && currentTermSetInfo && currentLanguageTag && ( < TaxonomyTree languageTag = { currentLanguageTag } onLoadMoreData = { taxonomyService . getTerms } pageSize = { 50 } setTerms = { setTerms } termSetInfo = { currentTermSetInfo } termStoreInfo = { currentTermStoreInfo } terms = { terms } onRenderActionButton = { props . onRenderActionButton } hideDeprecatedTerms = { false } showIcons = { true } /> ) || null ); }","title":"Standalone TaxonomyTree control"},{"location":"controls/MonacoEditor/","text":"Monaco Editor control \u00b6 This control is an implementation of the Monaco Editor. The Monaco Editor is the code editor that powers VS Code . Here is an example of the control: MonacoEditor dark theme: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { MonacoEditor } from \"@pnp/spfx-controls-react/lib/MonacoEditor\" ; Use the MonacoEditor control in your code as follows: < MonacoEditor value = { defaultValue } showMiniMap = { true } onValueChange = { onValueChange } language = { \"javascript\" } /> The onValueChange change event returns the upadated code and array with messages of errors on validation and can be implemented as follows: This validation is only available for JSON language Your onValueChange handler would follow a similar format to this: const onValueChange = ( newValue : string , validationErrors : string []) : void => { console . log ( newValue ); }; Or, if using React Hooks: const onValueChange = React . useCallback (( newValue : string , validationErrors : string []) : void => { console . log ( newValue );} , []); Implementation \u00b6 The MonacoEditor control can be configured with the following properties: Property Type Required Description value string yes default content for editor theme string no theme used by editor, two themes are supported 'vs' and 'vs-dark', default 'vs' readOnly boolean no indicate if editor is in read-only mode showLineNumbers boolean no editor show line number or not, default : yes onValueChange (newValue:string, validationErrors:string[]) => void no function to get code changes, return an array with validation error in case of language is 'JSON' language string yes editor code language, please see https://microsoft.github.io/monaco-editor/index.html for supported languages jsonDiagnosticsOptions monaco.languages.json.DiagnosticsOptions no define options to JSON validation, please see https://microsoft.github.io/monaco-editor/index.html for more details jscriptDiagnosticsOptions monaco.languages.typescript.DiagnosticsOptions no define options to javascript or typescript validation, please see https://microsoft.github.io/monaco-editor/index.html for more details","title":"MonacoEditor"},{"location":"controls/MonacoEditor/#monaco-editor-control","text":"This control is an implementation of the Monaco Editor. The Monaco Editor is the code editor that powers VS Code . Here is an example of the control: MonacoEditor dark theme:","title":"Monaco Editor control"},{"location":"controls/MonacoEditor/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { MonacoEditor } from \"@pnp/spfx-controls-react/lib/MonacoEditor\" ; Use the MonacoEditor control in your code as follows: < MonacoEditor value = { defaultValue } showMiniMap = { true } onValueChange = { onValueChange } language = { \"javascript\" } /> The onValueChange change event returns the upadated code and array with messages of errors on validation and can be implemented as follows: This validation is only available for JSON language Your onValueChange handler would follow a similar format to this: const onValueChange = ( newValue : string , validationErrors : string []) : void => { console . log ( newValue ); }; Or, if using React Hooks: const onValueChange = React . useCallback (( newValue : string , validationErrors : string []) : void => { console . log ( newValue );} , []);","title":"How to use this control in your solutions"},{"location":"controls/MonacoEditor/#implementation","text":"The MonacoEditor control can be configured with the following properties: Property Type Required Description value string yes default content for editor theme string no theme used by editor, two themes are supported 'vs' and 'vs-dark', default 'vs' readOnly boolean no indicate if editor is in read-only mode showLineNumbers boolean no editor show line number or not, default : yes onValueChange (newValue:string, validationErrors:string[]) => void no function to get code changes, return an array with validation error in case of language is 'JSON' language string yes editor code language, please see https://microsoft.github.io/monaco-editor/index.html for supported languages jsonDiagnosticsOptions monaco.languages.json.DiagnosticsOptions no define options to JSON validation, please see https://microsoft.github.io/monaco-editor/index.html for more details jscriptDiagnosticsOptions monaco.languages.typescript.DiagnosticsOptions no define options to javascript or typescript validation, please see https://microsoft.github.io/monaco-editor/index.html for more details","title":"Implementation"},{"location":"controls/MyTeams/","text":"MyTeams control \u00b6 This control show all Teams the user has access (joined),and for each Team the user can see the channels has permissions and quick open the channel or if callback is specified can return the Team Id and Channel Id for use in App. The user can quick see the members and owner of the group. This control uses the People component from mgt-toolkit that can be configured to show Person Card on hover. Please refer to required dependencies section to install the mgt-spfx library in your tenant. Here is an example of the control: Required dependencies \u00b6 In order to resolve an issue using controls from mgt-toolkit within SharePoint Framework solutions, the mgt team created an SPFx library that should be deployed to your tenant. For the MyTeams control to work, we had no other option but to add a dependency on the mgt-spfx library. More information about mgt-spfx is available here Simply download the mgt-spfx-2.2.0.sppkg file from the link below and deploy to the SharePoint app catalog, making the solution available to all sites in the tenant. mgt-spfx direct download link How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { MyTeams } from \"@pnp/spfx-controls-react/lib/MyTeams\" ; Use the MyTeams control in your code as follows: < MyTeams title = \"My Teams\" webPartContext = { context } themeVariant = { themeVariant } /> < MyTeams title = \"My Teams\" webPartContext = { context } themeVariant = { themeVariant } enablePersonCardInteraction = { true } onSelectedChannel = { onSelectedChannel } /> The onSelectedChannel callback returns the teamId and ChannelId and can be implemented as follows: const onSelectedChannel = ( teamsId : string , channelId : string ) => { console . log ( \"TeamsId\" , teamsId ); console . log ( \"ChannelId\" , channelId ); }; Implementation \u00b6 The MyTeams control can be configured with the following properties: Property Type Required Description webPartContext WebPartContext yes The context object of the SPFx loaded webpart title string no Title of WebPart themeVariant IReadonlyTheme no themeVariant enablePersonCardInteraction boolean no Show Person Card on hover onSelectedChannel (teamId:string,channelId:string) => void; no callBack with TeamId and ChannelId Selected MSGraph Permissions required \u00b6 This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All, TeamMember.Read.All and all Scopes used by mgt-people , and Person-Card components","title":"MyTeams"},{"location":"controls/MyTeams/#myteams-control","text":"This control show all Teams the user has access (joined),and for each Team the user can see the channels has permissions and quick open the channel or if callback is specified can return the Team Id and Channel Id for use in App. The user can quick see the members and owner of the group. This control uses the People component from mgt-toolkit that can be configured to show Person Card on hover. Please refer to required dependencies section to install the mgt-spfx library in your tenant. Here is an example of the control:","title":"MyTeams control"},{"location":"controls/MyTeams/#required-dependencies","text":"In order to resolve an issue using controls from mgt-toolkit within SharePoint Framework solutions, the mgt team created an SPFx library that should be deployed to your tenant. For the MyTeams control to work, we had no other option but to add a dependency on the mgt-spfx library. More information about mgt-spfx is available here Simply download the mgt-spfx-2.2.0.sppkg file from the link below and deploy to the SharePoint app catalog, making the solution available to all sites in the tenant. mgt-spfx direct download link","title":"Required dependencies"},{"location":"controls/MyTeams/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { MyTeams } from \"@pnp/spfx-controls-react/lib/MyTeams\" ; Use the MyTeams control in your code as follows: < MyTeams title = \"My Teams\" webPartContext = { context } themeVariant = { themeVariant } /> < MyTeams title = \"My Teams\" webPartContext = { context } themeVariant = { themeVariant } enablePersonCardInteraction = { true } onSelectedChannel = { onSelectedChannel } /> The onSelectedChannel callback returns the teamId and ChannelId and can be implemented as follows: const onSelectedChannel = ( teamsId : string , channelId : string ) => { console . log ( \"TeamsId\" , teamsId ); console . log ( \"ChannelId\" , channelId ); };","title":"How to use this control in your solutions"},{"location":"controls/MyTeams/#implementation","text":"The MyTeams control can be configured with the following properties: Property Type Required Description webPartContext WebPartContext yes The context object of the SPFx loaded webpart title string no Title of WebPart themeVariant IReadonlyTheme no themeVariant enablePersonCardInteraction boolean no Show Person Card on hover onSelectedChannel (teamId:string,channelId:string) => void; no callBack with TeamId and ChannelId Selected","title":"Implementation"},{"location":"controls/MyTeams/#msgraph-permissions-required","text":"This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All, TeamMember.Read.All and all Scopes used by mgt-people , and Person-Card components","title":"MSGraph Permissions required"},{"location":"controls/Pagination/","text":"Pagination Control \u00b6 This control renders a Pagination component which can be used to show limited information of data. For example, you can set up your search result for the first 10 and then when clicking on a new page make a new request for other 10 elements. Pagination on the page How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Pagination } from \"@pnp/spfx-controls-react/lib/pagination\" ; Use the Pagination control in your code as follows: < Pagination currentPage = { 3 } totalPages = { 13 } onChange = {( page ) => this . _getPage ( page )} limiter = { 3 } // Optional - default value 3 hideFirstPageJump // Optional hideLastPageJump // Optional limiterIcon = { \"Emoji12\" } // Optional /> With the onChange property you can get the selected Page in the Pagination component: private _getPage ( page : number ){ console . log ( 'Page:' , page ); } Implementation \u00b6 The Pagination control can be configured with the following properties: Property Type Required Description Default currentPage number yes The page initial selected totalPages number yes The total of page that you want to show on control onChange string yes When the page number change send the page number selected limiter string no The number of pages showing before the icon 3 hideFirstPageJump boolean no Hide the quick jump to the first page false hideLastPageJump boolean no Hide the quick jump to the last page false limiterIcon string no Limitir icon form Fluent IU More","title":"Pagination"},{"location":"controls/Pagination/#pagination-control","text":"This control renders a Pagination component which can be used to show limited information of data. For example, you can set up your search result for the first 10 and then when clicking on a new page make a new request for other 10 elements. Pagination on the page","title":"Pagination Control"},{"location":"controls/Pagination/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Pagination } from \"@pnp/spfx-controls-react/lib/pagination\" ; Use the Pagination control in your code as follows: < Pagination currentPage = { 3 } totalPages = { 13 } onChange = {( page ) => this . _getPage ( page )} limiter = { 3 } // Optional - default value 3 hideFirstPageJump // Optional hideLastPageJump // Optional limiterIcon = { \"Emoji12\" } // Optional /> With the onChange property you can get the selected Page in the Pagination component: private _getPage ( page : number ){ console . log ( 'Page:' , page ); }","title":"How to use this control in your solutions"},{"location":"controls/Pagination/#implementation","text":"The Pagination control can be configured with the following properties: Property Type Required Description Default currentPage number yes The page initial selected totalPages number yes The total of page that you want to show on control onChange string yes When the page number change send the page number selected limiter string no The number of pages showing before the icon 3 hideFirstPageJump boolean no Hide the quick jump to the first page false hideLastPageJump boolean no Hide the quick jump to the last page false limiterIcon string no Limitir icon form Fluent IU More","title":"Implementation"},{"location":"controls/PeoplePicker/","text":"People Picker \u00b6 This control renders a People picker field which can be used to select one or more users from a SharePoint group or site. The control can be configured as mandatory. It will show a custom error message if field is empty. Note You can also check out People Picker component in the Microsoft Graph Toolkit . Empty People Picker control with error message and tooltip Selecting People Selected people How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IPeoplePickerContext , PeoplePicker , PrincipalType } from \"@pnp/spfx-controls-react/lib/PeoplePicker\" ; Use the PeoplePicker control in your code as follows: const peoplePickerContext : IPeoplePickerContext = { absoluteUrl : this.props.context.pageContext.web.absoluteUrl , msGraphClientFactory : this.props.context.msGraphClientFactory , spHttpClient : this.props.context.spHttpClient }; < PeoplePicker context = { peoplePickerContext } titleText = \"People Picker\" personSelectionLimit = { 3 } groupName = { \"Team Site Owners\" } // Leave this blank in case you want to filter from all users showtooltip = { true } required = { true } disabled = { true } searchTextLimit = { 5 } onChange = { this . _getPeoplePickerItems } showHiddenInUI = { false } principalTypes = {[ PrincipalType . User ]} resolveDelay = { 1000 } /> With the onChange property you can get the selected People in the PeoplePicker : private _getPeoplePickerItems ( items : any []) { console . log ( 'Items:' , items ); } Use Substrate search \u00b6 Sometimes, depending on how your organization is configured regarding users and groups, performing search can be tricky. As the PeoplePicker is using the SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser endpoint under the hood, there is an optional parameter called useSubstrateSearch . Setting this to true will perform a search using the Microsoft 365 Substrate, which will go through centralized stored data in order to find requested info. More details about this feature can be found here and here . Implementation \u00b6 The People picker control can be configured with the following properties: Property Type Required Description Default context IPeoplePickerContext yes Context of the component, based on the SPFx context ( BaseComponentContext ). titleText string no Text to be displayed on the control groupName string no Group from which users are fetched. Leave it blank if need to filter all users. When both groupName and groupId specified groupName takes precedence. none groupId number | string | (string|number)[] no Group from which users are fetched. Leave it blank if need to filter all users. When both groupId and groupName specified groupName takes precedence. If string is specified, Microsoft 365 Group is used. If array is used, fetch results from multiple groups none personSelectionLimit number no Defines the limit of people that can be selected in the control 1 required boolean no Set if the control is required or not false disabled boolean no Set if the control is disabled or not false errorMessage string no Static error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive ( errorMessage takes precedence). onGetErrorMessage (items: IPersonaProps[]) => string | Promise no The method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this). When it returns string: If valid, it returns empty string. If invalid, it returns the error message string to be shown below the picker. When it returns Promise: The resolved value is display as error message. The rejected, the value is thrown away. errorMessageClassName string no applies custom styling to the error message section showtooltip boolean no Defines if need a tooltip or not false tooltipMessage string no Specify the tooltip message to display tooltipDirectional DirectionalHint no Direction where the tooltip would be shown onChange (items: IPersonaProps[]) => void no Get the selected users in the control. peoplePickerWPclassName string no applies custom styling to the people picker element peoplePickerCntrlclassName string no applies custom styling to the people picker control only defaultSelectedUsers string[] no Default selected user emails or login names, optionally append /title with forward slash. If user is not found then only optional title will be shown. If you do not have email or login name of inactive users just pass /title alone prefixed with slash. webAbsoluteUrl string no Specify the site URL on which you want to perform the user query call. If not provided, the people picker will perform a tenant wide people/group search. When provided it will search users/groups on the provided site. principalTypes PrincipalType[] no Define which type of data you want to retrieve: User, SharePoint groups, Security groups. Multiple are possible. ensureUser boolean no When ensure user property is true, it will return the local user ID on the current site when doing a tenant wide search. false allowUnvalidated boolean no When true, allow email addresses that have not been validated to be entered, effectively allowing any user. false suggestionsLimit number no Maximum number of suggestions to show in the full suggestion list. 5 resolveDelay number no Add delay to resolve and search users 200 placeholder string no Short text hint to display in empty picker styles Partial no Styles to apply on control searchTextLimit number no Specifies the minimum character count needed to begin retrieving search results. 2 useSubstrateSearch boolean no When true , performs a wider search using Microsoft 365 Substrate. false Enum PrincipalType The PrincipalType enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups. Name Value User 1 DistributionList 2 SecurityGroup 4 SharePointGroup 8 Interface IPeoplePickerContext Provides mandatory properties to search users on the tenant Value Type Description absoluteUrl string Current SPWeb absolute URL. msGraphClientFactory MSGraphClientFactory Instance of MSGraphClientFactory used for querying Microsoft Graph REST API. spHttpClient SPHttpClient Instance of SPHttpClient used for querying SharePoint REST API. MSGraph Permissions required \u00b6 This control requires at least one the following scopes if groupId is of type string : GroupMember.Read.All + User.ReadBasic.All Directory.Read.All","title":"PeoplePicker"},{"location":"controls/PeoplePicker/#people-picker","text":"This control renders a People picker field which can be used to select one or more users from a SharePoint group or site. The control can be configured as mandatory. It will show a custom error message if field is empty. Note You can also check out People Picker component in the Microsoft Graph Toolkit . Empty People Picker control with error message and tooltip Selecting People Selected people","title":"People Picker"},{"location":"controls/PeoplePicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { IPeoplePickerContext , PeoplePicker , PrincipalType } from \"@pnp/spfx-controls-react/lib/PeoplePicker\" ; Use the PeoplePicker control in your code as follows: const peoplePickerContext : IPeoplePickerContext = { absoluteUrl : this.props.context.pageContext.web.absoluteUrl , msGraphClientFactory : this.props.context.msGraphClientFactory , spHttpClient : this.props.context.spHttpClient }; < PeoplePicker context = { peoplePickerContext } titleText = \"People Picker\" personSelectionLimit = { 3 } groupName = { \"Team Site Owners\" } // Leave this blank in case you want to filter from all users showtooltip = { true } required = { true } disabled = { true } searchTextLimit = { 5 } onChange = { this . _getPeoplePickerItems } showHiddenInUI = { false } principalTypes = {[ PrincipalType . User ]} resolveDelay = { 1000 } /> With the onChange property you can get the selected People in the PeoplePicker : private _getPeoplePickerItems ( items : any []) { console . log ( 'Items:' , items ); }","title":"How to use this control in your solutions"},{"location":"controls/PeoplePicker/#use-substrate-search","text":"Sometimes, depending on how your organization is configured regarding users and groups, performing search can be tricky. As the PeoplePicker is using the SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser endpoint under the hood, there is an optional parameter called useSubstrateSearch . Setting this to true will perform a search using the Microsoft 365 Substrate, which will go through centralized stored data in order to find requested info. More details about this feature can be found here and here .","title":"Use Substrate search"},{"location":"controls/PeoplePicker/#implementation","text":"The People picker control can be configured with the following properties: Property Type Required Description Default context IPeoplePickerContext yes Context of the component, based on the SPFx context ( BaseComponentContext ). titleText string no Text to be displayed on the control groupName string no Group from which users are fetched. Leave it blank if need to filter all users. When both groupName and groupId specified groupName takes precedence. none groupId number | string | (string|number)[] no Group from which users are fetched. Leave it blank if need to filter all users. When both groupId and groupName specified groupName takes precedence. If string is specified, Microsoft 365 Group is used. If array is used, fetch results from multiple groups none personSelectionLimit number no Defines the limit of people that can be selected in the control 1 required boolean no Set if the control is required or not false disabled boolean no Set if the control is disabled or not false errorMessage string no Static error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive ( errorMessage takes precedence). onGetErrorMessage (items: IPersonaProps[]) => string | Promise no The method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this). When it returns string: If valid, it returns empty string. If invalid, it returns the error message string to be shown below the picker. When it returns Promise: The resolved value is display as error message. The rejected, the value is thrown away. errorMessageClassName string no applies custom styling to the error message section showtooltip boolean no Defines if need a tooltip or not false tooltipMessage string no Specify the tooltip message to display tooltipDirectional DirectionalHint no Direction where the tooltip would be shown onChange (items: IPersonaProps[]) => void no Get the selected users in the control. peoplePickerWPclassName string no applies custom styling to the people picker element peoplePickerCntrlclassName string no applies custom styling to the people picker control only defaultSelectedUsers string[] no Default selected user emails or login names, optionally append /title with forward slash. If user is not found then only optional title will be shown. If you do not have email or login name of inactive users just pass /title alone prefixed with slash. webAbsoluteUrl string no Specify the site URL on which you want to perform the user query call. If not provided, the people picker will perform a tenant wide people/group search. When provided it will search users/groups on the provided site. principalTypes PrincipalType[] no Define which type of data you want to retrieve: User, SharePoint groups, Security groups. Multiple are possible. ensureUser boolean no When ensure user property is true, it will return the local user ID on the current site when doing a tenant wide search. false allowUnvalidated boolean no When true, allow email addresses that have not been validated to be entered, effectively allowing any user. false suggestionsLimit number no Maximum number of suggestions to show in the full suggestion list. 5 resolveDelay number no Add delay to resolve and search users 200 placeholder string no Short text hint to display in empty picker styles Partial no Styles to apply on control searchTextLimit number no Specifies the minimum character count needed to begin retrieving search results. 2 useSubstrateSearch boolean no When true , performs a wider search using Microsoft 365 Substrate. false Enum PrincipalType The PrincipalType enum can be used to specify the types of information you want to query: User, Security groups, and/or SharePoint groups. Name Value User 1 DistributionList 2 SecurityGroup 4 SharePointGroup 8 Interface IPeoplePickerContext Provides mandatory properties to search users on the tenant Value Type Description absoluteUrl string Current SPWeb absolute URL. msGraphClientFactory MSGraphClientFactory Instance of MSGraphClientFactory used for querying Microsoft Graph REST API. spHttpClient SPHttpClient Instance of SPHttpClient used for querying SharePoint REST API.","title":"Implementation"},{"location":"controls/PeoplePicker/#msgraph-permissions-required","text":"This control requires at least one the following scopes if groupId is of type string : GroupMember.Read.All + User.ReadBasic.All Directory.Read.All","title":"MSGraph Permissions required"},{"location":"controls/Placeholder/","text":"Placeholder control \u00b6 This control renders a placeholder which can be used to show a message that the web part still has to be configured. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Placeholder } from \"@pnp/spfx-controls-react/lib/Placeholder\" ; Use the Placeholder control in your code as follows: < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> With custom element for description : < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = { defaultClassNames => < span className = { ` ${ defaultClassNames } ${ additionalStyles } ` } > Please configure the web part . < /span>} buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> With the onConfigure property you can define what it needs to do when you click on the button. Like for example opening the property pane: private _onConfigure = () => { // Context of the web part this . props . context . propertyPane . open (); } Sample of using the hideButton functionality for hiding the button when page is in read mode: < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' hideButton = { this . props . displayMode === DisplayMode . Read } onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> Sample to only display Placeholder when the web part is in edit mode: { this . displayMode === DisplayMode . Edit ? < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> : < div /> } Implementation \u00b6 The placeholder control can be configured with the following properties: Property Type Required Description buttonLabel string no Text label to be displayed on the button bellow the description. The button is optional. contentClassName string no This is the className that is applied to the root element of the content zone. You can use this to apply custom styles to the placeholder. description string | ((defaultClassNames: string) => React.ReactElement) yes Text description or render function for the placeholder. This appears bellow the Icon and IconText. iconName string yes The name of the icon that will be used in the placeholder. This is the same name as you can find on the Office UI Fabric icons page: Office UI Fabric icons . For example: Page or Add . iconText string | ((defaultClassNames: string) => React.ReactElement) yes Heading text or render function which is displayed next to the icon. hideButton boolean no Specify if you want to hide the button. Default is false . onConfigure function no onConfigure handler for the button. The button is optional. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.","title":"Placeholder"},{"location":"controls/Placeholder/#placeholder-control","text":"This control renders a placeholder which can be used to show a message that the web part still has to be configured.","title":"Placeholder control"},{"location":"controls/Placeholder/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Placeholder } from \"@pnp/spfx-controls-react/lib/Placeholder\" ; Use the Placeholder control in your code as follows: < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> With custom element for description : < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = { defaultClassNames => < span className = { ` ${ defaultClassNames } ${ additionalStyles } ` } > Please configure the web part . < /span>} buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> With the onConfigure property you can define what it needs to do when you click on the button. Like for example opening the property pane: private _onConfigure = () => { // Context of the web part this . props . context . propertyPane . open (); } Sample of using the hideButton functionality for hiding the button when page is in read mode: < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' hideButton = { this . props . displayMode === DisplayMode . Read } onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> Sample to only display Placeholder when the web part is in edit mode: { this . displayMode === DisplayMode . Edit ? < Placeholder iconName = 'Edit' iconText = 'Configure your web part' description = 'Please configure the web part.' buttonLabel = 'Configure' onConfigure = { this . _onConfigure } theme = { this . props . themeVariant } /> : < div /> }","title":"How to use this control in your solutions"},{"location":"controls/Placeholder/#implementation","text":"The placeholder control can be configured with the following properties: Property Type Required Description buttonLabel string no Text label to be displayed on the button bellow the description. The button is optional. contentClassName string no This is the className that is applied to the root element of the content zone. You can use this to apply custom styles to the placeholder. description string | ((defaultClassNames: string) => React.ReactElement) yes Text description or render function for the placeholder. This appears bellow the Icon and IconText. iconName string yes The name of the icon that will be used in the placeholder. This is the same name as you can find on the Office UI Fabric icons page: Office UI Fabric icons . For example: Page or Add . iconText string | ((defaultClassNames: string) => React.ReactElement) yes Heading text or render function which is displayed next to the icon. hideButton boolean no Specify if you want to hide the button. Default is false . onConfigure function no onConfigure handler for the button. The button is optional. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.","title":"Implementation"},{"location":"controls/Progress/","text":"Progress control \u00b6 This control shows progress of multiple SEQUENTIALLY executed actions. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Progress } from \"@pnp/spfx-controls-react/lib/Progress\" ; Use the Progress control in your code as follows: < Progress title = { 'Progress Test' } showOverallProgress = { true } showIndeterminateOverallProgress = { false } hideNotStartedActions = { false } actions = { this . state . progressActions } currentActionIndex = { this . state . currentProgressActionIndex } longRunningText = { 'This operation takes longer than expected' } longRunningTextDisplayDelay = { 7000 } height = { '350px' } /> Note : the control itself is not responsible for actions' execution. It only renders the actions, overall progress and actions' execution states. When using the control, you should implement actions execution. As example, you can have a base class that implements IProgressAction interface and has an execute method: class BaseAction implements IProgressAction { public get title () : string { ... } public get subActionsTitles () : string [] { ... } public get hasError () : boolean { ... } public get errorMessage () : string { ... } public async execute () : Promise < void > { ... } } Then, you have multiple actions derived from the base one: class FirstAction extends BaseAction { public async execute () : Promise < void > { // implementation for FirstAction } } class SecondAction extends BaseAction { public async execute () : Promise < void > { // implementation for SecondAction } } Now, in a component, where Progress is used you can have code as below: export interface IYourComponentState { progressActions : IProgressAction []; currentProgressActionIndex? : number ; // other state properties } // ... export class YourComponent extends React . Component < IYourComponentProps , IYourComponentState > { // all other code, including render with Progress reference listed above private _initActions () { this . setState ({ progressActions : [ new FirstAction (), new SecondAction () ] }); } private async _execute () { for ( let i = 0 ; i <= this . state . actions . length ; i ++ ) { this . setState ( currentProgressActionIndex : i ); if ( i < this . state . actions . length ) { await this . state . actions [ i ]. execute (); } } } } Implementation \u00b6 The Progress component can be configured with the following properties: Property Type Required Description title string no Title, or header, of the progress. showOverallProgress boolean true Specifies if overall progress indicator should be shown. showIndeterminateOverallProgress boolean no Specifies if indeterminate overall progress animation will be shown. hideNotStartedActions boolean yes Specifies if not started actions should not be rendered. actions IProgressAction[] yes Progress actions currentActionIndex number no Index of currently executing action heigth string no Height of the component longRunningText string no Text to be displayed for long running operations longRunningTextDisplayDelay number no Delay until longRunningText is displayed im milliseconds. If not set or 0 longRunningText is displayed right away. className string no Class name to be applied to the component headerClassName string no Header class name. Header contains title, progress indicator, and delay text actionsContainerClassName string no Actions container class name actionClassName string no Single action class name successIconName string no Success icon name. Default is CheckMark errorIconName string no Error icon name. Default is Error inProgressIconName string no InProgress icon name. Default is '', spinner is displayed.","title":"Progress"},{"location":"controls/Progress/#progress-control","text":"This control shows progress of multiple SEQUENTIALLY executed actions. Here is an example of the control in action:","title":"Progress control"},{"location":"controls/Progress/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Progress } from \"@pnp/spfx-controls-react/lib/Progress\" ; Use the Progress control in your code as follows: < Progress title = { 'Progress Test' } showOverallProgress = { true } showIndeterminateOverallProgress = { false } hideNotStartedActions = { false } actions = { this . state . progressActions } currentActionIndex = { this . state . currentProgressActionIndex } longRunningText = { 'This operation takes longer than expected' } longRunningTextDisplayDelay = { 7000 } height = { '350px' } /> Note : the control itself is not responsible for actions' execution. It only renders the actions, overall progress and actions' execution states. When using the control, you should implement actions execution. As example, you can have a base class that implements IProgressAction interface and has an execute method: class BaseAction implements IProgressAction { public get title () : string { ... } public get subActionsTitles () : string [] { ... } public get hasError () : boolean { ... } public get errorMessage () : string { ... } public async execute () : Promise < void > { ... } } Then, you have multiple actions derived from the base one: class FirstAction extends BaseAction { public async execute () : Promise < void > { // implementation for FirstAction } } class SecondAction extends BaseAction { public async execute () : Promise < void > { // implementation for SecondAction } } Now, in a component, where Progress is used you can have code as below: export interface IYourComponentState { progressActions : IProgressAction []; currentProgressActionIndex? : number ; // other state properties } // ... export class YourComponent extends React . Component < IYourComponentProps , IYourComponentState > { // all other code, including render with Progress reference listed above private _initActions () { this . setState ({ progressActions : [ new FirstAction (), new SecondAction () ] }); } private async _execute () { for ( let i = 0 ; i <= this . state . actions . length ; i ++ ) { this . setState ( currentProgressActionIndex : i ); if ( i < this . state . actions . length ) { await this . state . actions [ i ]. execute (); } } } }","title":"How to use this control in your solutions"},{"location":"controls/Progress/#implementation","text":"The Progress component can be configured with the following properties: Property Type Required Description title string no Title, or header, of the progress. showOverallProgress boolean true Specifies if overall progress indicator should be shown. showIndeterminateOverallProgress boolean no Specifies if indeterminate overall progress animation will be shown. hideNotStartedActions boolean yes Specifies if not started actions should not be rendered. actions IProgressAction[] yes Progress actions currentActionIndex number no Index of currently executing action heigth string no Height of the component longRunningText string no Text to be displayed for long running operations longRunningTextDisplayDelay number no Delay until longRunningText is displayed im milliseconds. If not set or 0 longRunningText is displayed right away. className string no Class name to be applied to the component headerClassName string no Header class name. Header contains title, progress indicator, and delay text actionsContainerClassName string no Actions container class name actionClassName string no Single action class name successIconName string no Success icon name. Default is CheckMark errorIconName string no Error icon name. Default is Error inProgressIconName string no InProgress icon name. Default is '', spinner is displayed.","title":"Implementation"},{"location":"controls/ProgressStepsIndicator/","text":"Progress Steps Indicator \u00b6 This control shows a progress of steps. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the ProgressStepsIndicator control as follows: import { ProgressStepsIndicator } from '\"@pnp/spfx-controls-react/lib/ProgressStepsIndicator' ; const progressSteps : IStep [] = [ { id : 0 , title : \"Step 1\" , description : \"Step 1 Description\" }, { id : 1 , title : \"Step 2\" , description : \"Step 2 Description\" }, { id : 3 , title : \"Step 3\" , description : \"Step 3 Description\" }, { id : 4 , title : \"Step 4\" , description : \"Step 4 Description\" }, { id : 5 , title : \"Step 5\" , description : \"Step 5 Description\" }, { id : 6 , title : \"Step 6\" , description : \"Step 6 Description\" }, ]; Use the ProgressStepsIndicator control in your code as follows: { < ProgressStepsIndicator steps = { progressSteps } currentStep = { 0 } themeVariant = { props . themeVariant } /> } Implementation \u00b6 The ProgressStepsIndicator control can be configured with the following properties: Property Type Required Description Default steps ISteps[] yes Perogress Steps currentStep number yes index of current step default is 0 themeVariant IReadonlyTheme undefined no Theme The IStep Interface definition: Interface IStep { id? : number ; title : string ; description : string ; }","title":"ProgressStepsIndicator"},{"location":"controls/ProgressStepsIndicator/#progress-steps-indicator","text":"This control shows a progress of steps. Here is an example of the control in action:","title":"Progress Steps Indicator"},{"location":"controls/ProgressStepsIndicator/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the ProgressStepsIndicator control as follows: import { ProgressStepsIndicator } from '\"@pnp/spfx-controls-react/lib/ProgressStepsIndicator' ; const progressSteps : IStep [] = [ { id : 0 , title : \"Step 1\" , description : \"Step 1 Description\" }, { id : 1 , title : \"Step 2\" , description : \"Step 2 Description\" }, { id : 3 , title : \"Step 3\" , description : \"Step 3 Description\" }, { id : 4 , title : \"Step 4\" , description : \"Step 4 Description\" }, { id : 5 , title : \"Step 5\" , description : \"Step 5 Description\" }, { id : 6 , title : \"Step 6\" , description : \"Step 6 Description\" }, ]; Use the ProgressStepsIndicator control in your code as follows: { < ProgressStepsIndicator steps = { progressSteps } currentStep = { 0 } themeVariant = { props . themeVariant } /> }","title":"How to use this control in your solutions"},{"location":"controls/ProgressStepsIndicator/#implementation","text":"The ProgressStepsIndicator control can be configured with the following properties: Property Type Required Description Default steps ISteps[] yes Perogress Steps currentStep number yes index of current step default is 0 themeVariant IReadonlyTheme undefined no Theme The IStep Interface definition: Interface IStep { id? : number ; title : string ; description : string ; }","title":"Implementation"},{"location":"controls/RichText/","text":"RichText control \u00b6 This control provides rich text editing and display capability. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { RichText } from \"@pnp/spfx-controls-react/lib/RichText\" ; The simplest way to use the RichText control in your code is as follows: < RichText value = { this . props . value } onChange = {( text )=> this . onTextChange ( text )} /> The value property should contain the HTML that you wish to display The onChange handler will be called every time a user changes the text. For example, to have your web part store the rich text as it is updated, you would use the following code: private onTextChange = ( newText : string ) => { this . properties . myRichText = newText ; return newText ; } It is possible to use the onChange handler as users type -- for example, the following code replaces all instance of the word bold with bold text. private onTextChange = ( newText : string ) => { newText = newText . replace ( \" bold \" , \" bold \" ); this . properties . description = newText ; return newText ; } By adding label property, the control is better identified, especially when used in a form < RichText label = \"My multiline text field\" value = { this . props . value } /> It is also possible to customize the control label's rendering: const richText = ( < RichText id = \"spfxRichText\" label = \"My multiline text field\" onRenderLabel = { onRenderCustomLabel } value = { this . props . value } /> ); const onRenderCustomLabel = ( rtProps : IRichTextProps ) : JSX . Element => { return < Label htmlFor = { rtProps . id } > { rtProps . label } < /Label>; } Implementation \u00b6 The RichText control can be configured with the following properties: Property Type Required Description id string no The ID to apply to the RichText control. label string no The label displayed above the RichText control. className string no The custom CSS class to apply to the RichText control. style React.CSSProperties no The custom styles to apply to the RichText control. isEditMode boolean no true indicates that users will be able to edit the content of the RichText control. false will display the rich text as read-only. styleOptions StyleOptions no Define the styles you want to show or hide for the rich text editor value string no Sets the rich text to display in the RichText control. onChange (text: string) => string no onChange handler for the RichText control. The function must return a string containing the rich text to display in the RichText control. onRenderLabel (props: IRichTextProps) => JSX.Element no Custom renderer for the RichText control's label. The function must return a JSX.Element . StyleOptions interface Property Type Required Description showAlign boolean no Indicates whether to show the Align toolbar button or not. Default value is true showBold boolean no Indicates whether to show the Bold toolbar button or not. Default value is true showItalic boolean no Indicates whether to show the Italic toolbar button or not. Default value is true showLink boolean no Indicates whether to show the Hyperlink toolbar button or not. Default value is true showList boolean no Indicates whether to show the List toolbar button or not. Default value is true showMore boolean no Indicates whether to show the More toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true showStyles boolean no Indicates whether to show the Headings toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true showUnderline boolean no Indicates whether to show the Underline toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true Note that setting showAlign , showBold , showItalic , showLink , showList , showStyles , or showUnderline to false does not remove the user's ability to apply the button's associated formatting -- it only hides the toolbar option. Also, if showMore is true , all options remain available in the formatting pane -- regardless whether they were turned off using show___ . To prevent users from applying specific formats, use the onChange handler to parse the rich text and remove the formatting as desired.","title":"RichText"},{"location":"controls/RichText/#richtext-control","text":"This control provides rich text editing and display capability.","title":"RichText control"},{"location":"controls/RichText/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { RichText } from \"@pnp/spfx-controls-react/lib/RichText\" ; The simplest way to use the RichText control in your code is as follows: < RichText value = { this . props . value } onChange = {( text )=> this . onTextChange ( text )} /> The value property should contain the HTML that you wish to display The onChange handler will be called every time a user changes the text. For example, to have your web part store the rich text as it is updated, you would use the following code: private onTextChange = ( newText : string ) => { this . properties . myRichText = newText ; return newText ; } It is possible to use the onChange handler as users type -- for example, the following code replaces all instance of the word bold with bold text. private onTextChange = ( newText : string ) => { newText = newText . replace ( \" bold \" , \" bold \" ); this . properties . description = newText ; return newText ; } By adding label property, the control is better identified, especially when used in a form < RichText label = \"My multiline text field\" value = { this . props . value } /> It is also possible to customize the control label's rendering: const richText = ( < RichText id = \"spfxRichText\" label = \"My multiline text field\" onRenderLabel = { onRenderCustomLabel } value = { this . props . value } /> ); const onRenderCustomLabel = ( rtProps : IRichTextProps ) : JSX . Element => { return < Label htmlFor = { rtProps . id } > { rtProps . label } < /Label>; }","title":"How to use this control in your solutions"},{"location":"controls/RichText/#implementation","text":"The RichText control can be configured with the following properties: Property Type Required Description id string no The ID to apply to the RichText control. label string no The label displayed above the RichText control. className string no The custom CSS class to apply to the RichText control. style React.CSSProperties no The custom styles to apply to the RichText control. isEditMode boolean no true indicates that users will be able to edit the content of the RichText control. false will display the rich text as read-only. styleOptions StyleOptions no Define the styles you want to show or hide for the rich text editor value string no Sets the rich text to display in the RichText control. onChange (text: string) => string no onChange handler for the RichText control. The function must return a string containing the rich text to display in the RichText control. onRenderLabel (props: IRichTextProps) => JSX.Element no Custom renderer for the RichText control's label. The function must return a JSX.Element . StyleOptions interface Property Type Required Description showAlign boolean no Indicates whether to show the Align toolbar button or not. Default value is true showBold boolean no Indicates whether to show the Bold toolbar button or not. Default value is true showItalic boolean no Indicates whether to show the Italic toolbar button or not. Default value is true showLink boolean no Indicates whether to show the Hyperlink toolbar button or not. Default value is true showList boolean no Indicates whether to show the List toolbar button or not. Default value is true showMore boolean no Indicates whether to show the More toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true showStyles boolean no Indicates whether to show the Headings toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true showUnderline boolean no Indicates whether to show the Underline toolbar button or not. Note that this option is indenpendent from the other show___ options. I.e.: Setting showBold to false will disable the Bold toolbar, but will not disable it from the formatting pane. Default value is true Note that setting showAlign , showBold , showItalic , showLink , showList , showStyles , or showUnderline to false does not remove the user's ability to apply the button's associated formatting -- it only hides the toolbar option. Also, if showMore is true , all options remain available in the formatting pane -- regardless whether they were turned off using show___ . To prevent users from applying specific formats, use the onChange handler to parse the rich text and remove the formatting as desired.","title":"Implementation"},{"location":"controls/SecurityTrimmedControl/","text":"SecurityTrimmedControl \u00b6 This control is intended to be used when you want to show or hide components based on the user permissions. The control can be used to check the user\u2019s permissions on the current site / list were the solution is loaded, or on a remote site / list. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { SecurityTrimmedControl , PermissionLevel } from \"@pnp/spfx-controls-react/lib/SecurityTrimmedControl\" ; import { SPPermission } from '@microsoft/sp-page-context' ; You can use the SecurityTrimmedControl as follows in your solutions: Checking permissions on the current site < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . currentWeb } permissions = {[ SPPermission . viewPages ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on the current list < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . currentList } permissions = {[ SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on remote site < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteWeb } remoteSiteUrl = \"https://.sharepoint.com/sites/\" permissions = {[ SPPermission . viewPages , SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on remote list / library < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteListOrLib } remoteSiteUrl = \"https://.sharepoint.com/sites/\" relativeLibOrListUrl = \"/sites//\" permissions = {[ SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Show a control when the user doesn't have permissions < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteListOrLib } remoteSiteUrl = \"https://.sharepoint.com/sites/\" relativeLibOrListUrl = \"/sites//\" permissions = {[ SPPermission . addListItems ]} noPermissionsControl = {< p > SOrry , you don ' t have permissions to this list .}> { /* Specify the components to load when user has the required permissions */ } Implementation \u00b6 The SecurityTrimmedControl can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Context of the web part, application customizer, field customizer, or list view command set. permissions SPPermission[] yes The permissions to check for the user. level PermissionLevel yes Specify where to check the user permissions: current site or list / remote site or list. remoteSiteUrl string no The URL of the remote site. Required when you want to check permissions on remote site or list. relativeLibOrListUrl string no The relative URL of the list or library. Required when you want to check permissions on remote list. folderPath string no Specify the name of a folder to check the user permissions against. Will be overridden if itemId is present. itemId number no Specify the ID of the item to check the user permissions against. Takes precedence over folder. className string no Specify the className to be used on the parent element. noPermissionsControl JSX.Element no Optional. Specify the control you want to render if user doesn't have permissions. showLoadingAnimation boolean no Optional. Specify should render loading animation. The PermissionLevel enum has the following values: Value Description Required properties currentWeb Checks permissions on the current web context , permissions currentList Checks permissions in the current loaded list context , permissions remoteWeb Checks permissions on the specified site URL context , permissions , remoteSiteUrl remoteListOrLib Checks permissions on the specified list/library URL in combination with the site URL context , permissions , remoteSiteUrl , relativeLibOrListUrl remoteListItem Check permissions on a specific item in a list/library context , permissions , remoteSiteUrl , relativeLibOrListUrl , itemId remoteFolder Check permissions on a specific folder context , permissions , remoteSiteUrl , relativeLibOrListUrl , folderPath","title":"SecurityTrimmedControl"},{"location":"controls/SecurityTrimmedControl/#securitytrimmedcontrol","text":"This control is intended to be used when you want to show or hide components based on the user permissions. The control can be used to check the user\u2019s permissions on the current site / list were the solution is loaded, or on a remote site / list.","title":"SecurityTrimmedControl"},{"location":"controls/SecurityTrimmedControl/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { SecurityTrimmedControl , PermissionLevel } from \"@pnp/spfx-controls-react/lib/SecurityTrimmedControl\" ; import { SPPermission } from '@microsoft/sp-page-context' ; You can use the SecurityTrimmedControl as follows in your solutions: Checking permissions on the current site < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . currentWeb } permissions = {[ SPPermission . viewPages ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on the current list < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . currentList } permissions = {[ SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on remote site < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteWeb } remoteSiteUrl = \"https://.sharepoint.com/sites/\" permissions = {[ SPPermission . viewPages , SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Checking permissions on remote list / library < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteListOrLib } remoteSiteUrl = \"https://.sharepoint.com/sites/\" relativeLibOrListUrl = \"/sites//\" permissions = {[ SPPermission . addListItems ]}> { /* Specify the components to load when user has the required permissions */ } Show a control when the user doesn't have permissions < SecurityTrimmedControl context = { this . props . context } level = { PermissionLevel . remoteListOrLib } remoteSiteUrl = \"https://.sharepoint.com/sites/\" relativeLibOrListUrl = \"/sites//\" permissions = {[ SPPermission . addListItems ]} noPermissionsControl = {< p > SOrry , you don ' t have permissions to this list .}> { /* Specify the components to load when user has the required permissions */ } ","title":"How to use this control in your solutions"},{"location":"controls/SecurityTrimmedControl/#implementation","text":"The SecurityTrimmedControl can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Context of the web part, application customizer, field customizer, or list view command set. permissions SPPermission[] yes The permissions to check for the user. level PermissionLevel yes Specify where to check the user permissions: current site or list / remote site or list. remoteSiteUrl string no The URL of the remote site. Required when you want to check permissions on remote site or list. relativeLibOrListUrl string no The relative URL of the list or library. Required when you want to check permissions on remote list. folderPath string no Specify the name of a folder to check the user permissions against. Will be overridden if itemId is present. itemId number no Specify the ID of the item to check the user permissions against. Takes precedence over folder. className string no Specify the className to be used on the parent element. noPermissionsControl JSX.Element no Optional. Specify the control you want to render if user doesn't have permissions. showLoadingAnimation boolean no Optional. Specify should render loading animation. The PermissionLevel enum has the following values: Value Description Required properties currentWeb Checks permissions on the current web context , permissions currentList Checks permissions in the current loaded list context , permissions remoteWeb Checks permissions on the specified site URL context , permissions , remoteSiteUrl remoteListOrLib Checks permissions on the specified list/library URL in combination with the site URL context , permissions , remoteSiteUrl , relativeLibOrListUrl remoteListItem Check permissions on a specific item in a list/library context , permissions , remoteSiteUrl , relativeLibOrListUrl , itemId remoteFolder Check permissions on a specific folder context , permissions , remoteSiteUrl , relativeLibOrListUrl , folderPath","title":"Implementation"},{"location":"controls/SiteBreadcrumb/","text":"SiteBreadcrumb control \u00b6 This control returns a breadcrumb based on the current location. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { SiteBreadcrumb } from \"@pnp/spfx-controls-react/lib/SiteBreadcrumb\" ; Use the SiteBreadcrumb control in your code as follows: < SiteBreadcrumb context = { this . props . context } /> Implementation \u00b6 The SiteBreadcrumb control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Pass the context of your web part or application customizer extension.","title":"SiteBreadcrumb"},{"location":"controls/SiteBreadcrumb/#sitebreadcrumb-control","text":"This control returns a breadcrumb based on the current location.","title":"SiteBreadcrumb control"},{"location":"controls/SiteBreadcrumb/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { SiteBreadcrumb } from \"@pnp/spfx-controls-react/lib/SiteBreadcrumb\" ; Use the SiteBreadcrumb control in your code as follows: < SiteBreadcrumb context = { this . props . context } />","title":"How to use this control in your solutions"},{"location":"controls/SiteBreadcrumb/#implementation","text":"The SiteBreadcrumb control can be configured with the following properties: Property Type Required Description context BaseComponentContext yes Pass the context of your web part or application customizer extension.","title":"Implementation"},{"location":"controls/SitePicker/","text":"SitePicker control \u00b6 This control allows you to select one or multiple available sites, site collections or hub sites. Here is an example of the control. SitePicker single selection mode: SitePicker multi-selection mode How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { SitePicker } from \"@pnp/spfx-controls-react/lib/SitePicker\" ; Use the SitePicker control in your code as follows: < SitePicker context = { this . props . context } label = { 'Select sites' } mode = { 'site' } allowSearch = { true } multiSelect = { false } onChange = {( sites ) => { console . log ( sites ); }} placeholder = { 'Select sites' } searchPlaceholder = { 'Filter sites' } /> The onChange change event returns the selected site(s). Implementation \u00b6 The SitePicker control can be configured with the following properties: Property Type Required Description allowSearch boolean no Specifies if search box is displayed for the component. Default: true . context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. deferredSearchTime number no The list will be filtered after users stop typing for deferredSearchTime milliseconds. Default: 200. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. initialSites ISite[] no Intial data to load in the 'Selected sites' area (optional). isDesc boolean no Specifies if the list is sorted in descending order. Default: false . label string no Label to use for the control. limitToCurrentSiteCollection boolean no Specifies if the options should be limited by the current site collections. Taken into consideration if selectionMode is set to web . mode 'associatedsites' | 'site' | 'web' | 'hub' no Defines what entities are available for selection: site collections, sites, hub sites and sites inside hub. Default: web . multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default: true . onChange (selectedSites: ISite[]) => void yes Selection change handler. orderBy 'title' | 'url' no Specifices if the list is sorted by title or url. Default: title . placeholder string no Placeholder label to show in the dropdown. searchPlaceholder string no Search input placeholder text. Displayed until search text is entered. trimDuplicates boolean no Specifies if the duplicates should be trimmed. false by default. Applicable if mode is set to site or web. additionalQuery string no If provided will be added to the search query as AND part. Applicable if mode is set to site or web. Interface ISite Property Type Required Description id string no ID of the site collection. title string no Title of the site. url string no URL of the site. webId string no ID of the site. **Note: the value is not populated if the mode is set to hub . hubSiteId string no ID of the hub site.","title":"SitePicker"},{"location":"controls/SitePicker/#sitepicker-control","text":"This control allows you to select one or multiple available sites, site collections or hub sites. Here is an example of the control. SitePicker single selection mode: SitePicker multi-selection mode","title":"SitePicker control"},{"location":"controls/SitePicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { SitePicker } from \"@pnp/spfx-controls-react/lib/SitePicker\" ; Use the SitePicker control in your code as follows: < SitePicker context = { this . props . context } label = { 'Select sites' } mode = { 'site' } allowSearch = { true } multiSelect = { false } onChange = {( sites ) => { console . log ( sites ); }} placeholder = { 'Select sites' } searchPlaceholder = { 'Filter sites' } /> The onChange change event returns the selected site(s).","title":"How to use this control in your solutions"},{"location":"controls/SitePicker/#implementation","text":"The SitePicker control can be configured with the following properties: Property Type Required Description allowSearch boolean no Specifies if search box is displayed for the component. Default: true . context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. deferredSearchTime number no The list will be filtered after users stop typing for deferredSearchTime milliseconds. Default: 200. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the control is disabled. initialSites ISite[] no Intial data to load in the 'Selected sites' area (optional). isDesc boolean no Specifies if the list is sorted in descending order. Default: false . label string no Label to use for the control. limitToCurrentSiteCollection boolean no Specifies if the options should be limited by the current site collections. Taken into consideration if selectionMode is set to web . mode 'associatedsites' | 'site' | 'web' | 'hub' no Defines what entities are available for selection: site collections, sites, hub sites and sites inside hub. Default: web . multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default: true . onChange (selectedSites: ISite[]) => void yes Selection change handler. orderBy 'title' | 'url' no Specifices if the list is sorted by title or url. Default: title . placeholder string no Placeholder label to show in the dropdown. searchPlaceholder string no Search input placeholder text. Displayed until search text is entered. trimDuplicates boolean no Specifies if the duplicates should be trimmed. false by default. Applicable if mode is set to site or web. additionalQuery string no If provided will be added to the search query as AND part. Applicable if mode is set to site or web. Interface ISite Property Type Required Description id string no ID of the site collection. title string no Title of the site. url string no URL of the site. webId string no ID of the site. **Note: the value is not populated if the mode is set to hub . hubSiteId string no ID of the hub site.","title":"Implementation"},{"location":"controls/TaxonomyPicker/","text":"Taxonomy Picker \u00b6 This control allows you to select one or more Terms from a TermSet via its name or TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the AnchorId. Disclaimer This control makes use of the ProcessQuery API end-points to retrieve the managed metadata information. This will get changed once the APIs for managing managed metadata will become available. Empty term picker Selecting terms Selected terms in picker Term picker: Auto Complete How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TaxonomyPicker , IPickerTerms } from \"@pnp/spfx-controls-react/lib/TaxonomyPicker\" ; Use the TaxonomyPicker control in your code as follows: < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onTaxPickerChange } isTermSetSelectable = { false } /> With the onChange property you can capture the event of when the terms in the picker has changed: private onTaxPickerChange ( terms : IPickerTerms ) { console . log ( \"Terms\" , terms ); } With the onNewTerm property you can capture the event, when text is in the input field and enter/return is pressed. With a controlled TaxonomyPicker, this enables you to create the term and have the same flow as in SharePoint Keywords fields. const onNewTerm = ( value : IPickerTerm ) : void => { if ( value ? . name && EmptyGuid === value . key ){ console . log ( `TaxonmyPicker.onNewTerm name= ${ value . name } ` , value ); // Create keyword } else { console . error ( `TaxonmyPicker.onNewTerm name= ${ value ? . name } ` , value ); } }; Term actions \u00b6 Since version 1.12.0 , you can apply term actions to all terms or specific ones. Term actions could for instance be used to retrieve the labels of the term, or retrieve other information. These term actions can be implemented as follows: < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onServicePickerChange } isTermSetSelectable = { false } termActions = {{ actions : [{ title : \"Get term labels\" , iconName : \"LocaleLanguage\" , id : \"test\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { console . log ( term . Name , term . TermsCount ); return { updateActionType : UpdateType.updateTermLabel , value : ` ${ term . Name } (updated)` }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && term . Name === \"internal\" ) }, { title : \"Hide term\" , id : \"hideTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { return { updateActionType : UpdateType.hideTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && ( term . Name . toLowerCase () === \"help desk\" || term . Name . toLowerCase () === \"multi-column valo site page\" )) }, { title : \"Disable term\" , id : \"disableTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { return { updateActionType : UpdateType.disableTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && term . Name . toLowerCase () === \"secured\" ) }, { title : \"Disable or hide term\" , id : \"disableOrHideTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { if ( term . TermsCount > 0 ) { return { updateActionType : UpdateType.disableTerm , value : true }; } return { updateActionType : UpdateType.hideTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => true }] }} /> We also provided a default term action which you can use to retrieve the term its labels and will update the term text in the TaxonomyPicker hierarchy. < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onServicePickerChange } isTermSetSelectable = { false } termActions = {{ actions : [ new TermLabelAction ( \"Get Labels\" )] }} /> Implementation \u00b6 The TaxonomyPicker control can be configured with the following properties: Property Type Required Description panelTitle string yes TermSet Picker Panel title. label string yes Text displayed above the Taxonomy Picker. disabled boolean no Specify if the control needs to be disabled. context BaseComponentContext yes Context of the current web part or extension. initialValues IPickerTerms no Defines the terms selected by default. For each term object selected by default, an empty string can be provided for the path and termset properties as these properties are ignored when setting initial values. allowMultipleSelections boolean no Defines if the user can select only one or many term sets. Default value is false. termsetNameOrID string yes The name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from. onChange function no captures the event of when the terms in the picker has changed. onNewTerm function no captures the event when text is in the input field and the user presses return isTermSetSelectable boolean no Specify if the TermSet itself is selectable in the tree view. disabledTermIds string[] no Specify which terms should be disabled in the term set so that they cannot be selected. disableChildrenOfDisabledParents boolean no Specify if you want to disable the child terms when their parent is disabled. anchorId string no Set the anchorid to a child term in the TermSet to be able to select terms from that level and below. termActions ITermActions no Allows to execute custom action on the term like e.g. get other term labelsITermActions. hideTagsNotAvailableForTagging boolean no Specifies if the tags marked with 'Available for tagging' = false should be hidden validateOnLoad boolean no Specifies if the initial values will be validated, when the component is loaded. Default value is false validateInput boolean no Specifies if the input text will be validated, when the component focus is changed hideDeprecatedTags boolean no Specifies if deprecated tags should be hidden placeholder string no Short text hint to display in empty picker errorMessage string no Static error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive ( errorMessage takes precedence). onGetErrorMessage (value: IPickerTerms) => string | Promise no The method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this). When it returns string: If valid, it returns empty string. If invalid, it returns the error message string to be shown below the picker. When it returns Promise: The resolved value is display as error message. The rejected, the value is thrown away. required boolean no Specifies if to display an asterisk near the label. Note that error message should be specified in onGetErrorMessage or errorMessage useSessionStorage boolean no Specify if the control uses session storage. Default is set to true for better performance. onPanelSelectionChange (prevValue: IPickerTerms, newValue: IPickerTerms) => void no Panel selection change handler. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. selectChildrenIfParentSelected boolean no Specifies if the children should be selected when parent item is selected (defaults to false). Interface IPickerTerm Property Type Required Description key string yes The ID of the term name string yes The name of the term path string yes The path of the term termSet string yes The Id of the parent TermSet of the term termSetName string no The Name of the parent TermSet of the term Interface IPickerTerms An Array of IPickerTerm Interface ITermActions Property Type Required Description Default actions ITermAction[] yes The array of supported actions termActionsDisplayStyle TermActionsDisplayStyle no Defines how to display term action button, available options: text, icon, text and icon text termActionsDisplayMode TermActionsDisplayMode no Defines how to display term actions, as buttons or dropdown buttons initialize (spTermService: SPTermStorePickerService) => Promise\\ no Initializes the term action with the taxonomy service Interface ITreeItemAction Property Type Required Description id string yes Unique id of the term action title string yes Action title iconName string no Name of the icon to be used to display action hidden boolean no Specify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering. invokeActionOnRender boolean no Specifies if you want to invoke the action on render applyToTerm (currentTerm: ITerm, triggerActionCallback: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: \"disabled\" | \"hidden\", value: boolean) => void) => Promise\\ | boolean yes Method checks if the current term is supported for the action. The method provices a couple of additional callback functions to make it possibe to programatically change the terms and its actions. actionCallback (spTermService: SPTermStorePickerService, currentTerm: ITerm) => Promise\\ yes Method to be executed when action is fired Interface UpdateAction Property Type Required Description updateActionType UpdateType yes Defines the type of update you want to perform value string | boolean no When updateTermLabel is used, it should return a string. When hideTerm or disableTerm are used, you should return a boolean. Enum UpdateType Value updateTermLabel updateTermsTree hideTerm disableTerm selectTerm","title":"TaxonomyPicker"},{"location":"controls/TaxonomyPicker/#taxonomy-picker","text":"This control allows you to select one or more Terms from a TermSet via its name or TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the AnchorId. Disclaimer This control makes use of the ProcessQuery API end-points to retrieve the managed metadata information. This will get changed once the APIs for managing managed metadata will become available. Empty term picker Selecting terms Selected terms in picker Term picker: Auto Complete","title":"Taxonomy Picker"},{"location":"controls/TaxonomyPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TaxonomyPicker , IPickerTerms } from \"@pnp/spfx-controls-react/lib/TaxonomyPicker\" ; Use the TaxonomyPicker control in your code as follows: < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onTaxPickerChange } isTermSetSelectable = { false } /> With the onChange property you can capture the event of when the terms in the picker has changed: private onTaxPickerChange ( terms : IPickerTerms ) { console . log ( \"Terms\" , terms ); } With the onNewTerm property you can capture the event, when text is in the input field and enter/return is pressed. With a controlled TaxonomyPicker, this enables you to create the term and have the same flow as in SharePoint Keywords fields. const onNewTerm = ( value : IPickerTerm ) : void => { if ( value ? . name && EmptyGuid === value . key ){ console . log ( `TaxonmyPicker.onNewTerm name= ${ value . name } ` , value ); // Create keyword } else { console . error ( `TaxonmyPicker.onNewTerm name= ${ value ? . name } ` , value ); } };","title":"How to use this control in your solutions"},{"location":"controls/TaxonomyPicker/#term-actions","text":"Since version 1.12.0 , you can apply term actions to all terms or specific ones. Term actions could for instance be used to retrieve the labels of the term, or retrieve other information. These term actions can be implemented as follows: < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onServicePickerChange } isTermSetSelectable = { false } termActions = {{ actions : [{ title : \"Get term labels\" , iconName : \"LocaleLanguage\" , id : \"test\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { console . log ( term . Name , term . TermsCount ); return { updateActionType : UpdateType.updateTermLabel , value : ` ${ term . Name } (updated)` }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && term . Name === \"internal\" ) }, { title : \"Hide term\" , id : \"hideTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { return { updateActionType : UpdateType.hideTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && ( term . Name . toLowerCase () === \"help desk\" || term . Name . toLowerCase () === \"multi-column valo site page\" )) }, { title : \"Disable term\" , id : \"disableTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { return { updateActionType : UpdateType.disableTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => ( term && term . Name && term . Name . toLowerCase () === \"secured\" ) }, { title : \"Disable or hide term\" , id : \"disableOrHideTerm\" , invokeActionOnRender : true , hidden : true , actionCallback : async ( taxService : SPTermStorePickerService , term : ITerm ) => { if ( term . TermsCount > 0 ) { return { updateActionType : UpdateType.disableTerm , value : true }; } return { updateActionType : UpdateType.hideTerm , value : true }; }, applyToTerm : ( term : ITerm , triggerActionCb : ( updateAction : UpdateAction ) => void , setActionStateForTerm : ( actionId : string , termId : string , type : \"disabled\" | \"hidden\" , value : boolean ) => void ) => true }] }} /> We also provided a default term action which you can use to retrieve the term its labels and will update the term text in the TaxonomyPicker hierarchy. < TaxonomyPicker allowMultipleSelections = { true } termsetNameOrID = \"Countries\" panelTitle = \"Select Term\" label = \"Taxonomy Picker\" context = { this . props . context } onChange = { this . onServicePickerChange } isTermSetSelectable = { false } termActions = {{ actions : [ new TermLabelAction ( \"Get Labels\" )] }} />","title":"Term actions"},{"location":"controls/TaxonomyPicker/#implementation","text":"The TaxonomyPicker control can be configured with the following properties: Property Type Required Description panelTitle string yes TermSet Picker Panel title. label string yes Text displayed above the Taxonomy Picker. disabled boolean no Specify if the control needs to be disabled. context BaseComponentContext yes Context of the current web part or extension. initialValues IPickerTerms no Defines the terms selected by default. For each term object selected by default, an empty string can be provided for the path and termset properties as these properties are ignored when setting initial values. allowMultipleSelections boolean no Defines if the user can select only one or many term sets. Default value is false. termsetNameOrID string yes The name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from. onChange function no captures the event of when the terms in the picker has changed. onNewTerm function no captures the event when text is in the input field and the user presses return isTermSetSelectable boolean no Specify if the TermSet itself is selectable in the tree view. disabledTermIds string[] no Specify which terms should be disabled in the term set so that they cannot be selected. disableChildrenOfDisabledParents boolean no Specify if you want to disable the child terms when their parent is disabled. anchorId string no Set the anchorid to a child term in the TermSet to be able to select terms from that level and below. termActions ITermActions no Allows to execute custom action on the term like e.g. get other term labelsITermActions. hideTagsNotAvailableForTagging boolean no Specifies if the tags marked with 'Available for tagging' = false should be hidden validateOnLoad boolean no Specifies if the initial values will be validated, when the component is loaded. Default value is false validateInput boolean no Specifies if the input text will be validated, when the component focus is changed hideDeprecatedTags boolean no Specifies if deprecated tags should be hidden placeholder string no Short text hint to display in empty picker errorMessage string no Static error message displayed below the picker. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive ( errorMessage takes precedence). onGetErrorMessage (value: IPickerTerms) => string | Promise no The method is used to get the validation error message and determine whether the picker value is valid or not. Mutually exclusive with the static string errorMessage (it will take precedence over this). When it returns string: If valid, it returns empty string. If invalid, it returns the error message string to be shown below the picker. When it returns Promise: The resolved value is display as error message. The rejected, the value is thrown away. required boolean no Specifies if to display an asterisk near the label. Note that error message should be specified in onGetErrorMessage or errorMessage useSessionStorage boolean no Specify if the control uses session storage. Default is set to true for better performance. onPanelSelectionChange (prevValue: IPickerTerms, newValue: IPickerTerms) => void no Panel selection change handler. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. selectChildrenIfParentSelected boolean no Specifies if the children should be selected when parent item is selected (defaults to false). Interface IPickerTerm Property Type Required Description key string yes The ID of the term name string yes The name of the term path string yes The path of the term termSet string yes The Id of the parent TermSet of the term termSetName string no The Name of the parent TermSet of the term Interface IPickerTerms An Array of IPickerTerm Interface ITermActions Property Type Required Description Default actions ITermAction[] yes The array of supported actions termActionsDisplayStyle TermActionsDisplayStyle no Defines how to display term action button, available options: text, icon, text and icon text termActionsDisplayMode TermActionsDisplayMode no Defines how to display term actions, as buttons or dropdown buttons initialize (spTermService: SPTermStorePickerService) => Promise\\ no Initializes the term action with the taxonomy service Interface ITreeItemAction Property Type Required Description id string yes Unique id of the term action title string yes Action title iconName string no Name of the icon to be used to display action hidden boolean no Specify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering. invokeActionOnRender boolean no Specifies if you want to invoke the action on render applyToTerm (currentTerm: ITerm, triggerActionCallback: (updateAction: UpdateAction) => void, setActionStateForTerm: (actionId: string, termId: string, type: \"disabled\" | \"hidden\", value: boolean) => void) => Promise\\ | boolean yes Method checks if the current term is supported for the action. The method provices a couple of additional callback functions to make it possibe to programatically change the terms and its actions. actionCallback (spTermService: SPTermStorePickerService, currentTerm: ITerm) => Promise\\ yes Method to be executed when action is fired Interface UpdateAction Property Type Required Description updateActionType UpdateType yes Defines the type of update you want to perform value string | boolean no When updateTermLabel is used, it should return a string. When hideTerm or disableTerm are used, you should return a boolean. Enum UpdateType Value updateTermLabel updateTermsTree hideTerm disableTerm selectTerm","title":"Implementation"},{"location":"controls/TeamChannelPicker/","text":"TeamChannelPicker control \u00b6 This control allows you to select one or multiple Team Channels based on user's permissions. Note You can also check out Microsoft Teams Channel Picker component in the Microsoft Graph Toolkit . Here is an example of the control: SelectTeamChannelPicker single selection mode: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { TeamChannelPicker } from \"@pnp/spfx-controls-react/lib/TeamChannelPicker\" ; Use the TeamChannelPicker control in your code as follows: < TeamChannelPicker label = \"Select Team channel\" teamId = { teamId } selectedChannels = { selectedTeamChannels } appcontext = { webpartContext } itemLimit = { 1 } onSelectedChannels = { _onSelectedTeamChannels } /> The _onSelectedTeamChannels change event returns the team channel(s) and can be implemented as follows: const _onSelectedTeamChannels (( tagList : ITag []) => { console . log ( tagList ); } Implementation \u00b6 The SelectTeamChannelPicker control can be configured with the following properties: Property Type Required Description teamId string yes Id of Team to get channels appcontext WebPartContext | ExtensionContext yes The context object of the SPFx loaded webpart or customizer. selectedChannels ITag[] yes Array with selected channels itemLimit number no number of allowed selected channels label string no Label of Picker styles IBasePickerStyles no Customer Styles of Picker onSelectedChannels: (tagsList:ITag[]) => void; yes callBack with channels Selected MSGraph Permissions required \u00b6 This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All,","title":"TeamChannelPicker"},{"location":"controls/TeamChannelPicker/#teamchannelpicker-control","text":"This control allows you to select one or multiple Team Channels based on user's permissions. Note You can also check out Microsoft Teams Channel Picker component in the Microsoft Graph Toolkit . Here is an example of the control: SelectTeamChannelPicker single selection mode:","title":"TeamChannelPicker control"},{"location":"controls/TeamChannelPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { TeamChannelPicker } from \"@pnp/spfx-controls-react/lib/TeamChannelPicker\" ; Use the TeamChannelPicker control in your code as follows: < TeamChannelPicker label = \"Select Team channel\" teamId = { teamId } selectedChannels = { selectedTeamChannels } appcontext = { webpartContext } itemLimit = { 1 } onSelectedChannels = { _onSelectedTeamChannels } /> The _onSelectedTeamChannels change event returns the team channel(s) and can be implemented as follows: const _onSelectedTeamChannels (( tagList : ITag []) => { console . log ( tagList ); }","title":"How to use this control in your solutions"},{"location":"controls/TeamChannelPicker/#implementation","text":"The SelectTeamChannelPicker control can be configured with the following properties: Property Type Required Description teamId string yes Id of Team to get channels appcontext WebPartContext | ExtensionContext yes The context object of the SPFx loaded webpart or customizer. selectedChannels ITag[] yes Array with selected channels itemLimit number no number of allowed selected channels label string no Label of Picker styles IBasePickerStyles no Customer Styles of Picker onSelectedChannels: (tagsList:ITag[]) => void; yes callBack with channels Selected","title":"Implementation"},{"location":"controls/TeamChannelPicker/#msgraph-permissions-required","text":"This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All,","title":"MSGraph Permissions required"},{"location":"controls/TeamPicker/","text":"TeamPicker control \u00b6 This control allows you to select one or multiple Teams based on user's permissions. Here is an example of the control: SelectTeamPicker single selection mode: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { SelectTeamPicker } from \"@pnp/spfx-controls-react/lib/TeamPicker\" ; Use the SelectTeamPicker control in your code as follows: < TeamPicker label = \"Select Team\" selectedTeams = { selectedTeams } appcontext = { webpartContext } itemLimit = { 1 } onSelectedTeams = { _onSelectedTeams } /> The _onSelectedTeams change event returns the team(s) and can be implemented as follows: const _onSelectedTeams (( tagList : ITag []) => { console . log ( tagList ); } Implementation \u00b6 The TeamPicker control can be configured with the following properties: Property Type Required Description appcontext WebPartContext | ExtensionContext yes The context object of the SPFx loaded webpart or customizer. selectedTeams ITag[] yes Array with Selected Teams itemLimit number no number of allowed selected items label string no Label of Picker styles IBasePickerStyles no Customer Styles of Picker onSelectedTeams: (tagsList:ITag[]) => void; yes callBack with teams Selected ## MSGraph Permissions required This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All,","title":"TeamPicker"},{"location":"controls/TeamPicker/#teampicker-control","text":"This control allows you to select one or multiple Teams based on user's permissions. Here is an example of the control: SelectTeamPicker single selection mode:","title":"TeamPicker control"},{"location":"controls/TeamPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { SelectTeamPicker } from \"@pnp/spfx-controls-react/lib/TeamPicker\" ; Use the SelectTeamPicker control in your code as follows: < TeamPicker label = \"Select Team\" selectedTeams = { selectedTeams } appcontext = { webpartContext } itemLimit = { 1 } onSelectedTeams = { _onSelectedTeams } /> The _onSelectedTeams change event returns the team(s) and can be implemented as follows: const _onSelectedTeams (( tagList : ITag []) => { console . log ( tagList ); }","title":"How to use this control in your solutions"},{"location":"controls/TeamPicker/#implementation","text":"The TeamPicker control can be configured with the following properties: Property Type Required Description appcontext WebPartContext | ExtensionContext yes The context object of the SPFx loaded webpart or customizer. selectedTeams ITag[] yes Array with Selected Teams itemLimit number no number of allowed selected items label string no Label of Picker styles IBasePickerStyles no Customer Styles of Picker onSelectedTeams: (tagsList:ITag[]) => void; yes callBack with teams Selected ## MSGraph Permissions required This control required the flowing scopes : at least : Team.ReadBasic.All, Channel.ReadBasic.All,","title":"Implementation"},{"location":"controls/TermSetNavigation/","text":"TermSetNavigation \u00b6 This control allows you to navigate and select a Term from a TermSet. You can also configure a context menu for a term to execute a specific action. TermSetNavigation How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TermSetNavigation } from '@pnp/spfx-controls-react/lib/TermSetNavigation' ; Use the TermSetNavigation control in your code as follows: < TermSetNavigation context = { context } themeVariant = { themeVariant } termSetId = { \"289180a0-4a8b-4f08-ae6e-ea3fb1b669e2\" } showContextMenu = { true } contextMenuItems = {[ { key : \"add\" , text : \"Add\" , iconProps : { iconName : \"add\" }, }, { key : \"adit\" , text : \"Edit\" , iconProps : { iconName : \"Edit\" }, }, { key : \"remove\" , text : \"Remove\" , iconProps : { iconName : \"delete\" }, }, ]} onSelected = { onSelect } onSelectedTermAction = { onSelectedTermAction } /> With the onSelected property you can get the selcted term: const onSelect = React . useCallback (( selected : TermStore.Term ) => { console . log ( selected ); }, []); With the onSelectedTermAction property you can get the the action on the contextMenu for tghe selcted term: const onSelectedTermAction = React . useCallback (( selected : TermStore.Term , option : string ) => { console . log ( selected , option ); }, []); Implementation \u00b6 The TermSetNavigation control can be configured with the following properties: Property Type Required Description themeVariant IReadonlyTheme yes ThemeVariant termSetId string yes Term Set Id context BaseComponentContext yes Context of the current web part or extension. showContextMenu boolean no If show ConextMenu for term contextMenuItems IContextualMenuItem[] no array of action to show on contextMenu, if is un defined the conbtecxtMenu won't be available onSelected onSelected?: (term: TermStore.Term) => void no return Term Sselcted onSelectedTermAction onSelectedTermAction?: (term : TermStore.Term, option:string) => void no return the action selected to to term ## MSGraph Permissions required This control required the flowing scopes : at least : , TermStore.Read.All, TermStore.ReadWrite.All, please use M365Cli or PnP Powershell to add these permissions.","title":"TermSetNavigation"},{"location":"controls/TermSetNavigation/#termsetnavigation","text":"This control allows you to navigate and select a Term from a TermSet. You can also configure a context menu for a term to execute a specific action. TermSetNavigation","title":"TermSetNavigation"},{"location":"controls/TermSetNavigation/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TermSetNavigation } from '@pnp/spfx-controls-react/lib/TermSetNavigation' ; Use the TermSetNavigation control in your code as follows: < TermSetNavigation context = { context } themeVariant = { themeVariant } termSetId = { \"289180a0-4a8b-4f08-ae6e-ea3fb1b669e2\" } showContextMenu = { true } contextMenuItems = {[ { key : \"add\" , text : \"Add\" , iconProps : { iconName : \"add\" }, }, { key : \"adit\" , text : \"Edit\" , iconProps : { iconName : \"Edit\" }, }, { key : \"remove\" , text : \"Remove\" , iconProps : { iconName : \"delete\" }, }, ]} onSelected = { onSelect } onSelectedTermAction = { onSelectedTermAction } /> With the onSelected property you can get the selcted term: const onSelect = React . useCallback (( selected : TermStore.Term ) => { console . log ( selected ); }, []); With the onSelectedTermAction property you can get the the action on the contextMenu for tghe selcted term: const onSelectedTermAction = React . useCallback (( selected : TermStore.Term , option : string ) => { console . log ( selected , option ); }, []);","title":"How to use this control in your solutions"},{"location":"controls/TermSetNavigation/#implementation","text":"The TermSetNavigation control can be configured with the following properties: Property Type Required Description themeVariant IReadonlyTheme yes ThemeVariant termSetId string yes Term Set Id context BaseComponentContext yes Context of the current web part or extension. showContextMenu boolean no If show ConextMenu for term contextMenuItems IContextualMenuItem[] no array of action to show on contextMenu, if is un defined the conbtecxtMenu won't be available onSelected onSelected?: (term: TermStore.Term) => void no return Term Sselcted onSelectedTermAction onSelectedTermAction?: (term : TermStore.Term, option:string) => void no return the action selected to to term ## MSGraph Permissions required This control required the flowing scopes : at least : , TermStore.Read.All, TermStore.ReadWrite.All, please use M365Cli or PnP Powershell to add these permissions.","title":"Implementation"},{"location":"controls/Toolbar/","text":"Dashboard control \u00b6 Toolbar component for Microsoft Teams. Note As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Toolbar } from '@pnp/spfx-controls-react/lib/Toolbar' ; Use the Toolbar control in your code as follows: < Toolbar actionGroups = {{ 'group1' : { 'action1' : { title : 'Edit' , iconName : 'Edit' , onClick : () => { console . log ( 'Edit action click' ); } }, 'action2' : { title : 'New' , iconName : 'Add' , onClick : () => { console . log ( 'New action click' ); } } } }} filters = {[{ id : \"f1\" , title : \"Fruits (any sweet, edible part of a plant that resembles fruit, even if it does not develop from a floral ovary)\" , items : [ { id : \"f1f1\" , title : \"Pomes\" }, { id : \"f1f2\" , title : \"Drupes\" }, { id : \"f1f3\" , title : \"Citruses\" }, { id : \"f1f4\" , title : \"Berries\" }, { id : \"f1f5\" , title : \"Melons\" }, ], }, { id : \"f3\" , title : \"Cacti\" , },]} find = { true } /> Controlled or uncontrolled management of selected filters \u00b6 The Toolbar component can internally manage the set of selected filters (uncontrolled) or the set of selected filters can be defined using property, selectedFilterIds (controlled). If property selectedFilterIds is undefined then the set of selected filter IDs is uncontrolled and the Toolbar will initialise with an empty set of selected filters. As the user toggles the Toolbar's filters the function set on property, onSelectedFiltersChange , will be called with an array parameter of the currently selected filter IDs. The implementation of this function can return void or an array of filter IDs that the Toolbar should set. By returning an array of filter IDs the onSelectedFiltersChange implementation can alter the selected filters of an uncontrolled Toolbar in response to user attempts to set/clear filters. If the selectedFilterIds property is defined then the set of selected filter IDs is controlled and the Toolbar shall display selected filters according the contents of the array property. The onSelectedFiltersChange function will still be called, but the returned value will have no effect on the filters displayed as selected by the Toolbar. Implementation \u00b6 The Toolbar component can be configured with the following properties: Property Type Required Description actionGroups TActionGroups yes Toolbar actions groups. filters TFilters no Toolbar filters. find boolean no Specifies if searchbox should be displayed. filtersSingleSelect boolean no Specifies if a user can select only one filter at a time. onSelectedFiltersChange (selectedFilters: string[]) => (string[] | void) no Filter changed handler. Called when user toggles selection of a filter. selectedFilterIds string[] no Specifies the IDs of the filters which should be displayed as selected by the Toolbar. onFindQueryChange (findQuery: string) => string no Search query changed handler. Type TActionGroups Provides Toolbar action groups settings type TActionGroups = { [ slug : string ] : TActions ; }; Type TActions Provides Toolbar actions settings type TActions = { [ actionKey : string ] : TAction ; }; Type TAction Provides Toolbar action settings Property Type Required Description title string yes Action title. iconName string no Action icon name. multi boolean no For future. onClick ComponentEventHandler no Action onClick handler. Type TFilters Provides Toolbar filters settings type TFilters = ObjectShorthandCollection < TreeItemProps , never > ;","title":"Toolbar"},{"location":"controls/Toolbar/#dashboard-control","text":"Toolbar component for Microsoft Teams. Note As this component is based on @fluentui/react-northstar the main usage scenario is Microsoft Teams projects. You can still use it in non-Teams related projects as well. Here is an example of the control in action:","title":"Dashboard control"},{"location":"controls/Toolbar/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { Toolbar } from '@pnp/spfx-controls-react/lib/Toolbar' ; Use the Toolbar control in your code as follows: < Toolbar actionGroups = {{ 'group1' : { 'action1' : { title : 'Edit' , iconName : 'Edit' , onClick : () => { console . log ( 'Edit action click' ); } }, 'action2' : { title : 'New' , iconName : 'Add' , onClick : () => { console . log ( 'New action click' ); } } } }} filters = {[{ id : \"f1\" , title : \"Fruits (any sweet, edible part of a plant that resembles fruit, even if it does not develop from a floral ovary)\" , items : [ { id : \"f1f1\" , title : \"Pomes\" }, { id : \"f1f2\" , title : \"Drupes\" }, { id : \"f1f3\" , title : \"Citruses\" }, { id : \"f1f4\" , title : \"Berries\" }, { id : \"f1f5\" , title : \"Melons\" }, ], }, { id : \"f3\" , title : \"Cacti\" , },]} find = { true } />","title":"How to use this control in your solutions"},{"location":"controls/Toolbar/#controlled-or-uncontrolled-management-of-selected-filters","text":"The Toolbar component can internally manage the set of selected filters (uncontrolled) or the set of selected filters can be defined using property, selectedFilterIds (controlled). If property selectedFilterIds is undefined then the set of selected filter IDs is uncontrolled and the Toolbar will initialise with an empty set of selected filters. As the user toggles the Toolbar's filters the function set on property, onSelectedFiltersChange , will be called with an array parameter of the currently selected filter IDs. The implementation of this function can return void or an array of filter IDs that the Toolbar should set. By returning an array of filter IDs the onSelectedFiltersChange implementation can alter the selected filters of an uncontrolled Toolbar in response to user attempts to set/clear filters. If the selectedFilterIds property is defined then the set of selected filter IDs is controlled and the Toolbar shall display selected filters according the contents of the array property. The onSelectedFiltersChange function will still be called, but the returned value will have no effect on the filters displayed as selected by the Toolbar.","title":"Controlled or uncontrolled management of selected filters"},{"location":"controls/Toolbar/#implementation","text":"The Toolbar component can be configured with the following properties: Property Type Required Description actionGroups TActionGroups yes Toolbar actions groups. filters TFilters no Toolbar filters. find boolean no Specifies if searchbox should be displayed. filtersSingleSelect boolean no Specifies if a user can select only one filter at a time. onSelectedFiltersChange (selectedFilters: string[]) => (string[] | void) no Filter changed handler. Called when user toggles selection of a filter. selectedFilterIds string[] no Specifies the IDs of the filters which should be displayed as selected by the Toolbar. onFindQueryChange (findQuery: string) => string no Search query changed handler. Type TActionGroups Provides Toolbar action groups settings type TActionGroups = { [ slug : string ] : TActions ; }; Type TActions Provides Toolbar actions settings type TActions = { [ actionKey : string ] : TAction ; }; Type TAction Provides Toolbar action settings Property Type Required Description title string yes Action title. iconName string no Action icon name. multi boolean no For future. onClick ComponentEventHandler no Action onClick handler. Type TFilters Provides Toolbar filters settings type TFilters = ObjectShorthandCollection < TreeItemProps , never > ;","title":"Implementation"},{"location":"controls/TreeView/","text":"TreeView control \u00b6 This graphical control allows to present a hierarchical view of information. Each tree item can have a number of subitems. This is often visualized by indentation in a list. A tree item can be expanded to reveal subitems (if exist), and collapsed to hide subitems. Here are examples of the control in action: With all possible options Without check boxes or when selection mode is 'None' Without check boxes, and selection mode is multiple How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TreeView , ITreeItem , TreeViewSelectionMode } from \"@pnp/spfx-controls-react/lib/TreeView\" ; Use the TreeView control in your code as follows: < TreeView items = { treeitems } defaultExpanded = { false } selectionMode = { TreeViewSelectionMode . Multiple } selectChildrenMode = { SelectChildrenMode . Select | SelectChildrenMode . Unselect } showCheckboxes = { true } treeItemActionsDisplayMode = { TreeItemActionsDisplayMode . ContextualMenu } defaultSelectedKeys = {[ 'key1' , 'key2' ]} expandToSelected = { true } defaultExpandedChildren = { true } onSelect = { this . onTreeItemSelect } onExpandCollapse = { this . onTreeItemExpandCollapse } onRenderItem = { this . renderCustomTreeItem } theme = { this . props . themeVariant } /> With the onSelect property you can capture the event of when the tree item in the TreeView has changed the selection: private onTreeItemSelect ( items : ITreeItem []) { console . log ( \"Items selected: \" , items ); } With the onExpandCollapse property you can capture the event of when the tree item in the TreeView has expanded or collapsed: private onTreeItemExpandCollapse ( item : ITreeItem , isExpanded : boolean ) { console . log (( isExpanded ? \"Item expanded: \" : \"Item collapsed: \" ) + item ); } Custom Rendering \u00b6 You can fully customize how tree items are rendered by providing the onRenderItem callback function and returning whatever JSX.Element you want. For example, you can define your function in a .tsx file like this: import * as React from 'react' ; private renderCustomTreeItem ( item : ITreeItem ) : JSX . Element { return ( < span > { item . iconProps && < i className = { \"ms-Icon ms-Icon--\" + item . iconProps . iconName } style = {{ paddingRight : '4px' }} /> } { item . label } < /span> ); } Implementation \u00b6 The TreeView control can be configured with the following properties: Property Type Required Description items ITreeItem[] yes An array of tree items to display. refer example . defaultExpanded boolean no Specify if the tree items are displayed as expanded by default (defaults to false. selectionMode enum no Specifies the selection mode of tree view (defaults to Single selection). selectChildrenIfParentSelected boolean no Specifies if the children should be selected when parent item is selected (defaults to false). Deprecated : prefer usage of selectChildrenMode for more flexibility. selectChildrenMode SelectChildrenMode no Specifies if the children should be selected when parent item is selected (defaults to None). Flagged enum, values can be combined eg. SelectChildrenMode.Select \\| SelectChildrenMode.Unselect showCheckboxes boolean yes Specify if the checkboxes should be displayed for selection. treeItemActionsDisplayMode TreeItemActionsDisplayMode no Specifies the display mode of the tree item actions. defaultSelectedKeys string[] no Specifies keys of items to be selected by default. expandToSelected boolean no Specifies if the tree view is expanded to display selected nodes. onExpandCollapse function no Defines a onExpandCollapse function to raise when the tree item has expanded or collapsed. onSelect function no Captures the event of when the tree item selection has changed. onRenderItem function no Optional callback to provide custom rendering of the item (default is simple text of item label and a checkbox for selection). defaultExpandedChildren boolean no Default expand / collapse behavior for the child nodes. By default this is set to true. defaultExpandedKeys string[] no Keys of items expanded by default. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded. Enum TreeViewSelectionMode Specifies the selection mode of tree item. Value Single Multiple None Enum SelectChildrenMode Specifies when the children of a selected item need to be automatically selected. Value Description None Children are never selected Select When selecting an item, its children are also selected Unselect When unselecting an item, its children are also unselected Mount When the component is mounted, all children of selected items are also selected Update When the component receives new props, all children of selected items are also selected All Shorthand for a combination of all of the above, same as SelectChildrenMode.Select \\| SelectChildrenMode.Unselect \\| SelectChildrenMode.Mount \\| SelectChildrenMode.Update Interface ITreeItem Each tree item in the treeitems property is defined as ITreeItem as follows: Property Type Required Description key string yes The unique ID of the tree item. label string yes Text displayed next to checkbox. subLabel string no The sub label of the tree item. iconProps IIconProps no Custom icon to be rendered before label. disabled boolean no Specify if the tree item needs to be disabled. Default is false. selectable boolean no Specify if the tree item can be selected. Default is true. data any no Specify an additional data of the tree item. actions ITreeItemAction[] no Specify list of actions for the tree item. children ITreeItem[] no Specify list of child tree items. Interface ITreeItemAction Specifies the list of actions for the tree item. Property Type Required Description id string yes Unique id of the action. title string yes Title of the action. iconProps IIconProps no Name of the icon to be used to display action. hidden boolean no Specify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering. invokeActionOnRender boolean no Specifies if you want to invoke the action on render. actionCallback (currentTreeItem: ITreeItem) => void yes Method to be executed when action is fired. Enum TreeItemActionsDisplayMode Specifies the display mode of the tree item action. Value Buttons ContextualMenu Example of array of tree items used to render control as in 2nd screenshot \u00b6 items : [ { key : \"R1\" , label : \"Root\" , subLabel : \"This is a sub label for node\" , iconProps : skypeCheckIcon , actions : [{ title : \"Get item\" , iconProps : { iconName : 'Warning' , style : { color : 'salmon' , }, }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }], children : [ { key : \"1\" , label : \"Parent 1\" , selectable : false , children : [ { key : \"3\" , label : \"Child 1\" , subLabel : \"This is a sub label for node\" , actions : [{ title : \"Share\" , iconProps : { iconName : 'Share' }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }], children : [ { key : \"gc1\" , label : \"Grand Child 1\" , actions : [{ title : \"Get Grand Child item\" , iconProps : { iconName : 'Mail' }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }] } ] }, { key : \"4\" , label : \"Child 2\" , iconProps : skypeCheckIcon } ] }, { key : \"2\" , label : \"Parent 2\" }, { key : \"5\" , label : \"Parent 3\" , disabled : true }, { key : \"6\" , label : \"Parent 4\" , selectable : true } ] }, { key : \"R2\" , label : \"Root 2\" , children : [ { key : \"8\" , label : \"Parent 5\" } ] } ] IconpProps in above example can be declared as below private skypeCheckIcon : IIconProps = { iconName : 'SkypeCheck' };","title":"TreeView"},{"location":"controls/TreeView/#treeview-control","text":"This graphical control allows to present a hierarchical view of information. Each tree item can have a number of subitems. This is often visualized by indentation in a list. A tree item can be expanded to reveal subitems (if exist), and collapsed to hide subitems. Here are examples of the control in action: With all possible options Without check boxes or when selection mode is 'None' Without check boxes, and selection mode is multiple","title":"TreeView control"},{"location":"controls/TreeView/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { TreeView , ITreeItem , TreeViewSelectionMode } from \"@pnp/spfx-controls-react/lib/TreeView\" ; Use the TreeView control in your code as follows: < TreeView items = { treeitems } defaultExpanded = { false } selectionMode = { TreeViewSelectionMode . Multiple } selectChildrenMode = { SelectChildrenMode . Select | SelectChildrenMode . Unselect } showCheckboxes = { true } treeItemActionsDisplayMode = { TreeItemActionsDisplayMode . ContextualMenu } defaultSelectedKeys = {[ 'key1' , 'key2' ]} expandToSelected = { true } defaultExpandedChildren = { true } onSelect = { this . onTreeItemSelect } onExpandCollapse = { this . onTreeItemExpandCollapse } onRenderItem = { this . renderCustomTreeItem } theme = { this . props . themeVariant } /> With the onSelect property you can capture the event of when the tree item in the TreeView has changed the selection: private onTreeItemSelect ( items : ITreeItem []) { console . log ( \"Items selected: \" , items ); } With the onExpandCollapse property you can capture the event of when the tree item in the TreeView has expanded or collapsed: private onTreeItemExpandCollapse ( item : ITreeItem , isExpanded : boolean ) { console . log (( isExpanded ? \"Item expanded: \" : \"Item collapsed: \" ) + item ); }","title":"How to use this control in your solutions"},{"location":"controls/TreeView/#custom-rendering","text":"You can fully customize how tree items are rendered by providing the onRenderItem callback function and returning whatever JSX.Element you want. For example, you can define your function in a .tsx file like this: import * as React from 'react' ; private renderCustomTreeItem ( item : ITreeItem ) : JSX . Element { return ( < span > { item . iconProps && < i className = { \"ms-Icon ms-Icon--\" + item . iconProps . iconName } style = {{ paddingRight : '4px' }} /> } { item . label } < /span> ); }","title":"Custom Rendering"},{"location":"controls/TreeView/#implementation","text":"The TreeView control can be configured with the following properties: Property Type Required Description items ITreeItem[] yes An array of tree items to display. refer example . defaultExpanded boolean no Specify if the tree items are displayed as expanded by default (defaults to false. selectionMode enum no Specifies the selection mode of tree view (defaults to Single selection). selectChildrenIfParentSelected boolean no Specifies if the children should be selected when parent item is selected (defaults to false). Deprecated : prefer usage of selectChildrenMode for more flexibility. selectChildrenMode SelectChildrenMode no Specifies if the children should be selected when parent item is selected (defaults to None). Flagged enum, values can be combined eg. SelectChildrenMode.Select \\| SelectChildrenMode.Unselect showCheckboxes boolean yes Specify if the checkboxes should be displayed for selection. treeItemActionsDisplayMode TreeItemActionsDisplayMode no Specifies the display mode of the tree item actions. defaultSelectedKeys string[] no Specifies keys of items to be selected by default. expandToSelected boolean no Specifies if the tree view is expanded to display selected nodes. onExpandCollapse function no Defines a onExpandCollapse function to raise when the tree item has expanded or collapsed. onSelect function no Captures the event of when the tree item selection has changed. onRenderItem function no Optional callback to provide custom rendering of the item (default is simple text of item label and a checkbox for selection). defaultExpandedChildren boolean no Default expand / collapse behavior for the child nodes. By default this is set to true. defaultExpandedKeys string[] no Keys of items expanded by default. theme IPartialTheme | ITheme no Set Fluent UI Theme. If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded. Enum TreeViewSelectionMode Specifies the selection mode of tree item. Value Single Multiple None Enum SelectChildrenMode Specifies when the children of a selected item need to be automatically selected. Value Description None Children are never selected Select When selecting an item, its children are also selected Unselect When unselecting an item, its children are also unselected Mount When the component is mounted, all children of selected items are also selected Update When the component receives new props, all children of selected items are also selected All Shorthand for a combination of all of the above, same as SelectChildrenMode.Select \\| SelectChildrenMode.Unselect \\| SelectChildrenMode.Mount \\| SelectChildrenMode.Update Interface ITreeItem Each tree item in the treeitems property is defined as ITreeItem as follows: Property Type Required Description key string yes The unique ID of the tree item. label string yes Text displayed next to checkbox. subLabel string no The sub label of the tree item. iconProps IIconProps no Custom icon to be rendered before label. disabled boolean no Specify if the tree item needs to be disabled. Default is false. selectable boolean no Specify if the tree item can be selected. Default is true. data any no Specify an additional data of the tree item. actions ITreeItemAction[] no Specify list of actions for the tree item. children ITreeItem[] no Specify list of child tree items. Interface ITreeItemAction Specifies the list of actions for the tree item. Property Type Required Description id string yes Unique id of the action. title string yes Title of the action. iconProps IIconProps no Name of the icon to be used to display action. hidden boolean no Specify if the action is hidden. This could be used for instance when you want to invoke the action right after rendering. invokeActionOnRender boolean no Specifies if you want to invoke the action on render. actionCallback (currentTreeItem: ITreeItem) => void yes Method to be executed when action is fired. Enum TreeItemActionsDisplayMode Specifies the display mode of the tree item action. Value Buttons ContextualMenu","title":"Implementation"},{"location":"controls/TreeView/#example-of-array-of-tree-items-used-to-render-control-as-in-2nd-screenshot","text":"items : [ { key : \"R1\" , label : \"Root\" , subLabel : \"This is a sub label for node\" , iconProps : skypeCheckIcon , actions : [{ title : \"Get item\" , iconProps : { iconName : 'Warning' , style : { color : 'salmon' , }, }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }], children : [ { key : \"1\" , label : \"Parent 1\" , selectable : false , children : [ { key : \"3\" , label : \"Child 1\" , subLabel : \"This is a sub label for node\" , actions : [{ title : \"Share\" , iconProps : { iconName : 'Share' }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }], children : [ { key : \"gc1\" , label : \"Grand Child 1\" , actions : [{ title : \"Get Grand Child item\" , iconProps : { iconName : 'Mail' }, id : \"GetItem\" , actionCallback : async ( treeItem : ITreeItem ) => { console . log ( treeItem ); } }] } ] }, { key : \"4\" , label : \"Child 2\" , iconProps : skypeCheckIcon } ] }, { key : \"2\" , label : \"Parent 2\" }, { key : \"5\" , label : \"Parent 3\" , disabled : true }, { key : \"6\" , label : \"Parent 4\" , selectable : true } ] }, { key : \"R2\" , label : \"Root 2\" , children : [ { key : \"8\" , label : \"Parent 5\" } ] } ] IconpProps in above example can be declared as below private skypeCheckIcon : IIconProps = { iconName : 'SkypeCheck' };","title":"Example of array of tree items used to render control as in 2nd screenshot"},{"location":"controls/UploadFiles/","text":"UploadFiles \u00b6 This control allows to drag and drop files and manage files before upload. How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { UploadFiles , } from '@pnp/spfx-controls-react/lib/UploadFiles' ; Use the UploadFiles control in your code as follows: < UploadFiles pageSize = { 20 } context = { context } title = \"Upload Files\" onUploadFiles = {( files ) => { console . log ( \"files\" , files ); }} themeVariant = { themeVariant } /> Implementation \u00b6 The UploadFiles can be configured with the following properties: Property Type Required Description pageSize number no number of files to show per page base on this value the height of control is calculate, default 15 context WebPartContext yes webPartContext title string yes title onUploadFiles (files: File[]) => void; yes Method that returns all Files[] themeVariant IReadonlyTheme no Theme Variant","title":"UploadFiles"},{"location":"controls/UploadFiles/#uploadfiles","text":"This control allows to drag and drop files and manage files before upload.","title":"UploadFiles"},{"location":"controls/UploadFiles/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { UploadFiles , } from '@pnp/spfx-controls-react/lib/UploadFiles' ; Use the UploadFiles control in your code as follows: < UploadFiles pageSize = { 20 } context = { context } title = \"Upload Files\" onUploadFiles = {( files ) => { console . log ( \"files\" , files ); }} themeVariant = { themeVariant } />","title":"How to use this control in your solutions"},{"location":"controls/UploadFiles/#implementation","text":"The UploadFiles can be configured with the following properties: Property Type Required Description pageSize number no number of files to show per page base on this value the height of control is calculate, default 15 context WebPartContext yes webPartContext title string yes title onUploadFiles (files: File[]) => void; yes Method that returns all Files[] themeVariant IReadonlyTheme no Theme Variant","title":"Implementation"},{"location":"controls/UserPicker/","text":"User Picker \u00b6 This control allows you to select one or more user from a AAD via its name or starting characters. ! Empty user picker Selecting Users Selected users in picker How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { UserPicker } from '@pnp/spfx-controls-react/lib/userPicker' ; import { IUserInfo } from '@pnp/spfx-controls-react/lib/userPicker/models/IUserInfo' ; Use the UserPicker control in your code as follows: < UserPicker context = { context } secondaryTextPropertyName = \"mail\" theme = { theme } label = { < div className = { styles . attributeHader } > < Person20Filled color = { tokens . colorBrandForeground1 } /> < Body1 > Select User < /Body1> < /div> } placeholder = { \"Search User\" } onSelectedUsers = { onSelectedUsers } onRemoveSelectedUser = { onRemovedUser } /> With the onSelectedUsers property you can capture the event of when the user in the picker has changed: const onSelectedUsers = React . useCallback (( users : IUserInfo []) => { console . log ( users ); }, []); With the onRemoveSelectedUser property you can capture the event, when the user is removed from picker. const onRemovedUser = React . useCallback (( user : IUserInfo ) => { console . log ( user ); }, []); Implementation \u00b6 The UseryPicker control can be configured with the following properties: Property Type Required Description userSelectionLimit number no Number selected users allowed label string or JSX.Element no Text or control displayed above the User Picker. required boolean no Specify if the control is required context BaseComponentContext yes Context of the current web part or extension. validationMessage string no Defines message to show on picker messageType \"error\", \"success\" , \"warning\" , \"none\" no Defines message type to show if validationMessage is defined onSelectedUsers (users: IUserInfo[]) => void no captures the event of when the users in the picker has changed. onRemoveSelectedUser (user: IUserInfo) => void no captures the event of when the user in the picker was removed placeholder string no placeholder to show defaultSelectdUsers IUserInfo[] no default users to show on the picker theme IReadonlyTheme no theme secondaryTextPropertyName values :\"jobTitle\" , \"department\" , \"mail\", \"officeLocation\" , \"mobilePhone\" , \"businessPhones\" , \"userPrincipalName\" no secondary text to show on persona card Interface IUserInfo extends User interface from `@microsoft/microsoft-graph-types`` Property Type Required Description userPhoto string yes userPhoto to show on Person card presence Presence yes user Presence","title":"User Picker"},{"location":"controls/UserPicker/#user-picker","text":"This control allows you to select one or more user from a AAD via its name or starting characters. ! Empty user picker Selecting Users Selected users in picker","title":"User Picker"},{"location":"controls/UserPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { UserPicker } from '@pnp/spfx-controls-react/lib/userPicker' ; import { IUserInfo } from '@pnp/spfx-controls-react/lib/userPicker/models/IUserInfo' ; Use the UserPicker control in your code as follows: < UserPicker context = { context } secondaryTextPropertyName = \"mail\" theme = { theme } label = { < div className = { styles . attributeHader } > < Person20Filled color = { tokens . colorBrandForeground1 } /> < Body1 > Select User < /Body1> < /div> } placeholder = { \"Search User\" } onSelectedUsers = { onSelectedUsers } onRemoveSelectedUser = { onRemovedUser } /> With the onSelectedUsers property you can capture the event of when the user in the picker has changed: const onSelectedUsers = React . useCallback (( users : IUserInfo []) => { console . log ( users ); }, []); With the onRemoveSelectedUser property you can capture the event, when the user is removed from picker. const onRemovedUser = React . useCallback (( user : IUserInfo ) => { console . log ( user ); }, []);","title":"How to use this control in your solutions"},{"location":"controls/UserPicker/#implementation","text":"The UseryPicker control can be configured with the following properties: Property Type Required Description userSelectionLimit number no Number selected users allowed label string or JSX.Element no Text or control displayed above the User Picker. required boolean no Specify if the control is required context BaseComponentContext yes Context of the current web part or extension. validationMessage string no Defines message to show on picker messageType \"error\", \"success\" , \"warning\" , \"none\" no Defines message type to show if validationMessage is defined onSelectedUsers (users: IUserInfo[]) => void no captures the event of when the users in the picker has changed. onRemoveSelectedUser (user: IUserInfo) => void no captures the event of when the user in the picker was removed placeholder string no placeholder to show defaultSelectdUsers IUserInfo[] no default users to show on the picker theme IReadonlyTheme no theme secondaryTextPropertyName values :\"jobTitle\" , \"department\" , \"mail\", \"officeLocation\" , \"mobilePhone\" , \"businessPhones\" , \"userPrincipalName\" no secondary text to show on persona card Interface IUserInfo extends User interface from `@microsoft/microsoft-graph-types`` Property Type Required Description userPhoto string yes userPhoto to show on Person card presence Presence yes user Presence","title":"Implementation"},{"location":"controls/VariantThemeProvider/","text":"Variant Theme Provider \u00b6 This control is a super set of the Theme Provider control, which not only allows you to pass the FluentUI Theme to the child controls, but also allows you to apply \"variants\" or generate a theme starting from the three basic colors, primary color, text color and color background. The idea comes from the possibility of \"highlighting\" a Web Part in the page or section where it is contained. By default, the SharePoint Modern Pages allow to change the set of colors which are then applied to all controls, but this can only be done at the site level (changing the site theme) or at the page section level (applying variations from the site theme). With this control we have the possibility to apply the variants to the single Web Part or to a portion of it. Here is an example of the control in action inside a Web Part: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the VariantThemeProvider control as follows: import { VariantThemeProvider , VariantType , IThemeColors } from \"@pnp/spfx-controls-react/lib/VariantThemeProvider\" ; Example on use the VariantThemeProvider control with the 'Neutral' variant on custom theme generated from the 'themeColors' property: const customThemeColors : IThemeColors = { primaryColor : \"#0078d4\" , textColor : \"#323130\" , backgroundColor : \"#ffffff\" } < VariantThemeProvider themeColors = { customThemeColors } variantType = { VariantType . Neutral }> { /* Child controls */ } Example on use the VariantThemeProvider control with the 'Strong' variant on theme passed with the from the 'theme' property: < VariantThemeProvider theme = { theme } variantType = { VariantType . Strong }> { /* Child controls */ } Implementation \u00b6 The VariantThemeProvider control can be configured with the following properties (inherits all the properties present in the FluentUI ThemeProvider control): Property Type Required Description as React.ElementType no A component that should be used as the root element of the ThemeProvider component. ref React.Ref no Optional ref to the root element. theme PartialTheme | Theme no Defines the theme provided by the user. renderer StyleRenderer no Optional interface for registering dynamic styles. Defaults to using merge-styles . Use this to opt into a particular rendering implementation, such as emotion , styled-components , or jss . Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation. applyTo element | body | none no Defines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of this control. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body. variantType VariantType no Variant type to apply to the theme. themeColors IThemeColors no Object used to generate a new theme from colors. Interface IThemeColors Property Type Required Description primaryColor string yes Primary Color of the theme. textColor string yes Text Color of the theme. backgroundColor string yes Background Color of the theme. Enum VariantType Type Description None Apply the theme without variations. Neutral Apply the 'Neutral' variation to the theme. Soft Apply the 'Soft' variation to the theme. Strong Apply the 'Strong' variation to the theme.","title":"VariantThemeProvider"},{"location":"controls/VariantThemeProvider/#variant-theme-provider","text":"This control is a super set of the Theme Provider control, which not only allows you to pass the FluentUI Theme to the child controls, but also allows you to apply \"variants\" or generate a theme starting from the three basic colors, primary color, text color and color background. The idea comes from the possibility of \"highlighting\" a Web Part in the page or section where it is contained. By default, the SharePoint Modern Pages allow to change the set of colors which are then applied to all controls, but this can only be done at the site level (changing the site theme) or at the page section level (applying variations from the site theme). With this control we have the possibility to apply the variants to the single Web Part or to a portion of it. Here is an example of the control in action inside a Web Part:","title":"Variant Theme Provider"},{"location":"controls/VariantThemeProvider/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In your component file, import the VariantThemeProvider control as follows: import { VariantThemeProvider , VariantType , IThemeColors } from \"@pnp/spfx-controls-react/lib/VariantThemeProvider\" ; Example on use the VariantThemeProvider control with the 'Neutral' variant on custom theme generated from the 'themeColors' property: const customThemeColors : IThemeColors = { primaryColor : \"#0078d4\" , textColor : \"#323130\" , backgroundColor : \"#ffffff\" } < VariantThemeProvider themeColors = { customThemeColors } variantType = { VariantType . Neutral }> { /* Child controls */ } Example on use the VariantThemeProvider control with the 'Strong' variant on theme passed with the from the 'theme' property: < VariantThemeProvider theme = { theme } variantType = { VariantType . Strong }> { /* Child controls */ } ","title":"How to use this control in your solutions"},{"location":"controls/VariantThemeProvider/#implementation","text":"The VariantThemeProvider control can be configured with the following properties (inherits all the properties present in the FluentUI ThemeProvider control): Property Type Required Description as React.ElementType no A component that should be used as the root element of the ThemeProvider component. ref React.Ref no Optional ref to the root element. theme PartialTheme | Theme no Defines the theme provided by the user. renderer StyleRenderer no Optional interface for registering dynamic styles. Defaults to using merge-styles . Use this to opt into a particular rendering implementation, such as emotion , styled-components , or jss . Note: performance will differ between all renders. Please measure your scenarios before using an alternative implementation. applyTo element | body | none no Defines where body-related theme is applied to. Setting to 'element' will apply body styles to the root element of this control. Setting to 'body' will apply body styles to document body. Setting to 'none' will not apply body styles to either element or body. variantType VariantType no Variant type to apply to the theme. themeColors IThemeColors no Object used to generate a new theme from colors. Interface IThemeColors Property Type Required Description primaryColor string yes Primary Color of the theme. textColor string yes Text Color of the theme. backgroundColor string yes Background Color of the theme. Enum VariantType Type Description None Apply the theme without variations. Neutral Apply the 'Neutral' variation to the theme. Soft Apply the 'Soft' variation to the theme. Strong Apply the 'Strong' variation to the theme.","title":"Implementation"},{"location":"controls/ViewPicker/","text":"ViewPicker control \u00b6 This control allows you to select available views from lists/libraries of the current site. Here is an example of the control: ViewPicker single selection mode: ViewPicker multi selection mode: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ViewPicker } from \"@pnp/spfx-controls-react/lib/ViewPicker\" ; Use the ViewPicker control in your code as follows: < ViewPicker context = { this . props . context } listId = { \"9f3908cd-1e88-4ab3-ac42-08efbbd64ec9\" } placeholder = { 'Select list view(s)' } orderBy = { orderBy . Title } multiSelect = { true } onSelectionChanged = { this . onViewPickerChange } /> The onSelectionChanged change event returns the selected view(s) and can be implemented as follows in your webpart: private onViewPickerChange = ( views : string | string []) => { console . log ( \"Views:\" , views ); } Implementation \u00b6 The ViewPicker control can be configured with the following properties Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the view picker control is disabled. filter string no Filter views from Odata query. label string no Label to use for the control. listId string no The List Id of the list. placeholder string no Placeholder label to show in the dropdown. orderBy Enum no How to order the set of views (By ID or Title). selectedView string OR string[] no Keys(View Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default to false . showBlankOption boolean no Whether or not to show a blank option. Default to false . viewsToExclude string[] no Defines view titles which should be excluded from the view picker control. webAbsoulteUrl string no Absolute Web Url of target site (user requires permissions) onSelectionChanged (newValue: string OR string[]): void no Callback function when the selected option changes. Enum orderBy Value Id Title","title":"ViewPicker"},{"location":"controls/ViewPicker/#viewpicker-control","text":"This control allows you to select available views from lists/libraries of the current site. Here is an example of the control: ViewPicker single selection mode: ViewPicker multi selection mode:","title":"ViewPicker control"},{"location":"controls/ViewPicker/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the control into your component: import { ViewPicker } from \"@pnp/spfx-controls-react/lib/ViewPicker\" ; Use the ViewPicker control in your code as follows: < ViewPicker context = { this . props . context } listId = { \"9f3908cd-1e88-4ab3-ac42-08efbbd64ec9\" } placeholder = { 'Select list view(s)' } orderBy = { orderBy . Title } multiSelect = { true } onSelectionChanged = { this . onViewPickerChange } /> The onSelectionChanged change event returns the selected view(s) and can be implemented as follows in your webpart: private onViewPickerChange = ( views : string | string []) => { console . log ( \"Views:\" , views ); }","title":"How to use this control in your solutions"},{"location":"controls/ViewPicker/#implementation","text":"The ViewPicker control can be configured with the following properties Property Type Required Description context BaseComponentContext yes The context object of the SPFx loaded webpart or customizer. className string no If provided, additional class name to provide on the dropdown element. disabled boolean no Whether or not the view picker control is disabled. filter string no Filter views from Odata query. label string no Label to use for the control. listId string no The List Id of the list. placeholder string no Placeholder label to show in the dropdown. orderBy Enum no How to order the set of views (By ID or Title). selectedView string OR string[] no Keys(View Ids) of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. multiSelect boolean no Optional mode indicates if multi-choice selections is allowed. Default to false . showBlankOption boolean no Whether or not to show a blank option. Default to false . viewsToExclude string[] no Defines view titles which should be excluded from the view picker control. webAbsoulteUrl string no Absolute Web Url of target site (user requires permissions) onSelectionChanged (newValue: string OR string[]): void no Callback function when the selected option changes. Enum orderBy Value Id Title","title":"Implementation"},{"location":"controls/WebPartTitle/","text":"WebPartTitle control \u00b6 This control renders a web part title that is changeable when the page is in edit mode. Here is an example of the control in action: How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In the root web part file, the one that extends from the BaseClientSideWebPart class. Pass the following properties to your web part main component: const element : React.ReactElement < IControlsTestProps > = React . createElement ( ControlsTest , { title : this.properties.title , displayMode : this.displayMode , updateProperty : ( value : string ) => { this . properties . title = value ; } } ); Add the title , displayMode , and updateProperty properties to the properties interface of your component: import { DisplayMode } from '@microsoft/sp-core-library' ; export interface IControlsTestProps { title : string ; displayMode : DisplayMode ; updateProperty : ( value : string ) => void ; } In your component file, import the WebPartTitle control as follows: import { WebPartTitle } from \"@pnp/spfx-controls-react/lib/WebPartTitle\" ; Use the WebPartTitle control in your code as follows: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } /> Adding a \"see all\" link \u00b6 Since version 1.13.0 the WebPartTitle control has the ability to show a \"see all\" link by using the moreLink property. The property gives you the flexibility to render the link or component you want to show next to the web part title. You can do this as like in the following example code: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } moreLink = { < Link href = \"https://pnp.github.io/sp-dev-fx-controls-react/\" > See all < /Link> } /> If you wish, you may pass a callback function instead, as per the following example code: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } moreLink = { ()=> { return ( < Link href = \"https://pnp.github.io/sp-dev-fx-controls-react/\" > See all < /Link>); } } /> The resulting web part title will look like the following: Implementation \u00b6 The WebPartTitle control can be configured with the following properties: Property Type Required Description displayMode DisplayMode yes This tells the control in which page mode it is rendering. title string yes The title value for the web part. updateProperty Function yes Function that you can pass to update the title in the root web part. className string no Optional property to specify a custom class that allows you to change the web part title style. placeholder string no Optional property to specify a custom placeholder to display when the title is editable. themeVariant IReadonlyTheme no The current loaded SharePoint theme/section background (More info: Supporting section backgrounds ). moreLink Function | JSX.Element no Optional property to render a See all link in the web part title.","title":"WebPartTitle"},{"location":"controls/WebPartTitle/#webparttitle-control","text":"This control renders a web part title that is changeable when the page is in edit mode. Here is an example of the control in action:","title":"WebPartTitle control"},{"location":"controls/WebPartTitle/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. In the root web part file, the one that extends from the BaseClientSideWebPart class. Pass the following properties to your web part main component: const element : React.ReactElement < IControlsTestProps > = React . createElement ( ControlsTest , { title : this.properties.title , displayMode : this.displayMode , updateProperty : ( value : string ) => { this . properties . title = value ; } } ); Add the title , displayMode , and updateProperty properties to the properties interface of your component: import { DisplayMode } from '@microsoft/sp-core-library' ; export interface IControlsTestProps { title : string ; displayMode : DisplayMode ; updateProperty : ( value : string ) => void ; } In your component file, import the WebPartTitle control as follows: import { WebPartTitle } from \"@pnp/spfx-controls-react/lib/WebPartTitle\" ; Use the WebPartTitle control in your code as follows: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } />","title":"How to use this control in your solutions"},{"location":"controls/WebPartTitle/#adding-a-see-all-link","text":"Since version 1.13.0 the WebPartTitle control has the ability to show a \"see all\" link by using the moreLink property. The property gives you the flexibility to render the link or component you want to show next to the web part title. You can do this as like in the following example code: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } moreLink = { < Link href = \"https://pnp.github.io/sp-dev-fx-controls-react/\" > See all < /Link> } /> If you wish, you may pass a callback function instead, as per the following example code: < WebPartTitle displayMode = { this . props . displayMode } title = { this . props . title } updateProperty = { this . props . updateProperty } moreLink = { ()=> { return ( < Link href = \"https://pnp.github.io/sp-dev-fx-controls-react/\" > See all < /Link>); } } /> The resulting web part title will look like the following:","title":"Adding a \"see all\" link"},{"location":"controls/WebPartTitle/#implementation","text":"The WebPartTitle control can be configured with the following properties: Property Type Required Description displayMode DisplayMode yes This tells the control in which page mode it is rendering. title string yes The title value for the web part. updateProperty Function yes Function that you can pass to update the title in the root web part. className string no Optional property to specify a custom class that allows you to change the web part title style. placeholder string no Optional property to specify a custom placeholder to display when the title is editable. themeVariant IReadonlyTheme no The current loaded SharePoint theme/section background (More info: Supporting section backgrounds ). moreLink Function | JSX.Element no Optional property to render a See all link in the web part title.","title":"Implementation"},{"location":"controls/charts/BarChart/","text":"ChartControl - Bar Chart \u00b6 Bar charts represent data values as vertical bars. Example Usage \u00b6 To create a bar chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(255, 159, 64, 0.2)' , 'rgba(255, 205, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(201, 203, 207, 0.2)' ], borderColor : [ 'rgb(255, 99, 132)' , 'rgb(255, 159, 64)' , 'rgb(255, 205, 86)' , 'rgb(75, 192, 192)' , 'rgb(54, 162, 235)' , 'rgb(153, 102, 255)' , 'rgb(201, 203, 207)' ], borderWidth : 1 }] }; // set the options const options : Chart.ChartOptions = { scales : { yAxes : [ { ticks : { beginAtZero : true } } ] } }; return ( < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> ); You can omit the backgroundColor , borderColor , and borderWidth values from the code above to render a chart using the default Office palette: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] }] }; // set the options const options : Chart.ChartOptions = { scales : { yAxes : [ { ticks : { beginAtZero : true } } ] } }; return ( < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> ); Which will produce the following chart: As with all charts, the backgroundColor and borderColor values can be one of the following: Array of colors ( string[] ): each data element in the dataset will be assigned a different color in the same order as they are listed in the array. If there are more data elements than colors, the remaining data elements will have a grey color. A single color ( string ): every data element in the dataset will use the same color. Variations \u00b6 Stacked Bar Chart \u00b6 If your bar chart has multiple datasets, you can render it as a stacked bar chart by changing the settings on the X and Y axes to enable stacking, as follows: const options : Chart.ChartOptions = { scales : { xAxes : [{ stacked : true }], yAxes : [{ stacked : true }] } }; In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ], fill : false , backgroundColor : 'rgba(255, 99, 132, 0.2)' , // same color for all data elements borderColor : 'rgb(255, 99, 132)' , // same color for all data elements borderWidth : 1 }, { label : 'My Second Dataset' , data : [ 15 , 29 , 30 , 8 , 26 , 35 , 20 ], fill : false , backgroundColor : 'rgba(255, 159, 64, 0.2)' , // same color for all data elements borderColor : 'rgb(255, 159, 64)' , // same color for all data elements borderWidth : 1 } ] }; Horizontal Bar Chart \u00b6 To render a horizontal bar, use the following code: < ChartControl type = { ChartType . HorizontalBar } data = { data } options = { options } /> Using the same options as above. Note that horizontal bar charts can also be stacked using the same approach as above. Dataset Properties \u00b6 Bar charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) For example, the following code will apply the value 'red:' to every element in the dataset. const data : Chart.ChartData = { datasets : [ { label : 'My First Dataset' , data : [ 10 , 20 , 30 , ], backgroundColor : 'red' } }; Whereas the following code will set 10 to backgroundColor 'red' , 20 to 'green' , and 30 to 'blue' . const data : Chart.ChartData = { datasets : [ { label : 'My First Dataset' , data : [ 10 , 20 , 30 , ], backgroundColor : [ 'red' , 'green' , 'blue' ] } }; Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The bar fill color. borderColor Color OR Color[] The bar border color. borderWidth number OR number[] The bar's border width. Measured in pixels. borderSkipped 'bottom' 'left' 'top' 'right' Specifies which border should be hidden when rendering bars. This option is useful when custom-rendering charts. data number[] { t: Date, y: number} The chart's data. Required. hoverBackgroundColor Color OR Color[] The bar's fill color when a mouse hovers over it hoverBorderColor Color OR Color[] The bar's border color when a mouse hovers over it. hoverBorderWidth number OR number[] The bar's border width when a mouse hovers over it. Data Structure \u00b6 number[] \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] The chart elements will be rendered in the same order as found in the array. Time Scales \u00b6 You can also provide dates and times instead of labels for each data element. Time scales should be provided as t (as in ticks ) and y coordinates: data : [ { \"t\" : new Date ( 'December 1 2018' ), \"y\" : 46 }, { \"t\" : new Date ( 'December 3 2018' ), \"y\" : 9 }, { \"t\" : new Date ( 'December 7 2018' ), \"y\" : 48 }, { \"t\" : new Date ( 'December 10 2018' ), \"y\" : 13 }, { \"t\" : new Date ( 'December 20 2018' ), \"y\" : 12 }, ] Or, if you prefer using moment.js : data : [ { \"t\" : moment ( 'December 1 2018' ). valueOf (), \"y\" : 46 }, { \"t\" : moment ( 'December 3 2018' ). valueOf (), \"y\" : 9 }, { \"t\" : moment ( 'December 7 2018' ). valueOf (), \"y\" : 48 }, { \"t\" : moment ( 'December 10 2018' ). valueOf (), \"y\" : 13 }, { \"t\" : moment ( 'December 20 2018' ). valueOf (), \"y\" : 12 }, ] (add the following to your imports:) import * as moment from 'moment' ; To render horizontal axis as a time series, use the following options: options = {{ scales : { xAxes : [{ type : 'time' , time : { displayFormats : { // choose the scale that applies to your data, // or pass all the scales 'millisecond' : 'MMM DD YYYY' , // use your own date format 'second' : 'MMM DD YYYY' , 'minute' : 'MMM DD YYYY' , 'hour' : 'MMM DD YYYY' , 'day' : 'MMM DD YYYY' , 'week' : 'MMM DD YYYY' , 'month' : 'MMM DD YYYY' , 'quarter' : 'MMM DD YYYY' , 'year' : 'MMM DD YYYY' , } } }] } }} Which will produce the following chart: NOTE: As with regular data elements, you should pass the time scale array in the order that you want them to appear. Otherwise, you will get disappointing results. Configuration \u00b6 The following configuration options are specific to bar charts: Name Type Default Description barPercentage number 0.9 How much of the category should each bar occupy, in percent. Value should be between 0 and 1. categoryPercentage number 0.8 How much each category should occupy, in percent. Value should be between 0 and 1. barThickness number OR \"flex\" Sets the thickness of each bar. If the default value is used, the bars will be equally sized to match the smallest interval. If number value is provided, the bar width will be set in pixels and barPercentage and categoryPercentage will be ignored. If \"flex\" is used, the widths are calculated automatically based on the previous and following samples so that they take the full available widths without overlap maxBarThickness number Sets the maximum width of every bar. gridLines.offsetGridLines boolean true true , bars will fall between the grid lines; grid lines will shift to the left by half a tick interval. If false , grid line will align with the middle of the bars. For More Information \u00b6 For more information on what options are available with Bar charts, refer to the Bar Chart documentation on Chart.js .","title":"Bar Chart"},{"location":"controls/charts/BarChart/#chartcontrol-bar-chart","text":"Bar charts represent data values as vertical bars.","title":"ChartControl - Bar Chart"},{"location":"controls/charts/BarChart/#example-usage","text":"To create a bar chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ], backgroundColor : [ 'rgba(255, 99, 132, 0.2)' , 'rgba(255, 159, 64, 0.2)' , 'rgba(255, 205, 86, 0.2)' , 'rgba(75, 192, 192, 0.2)' , 'rgba(54, 162, 235, 0.2)' , 'rgba(153, 102, 255, 0.2)' , 'rgba(201, 203, 207, 0.2)' ], borderColor : [ 'rgb(255, 99, 132)' , 'rgb(255, 159, 64)' , 'rgb(255, 205, 86)' , 'rgb(75, 192, 192)' , 'rgb(54, 162, 235)' , 'rgb(153, 102, 255)' , 'rgb(201, 203, 207)' ], borderWidth : 1 }] }; // set the options const options : Chart.ChartOptions = { scales : { yAxes : [ { ticks : { beginAtZero : true } } ] } }; return ( < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> ); You can omit the backgroundColor , borderColor , and borderWidth values from the code above to render a chart using the default Office palette: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [{ label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] }] }; // set the options const options : Chart.ChartOptions = { scales : { yAxes : [ { ticks : { beginAtZero : true } } ] } }; return ( < ChartControl type = { ChartType . Bar } data = { data } options = { options } /> ); Which will produce the following chart: As with all charts, the backgroundColor and borderColor values can be one of the following: Array of colors ( string[] ): each data element in the dataset will be assigned a different color in the same order as they are listed in the array. If there are more data elements than colors, the remaining data elements will have a grey color. A single color ( string ): every data element in the dataset will use the same color.","title":"Example Usage"},{"location":"controls/charts/BarChart/#variations","text":"","title":"Variations"},{"location":"controls/charts/BarChart/#stacked-bar-chart","text":"If your bar chart has multiple datasets, you can render it as a stacked bar chart by changing the settings on the X and Y axes to enable stacking, as follows: const options : Chart.ChartOptions = { scales : { xAxes : [{ stacked : true }], yAxes : [{ stacked : true }] } }; In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ], fill : false , backgroundColor : 'rgba(255, 99, 132, 0.2)' , // same color for all data elements borderColor : 'rgb(255, 99, 132)' , // same color for all data elements borderWidth : 1 }, { label : 'My Second Dataset' , data : [ 15 , 29 , 30 , 8 , 26 , 35 , 20 ], fill : false , backgroundColor : 'rgba(255, 159, 64, 0.2)' , // same color for all data elements borderColor : 'rgb(255, 159, 64)' , // same color for all data elements borderWidth : 1 } ] };","title":"Stacked Bar Chart"},{"location":"controls/charts/BarChart/#horizontal-bar-chart","text":"To render a horizontal bar, use the following code: < ChartControl type = { ChartType . HorizontalBar } data = { data } options = { options } /> Using the same options as above. Note that horizontal bar charts can also be stacked using the same approach as above.","title":"Horizontal Bar Chart"},{"location":"controls/charts/BarChart/#dataset-properties","text":"Bar charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) For example, the following code will apply the value 'red:' to every element in the dataset. const data : Chart.ChartData = { datasets : [ { label : 'My First Dataset' , data : [ 10 , 20 , 30 , ], backgroundColor : 'red' } }; Whereas the following code will set 10 to backgroundColor 'red' , 20 to 'green' , and 30 to 'blue' . const data : Chart.ChartData = { datasets : [ { label : 'My First Dataset' , data : [ 10 , 20 , 30 , ], backgroundColor : [ 'red' , 'green' , 'blue' ] } }; Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The bar fill color. borderColor Color OR Color[] The bar border color. borderWidth number OR number[] The bar's border width. Measured in pixels. borderSkipped 'bottom' 'left' 'top' 'right' Specifies which border should be hidden when rendering bars. This option is useful when custom-rendering charts. data number[] { t: Date, y: number} The chart's data. Required. hoverBackgroundColor Color OR Color[] The bar's fill color when a mouse hovers over it hoverBorderColor Color OR Color[] The bar's border color when a mouse hovers over it. hoverBorderWidth number OR number[] The bar's border width when a mouse hovers over it.","title":"Dataset Properties"},{"location":"controls/charts/BarChart/#data-structure","text":"","title":"Data Structure"},{"location":"controls/charts/BarChart/#number","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] The chart elements will be rendered in the same order as found in the array.","title":"number[]"},{"location":"controls/charts/BarChart/#time-scales","text":"You can also provide dates and times instead of labels for each data element. Time scales should be provided as t (as in ticks ) and y coordinates: data : [ { \"t\" : new Date ( 'December 1 2018' ), \"y\" : 46 }, { \"t\" : new Date ( 'December 3 2018' ), \"y\" : 9 }, { \"t\" : new Date ( 'December 7 2018' ), \"y\" : 48 }, { \"t\" : new Date ( 'December 10 2018' ), \"y\" : 13 }, { \"t\" : new Date ( 'December 20 2018' ), \"y\" : 12 }, ] Or, if you prefer using moment.js : data : [ { \"t\" : moment ( 'December 1 2018' ). valueOf (), \"y\" : 46 }, { \"t\" : moment ( 'December 3 2018' ). valueOf (), \"y\" : 9 }, { \"t\" : moment ( 'December 7 2018' ). valueOf (), \"y\" : 48 }, { \"t\" : moment ( 'December 10 2018' ). valueOf (), \"y\" : 13 }, { \"t\" : moment ( 'December 20 2018' ). valueOf (), \"y\" : 12 }, ] (add the following to your imports:) import * as moment from 'moment' ; To render horizontal axis as a time series, use the following options: options = {{ scales : { xAxes : [{ type : 'time' , time : { displayFormats : { // choose the scale that applies to your data, // or pass all the scales 'millisecond' : 'MMM DD YYYY' , // use your own date format 'second' : 'MMM DD YYYY' , 'minute' : 'MMM DD YYYY' , 'hour' : 'MMM DD YYYY' , 'day' : 'MMM DD YYYY' , 'week' : 'MMM DD YYYY' , 'month' : 'MMM DD YYYY' , 'quarter' : 'MMM DD YYYY' , 'year' : 'MMM DD YYYY' , } } }] } }} Which will produce the following chart: NOTE: As with regular data elements, you should pass the time scale array in the order that you want them to appear. Otherwise, you will get disappointing results.","title":"Time Scales"},{"location":"controls/charts/BarChart/#configuration","text":"The following configuration options are specific to bar charts: Name Type Default Description barPercentage number 0.9 How much of the category should each bar occupy, in percent. Value should be between 0 and 1. categoryPercentage number 0.8 How much each category should occupy, in percent. Value should be between 0 and 1. barThickness number OR \"flex\" Sets the thickness of each bar. If the default value is used, the bars will be equally sized to match the smallest interval. If number value is provided, the bar width will be set in pixels and barPercentage and categoryPercentage will be ignored. If \"flex\" is used, the widths are calculated automatically based on the previous and following samples so that they take the full available widths without overlap maxBarThickness number Sets the maximum width of every bar. gridLines.offsetGridLines boolean true true , bars will fall between the grid lines; grid lines will shift to the left by half a tick interval. If false , grid line will align with the middle of the bars.","title":"Configuration"},{"location":"controls/charts/BarChart/#for-more-information","text":"For more information on what options are available with Bar charts, refer to the Bar Chart documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/BubbleChart/","text":"ChartControl - Bubble Chart \u00b6 Bubble chart show elements across three dimensions. Each bubble in the chart is located according to the first two dimensions. The size of each bubble represents the thid dimension. Example Usage \u00b6 To create a bubble chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Bubble } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { datasets : [ { label : \"Bubble\" , data : [ { x : 10 , y : 20 , r : 20 }, { x : 85 , y : 50 , r : 35 }, { x : 70 , y : 70 , r : 5 }, { x : 40 , y : 100 , r : 5 }, { x : 50 , y : 50 , r : 12 }, { x : 30 , y : 80 , r : 15 }, { x : 20 , y : 30 , r : 15 }, { x : 40 , y : 10 , r : 10 } ] }] }; // set the options const options : Chart.ChartOptions = { legend : { display : false }, title : { display : true , text : \"My First Bubbles\" } }; return ( < ChartControl type = { ChartType . Bubble } data = { data } options = { options } /> ); Dataset Properties \u00b6 Bubble charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color OR Color[] The bubble's fill color. Default is 'rgba(0,0,0,0.1)' . borderColor Color OR Color[] The bubble's border color. Default is 'rgba(0,0,0,0.1)' . borderWidth number OR number[] The width of the bubble's border. Measured in pixels. Default is 3 . data { x: number, y:number, r: number}[] The data to render. Required. hoverBackgroundColor Color OR Color[] The bubble's background color when a mouse hovers over it. hoverBorderColor Color OR Color[] The bubble's border color when a mouse hovers over it. hoverBorderWidth number OR number[] The bubble's border width when a mouse hovers over it. Default is 1 . hoverRadius number OR number[] The bubble's radius when a mouse hovers over it. Default is 4 . hitRadius number OR number[] The bubble's radius when a mouse click event occurs. Default is 1 . label string The dataset's label pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of bubble. Default is 'circle' rotation number OR number[] The bubble's rotation, in degrees. Default is 0 . radius number OR number[] The bubble's radius. Default is 3 . Data Structure \u00b6 The data property of each dataset item consists of an x , y , and r coordinate. { // X Value x : number , // Y Value y : number , // Bubble radius in pixels r : number } NOTE: Unlike the x and y , the r value is measured in pixels and does not scale with the chart. For More Information \u00b6 For more information on what options are available with Bubble charts, refer to the Bubble Chart documentation on Chart.js .","title":"Bubble Chart"},{"location":"controls/charts/BubbleChart/#chartcontrol-bubble-chart","text":"Bubble chart show elements across three dimensions. Each bubble in the chart is located according to the first two dimensions. The size of each bubble represents the thid dimension.","title":"ChartControl - Bubble Chart"},{"location":"controls/charts/BubbleChart/#example-usage","text":"To create a bubble chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Bubble } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { datasets : [ { label : \"Bubble\" , data : [ { x : 10 , y : 20 , r : 20 }, { x : 85 , y : 50 , r : 35 }, { x : 70 , y : 70 , r : 5 }, { x : 40 , y : 100 , r : 5 }, { x : 50 , y : 50 , r : 12 }, { x : 30 , y : 80 , r : 15 }, { x : 20 , y : 30 , r : 15 }, { x : 40 , y : 10 , r : 10 } ] }] }; // set the options const options : Chart.ChartOptions = { legend : { display : false }, title : { display : true , text : \"My First Bubbles\" } }; return ( < ChartControl type = { ChartType . Bubble } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/BubbleChart/#dataset-properties","text":"Bubble charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color OR Color[] The bubble's fill color. Default is 'rgba(0,0,0,0.1)' . borderColor Color OR Color[] The bubble's border color. Default is 'rgba(0,0,0,0.1)' . borderWidth number OR number[] The width of the bubble's border. Measured in pixels. Default is 3 . data { x: number, y:number, r: number}[] The data to render. Required. hoverBackgroundColor Color OR Color[] The bubble's background color when a mouse hovers over it. hoverBorderColor Color OR Color[] The bubble's border color when a mouse hovers over it. hoverBorderWidth number OR number[] The bubble's border width when a mouse hovers over it. Default is 1 . hoverRadius number OR number[] The bubble's radius when a mouse hovers over it. Default is 4 . hitRadius number OR number[] The bubble's radius when a mouse click event occurs. Default is 1 . label string The dataset's label pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of bubble. Default is 'circle' rotation number OR number[] The bubble's rotation, in degrees. Default is 0 . radius number OR number[] The bubble's radius. Default is 3 .","title":"Dataset Properties"},{"location":"controls/charts/BubbleChart/#data-structure","text":"The data property of each dataset item consists of an x , y , and r coordinate. { // X Value x : number , // Y Value y : number , // Bubble radius in pixels r : number } NOTE: Unlike the x and y , the r value is measured in pixels and does not scale with the chart.","title":"Data Structure"},{"location":"controls/charts/BubbleChart/#for-more-information","text":"For more information on what options are available with Bubble charts, refer to the Bubble Chart documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/DoughnutChart/","text":"ChartControl - Doughnut Chart \u00b6 Doughnut charts are divided into segments, each of which shows the proportional value of the data. Example Usage \u00b6 To create a donut chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Doughnut } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Donut\" } }; return ( < ChartControl type = { ChartType . Doughnut } data = { data } options = { options } /> ); Dataset Properties \u00b6 Doughnut charts allow each dataset to have different configuration properties. Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it. Data Structure \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] Configuration \u00b6 The following configuration options are specific to doughnut charts: Name Type Default Description cutoutPercentage number 50 The percentage of the chart that is cut out of the middle. rotation number -0.5 * Math.PI The angle at which the doughtnut segments start circumference number 2 * Math.PI The total circumference of the donut chart. animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it. For More Information \u00b6 For more information on what options are available with Doughnut charts, refer to the Doughnut and Pie documentation on Chart.js .","title":"Doughnut Chart"},{"location":"controls/charts/DoughnutChart/#chartcontrol-doughnut-chart","text":"Doughnut charts are divided into segments, each of which shows the proportional value of the data.","title":"ChartControl - Doughnut Chart"},{"location":"controls/charts/DoughnutChart/#example-usage","text":"To create a donut chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Doughnut } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Donut\" } }; return ( < ChartControl type = { ChartType . Doughnut } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/DoughnutChart/#dataset-properties","text":"Doughnut charts allow each dataset to have different configuration properties. Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it.","title":"Dataset Properties"},{"location":"controls/charts/DoughnutChart/#data-structure","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ]","title":"Data Structure"},{"location":"controls/charts/DoughnutChart/#configuration","text":"The following configuration options are specific to doughnut charts: Name Type Default Description cutoutPercentage number 50 The percentage of the chart that is cut out of the middle. rotation number -0.5 * Math.PI The angle at which the doughtnut segments start circumference number 2 * Math.PI The total circumference of the donut chart. animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it.","title":"Configuration"},{"location":"controls/charts/DoughnutChart/#for-more-information","text":"For more information on what options are available with Doughnut charts, refer to the Doughnut and Pie documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/LineChart/","text":"ChartControl - Line Chart \u00b6 Line charts represent data values as plotted points on a line. Example Usage \u00b6 To create a line chart, add the ChartControl import: import { ChartControl } from \"@pnp/spfx-controls-react/lib/ChartControl\" ; Then render the ChartControl: < ChartControl type = 'line' data = { data } options = { options } /> Alternatively, you can use the following import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Followed by: < ChartControl type = { ChartType . Line } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : false , lineTension : 0 , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Line Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); Variations \u00b6 Curved lines \u00b6 You can render curved lines instead of straight lines by removing the lineTension setting from each dataset, or by setting it to a value other than 0 . For example, to render the above chart, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : false , //lineTension: 0, -- removed data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Curved Line Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); Area Chart \u00b6 To render an area chart, change the fill setting of the dataset to true . // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : true , lineTension : 0 , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Area Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); If your chart has negative and positive values, you can control where the filled area by setting the fill setting to one of the following value: fill Value Description Sample 'start' Fill from the bottom of the chart 'end' Fill from the top of the chart 'origin' Fill from the 'zero' line Same as true For example, the code below will set the fill value to start : // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : 'start' , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Area Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); Which renders the following chart: Stacked Area Chart \u00b6 If your bar chart has multiple datasets, you can render it as a stacked area chart by changing the settings on the Y axis to enable stacking, as follows: const options : Chart.ChartOptions = { scales : { yAxes : [{ stacked : true }] } }; In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset. For example, to render the above chart, use the following code: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : true , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, { label : 'My Second Dataset' , fill : true , lineTension : 0 , data : [ 45 , 49 , 88 , 71 , - 36 , 35 , 60 ], backgroundColor : 'rgba(255, 159, 64, 0.2)' , borderColor : 'rgb(255, 159, 64)' , borderWidth : 1 } ] }; const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Stacked Area Chart\" }, scales : { yAxes : [{ stacked : true }] } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); As with lines, you can set the lineTension value to render curved lines instead of straight lines: In addition to the fill values listed above, you can specify how each dataset fill: fill Value Type Description Sample Values number Fill to dataset by its absolute index 1 , 2 , 3 , ... string Fill to dataset by its relative index '-3' , '-2' , '-1' , '+1' , '+2' , '+3' , ... For example, if you use declare your datasets with the following fill values: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : \"start\" , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, { label : 'My Second Dataset' , fill : '-1' , lineTension : 0 , data : [ 45 , 49 , 88 , 71 , - 36 , 35 , 60 ], backgroundColor : 'rgba(255, 159, 64, 0.2)' , borderColor : 'rgb(255, 159, 64)' , borderWidth : 1 } ] }; Will cause the first dataset to fill from the bottom of the chart, while the second dataset will fill to the previous dataset (by it's relative index of -1 ) Dataset Properties \u00b6 Line charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . cubicInterpolationMode 'default' 'monotone' Determins which algorithm is used to interpolate a smooth curve between data points. data number[] Point[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it. showLine boolean The point's radius width when a mouse hovers over it. spanGaps boolean The point's radius width when a mouse hovers over it. steppedLine boolean 'before' 'after' Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting. Data Structure \u00b6 number[] \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , - 10 , 33 , - 47 ] The chart elements will be rendered in the same order as found in the array. Point[] \u00b6 You can also provide data elements with x and y coordinates: data : [{ x : 10 , y : 20 }, { x : 15 , y : 10 }] Point Configuration \u00b6 Point elements can be configured to change their appearance using the following configuration options: Name Type Default Description radius number 3 Point radius. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' 'circle' Style of point. rotation number 0 Rotation of the point, in degrees. backgroundColor Color 'rgba(0,0,0,0.1) Fill color. borderWidth number 1 Stroke width. borderColor Color 'rgba(0,0,0,0.1) Stroke color. hitRadius number 1 Extra radius added around the point to make it easier to detect mouse events. hoverRadius number 4 Point radius, when mouse hovers over point. hoverBorderWidth number 1 Stroke width, when mouse hovers over point. Configuration \u00b6 The following configuration options are specific to line charts: Name Type Default Description showLines boolean true Indicates whether a line will be drawn between each data point. A value of false will not render lines. spanGaps boolean false Indicates whether invalid number values ( NaN ) will cause a break in the line . A value of false will not span data gaps and cause a break in the line. For More Information \u00b6 For more information on what options are available with Line charts, refer to the Line Chart documentation on Chart.js .","title":"Line Chart"},{"location":"controls/charts/LineChart/#chartcontrol-line-chart","text":"Line charts represent data values as plotted points on a line.","title":"ChartControl - Line Chart"},{"location":"controls/charts/LineChart/#example-usage","text":"To create a line chart, add the ChartControl import: import { ChartControl } from \"@pnp/spfx-controls-react/lib/ChartControl\" ; Then render the ChartControl: < ChartControl type = 'line' data = { data } options = { options } /> Alternatively, you can use the following import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Followed by: < ChartControl type = { ChartType . Line } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : false , lineTension : 0 , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Line Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/LineChart/#variations","text":"","title":"Variations"},{"location":"controls/charts/LineChart/#curved-lines","text":"You can render curved lines instead of straight lines by removing the lineTension setting from each dataset, or by setting it to a value other than 0 . For example, to render the above chart, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : false , //lineTension: 0, -- removed data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Curved Line Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> );","title":"Curved lines"},{"location":"controls/charts/LineChart/#area-chart","text":"To render an area chart, change the fill setting of the dataset to true . // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : true , lineTension : 0 , data : [ 65 , 59 , 80 , 81 , 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Area Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); If your chart has negative and positive values, you can control where the filled area by setting the fill setting to one of the following value: fill Value Description Sample 'start' Fill from the bottom of the chart 'end' Fill from the top of the chart 'origin' Fill from the 'zero' line Same as true For example, the code below will set the fill value to start : // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : 'start' , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Area Chart\" } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); Which renders the following chart:","title":"Area Chart"},{"location":"controls/charts/LineChart/#stacked-area-chart","text":"If your bar chart has multiple datasets, you can render it as a stacked area chart by changing the settings on the Y axis to enable stacking, as follows: const options : Chart.ChartOptions = { scales : { yAxes : [{ stacked : true }] } }; In order to render each dataset with a different color, make sure to specify the backgroundColor and borderColor settings for each dataset. For example, to render the above chart, use the following code: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : true , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, { label : 'My Second Dataset' , fill : true , lineTension : 0 , data : [ 45 , 49 , 88 , 71 , - 36 , 35 , 60 ], backgroundColor : 'rgba(255, 159, 64, 0.2)' , borderColor : 'rgb(255, 159, 64)' , borderWidth : 1 } ] }; const options : Chart.ChartOptions = { legend : { display : false , }, title : { display : true , text : \"My First Stacked Area Chart\" }, scales : { yAxes : [{ stacked : true }] } }; return ( < ChartControl type = { ChartType . Line } data = { data } options = { options } /> ); As with lines, you can set the lineTension value to render curved lines instead of straight lines: In addition to the fill values listed above, you can specify how each dataset fill: fill Value Type Description Sample Values number Fill to dataset by its absolute index 1 , 2 , 3 , ... string Fill to dataset by its relative index '-3' , '-2' , '-1' , '+1' , '+2' , '+3' , ... For example, if you use declare your datasets with the following fill values: const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , fill : \"start\" , lineTension : 0 , data : [ - 65 , - 59 , 80 , 81 , - 56 , 55 , 40 ], backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , borderWidth : 1 }, { label : 'My Second Dataset' , fill : '-1' , lineTension : 0 , data : [ 45 , 49 , 88 , 71 , - 36 , 35 , 60 ], backgroundColor : 'rgba(255, 159, 64, 0.2)' , borderColor : 'rgb(255, 159, 64)' , borderWidth : 1 } ] }; Will cause the first dataset to fill from the bottom of the chart, while the second dataset will fill to the previous dataset (by it's relative index of -1 )","title":"Stacked Area Chart"},{"location":"controls/charts/LineChart/#dataset-properties","text":"Line charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . cubicInterpolationMode 'default' 'monotone' Determins which algorithm is used to interpolate a smooth curve between data points. data number[] Point[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it. showLine boolean The point's radius width when a mouse hovers over it. spanGaps boolean The point's radius width when a mouse hovers over it. steppedLine boolean 'before' 'after' Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting.","title":"Dataset Properties"},{"location":"controls/charts/LineChart/#data-structure","text":"","title":"Data Structure"},{"location":"controls/charts/LineChart/#number","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , - 10 , 33 , - 47 ] The chart elements will be rendered in the same order as found in the array.","title":"number[]"},{"location":"controls/charts/LineChart/#point","text":"You can also provide data elements with x and y coordinates: data : [{ x : 10 , y : 20 }, { x : 15 , y : 10 }]","title":"Point[]"},{"location":"controls/charts/LineChart/#point-configuration","text":"Point elements can be configured to change their appearance using the following configuration options: Name Type Default Description radius number 3 Point radius. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' 'circle' Style of point. rotation number 0 Rotation of the point, in degrees. backgroundColor Color 'rgba(0,0,0,0.1) Fill color. borderWidth number 1 Stroke width. borderColor Color 'rgba(0,0,0,0.1) Stroke color. hitRadius number 1 Extra radius added around the point to make it easier to detect mouse events. hoverRadius number 4 Point radius, when mouse hovers over point. hoverBorderWidth number 1 Stroke width, when mouse hovers over point.","title":"Point Configuration"},{"location":"controls/charts/LineChart/#configuration","text":"The following configuration options are specific to line charts: Name Type Default Description showLines boolean true Indicates whether a line will be drawn between each data point. A value of false will not render lines. spanGaps boolean false Indicates whether invalid number values ( NaN ) will cause a break in the line . A value of false will not span data gaps and cause a break in the line.","title":"Configuration"},{"location":"controls/charts/LineChart/#for-more-information","text":"For more information on what options are available with Line charts, refer to the Line Chart documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/PieChart/","text":"ChartControl - Pie Chart \u00b6 Pie charts are divided into segments, each of which shows the proportional value of the data. Example Usage \u00b6 To create a pie chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Pie } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 10 , 50 , 20 , 60 , 30 , 70 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; return ( < ChartControl type = { ChartType . Pie } data = { data } options = { options } /> ); Variations \u00b6 Half-Moon Pie charts \u00b6 By default, pie charts (and doughnut charts) render a whole circle. You can change the chart's circumference option to render partial circles. The default circumference value is 2 * Math.PI . To render a half-moon, specify a half value (i.e.: Math.PI ), as follows: const options : Chart.ChartOptions = { circumference : Math.PI , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; Which renders the following half-moon: To rotate the pie chart 90 degrees to the left, specify a rotation value in the chart's options. For example, to render the horizontal half-moon chart shown at the top of this section, use the following options: const options : Chart.ChartOptions = { circumference : Math.PI , rotation : - 1 * Math . PI , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; Doughnut charts \u00b6 Technically, doughnut charts and pie charts are derived from the same class in Chart.js , where a doughnut chart's cutoutPercentage is set to 50. If you wish to render simple doughnut charts, use the Doughnut Chart type . However, if you wish to customize how the pie/doughtnut chart is rendered, you can set the cutout percentage to a different value. For example, you can use the following code to render a custom \"fuel-gauge\" chart: const options : Chart.ChartOptions = { circumference : 1 * Math . PI , rotation : 1 * Math . PI , cutoutPercentage : 60 , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; Will produce the following chart: Dataset Properties \u00b6 Pie charts allow each dataset to have different configuration properties. Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it. Data Structure \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] Configuration \u00b6 The following configuration options are specific to pie charts: Name Type Default Description cutoutPercentage number 50 The percentage of the chart that is cut out of the middle. rotation number -0.5 * Math.PI The angle at which the pie segments start circumference number 2 * Math.PI The total circumference of the donut chart. animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it. For More Information \u00b6 For more information on what options are available with Pie charts, refer to the Doughtnut and Pie documentation on Chart.js .","title":"Pie Chart"},{"location":"controls/charts/PieChart/#chartcontrol-pie-chart","text":"Pie charts are divided into segments, each of which shows the proportional value of the data.","title":"ChartControl - Pie Chart"},{"location":"controls/charts/PieChart/#example-usage","text":"To create a pie chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Pie } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 10 , 50 , 20 , 60 , 30 , 70 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; return ( < ChartControl type = { ChartType . Pie } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/PieChart/#variations","text":"","title":"Variations"},{"location":"controls/charts/PieChart/#half-moon-pie-charts","text":"By default, pie charts (and doughnut charts) render a whole circle. You can change the chart's circumference option to render partial circles. The default circumference value is 2 * Math.PI . To render a half-moon, specify a half value (i.e.: Math.PI ), as follows: const options : Chart.ChartOptions = { circumference : Math.PI , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; Which renders the following half-moon: To rotate the pie chart 90 degrees to the left, specify a rotation value in the chart's options. For example, to render the horizontal half-moon chart shown at the top of this section, use the following options: const options : Chart.ChartOptions = { circumference : Math.PI , rotation : - 1 * Math . PI , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } };","title":"Half-Moon Pie charts"},{"location":"controls/charts/PieChart/#doughnut-charts","text":"Technically, doughnut charts and pie charts are derived from the same class in Chart.js , where a doughnut chart's cutoutPercentage is set to 50. If you wish to render simple doughnut charts, use the Doughnut Chart type . However, if you wish to customize how the pie/doughtnut chart is rendered, you can set the cutout percentage to a different value. For example, you can use the following code to render a custom \"fuel-gauge\" chart: const options : Chart.ChartOptions = { circumference : 1 * Math . PI , rotation : 1 * Math . PI , cutoutPercentage : 60 , legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Pie\" } }; Will produce the following chart:","title":"Doughnut charts"},{"location":"controls/charts/PieChart/#dataset-properties","text":"Pie charts allow each dataset to have different configuration properties. Properties are provided as arrays. Settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it.","title":"Dataset Properties"},{"location":"controls/charts/PieChart/#data-structure","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ]","title":"Data Structure"},{"location":"controls/charts/PieChart/#configuration","text":"The following configuration options are specific to pie charts: Name Type Default Description cutoutPercentage number 50 The percentage of the chart that is cut out of the middle. rotation number -0.5 * Math.PI The angle at which the pie segments start circumference number 2 * Math.PI The total circumference of the donut chart. animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it.","title":"Configuration"},{"location":"controls/charts/PieChart/#for-more-information","text":"For more information on what options are available with Pie charts, refer to the Doughtnut and Pie documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/PolarAreaChart/","text":"ChartControl - Polar Chart \u00b6 Polar charts are similar to pie charts, except that each segment has the same angle, and the radius of each segment differs depending on the value. Example Usage \u00b6 To create a polar area chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . PolarArea } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 10 , 50 , 20 , 60 , 30 , 70 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Polar\" } }; return ( < ChartControl type = { ChartType . PolarArea } data = { data } options = { options } /> ); Dataset Properties \u00b6 Polar area charts allow each dataset to have different configuration properties. Properties are provided as arrays. The settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it. Data Structure \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] Configuration \u00b6 The following configuration options are specific to polar area charts: Name Type Default Description rotation number -0.5 * Math.PI The angle at which the polar segments start animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it. For More Information \u00b6 For more information on what options are available with Polar Area charts, refer to the Polar Area documentation on Chart.js .","title":"Polar Area Chart"},{"location":"controls/charts/PolarAreaChart/#chartcontrol-polar-chart","text":"Polar charts are similar to pie charts, except that each segment has the same angle, and the radius of each segment differs depending on the value.","title":"ChartControl - Polar Chart"},{"location":"controls/charts/PolarAreaChart/#example-usage","text":"To create a polar area chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . PolarArea } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ], datasets : [ { label : 'My First Dataset' , data : [ 10 , 50 , 20 , 60 , 30 , 70 , 40 ] } ] }; // set the options const options : Chart.ChartOptions = { legend : { display : true , position : \"left\" }, title : { display : true , text : \"My First Polar\" } }; return ( < ChartControl type = { ChartType . PolarArea } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/PolarAreaChart/#dataset-properties","text":"Polar area charts allow each dataset to have different configuration properties. Properties are provided as arrays. The settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description backgroundColor Color[] The segment's fill color. borderColor Color[] The segment's border color. borderWidth number[] The segment's border width. Measured in pixels. data number[] The chart's data. Required. hoverBackgroundColor Color[] The segment's fill color when a mouse hovers over it hoverBorderColor Color[] The segment's border color when a mouse hovers over it. hoverBorderWidth number[] The segment's border width when a mouse hovers over it.","title":"Dataset Properties"},{"location":"controls/charts/PolarAreaChart/#data-structure","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ]","title":"Data Structure"},{"location":"controls/charts/PolarAreaChart/#configuration","text":"The following configuration options are specific to polar area charts: Name Type Default Description rotation number -0.5 * Math.PI The angle at which the polar segments start animation.animateRotate boolean true true will animate the chart while rotating it. animation.animateScale boolean false true will animate the chart while scaling it.","title":"Configuration"},{"location":"controls/charts/PolarAreaChart/#for-more-information","text":"For more information on what options are available with Polar Area charts, refer to the Polar Area documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/RadarChart/","text":"ChartControl - Radar Chart \u00b6 Radar charts are best used when comparing points of two or more datasets. Example Usage \u00b6 To create a radar chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Radar } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ \"Eating\" , \"Drinking\" , \"Sleeping\" , \"Designing\" , \"Coding\" , \"Cycling\" , \"Running\" ], datasets : [ // It is better to use multiple datasets for radar charts { label : \"My First Dataset\" , data : [ 65 , 59 , 90 , 81 , 56 , 55 , 40 ], fill : true , // semi-transparent colors are best backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , pointBackgroundColor : \"rgb(255, 99, 132)\" , pointBorderColor : \"#fff\" , pointHoverBackgroundColor : \"#fff\" , pointHoverBorderColor : \"rgb(255, 99, 132)\" }, { label : \"My Second Dataset\" , data : [ 28 , 48 , 40 , 19 , 96 , 27 , 100 ], fill : true , backgroundColor : \"rgba(54, 162, 235, 0.2)\" , borderColor : \"rgb(54, 162, 235)\" , pointBackgroundColor : \"rgb(54, 162, 235)\" , pointBorderColor : \"#fff\" , pointHoverBackgroundColor : \"#fff\" , pointHoverBorderColor : \"rgb(54, 162, 235)\" }] }; // set the options const options : Chart.ChartOptions = { // Using an aspect ratio of 1 will render a square chart area aspectRatio : 1 , elements : { line : { tension : 0 , borderWidth : 3 } } }; // render the chart return ( < ChartControl type = { ChartType . Radar } data = { data } options = { options } /> ); Dataset Properties \u00b6 Radar charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . data number[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it. Data Structure \u00b6 The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ] For More Information \u00b6 For more information on what options are available with Radar charts, refer to the Radar documentation on Chart.js .","title":"Radar Chart"},{"location":"controls/charts/RadarChart/#chartcontrol-radar-chart","text":"Radar charts are best used when comparing points of two or more datasets.","title":"ChartControl - Radar Chart"},{"location":"controls/charts/RadarChart/#example-usage","text":"To create a radar chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Radar } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { labels : [ \"Eating\" , \"Drinking\" , \"Sleeping\" , \"Designing\" , \"Coding\" , \"Cycling\" , \"Running\" ], datasets : [ // It is better to use multiple datasets for radar charts { label : \"My First Dataset\" , data : [ 65 , 59 , 90 , 81 , 56 , 55 , 40 ], fill : true , // semi-transparent colors are best backgroundColor : \"rgba(255, 99, 132, 0.2)\" , borderColor : \"rgb(255, 99, 132)\" , pointBackgroundColor : \"rgb(255, 99, 132)\" , pointBorderColor : \"#fff\" , pointHoverBackgroundColor : \"#fff\" , pointHoverBorderColor : \"rgb(255, 99, 132)\" }, { label : \"My Second Dataset\" , data : [ 28 , 48 , 40 , 19 , 96 , 27 , 100 ], fill : true , backgroundColor : \"rgba(54, 162, 235, 0.2)\" , borderColor : \"rgb(54, 162, 235)\" , pointBackgroundColor : \"rgb(54, 162, 235)\" , pointBorderColor : \"#fff\" , pointHoverBackgroundColor : \"#fff\" , pointHoverBorderColor : \"rgb(54, 162, 235)\" }] }; // set the options const options : Chart.ChartOptions = { // Using an aspect ratio of 1 will render a square chart area aspectRatio : 1 , elements : { line : { tension : 0 , borderWidth : 3 } } }; // render the chart return ( < ChartControl type = { ChartType . Radar } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/RadarChart/#dataset-properties","text":"Radar charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . data number[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it.","title":"Dataset Properties"},{"location":"controls/charts/RadarChart/#data-structure","text":"The data property of each dataset item consists of an array of numbers. Each point in the array corresponds to the matching label on the x axis: data : [ 20 , 10 , 33 , 47 ]","title":"Data Structure"},{"location":"controls/charts/RadarChart/#for-more-information","text":"For more information on what options are available with Radar charts, refer to the Radar documentation on Chart.js .","title":"For More Information"},{"location":"controls/charts/ScatterChart/","text":"ChartControl - Scatter Chart \u00b6 Scatter charts are similar to line charts, except that the X axis (the horizontal axis) uses data values. Unlike other charts, scatter charts use x and y coordinates. Example Usage \u00b6 To create a scatter chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Scatter } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { datasets : [{ label : 'Scatter Dataset' , data : [ { x : - 10 , y : 0 }, { x : 0 , y : 10 }, { x : 6 , y : 4 }, { x : 2 , y : 6 }, { x : - 4 , y : 7 }, { x : - 8 , y : 5 }, { x : 10 , y : 5 }] }] }; // set the options const options : Chart.ChartOptions = { scales : { xAxes : [{ type : 'linear' , position : 'bottom' }] } }; return ( < ChartControl type = { ChartType . Scatter } data = { data } options = { options } /> ); Dataset Properties \u00b6 Scatter charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . cubicInterpolationMode 'default' 'monotone' Determins which algorithm is used to interpolate a smooth curve between data points. data Point[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it. showLine boolean The point's radius width when a mouse hovers over it. spanGaps boolean The point's radius width when a mouse hovers over it. steppedLine boolean 'before' 'after' Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting. Data Structure \u00b6 The data property of each dataset item consists of an array of points. Each point in the array consist of an x and y coordinate. data : [{ x : 10 , y : 20 }, { x : 15 , y : 10 }] Point Configuration \u00b6 Point elements can be configured to change their appearance using the following configuration options: Name Type Default Description radius number 3 Point radius. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' 'circle' Style of point. rotation number 0 Rotation of the point, in degrees. backgroundColor Color 'rgba(0,0,0,0.1) Fill color. borderWidth number 1 Stroke width. borderColor Color 'rgba(0,0,0,0.1) Stroke color. hitRadius number 1 Extra radius added around the point to make it easier to detect mouse events. hoverRadius number 4 Point radius, when mouse hovers over point. hoverBorderWidth number 1 Stroke width, when mouse hovers over point. You can change the point configuration in the chart via the options.elements.point configuration. For example, to render the above chart, use the following code: const options : Chart.ChartOptions = { elements : { point : { pointStyle : \"triangle\" , radius : 10 , hoverRadius : 15 } }, scales : { xAxes : [{ type : 'linear' , position : 'bottom' }] } }; You can also control point configurations at the dataset level. TypeScript const data: Chart.ChartData = { datasets: [{ label: 'Triangle', data: [ { x: -10, y: 0 }, { x: 0, y: 10 }], pointStyle: \"triangle\", backgroundColor: 'red' }, { label: 'Rectangle', data: [ { x: -6, y: 6 }, { x: -4, y: 4 }], pointStyle: \"rectRounded\", backgroundColor: 'green' }, { label: 'Circle', data: [ { x: 2, y: 6 }, { x: 8, y: 2 } ], pointStyle: \"circle\", backgroundColor: 'blue' } ] }; Which renders the following chart: For More Information \u00b6 For more information on what options are available with Scatter charts, refer to the Scatter documentation on Chart.js .","title":"Scatter Chart"},{"location":"controls/charts/ScatterChart/#chartcontrol-scatter-chart","text":"Scatter charts are similar to line charts, except that the X axis (the horizontal axis) uses data values. Unlike other charts, scatter charts use x and y coordinates.","title":"ChartControl - Scatter Chart"},{"location":"controls/charts/ScatterChart/#example-usage","text":"To create a scatter chart, add the ChartControl import: import { ChartControl , ChartType } from '@pnp/spfx-controls-react/lib/ChartControl' ; Then render the ChartControl: < ChartControl type = { ChartType . Scatter } data = { data } options = { options } /> For example, to render the chart above, use the following code: // set the data const data : Chart.ChartData = { datasets : [{ label : 'Scatter Dataset' , data : [ { x : - 10 , y : 0 }, { x : 0 , y : 10 }, { x : 6 , y : 4 }, { x : 2 , y : 6 }, { x : - 4 , y : 7 }, { x : - 8 , y : 5 }, { x : 10 , y : 5 }] }] }; // set the options const options : Chart.ChartOptions = { scales : { xAxes : [{ type : 'linear' , position : 'bottom' }] } }; return ( < ChartControl type = { ChartType . Scatter } data = { data } options = { options } /> );","title":"Example Usage"},{"location":"controls/charts/ScatterChart/#dataset-properties","text":"Scatter charts allow each dataset to have different configuration properties. Some properties can be provided as arrays. When arrays are provided, the settings in the array will be applied to each data element in the same order (e.g.: first value applies to first element, second value to second element, etc.) Name Type Description label string Dataset label. Appears in the legend and tooltips. xAxisID string The axis ID for the X axis. If not specified, the dataset will be rendered on the first available X axis. If an ID is specified, the dataset will be rendered on that axis yAxisID string The axis ID for the Y axis. If not specified, the dataset will be rendered on the first available Y axis. If an ID is specified, the dataset will be rendered on that axis backgroundColor Color OR Color[] The fill color under the line. borderColor Color OR Color[] The color of the line. borderWidth number OR number[] The width of the line. Measured in pixels. borderDash number[] The length and spacing of dashes. Consist of an array of numbers that specify distances to alternately draw a line and a gap. If array length is odd, elements of the array will be repeated. If an empty array is provided, lines will be solid. borderDashOffset number The distance to offset dashes. borderCapStyle 'butt' 'round' 'square' Specifies the end of the lines. Default is 'butt '. borderJoinStyle 'bevel' 'round' 'miter' Determines the shape used to join two line segments where they meet. Default is 'miter' . cubicInterpolationMode 'default' 'monotone' Determins which algorithm is used to interpolate a smooth curve between data points. data Point[] The chart's data. Required. fill false number string 'start' 'end' 'origin' Controls how the dataset's area is filled. lineTension number Ttension of the Bezier curve line. 0 renders straight lines. Ignored if cubicInterpolationMode is set to monotone . pointBackgroundColor Color OR Color[] The point's fill color. pointBorderColor Color OR Color[] The point's border color. pointBorderWidth number OR number[] The point's border width. pointRadius number OR number[] The point's fill color. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' HTMLImageElement HTMLCanvasElement HTMLImageElement[] HTMLCanvasElement[] Style of point. pointRotation number OR number[] The point's roation, in degrees. pointHitRadius number OR number[] The point's border width. pointHoverBackgroundColor Color OR Color[] The point's background color when a mouse hovers over it. pointHoverBorderColor Color OR Color[] The point's border color when a mouse hovers over it. pointHoverBorderWidth number OR number[] The point's border width when a mouse hovers over it. pointHoverRadius number OR number[] The point's radius width when a mouse hovers over it. showLine boolean The point's radius width when a mouse hovers over it. spanGaps boolean The point's radius width when a mouse hovers over it. steppedLine boolean 'before' 'after' Determines whether the line is shown as a stepped line. Any value but false overrides the lineTension setting.","title":"Dataset Properties"},{"location":"controls/charts/ScatterChart/#data-structure","text":"The data property of each dataset item consists of an array of points. Each point in the array consist of an x and y coordinate. data : [{ x : 10 , y : 20 }, { x : 15 , y : 10 }]","title":"Data Structure"},{"location":"controls/charts/ScatterChart/#point-configuration","text":"Point elements can be configured to change their appearance using the following configuration options: Name Type Default Description radius number 3 Point radius. pointStyle 'circle' 'cross' 'crossRot' 'dash' 'line' 'rect' 'rectRounded' 'rectRot' 'star' 'triangle' 'circle' Style of point. rotation number 0 Rotation of the point, in degrees. backgroundColor Color 'rgba(0,0,0,0.1) Fill color. borderWidth number 1 Stroke width. borderColor Color 'rgba(0,0,0,0.1) Stroke color. hitRadius number 1 Extra radius added around the point to make it easier to detect mouse events. hoverRadius number 4 Point radius, when mouse hovers over point. hoverBorderWidth number 1 Stroke width, when mouse hovers over point. You can change the point configuration in the chart via the options.elements.point configuration. For example, to render the above chart, use the following code: const options : Chart.ChartOptions = { elements : { point : { pointStyle : \"triangle\" , radius : 10 , hoverRadius : 15 } }, scales : { xAxes : [{ type : 'linear' , position : 'bottom' }] } }; You can also control point configurations at the dataset level. TypeScript const data: Chart.ChartData = { datasets: [{ label: 'Triangle', data: [ { x: -10, y: 0 }, { x: 0, y: 10 }], pointStyle: \"triangle\", backgroundColor: 'red' }, { label: 'Rectangle', data: [ { x: -6, y: 6 }, { x: -4, y: 4 }], pointStyle: \"rectRounded\", backgroundColor: 'green' }, { label: 'Circle', data: [ { x: 2, y: 6 }, { x: 8, y: 2 } ], pointStyle: \"circle\", backgroundColor: 'blue' } ] }; Which renders the following chart:","title":"Point Configuration"},{"location":"controls/charts/ScatterChart/#for-more-information","text":"For more information on what options are available with Scatter charts, refer to the Scatter documentation on Chart.js .","title":"For More Information"},{"location":"controls/fields/FieldAttachmentsRenderer/","text":"FieldAttachmentsRenderer control \u00b6 This control renders Clip icon based on the provided count property is defined and greater than 0. Note: this control displays correctly starting with SharePoint Framework v1.4 Covered Fields \u00b6 Attachments How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldAttachmentsRenderer } from \"@pnp/spfx-controls-react/lib/FieldAttachmentsRenderer\" ; Use the FieldAttachmentsRenderer control in your code as follows: < FieldAttachmentsRenderer count = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldAttachmentsRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. count number no Amount of attachments. The icon is displayed if the property is defined and greater than 0","title":"FieldAttachmentsRenderer"},{"location":"controls/fields/FieldAttachmentsRenderer/#fieldattachmentsrenderer-control","text":"This control renders Clip icon based on the provided count property is defined and greater than 0. Note: this control displays correctly starting with SharePoint Framework v1.4","title":"FieldAttachmentsRenderer control"},{"location":"controls/fields/FieldAttachmentsRenderer/#covered-fields","text":"Attachments","title":"Covered Fields"},{"location":"controls/fields/FieldAttachmentsRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldAttachmentsRenderer } from \"@pnp/spfx-controls-react/lib/FieldAttachmentsRenderer\" ; Use the FieldAttachmentsRenderer control in your code as follows: < FieldAttachmentsRenderer count = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldAttachmentsRenderer/#implementation","text":"The FieldAttachmentsRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. count number no Amount of attachments. The icon is displayed if the property is defined and greater than 0","title":"Implementation"},{"location":"controls/fields/FieldDateRenderer/","text":"FieldDateRenderer control \u00b6 This control renders date string as a simple text. Covered Fields \u00b6 Date and Time How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldDateRenderer } from \"@pnp/spfx-controls-react/lib/FieldDateRenderer\" ; Use the FieldDateRenderer control in your code as follows: < FieldDateRenderer text = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Note: FieldDateRenderer doesn't provide functionality to render date in friendly format. It just renders the provided text as is. To learn more about friendly formatting please refer to FieldRendererHelper implementation. Implementation \u00b6 The FieldDateRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered","title":"FieldDateRenderer"},{"location":"controls/fields/FieldDateRenderer/#fielddaterenderer-control","text":"This control renders date string as a simple text.","title":"FieldDateRenderer control"},{"location":"controls/fields/FieldDateRenderer/#covered-fields","text":"Date and Time","title":"Covered Fields"},{"location":"controls/fields/FieldDateRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldDateRenderer } from \"@pnp/spfx-controls-react/lib/FieldDateRenderer\" ; Use the FieldDateRenderer control in your code as follows: < FieldDateRenderer text = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Note: FieldDateRenderer doesn't provide functionality to render date in friendly format. It just renders the provided text as is. To learn more about friendly formatting please refer to FieldRendererHelper implementation.","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldDateRenderer/#implementation","text":"The FieldDateRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered","title":"Implementation"},{"location":"controls/fields/FieldFileTypeRenderer/","text":"FieldFileTypeRenderer control \u00b6 This control renders document or folder icon based on file path. Office UI Fabric icons font is used to render the icons. Note: this control displays correctly starting with SharePoint Framework v1.4 Covered Fields \u00b6 Type (DocIcon) How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldFileTypeRenderer } from \"@pnp/spfx-controls-react/lib/FieldFileTypeRenderer\" ; Use the FieldFileTypeRenderer control in your code as follows: < FieldFileTypeRenderer path = { fileLeafRef } isFolder = { false } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldFileTypeRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. path string yes document/file path isFolder boolean no true if the icon should be rendered for a folder, not file","title":"FieldFileTypeRenderer"},{"location":"controls/fields/FieldFileTypeRenderer/#fieldfiletyperenderer-control","text":"This control renders document or folder icon based on file path. Office UI Fabric icons font is used to render the icons. Note: this control displays correctly starting with SharePoint Framework v1.4","title":"FieldFileTypeRenderer control"},{"location":"controls/fields/FieldFileTypeRenderer/#covered-fields","text":"Type (DocIcon)","title":"Covered Fields"},{"location":"controls/fields/FieldFileTypeRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldFileTypeRenderer } from \"@pnp/spfx-controls-react/lib/FieldFileTypeRenderer\" ; Use the FieldFileTypeRenderer control in your code as follows: < FieldFileTypeRenderer path = { fileLeafRef } isFolder = { false } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldFileTypeRenderer/#implementation","text":"The FieldFileTypeRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. path string yes document/file path isFolder boolean no true if the icon should be rendered for a folder, not file","title":"Implementation"},{"location":"controls/fields/FieldLookupRenderer/","text":"FieldLookupRenderer control \u00b6 This control renders lookup values. Each lookup item is clickable. Click on the lookup item leads to opening of referenced item's display form. Note: this control displays correctly starting with SharePoint Framework v1.4 Covered Fields \u00b6 Lookup (single, multi) How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldLookupRenderer } from \"@pnp/spfx-controls-react/lib/FieldLookupRenderer\" ; Use the FieldLookupRenderer control in your code as follows: < FieldLookupRenderer lookups = { event . fieldValue } fieldId = { '' } context = { this . context } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldLookupRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. lookups ISPFieldLookupValue[] yes Lookup field values. dispFormUrl boolean no Url of Display form for the list that is referenced by the lookup. onClick (args: ILookupClickEventArgs) => {} no Custom event handler of lookup item click. If not set the dialog with Display Form will be shown. fieldId string Field's id context IContext Customizer context. Must be providede if fieldId is set","title":"FieldLookupRenderer"},{"location":"controls/fields/FieldLookupRenderer/#fieldlookuprenderer-control","text":"This control renders lookup values. Each lookup item is clickable. Click on the lookup item leads to opening of referenced item's display form. Note: this control displays correctly starting with SharePoint Framework v1.4","title":"FieldLookupRenderer control"},{"location":"controls/fields/FieldLookupRenderer/#covered-fields","text":"Lookup (single, multi)","title":"Covered Fields"},{"location":"controls/fields/FieldLookupRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldLookupRenderer } from \"@pnp/spfx-controls-react/lib/FieldLookupRenderer\" ; Use the FieldLookupRenderer control in your code as follows: < FieldLookupRenderer lookups = { event . fieldValue } fieldId = { '' } context = { this . context } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldLookupRenderer/#implementation","text":"The FieldLookupRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. lookups ISPFieldLookupValue[] yes Lookup field values. dispFormUrl boolean no Url of Display form for the list that is referenced by the lookup. onClick (args: ILookupClickEventArgs) => {} no Custom event handler of lookup item click. If not set the dialog with Display Form will be shown. fieldId string Field's id context IContext Customizer context. Must be providede if fieldId is set","title":"Implementation"},{"location":"controls/fields/FieldNameRenderer/","text":"FieldNameRenderer control \u00b6 This control renders document's name as a link. The link provides either preview (if it is available) or direct download. Additionally, new documents are marked with \"Glimmer\" icon. Note: The Name column in document libraries is marked as noneditable. See this issue for details. Note Glimmer icon displays correctly starting with SharePoint Framework v1.4 Covered Fields \u00b6 Document Name (LinkFilename, LinkFilenameNomenu, FileLieafRef) How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldNameRenderer } from \"@pnp/spfx-controls-react/lib/FieldNameRenderer\" ; Use the FieldNameRenderer control in your code as follows: < FieldNameRenderer text = { 'Technical Requirements' } isLink = { true } isNew = { false } filePath = { 'https://contoso.sharepoint.com/Documents/tech-requirements.pdf' } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldNameRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. isLink boolean yes True if the name should be rendered as a link. isNew boolean no True if the document is new. filePath string no Path to the document. hasPreview boolean no True if the document has preview and link href should be constructed to display the preview (instead of direct document's link). The flag works only if onClick property is NOT defined. onClick (args: INameClickEventArgs) => {} no Custom handler for link click. If not set link click will lead to rendering document preview. Works if isLink is set to true onDoubleClick (args: INameClickEventArgs) => {} no Custom handler for link double click. If not set link If not set link will use OOTB behavior. Works if isLink is set to true","title":"FieldNameRenderer"},{"location":"controls/fields/FieldNameRenderer/#fieldnamerenderer-control","text":"This control renders document's name as a link. The link provides either preview (if it is available) or direct download. Additionally, new documents are marked with \"Glimmer\" icon. Note: The Name column in document libraries is marked as noneditable. See this issue for details. Note Glimmer icon displays correctly starting with SharePoint Framework v1.4","title":"FieldNameRenderer control"},{"location":"controls/fields/FieldNameRenderer/#covered-fields","text":"Document Name (LinkFilename, LinkFilenameNomenu, FileLieafRef)","title":"Covered Fields"},{"location":"controls/fields/FieldNameRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldNameRenderer } from \"@pnp/spfx-controls-react/lib/FieldNameRenderer\" ; Use the FieldNameRenderer control in your code as follows: < FieldNameRenderer text = { 'Technical Requirements' } isLink = { true } isNew = { false } filePath = { 'https://contoso.sharepoint.com/Documents/tech-requirements.pdf' } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldNameRenderer/#implementation","text":"The FieldNameRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. isLink boolean yes True if the name should be rendered as a link. isNew boolean no True if the document is new. filePath string no Path to the document. hasPreview boolean no True if the document has preview and link href should be constructed to display the preview (instead of direct document's link). The flag works only if onClick property is NOT defined. onClick (args: INameClickEventArgs) => {} no Custom handler for link click. If not set link click will lead to rendering document preview. Works if isLink is set to true onDoubleClick (args: INameClickEventArgs) => {} no Custom handler for link double click. If not set link If not set link will use OOTB behavior. Works if isLink is set to true","title":"Implementation"},{"location":"controls/fields/FieldRendererHelper/","text":"FieldRendererHelper class \u00b6 FieldRendererHelper class is used to automatically apply needed Field Control based on current Field parameters. How to use this class in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldRendererHelper } from \"@pnp/spfx-controls-react/lib/Utilities\" ; Use the FieldRendererHelper.getFieldRenderer method to asynchronously request proper React control (As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render ): public componentWillMount () { FieldRendererHelper . getFieldRenderer ( fieldValue , { className : this.props.className , cssProps : this.props.cssProps }, this . props . listItem , this . props . context ). then ( fieldRenderer => { // update state to re-render the Field Customizer this . setState ({ fieldRenderer : fieldRenderer }); }); } Render the requestted fieldRenderer : public render () : React . ReactElement < {} > { return ( < div className = { styles . cell } > { this . state . fieldRenderer } < /div> ); } Implementation \u00b6 The FieldRendererHelper class contains single method getFieldRenderer with next signature: public static getFieldRenderer ( fieldValue : any , props : IFieldRendererProps , listItem : ListItemAccessor , context : IContext ) : Promise < JSX . Element > Parameters: Parameter Type Description fieldValue any Value of the field. props IFieldRendererProps Basic properties interface for Field Controls. Contains className and cssProps properties listItem ListItemAccessor Current List Item context IContext SPFx Context","title":"FieldRendererHelper"},{"location":"controls/fields/FieldRendererHelper/#fieldrendererhelper-class","text":"FieldRendererHelper class is used to automatically apply needed Field Control based on current Field parameters.","title":"FieldRendererHelper class"},{"location":"controls/fields/FieldRendererHelper/#how-to-use-this-class-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldRendererHelper } from \"@pnp/spfx-controls-react/lib/Utilities\" ; Use the FieldRendererHelper.getFieldRenderer method to asynchronously request proper React control (As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render ): public componentWillMount () { FieldRendererHelper . getFieldRenderer ( fieldValue , { className : this.props.className , cssProps : this.props.cssProps }, this . props . listItem , this . props . context ). then ( fieldRenderer => { // update state to re-render the Field Customizer this . setState ({ fieldRenderer : fieldRenderer }); }); } Render the requestted fieldRenderer : public render () : React . ReactElement < {} > { return ( < div className = { styles . cell } > { this . state . fieldRenderer } < /div> ); }","title":"How to use this class in your solutions"},{"location":"controls/fields/FieldRendererHelper/#implementation","text":"The FieldRendererHelper class contains single method getFieldRenderer with next signature: public static getFieldRenderer ( fieldValue : any , props : IFieldRendererProps , listItem : ListItemAccessor , context : IContext ) : Promise < JSX . Element > Parameters: Parameter Type Description fieldValue any Value of the field. props IFieldRendererProps Basic properties interface for Field Controls. Contains className and cssProps properties listItem ListItemAccessor Current List Item context IContext SPFx Context","title":"Implementation"},{"location":"controls/fields/FieldTaxonomyRenderer/","text":"FieldTaxonomyRenderer control \u00b6 This control renders terms from Managed Metadata field. Covered Fields \u00b6 Managed Metadata How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTaxonomyRenderer } from \"@pnp/spfx-controls-react/lib/FieldTaxonomyRenderer\" ; Use the FieldTaxonomyRenderer control in your code as follows: < FieldTaxonomyRenderer terms = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldTaxonomyRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. terms ITerm[] yes Managed Metadata terms.","title":"FieldTaxonomyRenderer"},{"location":"controls/fields/FieldTaxonomyRenderer/#fieldtaxonomyrenderer-control","text":"This control renders terms from Managed Metadata field.","title":"FieldTaxonomyRenderer control"},{"location":"controls/fields/FieldTaxonomyRenderer/#covered-fields","text":"Managed Metadata","title":"Covered Fields"},{"location":"controls/fields/FieldTaxonomyRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTaxonomyRenderer } from \"@pnp/spfx-controls-react/lib/FieldTaxonomyRenderer\" ; Use the FieldTaxonomyRenderer control in your code as follows: < FieldTaxonomyRenderer terms = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldTaxonomyRenderer/#implementation","text":"The FieldTaxonomyRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. terms ITerm[] yes Managed Metadata terms.","title":"Implementation"},{"location":"controls/fields/FieldTextRenderer/","text":"FieldTextRenderer control \u00b6 This control renders simple text. Covered Fields \u00b6 Single line of text Multiple lines of text Choice Number Currency Yes/No Default renderer for uncovered types of fields How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTextRenderer } from \"@pnp/spfx-controls-react/lib/FieldTextRenderer\" ; Use the FieldTextRenderer control in your code as follows: < FieldTextRenderer text = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldTextRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered","title":"FieldTextRenderer"},{"location":"controls/fields/FieldTextRenderer/#fieldtextrenderer-control","text":"This control renders simple text.","title":"FieldTextRenderer control"},{"location":"controls/fields/FieldTextRenderer/#covered-fields","text":"Single line of text Multiple lines of text Choice Number Currency Yes/No Default renderer for uncovered types of fields","title":"Covered Fields"},{"location":"controls/fields/FieldTextRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTextRenderer } from \"@pnp/spfx-controls-react/lib/FieldTextRenderer\" ; Use the FieldTextRenderer control in your code as follows: < FieldTextRenderer text = { event . fieldValue } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldTextRenderer/#implementation","text":"The FieldTextRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered","title":"Implementation"},{"location":"controls/fields/FieldTitleRenderer/","text":"FieldTitleRenderer control \u00b6 This control renders title either as a simple text or as a link to the Display Form. Additional actions like Share and Context Menu are not implemented. Covered Fields \u00b6 List Item Title (Title, LinkTitle, LinkTitleNoMenu) How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTitleRenderer } from \"@pnp/spfx-controls-react/lib/FieldTitleRenderer\" ; Use the FieldTitleRenderer control in your code as follows: < FieldTitleRenderer text = { 'Technical Requirements' } isLink = { true } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldTitleRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. isLink boolean yes True if the name should be rendered as a link. baseUrl string no Web Url. Should be provided if onClick is not defined listId string no List Id. Should be provided if onClick is not defined id number no Item Id. Should be provided if onClick is not defined onClick (args: ITitleClickEventArgs) => {} no Custom title click event handler. If not set Display form for the item will be displayed.","title":"FieldTitleRenderer"},{"location":"controls/fields/FieldTitleRenderer/#fieldtitlerenderer-control","text":"This control renders title either as a simple text or as a link to the Display Form. Additional actions like Share and Context Menu are not implemented.","title":"FieldTitleRenderer control"},{"location":"controls/fields/FieldTitleRenderer/#covered-fields","text":"List Item Title (Title, LinkTitle, LinkTitleNoMenu)","title":"Covered Fields"},{"location":"controls/fields/FieldTitleRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldTitleRenderer } from \"@pnp/spfx-controls-react/lib/FieldTitleRenderer\" ; Use the FieldTitleRenderer control in your code as follows: < FieldTitleRenderer text = { 'Technical Requirements' } isLink = { true } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldTitleRenderer/#implementation","text":"The FieldTitleRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. isLink boolean yes True if the name should be rendered as a link. baseUrl string no Web Url. Should be provided if onClick is not defined listId string no List Id. Should be provided if onClick is not defined id number no Item Id. Should be provided if onClick is not defined onClick (args: ITitleClickEventArgs) => {} no Custom title click event handler. If not set Display form for the item will be displayed.","title":"Implementation"},{"location":"controls/fields/FieldUrlRenderer/","text":"FieldUrlRenderer control \u00b6 This control renders Hyperlink or Picture field value as a link or image. Covered Fields \u00b6 Hyperlink or Image Url in Links List How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldUrlRenderer } from \"@pnp/spfx-controls-react/lib/FieldUrlRenderer\" ; Use the FieldUrlRenderer control in your code as follows: // to show Url < FieldUrlRenderer text = { 'microsoft' } url = { 'http://www.microsoft.com' } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> // to show Image < FieldUrlRenderer url = { 'http://cdn.contoso.com/images/logo.png' } isImageUrl = { true } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldUrlRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. url string yes Url. isImageUrl boolean no True if the control should be rendered as an image.","title":"FieldUrlRenderer"},{"location":"controls/fields/FieldUrlRenderer/#fieldurlrenderer-control","text":"This control renders Hyperlink or Picture field value as a link or image.","title":"FieldUrlRenderer control"},{"location":"controls/fields/FieldUrlRenderer/#covered-fields","text":"Hyperlink or Image Url in Links List","title":"Covered Fields"},{"location":"controls/fields/FieldUrlRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldUrlRenderer } from \"@pnp/spfx-controls-react/lib/FieldUrlRenderer\" ; Use the FieldUrlRenderer control in your code as follows: // to show Url < FieldUrlRenderer text = { 'microsoft' } url = { 'http://www.microsoft.com' } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> // to show Image < FieldUrlRenderer url = { 'http://cdn.contoso.com/images/logo.png' } isImageUrl = { true } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldUrlRenderer/#implementation","text":"The FieldUrlRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. text string no Text to be rendered. url string yes Url. isImageUrl boolean no True if the control should be rendered as an image.","title":"Implementation"},{"location":"controls/fields/FieldUserRenderer/","text":"FieldUserRenderer control \u00b6 This control renders each referenced user/group as a link on a separate line. Hovering the link for users (not groups) leads to opening of Persona control. Note: some icons may be rendered incorrectly if used with SharePoint Framework v1.3 or earlier Covered Fields \u00b6 Person or Group How to use this control in your solutions \u00b6 Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldUserRenderer } from \"@pnp/spfx-controls-react/lib/FieldUserRenderer\" ; Use the FieldUserRenderer control in your code as follows: < FieldUserRenderer users = { event . fieldValue } context = { this . context } className = { 'some-class' } cssProps = {{ background : '#f00' }} /> Implementation \u00b6 The FieldUserRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. users IPrincipal no Users/groups to be displayed as they appear in event.fieldValue for Field Customizer's onRenderCell event. context IContext yes SPFx context.","title":"FieldUserRenderer"},{"location":"controls/fields/FieldUserRenderer/#fielduserrenderer-control","text":"This control renders each referenced user/group as a link on a separate line. Hovering the link for users (not groups) leads to opening of Persona control. Note: some icons may be rendered incorrectly if used with SharePoint Framework v1.3 or earlier","title":"FieldUserRenderer control"},{"location":"controls/fields/FieldUserRenderer/#covered-fields","text":"Person or Group","title":"Covered Fields"},{"location":"controls/fields/FieldUserRenderer/#how-to-use-this-control-in-your-solutions","text":"Check that you installed the @pnp/spfx-controls-react dependency. Check out the getting started page for more information about installing the dependency. Import the following modules to your component: import { FieldUserRenderer } from \"@pnp/spfx-controls-react/lib/FieldUserRenderer\" ; Use the FieldUserRenderer control in your code as follows: < FieldUserRenderer users = { event . fieldValue } context = { this . context } className = { 'some-class' } cssProps = {{ background : '#f00' }} />","title":"How to use this control in your solutions"},{"location":"controls/fields/FieldUserRenderer/#implementation","text":"The FieldUserRenderer component can be configured with the following properties: Property Type Required Description cssProps React.CSSProperties no CSS styles to apply to the renderer. className ICssInput no CSS classes to apply to the renderer. users IPrincipal no Users/groups to be displayed as they appear in event.fieldValue for Field Customizer's onRenderCell event. context IContext yes SPFx context.","title":"Implementation"},{"location":"controls/fields/main/","text":"Field Customizer Out-of-the-box Fields Controls \u00b6 These controls represent React controls that can be used in SPFx Field Customizers to provide rendering of the fields similar to out of the box experience. Additional benefit is ability to set custom css classes and styles to the component. Related UserVoice requests: https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/18810637-access-to-re-use-modern-field-render-controls https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/31530607-field-customizer-ability-to-call-ootb-render-meth Usage \u00b6 The main scenario to use this package is to import FieldRendererHelper class and to call getFieldRenderer method. This method returns a Promise with a proper field renderer ( Promise ) based on field's type. It means that it will automatically select proper component that should be rendered in this or that field. This method also contains logic to correctly process field's value and get correct text to display (for example, Friendly Text for DateTime fields). As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render . The resulting field renderer could be saved in the element's state and used later in render method. Here is an example on how it can be used inside custom Field Customizer component (.tsx file): export interface IOotbFieldsState { fieldRenderer? : JSX.Element ; } //... @override public componentWillMount () { FieldRendererHelper . getFieldRenderer ( this . props . value , { className : this.props.className , cssProps : this.props.cssProps }, this . props . listItem , this . props . context ). then ( fieldRenderer => { this . setState ({ fieldRenderer : fieldRenderer }); }); } public render () : React . ReactElement < {} > { return ( < div className = { styles . cell } > { this . state . fieldRenderer } < /div> ); } Additionally, any of included components can be used by itself. FieldRendererHelper \u00b6 FieldRendererHelper class is a recommended way to use Field Controls as it provides additional functionality to automatically render the content for any type of fields. Available Controls \u00b6 The following Field Controls are currently available: FieldAttachmentsRenderer (renders Clip icon based on the provided count property is defined and greater than 0) FieldDateRenderer (renders date string as a simple text) FieldFileTypeRenderer (renders document or folder icon based on file path) FieldLookupRenderer (renders lookup values) FieldNameRenderer (renders document's name as a link) FieldTaxonomyRenderer (renders terms from Managed Metadata field) FieldTextRenderer (renders simple text) FieldTitleRenderer (renders title either as a simple text or as a link to the Display Form) FieldUrlRenderer (renders Hyperlink or Picture field value as a link or image) FieldUserRenderer (renders each referenced user/group as a link on a separate line)","title":"Getting started"},{"location":"controls/fields/main/#field-customizer-out-of-the-box-fields-controls","text":"These controls represent React controls that can be used in SPFx Field Customizers to provide rendering of the fields similar to out of the box experience. Additional benefit is ability to set custom css classes and styles to the component. Related UserVoice requests: https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/18810637-access-to-re-use-modern-field-render-controls https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/31530607-field-customizer-ability-to-call-ootb-render-meth","title":"Field Customizer Out-of-the-box Fields Controls"},{"location":"controls/fields/main/#usage","text":"The main scenario to use this package is to import FieldRendererHelper class and to call getFieldRenderer method. This method returns a Promise with a proper field renderer ( Promise ) based on field's type. It means that it will automatically select proper component that should be rendered in this or that field. This method also contains logic to correctly process field's value and get correct text to display (for example, Friendly Text for DateTime fields). As the method returns Promise it should be called in one of React component lifecycle methods, for example, componentWillMount that will occur before render . The resulting field renderer could be saved in the element's state and used later in render method. Here is an example on how it can be used inside custom Field Customizer component (.tsx file): export interface IOotbFieldsState { fieldRenderer? : JSX.Element ; } //... @override public componentWillMount () { FieldRendererHelper . getFieldRenderer ( this . props . value , { className : this.props.className , cssProps : this.props.cssProps }, this . props . listItem , this . props . context ). then ( fieldRenderer => { this . setState ({ fieldRenderer : fieldRenderer }); }); } public render () : React . ReactElement < {} > { return ( < div className = { styles . cell } > { this . state . fieldRenderer } < /div> ); } Additionally, any of included components can be used by itself.","title":"Usage"},{"location":"controls/fields/main/#fieldrendererhelper","text":"FieldRendererHelper class is a recommended way to use Field Controls as it provides additional functionality to automatically render the content for any type of fields.","title":"FieldRendererHelper"},{"location":"controls/fields/main/#available-controls","text":"The following Field Controls are currently available: FieldAttachmentsRenderer (renders Clip icon based on the provided count property is defined and greater than 0) FieldDateRenderer (renders date string as a simple text) FieldFileTypeRenderer (renders document or folder icon based on file path) FieldLookupRenderer (renders lookup values) FieldNameRenderer (renders document's name as a link) FieldTaxonomyRenderer (renders terms from Managed Metadata field) FieldTextRenderer (renders simple text) FieldTitleRenderer (renders title either as a simple text or as a link to the Display Form) FieldUrlRenderer (renders Hyperlink or Picture field value as a link or image) FieldUserRenderer (renders each referenced user/group as a link on a separate line)","title":"Available Controls"},{"location":"guides/","text":"Project guides \u00b6 Following is an overview of guides for this project. If you're considering contributing to the project, reading up on these guides will help you understand the project structure and get started developing for it. Contributing - how you can contribute to the project Minimal Path to Awesome - setup your development environment Submitting a PR - how to submit a PR Migrating from V1 - how to migrate from v1","title":"Overview"},{"location":"guides/#project-guides","text":"Following is an overview of guides for this project. If you're considering contributing to the project, reading up on these guides will help you understand the project structure and get started developing for it. Contributing - how you can contribute to the project Minimal Path to Awesome - setup your development environment Submitting a PR - how to submit a PR Migrating from V1 - how to migrate from v1","title":"Project guides"},{"location":"guides/contributing/","text":"Contribution guidelines \u00b6 We appreciate that you're interested in helping with moving the project forward. Before you submit your first PR, please read the following guide. We'd hate to see you work on something that someone else is already working on, something that we agreed not to do or something that doesn't match the project. Sharing is caring! You have an idea for a new component \u00b6 Awesome! Good ideas are invaluable for every product. Before you start hacking away, please check if there is no similar idea already listed in the issue list . If not, please create a new issue describing your idea. Once we agree on the feature scope and architecture, the feature will be ready for building. Don't hesitate to mention in the issue if you'd like to build the feature yourself. When building a new control, try to add your control to the default provided web part so that everyone can test it out. Please also provide the documentation for your controls in the documentation section . You have a suggestion for improving an existing component \u00b6 Nothing is perfect. If you have an idea how to improve an existing command or the CLI, let us know by submitting an issue in the issue list . Some things are done for a reason, but some are not. Let's discuss what you think and see how the project could be improved for everyone. You've found a bug \u00b6 Bugs happen. When you find a bug, please have a look at the issue list if a similar bug has already been logged. If not, let us know what doesn't work and how we can reproduce it. If we can't reproduce your bug, we will ask you for clarification, which will only make it longer to fix it. Fixing typos \u00b6 Typos are embarrassing! Most PR's that fix typos will be accepted immediately. In order to make it easier to review the PR, please narrow the focus instead of sending a huge PR of fixes. Tips \u00b6 Before contributing: ensure that the dev branch on your fork is in sync with the original sp-dev-fx-controls-react repository # assuming you are in the folder of your locally cloned fork.... git checkout dev # assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo git fetch upstream # update your local dev to be a mirror of what's in the main repo git pull --rebase upstream dev create a feature branch for your change. If you'll get stuck on an issue or merging your PR will take a while, this will allow you to have a clean dev branch that you can use for contributing other changes git checkout -b my-contribution DO's & DON'Ts \u00b6 DO follow the same project and test structure as the existing project. DO include tests when adding new functionality and features. When fixing bugs, start with adding a test that highlights how the current behavior is broken. DO keep discussions focused. When a new or related topic comes up it's often better to create new issue than to side track the conversation. DO NOT submit PR's for coding style changes. DO NOT surprise us with big PR's. Instead file an issue & start a discussion so we can agree on a direction before you invest a large amount of time. DO NOT commit code you didn't write. DO NOT submit PR's that refactor existing code without a discussion first.","title":"Contributing"},{"location":"guides/contributing/#contribution-guidelines","text":"We appreciate that you're interested in helping with moving the project forward. Before you submit your first PR, please read the following guide. We'd hate to see you work on something that someone else is already working on, something that we agreed not to do or something that doesn't match the project. Sharing is caring!","title":"Contribution guidelines"},{"location":"guides/contributing/#you-have-an-idea-for-a-new-component","text":"Awesome! Good ideas are invaluable for every product. Before you start hacking away, please check if there is no similar idea already listed in the issue list . If not, please create a new issue describing your idea. Once we agree on the feature scope and architecture, the feature will be ready for building. Don't hesitate to mention in the issue if you'd like to build the feature yourself. When building a new control, try to add your control to the default provided web part so that everyone can test it out. Please also provide the documentation for your controls in the documentation section .","title":"You have an idea for a new component"},{"location":"guides/contributing/#you-have-a-suggestion-for-improving-an-existing-component","text":"Nothing is perfect. If you have an idea how to improve an existing command or the CLI, let us know by submitting an issue in the issue list . Some things are done for a reason, but some are not. Let's discuss what you think and see how the project could be improved for everyone.","title":"You have a suggestion for improving an existing component"},{"location":"guides/contributing/#youve-found-a-bug","text":"Bugs happen. When you find a bug, please have a look at the issue list if a similar bug has already been logged. If not, let us know what doesn't work and how we can reproduce it. If we can't reproduce your bug, we will ask you for clarification, which will only make it longer to fix it.","title":"You've found a bug"},{"location":"guides/contributing/#fixing-typos","text":"Typos are embarrassing! Most PR's that fix typos will be accepted immediately. In order to make it easier to review the PR, please narrow the focus instead of sending a huge PR of fixes.","title":"Fixing typos"},{"location":"guides/contributing/#tips","text":"Before contributing: ensure that the dev branch on your fork is in sync with the original sp-dev-fx-controls-react repository # assuming you are in the folder of your locally cloned fork.... git checkout dev # assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo git fetch upstream # update your local dev to be a mirror of what's in the main repo git pull --rebase upstream dev create a feature branch for your change. If you'll get stuck on an issue or merging your PR will take a while, this will allow you to have a clean dev branch that you can use for contributing other changes git checkout -b my-contribution","title":"Tips"},{"location":"guides/contributing/#dos-donts","text":"DO follow the same project and test structure as the existing project. DO include tests when adding new functionality and features. When fixing bugs, start with adding a test that highlights how the current behavior is broken. DO keep discussions focused. When a new or related topic comes up it's often better to create new issue than to side track the conversation. DO NOT submit PR's for coding style changes. DO NOT surprise us with big PR's. Instead file an issue & start a discussion so we can agree on a direction before you invest a large amount of time. DO NOT commit code you didn't write. DO NOT submit PR's that refactor existing code without a discussion first.","title":"DO's & DON'Ts"},{"location":"guides/migrate-from-v1/","text":"Migrating from v1 to v2 \u00b6 Most of the controls have no breaking changes when moving from v1 to v2. However, some APIs were changed to make the library more stable and controls behavior more even. Also, we've bumped up React and Fluent UI versions used in the library. It means you will need to update the package.json file in your SPFx projects. The below guide is an overview of what it takes to migrate from v1 to v2. If we missed something, please let us know on the issues list so we can update the guide. Thanks! v2 Supports SharePoint Online only \u00b6 V2 of Reusable Controls is based on SharePoint Framework 1.11. Due to this change, it does not support SharePoint on-premises. Please, use v1 if you plan to deploy your solution on-premises. React and Fluent UI versions \u00b6 V2 of Reusable Controls uses React.js v16.8.5 and Fluent UI (Office UI Fabric React) v6.214.0. Although it is not necessary to use the same modules' versions in your project, we highly recommend to update your solution accordingly: \"dependencies\" : { // other dependencies \"office-ui-fabric-react\" : \"6.214.0\" , \"react\" : \"16.8.5\" , \"react-dom\" : \"16.8.5\" }, \"devDependencies\" : { \"@types/react\" : \"16.8.8\" , \"@types/react-dom\" : \"16.8.3\" , }, The easiest way to upgrade the SharePoint Framework solution is to use Office365 CLI spfx project upgrade command. APIs Changes \u00b6 PeoplePicker \u00b6 isRequired is renamed to required The property has been renamed to use the common approach for mandatory field naming. errorMessage represents a static error message to be displayed in the control. In v1 errorMessage is used to provide the text that will be displayed if the field is set as required and no value is selected. In v2 you can use this property to display an error message for whatever reason statically. /** * Static error message displayed below the text field. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence). */ errorMessage? : string ; onGetErrorMessage to get error messages dynamically. The method is used to get the validation error message and determine whether the input value is valid. Mutually exclusive with the static string errorMessage (it will take precedence over this). /** * The method is used to get the validation error message and determine whether the picker value is valid. * Mutually exclusive with the static string errorMessage (it will take precedence over this). * * When it returns string: * - If valid, it returns empty string. * - If invalid, it returns the error message string and the picker will * show an error message below the picker. * * When it returns Promise: * - The resolved value is display as error message. * - The rejected, the value is thrown away. * */ onGetErrorMessage ?: ( items : IPersonaProps []) => string | Promise < string > ; showRequiredError has been deleted. Use errorMessage or onGetErrorMessage to provide the error message. selectedItems is renamed to onChange onChange better describes the purpose of the property. ### FolderPicker FolderPicker default picker has been removed. If you used FolderPicker as: typescript import FolderPicker from '@pnp/spfx-controls-react/lib/controls/folderPicker/FolderPicker'; You should update to typescript import { FolderPicker } from '@pnp/spfx-controls-react/lib/FolderPicker';","title":"Migrate v1 to v2"},{"location":"guides/migrate-from-v1/#migrating-from-v1-to-v2","text":"Most of the controls have no breaking changes when moving from v1 to v2. However, some APIs were changed to make the library more stable and controls behavior more even. Also, we've bumped up React and Fluent UI versions used in the library. It means you will need to update the package.json file in your SPFx projects. The below guide is an overview of what it takes to migrate from v1 to v2. If we missed something, please let us know on the issues list so we can update the guide. Thanks!","title":"Migrating from v1 to v2"},{"location":"guides/migrate-from-v1/#v2-supports-sharepoint-online-only","text":"V2 of Reusable Controls is based on SharePoint Framework 1.11. Due to this change, it does not support SharePoint on-premises. Please, use v1 if you plan to deploy your solution on-premises.","title":"v2 Supports SharePoint Online only"},{"location":"guides/migrate-from-v1/#react-and-fluent-ui-versions","text":"V2 of Reusable Controls uses React.js v16.8.5 and Fluent UI (Office UI Fabric React) v6.214.0. Although it is not necessary to use the same modules' versions in your project, we highly recommend to update your solution accordingly: \"dependencies\" : { // other dependencies \"office-ui-fabric-react\" : \"6.214.0\" , \"react\" : \"16.8.5\" , \"react-dom\" : \"16.8.5\" }, \"devDependencies\" : { \"@types/react\" : \"16.8.8\" , \"@types/react-dom\" : \"16.8.3\" , }, The easiest way to upgrade the SharePoint Framework solution is to use Office365 CLI spfx project upgrade command.","title":"React and Fluent UI versions"},{"location":"guides/migrate-from-v1/#apis-changes","text":"","title":"APIs Changes"},{"location":"guides/migrate-from-v1/#peoplepicker","text":"isRequired is renamed to required The property has been renamed to use the common approach for mandatory field naming. errorMessage represents a static error message to be displayed in the control. In v1 errorMessage is used to provide the text that will be displayed if the field is set as required and no value is selected. In v2 you can use this property to display an error message for whatever reason statically. /** * Static error message displayed below the text field. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence). */ errorMessage? : string ; onGetErrorMessage to get error messages dynamically. The method is used to get the validation error message and determine whether the input value is valid. Mutually exclusive with the static string errorMessage (it will take precedence over this). /** * The method is used to get the validation error message and determine whether the picker value is valid. * Mutually exclusive with the static string errorMessage (it will take precedence over this). * * When it returns string: * - If valid, it returns empty string. * - If invalid, it returns the error message string and the picker will * show an error message below the picker. * * When it returns Promise: * - The resolved value is display as error message. * - The rejected, the value is thrown away. * */ onGetErrorMessage ?: ( items : IPersonaProps []) => string | Promise < string > ; showRequiredError has been deleted. Use errorMessage or onGetErrorMessage to provide the error message. selectedItems is renamed to onChange onChange better describes the purpose of the property. ### FolderPicker FolderPicker default picker has been removed. If you used FolderPicker as: typescript import FolderPicker from '@pnp/spfx-controls-react/lib/controls/folderPicker/FolderPicker'; You should update to typescript import { FolderPicker } from '@pnp/spfx-controls-react/lib/FolderPicker';","title":"PeoplePicker"},{"location":"guides/mpa/","text":"Minimal Path to Awesome \u00b6 The shortest way to prepare your local copy of the project for development and testing. Install prerequisites \u00b6 Before you start contributing to this project, you will need Node.js. This project (current version 3.x) has been tested with the 18.x version of Node.js and the version of NPM that comes with it. You can use Node Version Manager or Node Version Switcher to switch between different versions of Node.js. Get the local version of the project \u00b6 fork this repository clone your fork in the command line, run the following commands: npm install to restore dependencies npm install -g gulp-cli in order to run gulp commands (run npm list -g gulp-cli to check if already installed on your machine or not) gulp serve to serve your project (or npm run serve if you want to use spfx-fast-serve ) Start making your changes Run the project locally \u00b6 As this project embeds a SPFx solution, you have the ability to test all the controls on your machine. You can also debug the controls in any supported language by running one of the following commands (for example in french ): gulp serve --locale=fr-fr npx fast-serve --locale=fr-fr (if using spfx-fast-serve ) Beware that both argument and value have to be lower case. Supported locales are listed in the following project's path: src\\loc . Warning As long as you have access to a SharePoint Online environment (for v2 and after), you can test the components from your machine. But to test the web part as a Teams Tab, you have to first deploy the SPFx solution (and sync it to Teams). You also have to deploy the SharePoint Framework library for Microsoft Graph Toolkit v2.9.0. So be sure to be at least SharePoint Administrator . SPFx web part \u00b6 The web part is called ControlsTest and is available for both SharePoint Online and Teams. To test it on SharePoint, go to the workbench page https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/workbench.aspx and add the web part. To test it on Teams, once the project deployed on the tenant accordingly, add the web part as a Tab (from a team for example). To update the host component, open the ControlsTest React component located in the following project's relative path: src\\webparts\\controlsTest\\components\\ControlsTest.tsx . SPFx application customizer \u00b6 This extension is called TestApplicationCustomizer . To test it, go to the following URL (after updating the parameters): https://[SHAREPOINT_SITE].sharepoint.com?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={\"ca9eac70-7343-4972-88d6-672d50e9cf38\":{\"location\":\"ClientSideExtension.ApplicationCustomizer\"}} To update the host component, open the TestApp React component located in the following project's relative path: src\\extensions\\testApp\\TestApp.tsx . SPFx form customizer \u00b6 This extension is called TestForm . To test it, you have to configure it first: Open the serve.json file (located in the config folder) Replace the rootFolder property (under serveConfigurations ==> default ==> formCustomizer ), which contains a server relative URL, to target the list on which you want to test the extension Then go to the following URL (after updating the parameters): https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/SPListForm.aspx?debugManifestsFile=https://localhost:4321/temp/manifests.js&loadSPFX=true&componentId=f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8&PageType=8&RootFolder=[OPTIONAL_SERVER_RELATIVE_URL]/Lists/[LIST_NAME] To update the host component, open the TestForm React component located in the following project's relative path: src\\extensions\\testForm\\components\\TestForm.tsx . Documentation \u00b6 SharePoint Framework React Controls uses MkDocs to publish documentation pages. See more information about installing MkDocs on your operating system at http://www.mkdocs.org/#installation . Also, documentation uses custom MkDocs theme that should be installed as well. See Material theme for MkDocs . Currently, documentation is working with version 3.1.0. Once you have MkDocs installed on your machine, in the command line: run cd ./docs/documentation to change directory to where the manual pages are stored run mkdocs serve to start the local web server with MkDocs and view the documentation in the web browser","title":"Minimal Path to Awesome"},{"location":"guides/mpa/#minimal-path-to-awesome","text":"The shortest way to prepare your local copy of the project for development and testing.","title":"Minimal Path to Awesome"},{"location":"guides/mpa/#install-prerequisites","text":"Before you start contributing to this project, you will need Node.js. This project (current version 3.x) has been tested with the 18.x version of Node.js and the version of NPM that comes with it. You can use Node Version Manager or Node Version Switcher to switch between different versions of Node.js.","title":"Install prerequisites"},{"location":"guides/mpa/#get-the-local-version-of-the-project","text":"fork this repository clone your fork in the command line, run the following commands: npm install to restore dependencies npm install -g gulp-cli in order to run gulp commands (run npm list -g gulp-cli to check if already installed on your machine or not) gulp serve to serve your project (or npm run serve if you want to use spfx-fast-serve ) Start making your changes","title":"Get the local version of the project"},{"location":"guides/mpa/#run-the-project-locally","text":"As this project embeds a SPFx solution, you have the ability to test all the controls on your machine. You can also debug the controls in any supported language by running one of the following commands (for example in french ): gulp serve --locale=fr-fr npx fast-serve --locale=fr-fr (if using spfx-fast-serve ) Beware that both argument and value have to be lower case. Supported locales are listed in the following project's path: src\\loc . Warning As long as you have access to a SharePoint Online environment (for v2 and after), you can test the components from your machine. But to test the web part as a Teams Tab, you have to first deploy the SPFx solution (and sync it to Teams). You also have to deploy the SharePoint Framework library for Microsoft Graph Toolkit v2.9.0. So be sure to be at least SharePoint Administrator .","title":"Run the project locally"},{"location":"guides/mpa/#spfx-web-part","text":"The web part is called ControlsTest and is available for both SharePoint Online and Teams. To test it on SharePoint, go to the workbench page https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/workbench.aspx and add the web part. To test it on Teams, once the project deployed on the tenant accordingly, add the web part as a Tab (from a team for example). To update the host component, open the ControlsTest React component located in the following project's relative path: src\\webparts\\controlsTest\\components\\ControlsTest.tsx .","title":"SPFx web part"},{"location":"guides/mpa/#spfx-application-customizer","text":"This extension is called TestApplicationCustomizer . To test it, go to the following URL (after updating the parameters): https://[SHAREPOINT_SITE].sharepoint.com?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={\"ca9eac70-7343-4972-88d6-672d50e9cf38\":{\"location\":\"ClientSideExtension.ApplicationCustomizer\"}} To update the host component, open the TestApp React component located in the following project's relative path: src\\extensions\\testApp\\TestApp.tsx .","title":"SPFx application customizer"},{"location":"guides/mpa/#spfx-form-customizer","text":"This extension is called TestForm . To test it, you have to configure it first: Open the serve.json file (located in the config folder) Replace the rootFolder property (under serveConfigurations ==> default ==> formCustomizer ), which contains a server relative URL, to target the list on which you want to test the extension Then go to the following URL (after updating the parameters): https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/SPListForm.aspx?debugManifestsFile=https://localhost:4321/temp/manifests.js&loadSPFX=true&componentId=f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8&PageType=8&RootFolder=[OPTIONAL_SERVER_RELATIVE_URL]/Lists/[LIST_NAME] To update the host component, open the TestForm React component located in the following project's relative path: src\\extensions\\testForm\\components\\TestForm.tsx .","title":"SPFx form customizer"},{"location":"guides/mpa/#documentation","text":"SharePoint Framework React Controls uses MkDocs to publish documentation pages. See more information about installing MkDocs on your operating system at http://www.mkdocs.org/#installation . Also, documentation uses custom MkDocs theme that should be installed as well. See Material theme for MkDocs . Currently, documentation is working with version 3.1.0. Once you have MkDocs installed on your machine, in the command line: run cd ./docs/documentation to change directory to where the manual pages are stored run mkdocs serve to start the local web server with MkDocs and view the documentation in the web browser","title":"Documentation"},{"location":"guides/submitting-pr/","text":"Submitting a PR \u00b6 We appreciate your initiative and would love to integrate your work with the rest of the project! Here is how you can help us do it as quickly as possible. check, that your feature branch is up-to-date. If it's not, there is a risk of merge conflicts or other issues that will complicate merging your changes into the main repository. Refer to these resources for more information on syncing your repo: GitHub Help: Syncing a Fork AC: Keep Your Forked Git Repo Updated with Changes from the Original Upstream Repo Looking for a quick cheat sheet? Look no further: # assuming you are in the folder of your locally cloned fork.... git checkout dev # assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo git fetch upstream # update your local dev branch to be a mirror of what's in the main repo git pull --rebase upstream dev # switch to your branch where you are working, say \"issue-xyz\" git checkout issue-xyz # update your branch to update its fork point to the current tip of dev & put your changes on top of it git rebase dev submit PR to the dev branch of the main repo. PRs submitted to other branches will be declined let us know what's in the PR: is it a new command, bug fix or a minor update in the docs? The clearer the information you provide, the quicker your PR can be verified and merged ideally 1 PR = 1 commit - this makes it easier to keep the log clear for everyone and track what's changed. If you're new to working with git, we'll squash your commits for you when merging your changes into the main repo don't worry about changing the version or adding yourself to the list of contributors in package.json . We'll do that for you when merging your changes.","title":"Submitting a PR"},{"location":"guides/submitting-pr/#submitting-a-pr","text":"We appreciate your initiative and would love to integrate your work with the rest of the project! Here is how you can help us do it as quickly as possible. check, that your feature branch is up-to-date. If it's not, there is a risk of merge conflicts or other issues that will complicate merging your changes into the main repository. Refer to these resources for more information on syncing your repo: GitHub Help: Syncing a Fork AC: Keep Your Forked Git Repo Updated with Changes from the Original Upstream Repo Looking for a quick cheat sheet? Look no further: # assuming you are in the folder of your locally cloned fork.... git checkout dev # assuming you have a remote named `upstream` pointing to the official **sp-dev-fx-controls-react** repo git fetch upstream # update your local dev branch to be a mirror of what's in the main repo git pull --rebase upstream dev # switch to your branch where you are working, say \"issue-xyz\" git checkout issue-xyz # update your branch to update its fork point to the current tip of dev & put your changes on top of it git rebase dev submit PR to the dev branch of the main repo. PRs submitted to other branches will be declined let us know what's in the PR: is it a new command, bug fix or a minor update in the docs? The clearer the information you provide, the quicker your PR can be verified and merged ideally 1 PR = 1 commit - this makes it easier to keep the log clear for everyone and track what's changed. If you're new to working with git, we'll squash your commits for you when merging your changes into the main repo don't worry about changing the version or adding yourself to the list of contributors in package.json . We'll do that for you when merging your changes.","title":"Submitting a PR"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..0f8724efd --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 000000000..b77754423 Binary files /dev/null and b/sitemap.xml.gz differ