+
+
+ {
+ (!this.props.list) ?
+
+ :
+ this.state.hasError ?
+
+ {this.state.errorMessage}
+
+ :
+ this.state.isLoading ?
+
+ :
+ this.state.carouselImages.length == 0 ?
+
+
+
+
+ :
+
+
+
+ {
+ if (!this.state.loadingImage)
+ $(".slideLoading").removeClass("slideLoading");
+ }}>
+ {
+ this.state.carouselImages
+ }
+
+
+ {
+ this.state.loadingImage &&
+
+ }
+
+ }
+
+ );
+ }
+}
diff --git a/samples/react-carousel/src/webparts/carousel/components/ICarouselProps.ts b/samples/react-carousel/src/webparts/carousel/components/ICarouselProps.ts
new file mode 100644
index 000000000..76ea9458e
--- /dev/null
+++ b/samples/react-carousel/src/webparts/carousel/components/ICarouselProps.ts
@@ -0,0 +1,11 @@
+import { WebPartContext } from "@microsoft/sp-webpart-base";
+import { DisplayMode } from '@microsoft/sp-core-library';
+export interface ICarouselProps {
+ title: string;
+ siteUrl: string;
+ list: string;
+ context: WebPartContext;
+ numberImages: number;
+ updateProperty: (value: string) => void;
+ displayMode: DisplayMode;
+}
diff --git a/samples/react-carousel/src/webparts/carousel/components/ICarouselState.ts b/samples/react-carousel/src/webparts/carousel/components/ICarouselState.ts
new file mode 100644
index 000000000..2702081cd
--- /dev/null
+++ b/samples/react-carousel/src/webparts/carousel/components/ICarouselState.ts
@@ -0,0 +1,10 @@
+import { ICarouselImages } from './ICarouselmages';
+export interface ICarouselState {
+ carouselImages: any[];
+ isLoading: boolean;
+ errorMessage: string;
+ hasError: boolean;
+ teamsTheme: string;
+ photoIndex: number;
+ loadingImage: boolean;
+}
diff --git a/samples/react-carousel/src/webparts/carousel/components/ICarouselmages.ts b/samples/react-carousel/src/webparts/carousel/components/ICarouselmages.ts
new file mode 100644
index 000000000..92200ad7b
--- /dev/null
+++ b/samples/react-carousel/src/webparts/carousel/components/ICarouselmages.ts
@@ -0,0 +1,8 @@
+export interface ICarouselImages {
+ imageUrl: string;
+ serverRelativeUrl: string;
+ caption: string;
+ mediaType: string;
+ description: string;
+ linkUrl: string;
+}
diff --git a/samples/react-carousel/src/webparts/carousel/loc/en-us.js b/samples/react-carousel/src/webparts/carousel/loc/en-us.js
new file mode 100644
index 000000000..dcc109672
--- /dev/null
+++ b/samples/react-carousel/src/webparts/carousel/loc/en-us.js
@@ -0,0 +1,12 @@
+define([], function() {
+ return {
+ "PropertyPaneDescription": "Please select site and library to show in Carousel",
+ "BasicGroupName": "Properties",
+ "ListFieldLabel": "Library",
+ "SiteUrlFieldLabel": 'Site Url',
+ "WebPartConfigButtonLabel": "Configure",
+ "WebpartConfigDescription": "Please configure Image Library ",
+ "WebpartConfigIconText": "Configure your Carousel Web Part",
+ "TitleLabel": 'Web Part Title'
+ }
+});
diff --git a/samples/react-carousel/src/webparts/carousel/loc/mystrings.d.ts b/samples/react-carousel/src/webparts/carousel/loc/mystrings.d.ts
new file mode 100644
index 000000000..4572a13b1
--- /dev/null
+++ b/samples/react-carousel/src/webparts/carousel/loc/mystrings.d.ts
@@ -0,0 +1,15 @@
+declare interface ICarouselWebPartStrings {
+ PropertyPaneDescription: string;
+ BasicGroupName: string;
+ SiteUrlFieldLabel: string;
+ ListFieldLabel: string;
+ WebPartConfigButtonLabel: string;
+ WebpartConfigDescription: string;
+ WebpartConfigIconText: string;
+ TitleLabel:string;
+}
+
+declare module 'CarouselWebPartStrings' {
+ const strings: ICarouselWebPartStrings;
+ export = strings;
+}
diff --git a/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_color.png b/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_color.png
new file mode 100644
index 000000000..a8d279707
Binary files /dev/null and b/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_color.png differ
diff --git a/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_outline.png b/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_outline.png
new file mode 100644
index 000000000..6df4a038d
Binary files /dev/null and b/samples/react-carousel/teams/6d2b91a3-2b33-492b-a372-f7d97dfc06cd_outline.png differ
diff --git a/samples/react-carousel/tools/pre-version.js b/samples/react-carousel/tools/pre-version.js
new file mode 100644
index 000000000..c1373dd6d
--- /dev/null
+++ b/samples/react-carousel/tools/pre-version.js
@@ -0,0 +1,64 @@
+/**
+ * This script updates the package-solution version analogue to the
+ * the package.json file.
+ */
+
+if (process.env.npm_package_version === undefined) {
+
+ throw 'Package version cannot be evaluated';
+
+}
+
+// define path to package-solution file
+const solution = './config/package-solution.json',
+ teams = './teams/manifest.json';
+
+// require filesystem instance
+const fs = require('fs');
+
+// get next automated package version from process variable
+const nextPkgVersion = process.env.npm_package_version;
+
+// make sure next build version match
+const nextVersion = nextPkgVersion.indexOf('-') === -1 ?
+ nextPkgVersion : nextPkgVersion.split('-')[0];
+
+// Update version in SPFx package-solution if exists
+if (fs.existsSync(solution)) {
+
+ // read package-solution file
+ const solutionFileContent = fs.readFileSync(solution, 'UTF-8');
+ // parse file as json
+ const solutionContents = JSON.parse(solutionFileContent);
+
+ // set property of version to next version
+ solutionContents.solution.version = nextVersion + '.0';
+
+ // save file
+ fs.writeFileSync(
+ solution,
+ // convert file back to proper json
+ JSON.stringify(solutionContents, null, 2),
+ 'UTF-8');
+
+}
+
+// Update version in teams manifest if exists
+if (fs.existsSync(teams)) {
+
+ // read package-solution file
+ const teamsManifestContent = fs.readFileSync(teams, 'UTF-8');
+ // parse file as json
+ const teamsContent = JSON.parse(teamsManifestContent);
+
+ // set property of version to next version
+ teamsContent.version = nextVersion;
+
+ // save file
+ fs.writeFileSync(
+ teams,
+ // convert file back to proper json
+ JSON.stringify(teamsContent, null, 2),
+ 'UTF-8');
+
+}
diff --git a/samples/react-carousel/tsconfig.json b/samples/react-carousel/tsconfig.json
new file mode 100644
index 000000000..471a0daa0
--- /dev/null
+++ b/samples/react-carousel/tsconfig.json
@@ -0,0 +1,38 @@
+{
+ "extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
+ "compilerOptions": {
+ "target": "es5",
+ "forceConsistentCasingInFileNames": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "jsx": "react",
+ "declaration": true,
+ "sourceMap": true,
+ "experimentalDecorators": true,
+ "skipLibCheck": true,
+ "outDir": "lib",
+ "inlineSources": false,
+ "strictNullChecks": false,
+ "noUnusedLocals": false,
+ "typeRoots": [
+ "./node_modules/@types",
+ "./node_modules/@microsoft"
+ ],
+ "types": [
+ "es6-promise",
+ "webpack-env"
+ ],
+ "lib": [
+ "es5",
+ "dom",
+ "es2015.collection"
+ ]
+ },
+ "include": [
+ "src/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules",
+ "lib"
+ ]
+}
\ No newline at end of file
diff --git a/samples/react-carousel/tslint.json b/samples/react-carousel/tslint.json
new file mode 100644
index 000000000..23fa2aa43
--- /dev/null
+++ b/samples/react-carousel/tslint.json
@@ -0,0 +1,30 @@
+{
+ "extends": "@microsoft/sp-tslint-rules/base-tslint.json",
+ "rules": {
+ "class-name": false,
+ "export-name": false,
+ "forin": false,
+ "label-position": false,
+ "member-access": true,
+ "no-arg": false,
+ "no-console": false,
+ "no-construct": false,
+ "no-duplicate-variable": true,
+ "no-eval": false,
+ "no-function-expression": true,
+ "no-internal-module": true,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-unnecessary-semicolons": true,
+ "no-unused-expression": true,
+ "no-use-before-declare": true,
+ "no-with-statement": true,
+ "semicolon": true,
+ "trailing-comma": false,
+ "typedef": false,
+ "typedef-whitespace": false,
+ "use-named-parameter": true,
+ "variable-name": false,
+ "whitespace": false
+ }
+}
\ No newline at end of file