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 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +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.
+ + + + + + + + + +Dashboard
: added new WidgetSize #1845Dashboard
: IWidgetLink improvements #1813DynamicForm
: custom sorting #1802ImagePicker
: new Control ImagePicker #1820UserPicker
: new Control UserPicker #1675DynamicForm
: DynamicForm storeLastActiveTab option #1879 #1879FilePicker
: Image picker enhancements #1805DynamicForm
: Adds ability to create files/folders in subfolder using DynamicForm. #1901AdaptiveCardHost
: lock down adaptive-expression package version #1876ListItemPicker
: PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. #1887ListItemAttachments
: Fix 1858 to correct Chinese localization files #1894 #1894DynamicForm
: Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type #1872GridLayout
: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. 1851DynamicForm
: Always Show Required Field Validation Error In FormDisplayMode.Edit Mode #1775DynamicForm
: Required Field Validation won't work #1760DynamicForm
: Adds ability to render file/folder name field in DynamicForm and Field. #1906Special 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.
+DynamicForm
: enable/disable save button #1810PeoplePicker
: add new prop - useSubstrateSearch
#1819SitePicker
: add button to clear single / multiple selection #1839DynamicForm
: more than 100 lookups and date format in lookup field #1722Richtext
: can not undo ordered lists #1135FilePicker
: fixing organization tab browsing issue #1861PeoplePicker
: method to clear the array #1838SitePicker
: documentation patch #1842Special thanks to our contributors (in alphabetical order): Alex Terentiev, Antanina Druzhkina, Guido Zambarda, Luccas Castro, Michaël Maillot, Niels Söth, srpmtt.
+FilePicker
: Fix issue with adding link by typing in 'From a link' tab #1814Special thanks to our contributors (in alphabetical order): Antanina Druzhkina, Elio Struyf.
+DynamicField
: Added orderBy to DynamicField props for lookup fields #1747DateTimePicker
: disable array of dates #516DynamicForm
: new customIcons
property to allow custom icons for the form #1745RichText
: Added style property to Rich text control #1773fast-serve
: Fast-serve update to match the most recent changes. #1782PeoplePicker
: Added context optimization #1764Multiple controls
: Wrong fluentui imports cause webpack build errors #1763FileTypeIcon
: Added standard events #1789FolderPicker
: Update documentation on how to use the control with siteAbsoluteUrl property #1743DynamicForm
: Error on rendering DynamicForm when having a Date Field with internal name starting with underscore ('_')#1738DynamicForm
: Dynamic form loading error in other site #1758Special thanks to our contributors (in alphabetical order): Guido Zambarda, Harminder Singh, IRRDC, Matthias Z'Brun, Michaël Maillot, Nishkalank Bezawada, Sergei Sergeev, srpmtt.
+DyanmicForm
: Added file handling #1625DynamicForm
: Custom Formatting and Validation, ControlsTestWebPart updates #1672PeoplePicker
: Added custom filter to PeoplePicker selection #1657RichText
: Align RichText heading styles and font sizes with OOB SharePoint text web part #1706ModernTaxonomyPicker
: not displaying suggestions when typing in values - API not found error #1688DynamicForm
: Disable issue on fieldOverrides field control when onBeforeSubmit return true #1715PeoplePicker
: PeoplePicker returns no results with webAbsoluteUrl and ensureUser #1669DynamicForm
: [DynamicForm] Fixing multi taxonomy field (loading + saving existing item) #1739Special thanks to our contributors (in alphabetical order): Guido Zambarda, Lars Fernhomberg, Mark Bice, Michaël Maillot, Nishkalank Bezawada, Tom G, wuxiaojun514.
+Special thanks to our contributor: IRRDC.
+DynamicForm
: Additional check to see if DefaultValue is an object. No more null comparisons, which should have been undefined comparisonsSpecial thanks to our contributor: IRRDC.
+FieldCollectionData
: render on page instead of panel and added combobox and peoplepicker controls #1588FieldCollectionData
: added date field control and updated number field #1600ListItemComments
: Added ListItemComments component to Controls.tsx #1621FolderPicker
: Improve documentation of FolderPicker #1379RichText
: Add https:// as placeholder instead of textbox value when adding url #1651PeoplePicker
: new property to starting the search after n characters #374AccessibleAccordion
: fix typo in documentation #1634DynamicForm
: fix issue with MultiChoice field #1510Localization
: Update dutch translations #1635TaxonomyPicker
: suggested item contains double termset name #1597DynamicForm
: DynamicForm does not properly handle NULL default values for Taxonomy fields #1267DynamicForm
: New items are always created with the default content type if the list has multiple content types #1626PeoplePicker
: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 #1614DynamicForm
: Number validations are working, but the percentage values are not getting saved #1601DynamicForm
: Number validation is preventing form save in certain circumstances, not enabled for currency fields #1604ListItemAttachments
: Inconsistent file handling #1644Localization
: Update Japanese translations #1686ListItemPicker
: Fix docs for onSelectedItem #1690ComboBoxListItemPicker
: Fix docs for onSelectedItem #1690ListItemAttachments
: Fix click behavior in ListItemAttachments component #1692Special 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.
+TermSetNavigation
: new control TermSetNavigation #1527FolderExplorer
: show files on folder explorer control #1502DynamicForm
: Fixed typo in property name #1529DynamicForm
: validation error dialog added #1531DateTimePicker
: Add new property initialPickerDate #1581ModernTaxonomyPicker
: can't find term when UI is in language not supported by term store #1573AdaptiveCardHost
: Add null check for adaptive card elements #1574ControlsTestWebPart
: Updated the ControlsTestWebPart to show the controls filtered by control type #1547fast-serve
: Fast-serve updated to the latest version and serve warnings fixed #1589DynamicForm
: DynamicForm Number min max #1585FieldPicker
: Changed react import to fix cannot be used as a JSX component
error #1500Localization
: Fixes to Italian localization #1532Localization
: Fixes to Netherlands localization #1537ListItemAttachments
: Fix the OnClick handler when clicking on the document card #1541fast-serve
: Fix issue with File and Directory Entries API #1555FilePicker
: Tile view issue on first render #1558DynamicForm
lookups - first time you select an option from a lookup, it doesnt select it #1535DynamicForm
: Fields of type Note don't get disabled #1264ListItemAttachments
: Fix for files containing dots in the name #1580PeoplePicker
: Shows wrong value in Dynamic Form when null is provided #1421DynamicForm
: Error on save when clearing person from Person or Group field and leaving it blank #1578DynamicForm
: Number validation is not working, if the field is set to minimum and maximum value #1571DynamicForm
: controls are shown with error messages even if the values are assigned #1133Special 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.
+DateTimePicker
: Fixed DateTimePicker strings in Danish Locale #1498FieldCollectionData
: Adds panelProps property to FieldCollectionData #1525DynamicForm
: Fixes DynamicForm trying to load TaxonomyFields with wrong display name #1422ListItemAttachments
: FIX: Cannot download items when it has a ilegal character #1484FilePicker
: FIX: recent tab empty until re-render #1482Dynamic Form
: Adds onListItemLoaded handler to DynamicForm #1472Dynamic Form
: Fix for the DynamicForm when a defaultValue is null and the code try to call the split method on it. #1486DynamicForm
: DynamicForm - Fixing Required Multi Field Saving Problem #1489FolderExplorer
: FolderExplorer doesn't explore folders with ' in the name #1491DynamicForm
: cannot display lookup value when the source field is not Title #1511FilePicker
:Features/1478 filepicker tiles view #1521Special 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.
+UploadFiles
: New Upload Files control #1388ListItemPicker
: use list name as well as GUID to point to list #1355ListItemPicker
: Add Styles property to ListItemPicker and ComboBoxListItemPicker #1407SitePicker
: Pass styles
property to Dropdown #1389FilePicker
: Site Tab - Many Document Libraries No Scrolling #1413DynamicForm
: Add respectETag
option to DynamicForm
#1395MonacoEditor
: Fixed minor typos and misleading instructions #1415RichText
: label
property is missing #1375PeoplePicker
: PeopleSearch service should also find people by userPrincipalName when group transitive membership check is used. #1446AdaptiveCardDesignerHost
: Add Sample Data to Adaptive Card Editor #1425AdaptiveCardHost
: Logic to prevent re-renders (flicker) #1425ListItemComments
: Add new parameter for ListItemComments to highlight comment #1430ComboBoxListItemPicker
: Update ComboBoxListItemPicker.md #1470DateTimePicker
: broken link for getErrorMessage
property fixed #1277ProgressStepsIndicator
: Fix missing image reference in Progress Steps Indicator #1409DynamicForm
: Dynamicform is hanging on the loading screen if the list has a single value list lookup field #1393ListView
: Update ListView control docs to use a valid field for the icon #1398Accordion
: Fixing Accordion control documentation image issue #1408DynamicForm
: Cannot read properties of undefined (reading 'startsWith') when submitting the form with contentType={undefined]
#1431FilePicker
: Fix site breadcrumb navigation #1368DynamicForm
: Initialize changedValue with defaultValue #1454DynamicForm
: Fix image path #1455DynamicForm
: Check empty array and trasform it in set as null #1456FilePicker
: Fix site browser resize #1457ModernTaxonomyPicker
Fix - Show ModernTaxonomyPicker label in correct form #1459DynamicForm
: Update DynamicForm.tsx #1462FilePicker
: Fix breadcrumb nav #1458DateTimePicker
: Date picker locale #1464DateTimePicker
: Date picker locale #1095RichText
: Use theme colors - fix dark mode #669FilePicker
: Use theme colors - fix dark mode #1132Special 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.
+DynamicForm
: support cretion of document sets #1335SitePicker
: add HubId to filter to only sites within a hub #1346FilePicker
: panel causes SharePoint to Throttle due to infinite loop fetching files #1325ContentTypePicker
: problem importing control #1337FilePicker
: correctly request data from provided webAbsoluteUrl
#1340ModernTaxonomyPicker
: Fix infinite loop #1342ModernTaxonomyPicker
: improve display of the term path to align with out of the box control UI #1343FolderPicker
: get folders of other site url instead of the current context/site #1305FilePicker
: browsing Site / Doclibs loops and floods SPO Service with requests and causes http 429 #1350TaxonomyPicker
: control allows select deprecated/untaggable terms when typing #1093SitePicker
: prevent infinite loop when fetching sites #1346DynamicForm
: AnchorId
of TaxonomyField
gets ignored and the whole tree is rendered #1310Special 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.
+ProgressStepsIndicator
: New control that shows a progress of steps. #1322DynamicForm
: Add taxonomy tree to test harness #1269ModernTaxonomyPicker
: ability to disallow selecting children #1279PeoplePicker
: Use webAbsoluteUrl if provided through props to ensure user #1273DynamicForm
: Support for hidden fields #1307Placeholder
: Documentation example to only display in edit mode #1280DynamicForm
: Update documentation regarding onBeforeSubmit #1319DynamicForm
: FirstDayOfWeek in DatePickers from webs regional settings #1317PeoplePicker
: fixes where people picker returns no results #1292FilePicker
: Tile view fix #1272RichText
: Fix broken arrow icons #1302TaxonomyPicker
: Does not show term set labels in Version 3.10.0 #1299TaxonomyPicker
: Dynamic form select term not working #1303DynamicForm
: Check if hiddenfields property is undefined #1314DynamicForm
: PeoplePicker preselects wrong user if PrincipalType allows groups #1315Special 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.
+DynamicForm
: possibility to override field rendering for individual fields #1257ModernTaxonomyPicker
: Display the full path of a term #1172DateTimePicker
: onChange
not triggered when clearing date #1277Special thanks to our contributors (in alphabetical order): Bart-Jan Dekker, Edin Kapic, Milan Holemans, Steve Beaugé.
+EnhancedThemeProvider
: Added 'EnhancedThemeProvider' control #1202FieldPicker
: Added FieldPicker
control #1219ContentTypePicler
: Added ContentTypePicker
control #1220ModernAudio
: Added ModernAudio
control #1224AdaptiveCardDesignerHost
: Added AdaptiveCardDesignerHost
control #1237DateTimePicker
: Added button to clear date #1217Toolbar
: Allow filters on a Toolbar to be controlled externally #1222PeoplePicker
: add new allowUnvalidated option to allow adding non-tenant users #1232DynamicForm
: Add support for webAbsoluteUrl
#1244Localization
: Updates to English localizations #1207Localization
: Updates to Dutch localizations #1209Localization
: Updates to Danish localizations #1233TaxonomyPicker
: Check if cultureInfo is valid #1226FieldCollectionData
: Updated docs to fix duplicated property #1236Changelog
: Fix changelog script by setting CHANGELOG.JSON filename extension to lower case #1242PeoplePicker
: PeoplePicker validation on focus out #1221DynamicForm
: Cannot display lookup value when the source field is not Title #1215FilePicker
: the endPoint for webSearch do not work #1256Special 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.
+LivePersona
: Fix LivePersona not showing card on hover #1241PeoplePicker
: Allow the use of multiple groupId-s #1163PeoplePicker
: search users in nested security groups #1173ModenrTaxonomyPicker
: Add more complete example of TaxonomyTree usage #1190AdaptiveCardHost
: Add SPFx Context property #1145AdaptiveCardHost
: Remove the isUniqueControlInPage
from the control by rebuilding the way to apply AC CSS class names #1154ListView
: Different background color to even and odd rows in ListView #1153AccessibleAccordion
: Support of section variations #1195TreeView
: Support of section variations #1196LocationPicker
: Resolve issue when in root site #1162LocationPicker
: Trigger onChange on picker clear action #1165TreeView
: TreeView Control is broken after updating to v3.7.0 #1170TreeView
: collapses on selection of a child node #1182TreeView
: expanded nodes state is getting lost after refresh #1062TaxonomyPicker
: Sorting the terms in locale language #1160ComboboxListItemPicker
: options are not reloaded after the filter is changed #1180FieldRendererHelper
: Add missing PnPjs import to SPHelper #1140RichText
: Update font style and font size on property pane #1151Placeholder
: Support section variations for themes #1193VariantThemeProvider
: new VariantThemeProvider
control #1120MonacoEditor
: new MonacoEditor
control #1134Carousel
: Prev and Next Buttons are not labeled, and read as 'Unlabeled button' by screen readers #1137TreeView
: Ability to set keys of items that should be expanded by default #1084FilePicker
: defaultFolderAbsolutePath
doesn't work with webAbsoluteUrl
#1129LocationPicker
: Location picker not resolving locations #1149DynamicForm
: RichText
Field losing focus on typing #1024LivePersona
: Documentation fix for template
type #1147AdaptiveCardHost
: React control that allows you to render an Adaptive Card as a component #1096ModernTaxonomyPicker
: ability to add action buttons to terms #1058FilePicker
: allow to select files from other sites #907Localization
: Update Swedish translations #1099FilePicker
: ability to allow external link and disable file existance chech commitFilePicker
: support for multi-select on additional sources #1047DateTimePicker
: new property for allowTextInput #1094LivePersona
: Cannot find module '@pnp/spfx-controls-react/lib/LivePersona'#1069ListView
: documentation spelling mistake 'ColumndName' #1063DynamicForm
: doesn't load or save correctly when field name starts with a special character #1077DynamicForm
: fields in DynamicForm do not honour regional settings #1075DynamicForm
: Boolean fields do not honour the default value in list settings #1073TaxonomyPicker
: table markdown fix in documentation #1072WebPartTitle
: Fix for styling of WebPartTitle to better match the styling of the oob webpart titles. #1088LivePersona
: fix for documentation typos #1106LivePersona
: remove property for SPFx context #1108Special 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.
+mgt
package to the latest version #1038ListView
: Add ability to provide CSS class names for list wrapper and list itself #1007IconPicker
: onCancel
property is added #1043DynamicForm
: disabledFields
property added #987ListPicker
: Add multi numbers support for baseTemplate option #1016ComboboxListItemPicker
: Add option to sort the items in the picker #985PeoplePicker
: Added filter for Microsoft 365 Group #985Accordion
: Added custom icons #1033PeoplePicker
: Added Styles property #1061FilePicker
: defaultFolderAbsolutePath
does not work Out of context #1023ModernTaxonomyPicker
: correctly display with RTL mode #1041FilePicker
: Fixed showing the selection circle on recent tabs #1048FilePicker
: Your organisation tab breadcrumb not working #1056Special 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.
+ModernTaxonomyPicker
: New control ModernTaxonomyPicker #1014LocationPicker
: Update docs #1009FileTypeIcon
: Add support of 20px icons#1013Pagination
: Update import from lodash #1021ChartControl
: Charts not updating properly when properties are changed #997TaxonomyPicker
: suggestions language is always English #879TaxonomyPicker
: errorMessage
label not being removed #953FilePicker
: Sorting Not Working as Expected in Site Tab #1011FilePicker
: Site Tab - Lots of file types don't have appropriate icons #1012LocationPicker
: Correct documentation #1019FilePicker
: fileNameWithoutExtension
not calculated right #1022FieldUserRenderer
: Add missing PnPJS imports #1025Special thanks to our contributors (in alphabetical order): Dennis Kuhn, Gautam Sheth, Jean-Luc Richer, hesperanca, Kiryl Shchasny, Patrik Hellgren, Peter Paul Kirschner, Ravichandran Krishnasamy.
+FilePicker
: spanish translation for Stock Images labels #946FilePicker
: Add support for a defaultFolderAbsolutePath prop #947DynamicForm
: Returning PnPJS IItem
in onSubmitted
event based on returnListItemInstanceOnSubmit
property #944DateTimePicker
: Add property for minutes dropdown increment #939ListItemPicker
: add property to show all options by default #955ListItemPicker
: Missing translation keys, improved FI, NL translation #957TaxonomyPicker
: Added onNewTerm called when enter is pressed #967DynamicForm
: Principal Types support #956DateTimePicker
: Expose allowTextInput from the underlying date picker #928Dynamic Form
: Show field descriptions #975RichText
: Image button is checked when hyperlink is added to the text #948RichText
: impossible to display link with the text equal to the url #949ComboBoxListItemPicker
: defaultSelectedItems not working #954Dynamic Form
: query items in a folder (managed metadata field) #973PeoplePicker
: Default selected items for groups #958Carousel
: Carousel is missing import of ICarouselImageProps
#986DynamicForm
example has incorrect syntax #990Special 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.
+ListItemAttachments
: Add new label and description properties #943ListPicker
: ListPicker
stopped working in upgrade from 3.1.0 to 3.2.0 #945ListItemAttachments
: Fixed multiple bugs #943fast-serve
: Add fast-serve support #916ComboBoxListItemPicker
and ListItemPicker
: Add label to control #914PeoplePicker
: new property groupId
. #917ListPicker
: add contenttype id to list picker #894ListPicker
: Few more tests with a little better description #906RichText
: correct event handler name #898SitePicker
: SitePicker
does not display initial sites until you click the dropdown to select #895DatePicker
: Fix Spanish loc strings #923FilePicker
: invalid CSS: relative in quotes. #930MyTeams
: Update MyTeams to use new library mgt-spfx #918FieldCollectionData
: FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929Special 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.
+TeamPicker
: new Team Picker control #846TeamChannelPicker
: new Team Channel Picker control #846SitePicker
: new Site Picker control #868DocumentLibraryBrowser
, SiteFilePickerTab
: jest unit tests #866 DragDropFiles
: new DragDropFiles control #861MyTeams
: new MyTeams control #874TeamChannelPicker
: new TeamChannelPicker control #874TeamPicker
: new TeamPicker control #874ListView
: Use new DragDropFiles control #861FilePicker
: Use new DragDropFiles control #861ListView
: Ability to provide custom sorting function #880FilePicker
: Allow panel on FilePicker to be invoked after first load #886FilePicker
: Allow FilePicker button to be hidden #887FilePicker
: Change same function to return an array of objectsListView
: typos fixes #855PeoplePicker
: error message isn't cleared after onGetErrorMessage
returns an empty string #841TreeView
: Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870FilePicker
: React crash on large folders #826ListItemAttachments
: updated filename replacement logic #873RichText
: Adding a link does not work #875FilePicker
: Stock images url is getting a 404 server error #882Special thanks to our contributors (in alphabetical order): Ari Gunawan, aroraans1512, cwparsons, joaojmendes, Kunj Balkrishna Sangani, Marcin Wojciechowski, Yannick Reekmans, André Lage.
+FilePicker
: spanish translation for Stock Images labels #946FilePicker
: Add support for a defaultFolderAbsolutePath prop #947DynamicForm
: Returning PnPJS IItem
in onSubmitted
event based on returnListItemInstanceOnSubmit
property #944DateTimePicker
: Add property for minutes dropdown increment #939DynamicForm
: Principal Types support #956Dynamic Form
: Show field descriptions #975RichText
: Image button is checked when hyperlink is added to the text #948RichText
: impossible to display link with the text equal to the url #949ComboBoxListItemPicker
: defaultSelectedItems not working #954PeoplePicker
: Default selected items for groups #958Special thanks to our contributors (in alphabetical order): Alexey Morozov, Daniel Stratton, Ketill Antoníus Ágústsson, Ravichandran Krishnasamy, Sergio Ortega Martín.
+ComboBoxListItemPicker
and ListItemPicker
: Add label to control #910PeoplePicker
: new property groupId
. #917SitePicker
: SitePicker
does not display initial sites until you click the dropdown to select #895FilePicker
: invalid CSS: relative in quotes. #930FieldCollectionData
: FieldCollectionData is not setting sortIdx on resulting collection when using 'Add and Save' #929Special thanks to our contributors (in alphabetical order): Nikolay Belykh, Patrik Hellgren, Peter Paul Kirschner, Ravichandran Krishnasamy.
+DragDropFiles
: new DragDropFiles control #856SitePicker
new Site Picker control #867Controls
Add locale strings for pt-br #865ListView
: Use new DragDropFiles control #856FilePicker
: Use new DragDropFiles control #856ListView
: Ability to provide custom sorting function #880FilePicker
: Allow panel on FilePicker to be invoked after first load #886FilePicker
: Allow FilePicker button to be hidden #887FilePicker
: Changed save function to return an array of objectsPeoplePicker
: error message isn't cleared after onGetErrorMessage
returns an empty string #841TreeView
: Not able to select/deselect checkbox in spfx-controls-react TreeView after assign the defaultSelectedKeys value #870FilePicker
: React crash on large folders #826ListItemAttachments
: updated filename replacement logic #873RichText
: Adding a link does not work #875FilePicker
: Stock images url is getting a 404 server error #882Special thanks to our contributors (in alphabetical order): André Lage, cwparsons, Kunj Balkrishna Sangani, Yannick Reekmans.
+IconPicker
: search icons using contains
comparison.FilePicker
: default alphabet sorting #824ListItemPicker
: ability to provide orderBy
#829Dashboard
: Dashboard widget wrapper for styling and error catching #836FolderExplorer
: Update folder explorer documentation #835IconPicker
: Fix case sensitive fluent icon search service #814Carousel
: documentation fix - broken table style #817AccessibleAccordion
: documentation link is broken #818TreeView
: Fix two potential null reference issues #832RichText
: Problem with bullets and number list #795FolderPicker
: Correct FolderPicker link alignmentSpecial thanks to our contributors (in alphabetical order): Anoop Tatti, Ari Gunawan, Gautam Sheth, Kunj Balkrishna Sangani, Marcin Wojciechowski, Mark Bice, Nizar Grindi, Yannick Reekmans.
+TreeView
: Adding support to clear TreeView selected items by passing an empty array. #787FilePicker
: new property includePageLibraries
to optionally display Site Pages library on Site tab #601ListItemPicker
: Support of Calculated
columns #805Progress
: Documentation update to have consistency in variables names #811FolderExplorer
: Add support for sorting folder explorer items #812ListView
: Selection is reset when putting a ListView inside a React Component that controls its items and selection props #251PeoplePicker
: Removed unwanted new line in help content. #783TreeView
: TreeViewSelectionMode
added in the import #780TreeView
: removed unwanted comma #779IFrameDialog
: height unable to resize relative to screen size, even if we provide in % it is taking default value. #636DateTimePicker
: Clear Date functionality #799Special thanks to our contributors (in alphabetical order): Ari Gunawan, Joel Rodrigues, Mike Myers, Ravichandran Krishnasamy, San.
+AccessibleAccordion
control #770Placeholder
: support of custom rendering for iconText
and description
PeoplePicker
: ability just to display inactive users name (ideally the value fetched from 'Author/Title') #768TaxonomyPicker
: New onPanelSelectionChange
property added. Can be used to interact with the control while selecting items in the panel, before Click or Cancel is clicked. #761TaxonomyPicker
: selectChildrenIfParentSelected
property added. Specifies if the children should be selected when parent item is selected (defaults to false). #765ListPicker
: ability to pick lists from specified site using webAbsoluteUrl
property.FilePicker
: buttonIconProps
to define properties of the button's icon #770DateTimePicker
: documentation fix #767PeoplePicker
: documentation fix - Changed isRequired property to new required #769IFramePanel
link on home page #775FilePicker
: updated onChaged
to onChange
#776Special thanks to our contributors (in alphabetical order): André Lage, Christian Metz, Gaurav Goyal, Leif Frederiksen, Ravichandran Krishnasamy, San, João Mendes.
+TaxonomyPicker
: Added useSessionStorage
property #759FilePicker
: documentation fix: '|' not escaped #756TaxonomyPicker
: Return TermSetId
for suggestions #762WebPartTitle
: Fluent UI Updates to SharePoint - WebPartTitle control too thin now #605ListView
: Sticky Header scrolling issue #734DateTimePicker
: hours dropdown not re-rendered when state changed programmatically #757RichText
: controlled mode doesn't work #666Special thanks to our contributors (in alphabetical order): Gautam Sheth, Marcin Wojciechowski, Nikolay Belykh, André Lage.
+RichText
: Add image support #705FilePicker
: Add file size to the Upload tab and IFilePickerResult
#706FieldCollectionData
: SearchBox
instead of TextBox
#719TaxonomyPicker
: control does not show an error message for an invalid/unresolved input #728FilePicker
: reduce bundle size #732FilePicker
: Custom render callbacks for the 'Upload' and 'Link' tabs #746ListItemPicker
: When use defaultSelectedItems, ListItemPicker allows you to select dublicate entries #722DateTimePicker
: time portion not re-rendered when state changed programmatically - when time is displayed as dropdown only #713PeoplePicker
: errorMessage
not being removed #730ListItemAttachment
: the control is not fully disabled #736TaxonomyPicker
: icons are not being rendered on Classic SharePoint pages #735FilePicker
: Site Tab does not load document if we access SharePoint site in different language than default language of the site #724TaxonomyPicker
: sessionStorage
exceeds max-size when browsing large termsets #739FolderExplorer
and FolderPicker
do not seem to work for document libraries #741FilePicker
: onChange
event does not exist despite being documented #747ListItemPicker
: Selected values are not getting cleared or reset #659Special thanks to our contributors (in alphabetical order): Abderahman Moujahid, avadhootdindorkar, Devang Bhavsar, Gautam Sheth, Konrad K., Nikolay Belykh, Vertamin.
+Carousel
: Ability to display indicators in a dedicated block #681FilePicker
: Org Assets are not displayed for non-admin users #687ListView
: Drag and Drop option #679FolderExplorerService
: support special characters if folder name #691ListView
: Sticky Header #634IconPicker
: get icons from @uifabric/icons/lib/data/AllIconNames.json
ListView
: Sticky header with className
instead of additional components #696ListView
: StickyHeader
code consistency #697TreeView
: Added (optional) property 'defaultExpandedChildren' that controls the behavior of the expansion of child elements.#698RichText
: Cannot add link in first line #672TaxonomyPicker
: Ability to reset the TaxonomyPicker (Remove all selected Terms) #367TaxonomyPicker
: the disabled
property is a boolean
and not a string
as currently specified #695ComboBoxListItemPicker
: update options when listId
has been changed #683FilePicker
: styles are updated to match OOB control #700Special thanks to our contributors (in alphabetical order): Abderahman88, André Lage, Gautam Sheth.
+FilePicker
: added additional properties - isPanelOpen
and onCancel
#668PeoplePicker
: Disabled doesn't work #484Pagination
: control not re-rendering when currentPage
is updated in state #663Special thanks to our contributor: Gautam Sheth.
+FilePicker
: Stock images option added #593TaxonomyPicker
: Add the 'required' property #216TaxonomyPicker
: Add errorMessage
and onGetErrorMessage
props #600ListItemPicker
: ability to use substring search instead of startswith #583Map
: return display name and address details for the location #585Map
: support for draggable and static Bing maps #586TaxonomyPicker
: onLoad validation #602FieldCollectionData
: Add pagining and filtering #617TaxonomyPicker
: Finding terms with labels #288FileTypeIcon
: Added support for additional file type in Image
mode #640ComboBoxListItemPicker
: fetching only 100 items #569TaxonomyPicker
: browse (tree view) doesn't work with SP 2016 On-Premises #183FilePicker
: default tab when opened shows hidden RecentTab #477PeoplePicker
: The required error message not showing #590ListItemAttachments
: fails in Microsoft Teams Tab SPFx applications #582Carousel
: Changing pages doesn't work #609TaxonomyPicker
: no suggestions are displayed if anchorId
is not setTaxonomyPicker
: Suggestion/match does not work as expected #604TaxonomyPicker
: Include check for separator while filtering path of terms when anchorId is configured #625FilePicker
: Bing API search issue #633ListView
: Sort fires selection #621Map
: A minor issue in componentWillUpdate method to get the next props rather than the current props.#641IFrameDialog
: dialog size is incorrect when opening the dialog second time #615FolderPicker
: imports don't work #614FilePicker
: Yor Organization tab is not shown #596FolderPicker
, FolderExplorer
: Controls don't let you explore sub folders if parent folder has apostrophe (') in its name.#644PeoplePicker
: image for a user picked in PeoplePicker didn't get resolved #646IconPicker
: renderOption
dialog
should be lowercased. #649Special 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.
+ListView
: Add clear button to filter text box #549FolderExplorer
: Add clear button to filter text box #553TreeView
: there should be possibility to collapse the first level nodes by default #561TreeView
: Expand to selected #559DateTimePicker
: When using the datetimePicker I would like to have an opportunity to set maximum/minimum date like in Office UI Fabric #497TaxonomyPicker
: Added the selectTerm
, hideTerm
, and disableTerm
actions #578TaxonomyPicker
: Added the functionality to enable/disable term actions on the fly #578Carousel
: indicators, slide animation, auto cycling, easier basic usage #587TaxonomyPicker
: Correct the AnchorID getting all TermSet search options #150TreeView
: Some tables in TreeView documentation are displayed as plain text. #562ComboBoxListItemPicker
, ListItemPicker
: Show error span if error is present #557TreeView
: defaultExpanded: true
doesn't work #560IListPicker
: typo fix #574DateTimePicker
: DateTime Picker noon/midnight issue with 12 hour format #576Special thanks to our contributors (in alphabetical order): Chad Eiserloh, Gautam Sheth, Koen Zomers, Markus Langer, Nanddeep Nachan, Prasad Kasireddy, David Ramalho, Siddharth Vaghasia.
+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 #534IconPicker
: renderOption
property to render icons list as a panel or dialog #537ComboBoxListItemPicker
documentation fix: Updated import statement in docs for ComboBoxListItemPicker #510ComboBoxListItemPicker
component to landing page #511FilePicker
: 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 #533ListItemAttachment
: when I upload a file that contains an hyphen, the "-" char is replaced by an empty string #526IconPicker
shows selected icon only during the first opening #513ComboBoxListItemPicker
: onSelectedItem
passing data to callback method but with attributes value as undefined
#519FilePicker
: filename is not visible on Upload tab #518IconPicker
: Search doesn't work at all #512ComboBoxListItemPicker
documentation fix: correct onSelectedItem
notation #547FieldUserRenderer
: displayName
in FieldUserHoverCard
is not updated if props
of the FIeldUserRenderer
have been changed #542Special 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.
+ComboBoxListItemPicker
component #292Localization
: Project now supports localization of all SharePoint Online languages (auto translation via Cognitive Services) #456IconPicker
: component #485FolderExplorer
component #499SecurityTrimmedControl
: Added the option to show a control when the user doesn't have permissions 307PnP Telemetry
service opt-out support #475TaxonomyPicker
: Possibility to hide deprecated and "Available for Tagging"= false terms #421FilePicker
- French translation #449TaxonomyPicker
: Placeholder for Taxonomy Picker #464ListItemPicker
, PeoplePicker
: Placeholder for ListItemPicker
and PeoplePicker
#486FilePicker
: Do not store active tab in url's hash #488DateTimePicker
: Placeholder property option added #503RichText
: problem with edit mode #445ListView
documentation: Typo - the first occurrence of maxWidth should be minWidth #400RichText
: Text indent buttons were copy-paste of subscript and superscript buttons. Clicking on the text-indent buttons would call subscript or superscript instead. #454RichText
: Fix of removing text and inserting link instead #455FilePicker
: Read file content in IE11 #444ListPicker
: listPicker always return "test" when multiple allowed #458FilePicker
: Button text overflow fix + global classnames and propertiesFieldUserRenderer
: implementation of api/SP.UserProfiles.PeopleManager/GetPropertiesFor
is not working on on-prem #468Placeholder
: Placeholder component is not rendering after a string change in it's properties #469ListView
documentation update: minWidth
instead of maxWidth
#480DateTimePicker
: Minutes and Seconds validation #495FilePicker
: bingAPIKey not working #489Special 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.
+FilePicker
: Fixes for OneDrive CORS issues #407ListItemPicker
: added new control property filter
#392Placeholder
: remove unused and vendor specific CSS #426FilePicker
: updated accepts
value in props #404FilePicker
control doesn't work in many languages due to missing localization keys #412DateTimePicker
: dropdown for time not handling AM/PM correctly #405index
page: updated link to Chart controls #417ListItemPicker
: valueColumnInternalName
should be keyColumnInternalName
RichText
: Fix "Align Left" button #429FilePicker
: misspelling #432IFramePanel
: Fix doubled scroll issue when iframe content is higher than frame height #431PeoplePicker
: errorMessage
not showing #420IFrameDialog
: commitPopUp
typo causes popups with classic forms to not close after hitting save #433Special 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.
+FilePicker
: New control added to the library #366GridLayout
: New control added to the library #350Carousel
: New control added to the library #227TaxonomyPicker
: Localization keys added to the buttons #361DateTimePicker
: added options to render time part as mask or dropdown #330ListItemPicker
: option to select a key column #350, #381RichText
: 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. #385TaxonomyPicker
: Tags icon styling issue on IE11 #356DateTimePicker
: Does not respect dateLabel and timeLabel #346PeoplePicker
: Get loginName with ensureUser #342PeoplePicker
: Fix missing required field label #371Special thanks to our contributors (in alphabetical order): amortsell, Hugo Bernier, Robert Lindström, pfc2k8, Piotr Siatka, Alex Terentiev, Luis Robertto Mello, eweintraub.
+SecurityTrimmedControl
: Added a wrapper className
property for the parent element #325ListPicker
: Add ability to filter the control via OData #319IFrameDialog
: closing dialog on commit #313WebPartTitle
add support for section background color #258ListPicker
: Fix for available dropdown selection after selection was done #315RichText
: Issue on rendering the control in view mode #287Special thanks to our contributors (in alphabetical order): Amr Fouad, Joel Jeffery, Mark Powney, Dominik Schmieder, Alex Terentiev, Zhephyr.
+Lithuanian
localization #285IFrameDialog
: dimensions issue #303DateTimePicker
: IE11 layout issue #301FileTypeIcon
: Only displays PDF's in SPFx 1.8.2
#300FieldNameRenderer
: Fails to encode URI when hasPreview
#296TaxonomyPicker
: Cannot find name `TermLabelAction #293ListItemAttachments
: Move deleted attachments to the recycle bin #291DateTimePicker
: Does not respect isMonthPickerVisible
prop #283ListItemAttachments
: Render issue fixed + improvements to the attachment API calls #282RichText
: Fixes an issue when hitting enter in the control #277Special thanks to our contributors (in alphabetical order): Tautvydas Duda, Thomas Granheim, Robert Lindström, Alex Terentiev.
+WebPartTitle
: Fix for className property which is not defined #281RichText
: Fix issue where control turns drop-downs black #279Special thanks to our contributor: Hugo Bernier.
+Progress
: New control added #230DateTimePicker
: New control added #21RichText
: New control added #20SecurityTrimmedControl
: Support for item and folder permission checks added #271Lithuanian
localization #247FileTypeIcon
: Added support for PDF icon file types #260WebPartTitle
: Added the ability to render a see all
link or custom component #228PeoplePicker
: Fix for single quotes around the ms-peoplepicker class #275RichText
: Fix for toolbar that appears at top of the page #265ListItemAttachments
: Updated import statement reference in the documentation #254ListView
: Updated documentation for the iconFieldName
property #245Special thanks to our contributors (in alphabetical order): Francis, Fredrik Andreasson, Hugo Bernier, Tautvydas Duda, Özgür Ersoy, Robert Lindström, Alex Terentiev.
+TaxonomyPicker
: Terms are sorted incorrectly under the wrong parent #199 #229TaxonomyPicker
: Issue with custom sort order of items underneath root terms #231PeoplePicker
: Fix for issue where values couldn't be cleared #234Special thanks to our contributors (in alphabetical order): Patrik Hellgren, João Mendes, David Opdendries, Piotr Siatka, Alex Terentiev, Tse Kit Yam.
+Map
: Newly introduced map control is available #14ChartControl
: Newly introduced control to render charts #15PeoplePicker
: Allow the people picker to search on site level and on tenant level #97ListView
: Added support for filtering #99PeoplePicker
: Make the titleText property not required #184Placeholder
: Added the ability to specify if the button can be hidden #206office-ui-fabric-react
to the same version as in SPFx 1.7.0IFrameDialog
: fix for spinner which keeps appearing on the iframe #154PeoplePicker
: fix SharePoint groups which could not be retrieved #161TaxonomyPicker
: fix sort order with lowercased terms #205Special thanks to our contributors (in alphabetical order): Hugo Bernier, joaojmendes, Asish Padhy, Piotr Siatka, Anoop Tatti, Alex Terentiev, Tse Kit Yam.
+ListItemPicker
: New field control #165PeoplePicker
: Move defaultSelectedUsers from ComponentWillMount to ComponentDidUpdate Lifecycle #135PeoplePicker
: Initialize with users from a list item #138PeoplePicker
: Remove Messagebar error handling to match Office UI Fabric field error styling #140PeoplePicker
: REST API filter and nometadata header added to reduce payload #139PeoplePicker
: Allow to set the maximum number of suggestions suggestionsLimit
#143 #148TaxonomyPicker
: retreiving the terms in the correct custom sort order #146PeoplePicker
: Documentation format updated to make it easier to check the default values #159Special 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.
+FieldLookupRenderer
: Lookup dialog is empty #131IFrameDialog
: Unnecessary horizontal scroll in IFrame dialog #132PeoplePicker
: Suggested People not loading after first selection #134Special thanks to our contributors (in alphabetical order): Gautam Sheth, Alex Terentiev.
+PeoplePicker
: Specify to hide or show the users/groups which are hidden in the UI #122WebPartTitle
: changing font-sizes on different resolutions #114WebPartTitle
: Added accessibility tags for web part title #121ListView
: Resizable columns - introduced a isResizable
property #119FieldNameRenderer
double click support added #116TaxonomyPicker
: table markup changed to DIV #113PeoplePicker
: ability to specify the source site to load users from #110TaxonomyPicker
: Disable the terms which are set as deprecated or unavailable for tagging #109PeoplePicker
: Specify principle type to retrieve (users, groups, ...) #94FieldLookupRenderer
: Fixed URL querystring params #126IFrameDialog
: dialog width is not correct in IE11 #118PeoplePicker
: fix freezes when typing in search values #117Special thanks to our contributors (in alphabetical order): Thomas Lamb, Joel Rodrigues, Mikael Svenson, Alex Terentiev.
+PeoplePicker
: added functionality to initialize the control with person(s) or group(s) #98PeoplePicker
: support for searching on contains #93PeoplePicker
: find user based on email address #95FieldNameRenderer
onClick does not suppress default link behavior #103Special thanks to our contributors (in alphabetical order): Octavie van Haaften, Asish Padhy, Mikael Svenson, Alex Terentiev.
+Special thanks to our contributor: Octavie van Haaften.
+PeoplePicker
control added #19TaxonomyPicker
to specify which terms are disabled/not-selectable #82TaxonomyPicker
where values are not updated by an async change #83FieldUserRenderer
uses email prop for GetPropertiesFor
#84ListView
when user clicked on the group header #86Special thanks to our contributors (in alphabetical order): Asish Padhy, Alex Terentiev.
+SecurityTrimmedControl
control got added #74TaxonomyPicker
to also be used in Application Customizer #77npm postinstall
script to automatically add the locale config #78Placeholder
control #76selection
property was not provided to the ListView
#65ListView
item selection after items array updates #55WebPartTitle
hide control completely when emptyListView
control while items were selected. Indexes were not updated.FieldTaxonomyRenderer
got fixed to support single and multiple valuesIFrameDialog
was added to the projectWebPartTitle
controlFileTypeIcon
icon fixed where it did not render an icon. This control should now works in SPFx extensions.WebPartTitle
control to inherit colorWebPartTitle
control got addedListView
control when selection is used in combination with setState
.ListView
controlAll 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
+
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.
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.
+ + + + + + + + + + +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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.Accordion
control as follows:import {
+ Accordion,
+ AccordionItem,
+ AccordionItemHeading,
+ AccordionItemButton,
+ AccordionItemPanel,
+} from "@pnp/spfx-controls-react/lib/AccessibleAccordion";
+
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>
+}
+
The Accordion
control can be configured with the following properties:
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. | ++ |
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 | ++ |
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 <h1> tag, and likewise a value of 6 would make it equivalent to an <h6> tag. |
+3 |
+
Property | +Type | +Required | +Description | +Default | +
---|---|---|---|---|
className | +string | +no | +Class(es) to apply to the 'button' element. | +"accordion__button" | +
Property | +Type | +Required | +Description | +Default | +
---|---|---|---|---|
className | +string | +no | +Class(es) to apply to element. | +"accordion__panel" | +
Property | +Type | +Required | +Description | +Default | +
---|---|---|---|---|
children | +({ expanded: boolean, disabled: booleam }): JSX.Element | +yes | +item's children. | ++ |
resetNextUuid : () => void
+
Resets the internal counter for Accordion items' identifiers (including id
+attributes). For use in test suites and isomorphic frameworks.
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.Accordion
control as follows:import { Accordion } from "@pnp/spfx-controls-react/lib/Accordion";
+
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>
+ ))
+}
+
Accordion
control with custom icons:{
+ <Accordion title={item.Question} defaultCollapsed={true} className={"itemCell"} key={index} collapsedIcon={"Rocket"} expandedIcon={"InkingTool"}>
+}
+
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 | +
This control allows you to embed the official Adaptive Cards designer inside a React SPFx solution.
+The control consists of 2 components:
+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:
+ +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";
+
AdaptiveCardDesignerHost
control with only required properties:<AdaptiveCardDesignerHost
+ headerText="Adaptive Card Designer"
+ buttonText="Open the Designer"
+ context={props.context}
+ onSave={(payload: object) => setCard(payload)}
+/>
+
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}
+/>
+
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 | +- | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.AdaptiveCardHost
control as follows:import { AdaptiveCardHost, IAdaptiveCardHostActionResult, AdaptiveCardHostThemeType, Action, CardElement, CardObjectRegistry, HostCapabilities } from "@pnp/spfx-controls-react/lib/AdaptiveCardHost";
+
AdaptiveCardHost
control with only required properties:<AdaptiveCardHost
+ card={card}
+ onInvokeAction={(action) => alert(JSON.stringify(action))}
+ onError={(error) => alert(error.message)}
+ context={this.props.context}
+/>
+
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}
+/>
+
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}
+/>
+
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}
+/>
+
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}
+/>
+
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}
+/>
+
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}
+/>
+
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 |
+no | +Invoked to manage Elements to the current Adaptive Card instance. | +
onSetCustomActions | +(registry: CardObjectRegistry |
+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 | +
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 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
.
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.AnimatedDialog
control as follows:import { AnimatedDialog } from "@pnp/spfx-controls-react/lib/AnimatedDialog";
+
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>
+
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>
+
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>
+
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>
+
$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;
+ }
+ }
+}
+
In addition to theOffice 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. |
++ |
A slideshow component for cycling through elements—images or slides of text—like a carousel.
+Here is an example of the control in action:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { Carousel } from "@pnp/spfx-controls-react/lib/Carousel";
+
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}`); }}
+/>
+
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<HTMLElement> | React.TouchEvent<HTMLElement>, 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 | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ChartControl, ChartType } from '@pnp/spfx-controls-react/lib/ChartControl';
+
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]
+ }]
+ }} />
+
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:
+ +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.
+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>}
+/>
+
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>}
+/>
+
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.
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:
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.
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
+ }
+ }]
+ }
+ }} />
+
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. | +
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 | +
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. | +
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 | ++ |
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. | +
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:
+ + + + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ComboBoxListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
+
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} />
+
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} />
+
<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} />
+
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);
+}
+
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 | +
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ContentTypePicker } from "@pnp/spfx-controls-react/lib/ContentTypePicker";
+
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}
+/>
+
onSelectionChanged
change event returns the content type(s) and can be implemented as follows:private onContentTypePickerChanged (contentTypes: ISPContentType | ISPContentType[]) {
+ console.log("Content types:", contentTypes);
+}
+
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 | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { WidgetSize, Dashboard } from '@pnp/spfx-controls-react/lib/Dashboard';
+
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,
+ }]} />
+
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. | +
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
+
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { DateTimePicker, DateConvention, TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker';
+
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} />
+
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;
+
This control allows to drag and drop files in pre defined areas.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { DragDropFiles } from "@pnp/spfx-controls-react/lib/DragDropFiles";
+
<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>
+
ListView with drag and drop applied
+ +FilePicker with drag and drop applied
+ +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);
+ }
+ }
+
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. | +
This control can dynamically generate SharePoint list or SharePoint document library form and everything controlled through list setting.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { DynamicForm } from "@pnp/spfx-controls-react/lib/DynamicForm";
+
<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>
+
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.
+ +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<void> | +no | +List item loaded handler. Allows to access list item information after it's loaded. | +
onBeforeSubmit | +(listItemData: any) => Promise<boolean> | +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\<IDynamicFieldProps>}} | +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. | +
IValidationErrorDialogProps
¶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 | +
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
.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:
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):
+
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.EnhancedThemeProvider
control as follows:import { EnhancedThemeProvider, getDefaultTheme, useTheme, ThemeContext } from "@pnp/spfx-controls-react/lib/EnhancedThemeProvider";
+
EnhancedThemeProvider
control with only required properties:<EnhancedThemeProvider context={this.props.context}>
+ {/* controls to apply the theme to */}
+</EnhancedThemeProvider>
+
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.
+export const ChildFunctionComponent = () => {
+ const theme = useTheme();
+
+ return (
+ <DefaultButton theme={theme}>Example Child Control</DefaultButton>
+ );
+}
+
export class ChildClassComponent extends React.Component {
+ public render() {
+ return (
+ <ThemeContext.Consumer>
+ {theme =>
+ <DefaultButton theme={theme}>Example Child Control</DefaultButton>
+ }
+ </ThemeContext.Consumer>
+ )
+ }
+};
+
<EnhancedThemeProvider applyTo="element" context={this.props.context} theme={this.props.themeVariant}>
+ <ChildFunctionComponent />
+ <ChildClassComponent />
+</EnhancedThemeProvider>
+
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. | +
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
+ }
+]
+
@pnp/spfx-controls-react
dependency. Check out The getting started page for more information about installing the dependency.import { FieldCollectionData, CustomCollectionFieldType } from '@pnp/spfx-controls-react/lib/FieldCollectionData';
+
<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
+ }
+ ]}
+/>
+
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);
+ }}), " 🎉"
+ )
+ );
+ }
+}
+
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. |
+
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldPicker } from "@pnp/spfx-controls-react/lib/FieldPicker";
+
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}
+/>
+
onSelectionChanged
change event returns the field(s) and can be implemented as follows:private onFieldPickerChanged (fields: ISPField | ISPField[]) {
+ console.log("Fields:", fields);
+}
+
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 | +
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.
+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 support 3 types of views : List, Compact list and Tiles. In case Tiles view is selected, the control shows the thumbnail of the file. +
+The control displays breadcrumb navigation that allows to easily switch folders or document libraries. +
+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. +
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FilePicker, IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker';
+
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}
+/>
+
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);
+ }
+ }
+ }
+
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. | +
This control returns the file type icon based on a specified file path or application.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FileTypeIcon, ApplicationType, IconType, ImageSize } from "@pnp/spfx-controls-react/lib/FileTypeIcon";
+
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} />
+
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<HTMLElement> | +no | +Event triggered when the icon is clicked. | +
onDoubleClick | +React.MouseEvent<HTMLElement> | +no | +Event triggered when the icon is double clicked. | +
onMouseEnter | +React.MouseEvent<HTMLElement> | +no | +Event triggered when the mouse cursor enters the icon (without event bubbling). | +
onMouseLeave | +React.MouseEvent<HTMLElement> | +no | +Event triggered when the mouse cursor leaves the icon. | +
onMouseOver | +React.MouseEvent<HTMLElement> | +no | +Event triggered when the mouse cursor enters the icon (with event bubbling). | +
onMouseUp | +React.MouseEvent<HTMLElement> | +no | +Event triggered when the mouse button is released after clicked on the icon. | +
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FolderExplorer, IFolder } from "@pnp/spfx-controls-react/lib/FolderExplorer";
+
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} />
+
onSelect
change event returns the selected folder and can be implemented as follows:private _onFolderSelect = (folder: IFolder): void => {
+ console.log('selected folder', folder);
+}
+
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 | +
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FolderPicker, IFolder } from "@pnp/spfx-controls-react/lib/FolderPicker";
+
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} />
+
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"/>
+
onSelect
change event returns the selected folder and can be implemented as follows:private _onFolderSelect = (folder: IFolder): void => {
+ console.log('selected folder', folder);
+}
+
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} />
+
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. | +
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.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { GridLayout } from "@pnp/spfx-controls-react/lib/GridLayout";
+
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"
+ }]
+ };
+ }
+
thumbnail
, title
, name
, profileImageSrc
, location
and activity
to coincide with the Fabric UI DocumentCard
elements, but you can use any properties you need.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 removeDocumentCard
elements and to render a compact layout. You may choose to ignore theisCompact
parameter if you do not wish to handle compact layouts.
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)}
+ />
+
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 | +
This control allows you to select an emoji from emoji bar or select from picker.
+HoverReactionsBar
+ + + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { HoverReactionsBar } from '@pnp/spfx-controls-react/lib/HoverReactionsBar';
+
HoverReactionsBar
control in your code as follows:<HoverReactionsBar
+ isOpen={isOpenHoverReactionBar}
+ onSelect={onSelectEmoji}
+ onDismiss={(): void => {
+ setIsOpenHoverReactionBar(false);
+ }}
+ target={divRefAddReaction.current as HTMLDivElement}
+/>
+
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 ;
+
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 | +
This control renders a Dialog with an iframe as content.
+Here is an example of the control in action:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { IFrameDialog } from "@pnp/spfx-controls-react/lib/IFrameDialog";
+
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'}/>
+
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 |
+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) | +
This control renders a Panel with an iframe as content.
+Here is an example of the control in action:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.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)} />
+
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) | +
Control that allows to search and select an icon from office-ui-fabric-react icons.
+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 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 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. +
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker';
+
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}); }} />
+
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. |
+
This control allows you to select or Upload Image from SharePoint, Ondrive or Stock Images.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ImagePicker } from '@pnp/spfx-controls-react/lib/ImagePicker';
+
ImagePicker
control in your code as follows: <ImagePicker
+ onFileSelected={handleFileSelected}
+ onDeleteFile={handleDeleteFile}
+ selectedFileUrl={selectedImageUrl}
+ context={appContext}
+ >
+
onFileSelect
property you can get the selected image:typescript
+ const handleFileSelected = React.useCallback(async (file: IFilePickerResult) => {
+ console.log("file", file);
+ }, []);
onDelete
property you can execute a callback after delete the image:const onDeleteFile = React.useCallback(async () => {
+ console.log("onDeleteFile");
+}, []);
+
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 | +
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:
+ + + + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttachments';
+
ListItemAttachments
control in your code as follows:<ListItemAttachments listId='dfa283f4-5faf-4d54-b6b8-5bcaf2725af5'
+ itemId={1}
+ context={this.props.context}
+ disabled={false} />
+
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);
+ }} />
+
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. |
+
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:
+ + + + + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ListItemComments } from '@pnp/spfx-controls-react/lib/ListItemComments';
+
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.
+ +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). +
+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 | +
This control requires at least the flowing scopes: People.Read
, User.ReadBasic.All
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:
+ + + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
+
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} />
+
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}`);
+ }
+}
+
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 | +
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
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ListPicker } from "@pnp/spfx-controls-react/lib/ListPicker";
+
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} />
+
onSelectionChanged
change event returns the list(s) and can be implemented as follows:private onListPickerChange (lists: string | string[]) {
+ console.log("Lists:", lists);
+}
+
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 | +
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`);
+ }
+}
+
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 will look like the following:
+ +Once you click on an action, you will see the alert:
+ + + + + + + + + + + +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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
+
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);
+}
+
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.
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);
+ }
+ }
+
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. | +
This control allows you to use LivePersona Card available on SharePoint Online.
+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
+Here is an example of the control:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { LivePersona } from "@pnp/spfx-controls-react/lib/LivePersona";
+
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}
+/>
+
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. | +
This control allows you to search and select the Location, also allows enter a custom location.
+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";
+
<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 | +
---|
+ |
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. | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.Map
control as follows:import { Map, ICoordinates, MapType } from "@pnp/spfx-controls-react/lib/Map";
+
Map
control in your code as follows:<Map titleText="New of London"
+ coordinates={{ latitude: 51.507351, longitude: -0.127758 }}
+ enableSearch={true} />
+
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 | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ModernAudio, ModernAudioLabelPosition } from "@pnp/spfx-controls-react/lib/ModernAudio";
+
ModernAudio
control in your code as follows:<ModernAudio
+ audioUrl='https://www.winhistory.de/more/winstart/mp3/vista.mp3'
+ label="Audio Control"
+ labelPosition={ModernAudioLabelPosition.TopCenter} />
+
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 | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ModernTaxonomyPicker } from "@pnp/spfx-controls-react/lib/ModernTaxonomyPicker";
+
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}
+/>
+
onChange
property you can capture the event of when the terms in the picker has changed:private onTaxPickerChange(terms : ITermInfo[]) {
+ console.log("Terms", terms);
+}
+
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}}
+ />
+ );
+ }
+ }}
+/>
+
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. | +
You can also use the TaxonomyTree
control separately to just render a stand-alone tree-view of a term set with action buttons.
TaxonomyTree
control in your code as follows: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
+ );
+}
+
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { MonacoEditor } from "@pnp/spfx-controls-react/lib/MonacoEditor";
+
MonacoEditor
control in your code as follows: <MonacoEditor value={defaultValue}
+ showMiniMap={true}
+ onValueChange={onValueChange}
+ language={"javascript"}/>
+
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);} , []);
+
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 | +
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:
+ + + +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.
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { MyTeams } from "@pnp/spfx-controls-react/lib/MyTeams";
+
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}
+ />
+
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);
+ };
+
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 | +
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
+ + + + + + + + + +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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
+
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
+/>
+
onChange
property you can get the selected Page in the Pagination component:private _getPage(page: number){
+ console.log('Page:', page);
+}
+
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 | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { IPeoplePickerContext, PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
+
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} />
+
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.
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<string> | +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:
When it returns Promise<string>:
|
++ |
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<IBasePickerStyles> | +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. | +
This control requires at least one the following scopes if groupId
is of type string
:
This control renders a placeholder which can be used to show a message that the web part still has to be configured.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
+
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} />
+
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} />
+
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 />
+}
+
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. | +
This control shows progress of multiple SEQUENTIALLY executed actions.
+Here is an example of the control in action:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { Progress } from "@pnp/spfx-controls-react/lib/Progress";
+
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();
+ }
+ }
+ }
+}
+
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. | +
This control shows a progress of steps.
+Here is an example of the control in action:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.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" },
+];
+
ProgressStepsIndicator
control in your code as follows:{
+ <ProgressStepsIndicator steps={progressSteps} currentStep={0} themeVariant={props.themeVariant} />
+}
+
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;
+}
+
This control provides rich text editing and display capability.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { RichText } from "@pnp/spfx-controls-react/lib/RichText";
+
RichText
control in your code is as follows:<RichText value={this.props.value}
+ onChange={(text)=>this.onTextChange(text)}
+/>
+
value
property should contain the HTML that you wish to displayonChange
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;
+}
+
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>;
+}
+
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
tofalse
does not remove the user's ability to apply the button's associated formatting -- it only hides the toolbar option. Also, ifshowMore
istrue
, all options remain available in the formatting pane -- regardless whether they were turned off usingshow___
. To prevent users from applying specific formats, use theonChange
handler to parse the rich text and remove the formatting as desired.
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.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { SecurityTrimmedControl, PermissionLevel } from "@pnp/spfx-controls-react/lib/SecurityTrimmedControl";
+import { SPPermission } from '@microsoft/sp-page-context';
+
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>
+
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 |
+
This control returns a breadcrumb based on the current location.
++
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { SiteBreadcrumb } from "@pnp/spfx-controls-react/lib/SiteBreadcrumb";
+
SiteBreadcrumb
control in your code as follows:<SiteBreadcrumb context={this.props.context} />
+
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. | +
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
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { SitePicker } from "@pnp/spfx-controls-react/lib/SitePicker";
+
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'} />
+
onChange
change event returns the selected site(s).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. | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";
+
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} />
+
onChange
property you can capture the event of when the terms in the picker has changed:private onTaxPickerChange(terms : IPickerTerms) {
+ console.log("Terms", terms);
+}
+
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 );
+ }
+ };
+
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")]
+ }} />
+
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<string> | +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:
When it returns Promise<string>:
|
+
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\<void> | +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> | 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\<UpdateAction> | +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 | +
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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { TeamChannelPicker } from "@pnp/spfx-controls-react/lib/TeamChannelPicker";
+
TeamChannelPicker
control in your code as follows:<TeamChannelPicker label="Select Team channel"
+ teamId={teamId}
+ selectedChannels={selectedTeamChannels}
+ appcontext={webpartContext}
+ itemLimit={1}
+ onSelectedChannels={_onSelectedTeamChannels}/>
+
_onSelectedTeamChannels
change event returns the team channel(s) and can be implemented as follows:const _onSelectedTeamChannels ((tagList: ITag[]) => {
+ console.log(tagList);
+ }
+
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 | +
This control required the flowing scopes :
+at least : Team.ReadBasic.All, Channel.ReadBasic.All,
+ + + + + + + + + +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:
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { SelectTeamPicker } from "@pnp/spfx-controls-react/lib/TeamPicker";
+
SelectTeamPicker
control in your code as follows:<TeamPicker label="Select Team"
+ selectedTeams={selectedTeams}
+ appcontext={webpartContext}
+ itemLimit={1}
+ onSelectedTeams={_onSelectedTeams}/>
+
_onSelectedTeams
change event returns the team(s) and can be implemented as follows:const _onSelectedTeams ((tagList: ITag[]) => {
+ console.log(tagList);
+ }
+
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,
+ + + + + + + + + +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
+ + +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { TermSetNavigation } from '@pnp/spfx-controls-react/lib/TermSetNavigation';
+
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}
+ />
+
onSelected
property you can get the selcted term: const onSelect = React.useCallback((selected: TermStore.Term) => {
+ console.log(selected);
+ }, []);
+
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);
+ }, []);
+
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.
+ + + + + + + + + + +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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { Toolbar } from '@pnp/spfx-controls-react/lib/Toolbar';
+
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} />
+
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.
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<ToolbarItemProps> | +no | +Action onClick handler. |
+
Type TFilters
Provides Toolbar filters settings
+type TFilters = ObjectShorthandCollection<TreeItemProps, never>;
+
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { TreeView, ITreeItem, TreeViewSelectionMode } from "@pnp/spfx-controls-react/lib/TreeView";
+
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} />
+
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);
+}
+
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);
+}
+
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>
+ );
+}
+
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 | +
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' };
+
This control allows to drag and drop files and manage files before upload.
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import {
+ UploadFiles,
+} from '@pnp/spfx-controls-react/lib/UploadFiles';
+
<UploadFiles
+ pageSize={20}
+ context={context}
+ title="Upload Files"
+ onUploadFiles={(files) => {
+ console.log("files", files);
+ }}
+ themeVariant={themeVariant}
+ />
+
+ +
+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 | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { UserPicker } from '@pnp/spfx-controls-react/lib/userPicker';
+import { IUserInfo } from '@pnp/spfx-controls-react/lib/userPicker/models/IUserInfo';
+
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}
+/>
+
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);
+}, []);
+
onRemoveSelectedUser
property you can capture the event, when the user is removed from picker.const onRemovedUser = React.useCallback((user: IUserInfo) => {
+ console.log(user);
+}, []);
+
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 | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.VariantThemeProvider
control as follows:import { VariantThemeProvider, VariantType, IThemeColors } from "@pnp/spfx-controls-react/lib/VariantThemeProvider";
+
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>
+
VariantThemeProvider
control with the 'Strong' variant on theme passed with the from the 'theme' property:<VariantThemeProvider
+ theme={theme}
+ variantType={VariantType.Strong}>
+ {/* Child controls */}
+</VariantThemeProvider>
+
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. | +
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:
+
@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { ViewPicker } from "@pnp/spfx-controls-react/lib/ViewPicker";
+
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} />
+
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);
+ }
+
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 | +
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:
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.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;
+ }
+ }
+);
+
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;
+}
+
WebPartTitle
control as follows:import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
+
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:
+ +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. | +
Bar charts represent data values as vertical bars.
+ +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:
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.string
): every data element in the dataset will use the same color.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
+ }
+ ]
+ };
+
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.
+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. | +
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.
+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.
+
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 on what options are available with Bar charts, refer to the Bar Chart documentation on Chart.js.
+ + + + + + + + + + +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.
+ +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}
+ />);
+
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 . |
+
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
andy
, ther
value is measured in pixels and does not scale with the chart.
For more information on what options are available with Bubble charts, refer to the Bubble Chart documentation on Chart.js.
+ + + + + + + + + + +Doughnut charts are divided into segments, each of which shows the proportional value of the data.
+ +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}
+ />);
+
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. | +
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 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 on what options are available with Doughnut charts, refer to the Doughnut and Pie documentation on Chart.js.
+ + + + + + + + + + +Line charts represent data values as plotted points on a line.
+ +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}
+ />);
+
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}
+ />);
+
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:
+ +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
)
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. |
+
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.
+You can also provide data elements with x
and y
coordinates:
data: [{
+ x: 10,
+ y: 20
+}, {
+ x: 15,
+ y: 10
+}]
+
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. | +
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 on what options are available with Line charts, refer to the Line Chart documentation on Chart.js.
+ + + + + + + + + + +Pie charts are divided into segments, each of which shows the proportional value of the data.
+ +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}
+ />);
+
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"
+ }
+ };
+
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:
+ +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. | +
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 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 on what options are available with Pie charts, refer to the Doughtnut and Pie documentation on Chart.js.
+ + + + + + + + + + +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.
+ +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}
+ />);
+
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. | +
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 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 on what options are available with Polar Area charts, refer to the Polar Area documentation on Chart.js.
+ + + + + + + + + + +Radar charts are best used when comparing points of two or more datasets.
+ +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}
+ />);
+
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. | +
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 on what options are available with Radar charts, refer to the Radar documentation on Chart.js.
+ + + + + + + + + + +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.
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}
+ />);
+
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. |
+
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 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 on what options are available with Scatter charts, refer to the Scatter documentation on Chart.js.
+ + + + + + + + + + +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
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldAttachmentsRenderer } from "@pnp/spfx-controls-react/lib/FieldAttachmentsRenderer";
+
FieldAttachmentsRenderer
control in your code as follows:<FieldAttachmentsRenderer count={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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 | +
This control renders date string as a simple text.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldDateRenderer } from "@pnp/spfx-controls-react/lib/FieldDateRenderer";
+
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.
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 | +
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldFileTypeRenderer } from "@pnp/spfx-controls-react/lib/FieldFileTypeRenderer";
+
FieldFileTypeRenderer
control in your code as follows:<FieldFileTypeRenderer path={fileLeafRef} isFolder={false} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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 | +
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
++
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldLookupRenderer } from "@pnp/spfx-controls-react/lib/FieldLookupRenderer";
+
FieldLookupRenderer
control in your code as follows:<FieldLookupRenderer lookups={event.fieldValue} fieldId={'<field-guid>'} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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 | ++ |
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
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldNameRenderer } from "@pnp/spfx-controls-react/lib/FieldNameRenderer";
+
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' }} />
+
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 |
+
FieldRendererHelper class is used to automatically apply needed Field Control based on current Field parameters.
+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";
+
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
+ });
+ });
+ }
+
fieldRenderer
:public render(): React.ReactElement<{}> {
+ return (
+ <div className={styles.cell}>
+ {this.state.fieldRenderer}
+ </div>
+ );
+ }
+
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 | +
This control renders terms from Managed Metadata field.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldTaxonomyRenderer } from "@pnp/spfx-controls-react/lib/FieldTaxonomyRenderer";
+
FieldTaxonomyRenderer
control in your code as follows:<FieldTaxonomyRenderer terms={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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. | +
This control renders simple text.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldTextRenderer } from "@pnp/spfx-controls-react/lib/FieldTextRenderer";
+
FieldTextRenderer
control in your code as follows:<FieldTextRenderer text={event.fieldValue} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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 | +
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.
+ +@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldTitleRenderer } from "@pnp/spfx-controls-react/lib/FieldTitleRenderer";
+
FieldTitleRenderer
control in your code as follows:<FieldTitleRenderer text={'Technical Requirements'} isLink={true} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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. | +
This control renders Hyperlink or Picture field value as a link or image.
++
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldUrlRenderer } from "@pnp/spfx-controls-react/lib/FieldUrlRenderer";
+
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' }} />
+
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. | +
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
+@pnp/spfx-controls-react
dependency. Check out the getting started page for more information about installing the dependency.import { FieldUserRenderer } from "@pnp/spfx-controls-react/lib/FieldUserRenderer";
+
FieldUserRenderer
control in your code as follows:<FieldUserRenderer users={event.fieldValue} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
+
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. | +
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
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 class is a recommended way to use Field Controls as it provides additional functionality to automatically render the content for any type of fields.
+The following Field Controls are currently available:
+count
property is defined and greater than 0)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!
+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.
+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.
+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.
+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.
+Before contributing:
+# 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
+
git checkout -b my-contribution
+
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.
+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 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.
+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.
isRequired
is renamed to required
errorMessage
represents a static error message to be displayed in the control. errorMessage
is used to provide the text that will be displayed if the field is set as required
and no value is selected./**
+ * 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 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.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';
The shortest way to prepare your local copy of the project for development and testing.
+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.
+npm install
to restore dependenciesnpm 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
)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.
+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.
+This extension is called TestApplicationCustomizer. To test it, go to the following URL (after updating the parameters):
+ +To update the host component, open the TestApp React component located in the following project's relative path: src\extensions\testApp\TestApp.tsx.
+This extension is called TestForm. To test it, you have to configure it first:
+rootFolder
property (under serveConfigurations
==> default
==> formCustomizer
), which contains a server relative URL, to target the list on which you want to test the extensionThen go to the following URL (after updating the parameters):
+ +To update the host component, open the TestForm React component located in the following project's relative path: src\extensions\testForm\components\TestForm.tsx.
+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:
+cd ./docs/documentation
to change directory to where the manual pages are storedmkdocs serve
to start the local web server with MkDocs and view the documentation in the web browserWe 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
+
package.json
. We'll do that for you when merging your changes.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.
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.
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
+
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"
+
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();
+
The following controls are currently available:
+AccessibleAccordion
-based implementation)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.
+count
property is defined and greater than 0)