![The web part in action](./assets/ComparerWebPart.gif)
## Summary
Allows users to compare Before and After pictures, with a draggable slider. Implements a custom file picker.
## Background
The Microsoft UI Fabric team (formerly Office UI Fabric) recently released a [web site](https://fluentfabric.azurewebsites.net/#/components) that allows you to compare the current version of the Office UI Fabric components side by side with their upcoming Fluent versions, using a cool image slider.
![Microsoft Ui Fabric slider in action](./assets/FluentSlider.gif)
I wanted to re-create a version of the slider that would allow a user to compare two images, side by side.
Re-creating the slider was pretty easy (they use [react-draggable](https://github.com/mzabriskie/react-draggable) to handle dragging); I wanted to make it possible for users to select the
Before and After pictures to use the SharePoint File Picker dialog.
After a lot of digging around, I decided to re-create my own.
After all, one of the premises of SPFx is that SPFx gives us -- the SharePoint developer community -- a framework to build the same web parts that Microsoft's own developers do. Right?
This sample re-creates the SharePoint file picker (or, more accurately, the SharePoint image picker) that is used by out-of-the-box web parts such as the Image and Hero web parts. My goal was to create something that would be re-usable,
and would be as close as possible from the out-of-the-box picker. In fact, as I was testing the app, I found myself testing the out-of-the-box picker when I thought I was testing my own file picker.
After building this sample, I can confirm that it _is_ possible to build web parts that look and feel like the out-of-the-box web parts using SPFx.
| Every SPFx version is only compatible with specific version(s) of Node.js. In order to be able to build this sample, please ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg)
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
* Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-comparer) then unzip it)
* In the web browser navigate to the hosted version of the SharePoint workbench located in the same site as where the Tasks list is, eg. *https://contoso.sharepoint.com/sites/team/_layouts/15/workbench.aspx*.
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit https://aka.ms/spfx-devcontainer for further instructions.
The sample `PropertyPanelFilePicker` is designed to mimic the standard SharePoint file picker dialog. As such, it includes a **Web search** which uses Bing to return search results.
![Web search with a Bing API key](./assets/WebSearch.gif)
However, the feature requires a Bing API key in order to work. If you do not have a Bing API key, the `PropertyPanelFilePicker` will display a message indicating that the Bing API key is missing.
![Web search without a Bing API key](./assets/WebSearchNoAPI.png)
### To Configure a Bing API key (Optional)
This sample uses **SharePoint Online Tenant Properties** to store the API key. The idea is that if you get an
API key for your organization to use, you want to store it in one place -- the **Tenant Properties** -- instead of having to re-enter the API key
in every web part that needs it.
To configure your API key, use the following steps:
1. If you don't already have a Bing Web Search API key, go to the [Bing Web Search](https://azure.microsoft.com/en-us/services/cognitive-services/bing-web-search-api/) API page and request a key.
2. To set the API key, you'll need to use the **Office 365 CLI**. If you haven't installed it yet, you can get it [from here](https://pnp.github.io/office365-cli/?utm_campaign=Use+SharePoint+Online+tenant+properties&utm_medium=page&utm_source=msft_docs).
3. Using **Office 365 CLI**, enter the following command, making sure to change **value** with your actual Bing API key, and **appCatalogUrl** with your tenant's app catalog (e.g.: https://contoso.sharepoint.com/sites/apps).
```PowerShell
spo storageentity set --appCatalogUrl <appCatalogUrl> --key BingApi --value <value>
```
4. If you want to verify that your API key is stored, use the following command to list all your tenant properties:
```PowerShell
spo storageentity list --appCatalogUrl <appCatalogUrl>
```
If all goes well, you should see an entry called **BingApi** containing your Bing API key.
### To hide the Web search tab
If you want to use this web part without the **Web search** tab, you can simply disable it from the code. To do so, use the following steps:
1. In the solution, open the **ComparerWebPart.ts** file.
2. Look for a line at the top of the file that looks like this:
```TypeScript
const DISABLE_WEB_SEARCH_TAB: boolean = false;
```
3. Change the `false` to `true`
4. Save and rebuild/redeploy the web part.
This constant will be applied to both `PropertyPaneFilePicker` controls used in the web part.
You can also simply set each `PropertyPaneFilePicker`'s `disableWebSearchTab` property to `true`.
## Features
* Using Tenant property
* Using of Office UI Fabric React Selection control
* Using of Office UI Fabric React Selection control
* Making CORS calls within an SPFx component
### Resources
* [Fluent for Fabric](https://fluentfabric.azurewebsites.net/#/components)
* [Build custom controls for the property pane](https://learn.microsoft.com/sharepoint/dev/spfx/web-parts/guidance/build-custom-property-pane-controls)
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**