diff --git a/README.md b/README.md
index 5fb136f2..af0b3990 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Fabric is a responsive, mobile-first collection of styles and tools designed to
##Get started
-For a quick start, reference the latest release of Fabric from a CDN or add a copy to your project. See [Getting Started](http://dev.office.com/fabric/getting-started) on the [Office UI Fabric site](http://dev.office.com/fabric) for full details.
+For a quick start, reference the latest release of Fabric from a CDN or add a copy to your project. See [Get Started](http://dev.office.com/fabric/get-started) on the [Office UI Fabric site](http://dev.office.com/fabric) for full details.
Want to customize Fabric for your project? See [Building Fabric](https://github.com/OfficeDev/Office-UI-Fabric/blob/master/ghdocs/BUILDING.md) to learn about the build process.
@@ -37,4 +37,4 @@ All files on the Office UI Fabric GitHub repository are subject to the MIT licen
##Changelog
-We use [GitHub Releases](https://github.com/blog/1547-release-your-software) to manage our releases, including the changelog between every release. View a complete list of additions, fixes, and changes since 1.0 on the [Releases page](https://github.com/OfficeDev/Office-UI-Fabric/releases).
+We use [GitHub Releases](https://github.com/blog/1547-release-your-software) to manage our releases, including the changelog between every release. View a complete list of additions, fixes, and changes since 1.0 on the [releases](https://github.com/OfficeDev/Office-UI-Fabric/releases) page.
diff --git a/gulp/ComponentJS.js b/gulp/ComponentJS.js
new file mode 100644
index 00000000..1015265a
--- /dev/null
+++ b/gulp/ComponentJS.js
@@ -0,0 +1,97 @@
+var gulp = require('gulp');
+var Banners = require('./modules/Banners');
+var Config = require('./modules/Config');
+var ErrorHandling = require('./modules/ErrorHandling');
+var Plugins = require('./modules/Plugins');
+
+//
+// Clean/Delete Tasks
+// ----------------------------------------------------------------------------
+
+gulp.task('ComponentJS-nuke', function () {
+ return Plugins.del.sync([Config.paths.distJS, Config.paths.distLibPath]);
+});
+
+
+//
+// Library tasks
+// ----------------------------------------------------------------------------
+gulp.task('ComponentJS-copyLib', function() {
+ return gulp.src(Config.paths.srcLibPath + '/**/*')
+ .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
+ .pipe(Plugins.changed(Config.paths.distLibPath))
+ .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
+ title: "Copying /lib folder to dist folder"
+ })))
+ .pipe(gulp.dest(Config.paths.distLibPath));
+});
+
+//
+// Typescript tasks
+// ----------------------------------------------------------------------------
+
+gulp.task('ComponentJS-typescript', function() {
+ var tscResult = gulp.src(Config.paths.componentsPath + '/**/*.ts')
+
+ // only process TS files that have changed since last compiled to /dist/Components
+ .pipe(Plugins.changed(Config.paths.distComponents, {extension: '.js'}))
+ .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
+
+ // tslint options set by tslint.json
+ .pipe(Plugins.tslint())
+ .pipe(Plugins.tslint.report("verbose"))
+
+ // Typescript project is set to give us both definitions and javascript
+ .pipe(Plugins.tsc(Config.typescriptProject));
+
+ return Plugins.mergeStream( [
+
+ // place .d.ts output in both the Samples folder and the Components folder
+ tscResult.dts.pipe(gulp.dest(Config.paths.distSamples + '/Components'))
+ .pipe(gulp.dest(Config.paths.distComponents))
+ .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
+ title: "Output Fabric Component .d.ts built from TypeScript"
+ }))),
+
+ // place .js output in both the Samples folder and the Components folder
+ tscResult.js.pipe(gulp.dest(Config.paths.distSamples + '/Components'))
+ .pipe(gulp.dest(Config.paths.distComponents))
+ .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
+ title: "Output Fabric Component .js built from TypeScript"
+ })))
+ ]);
+});
+
+//
+// Concat and minify the output files into a single fabric.js file
+gulp.task('ComponentJS-concatJS', ['ComponentJS-typescript'], function() {
+
+ return gulp.src(Config.paths.distComponents + '/**/*.js')
+ .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
+ .pipe(Plugins.concat('fabric.js'))
+ .pipe(Plugins.header(Banners.getJSCopyRight()))
+ .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
+ title: "Concat Fabric Component JS"
+ })))
+ .pipe(gulp.dest(Config.paths.distJS))
+ .pipe(Plugins.rename('fabric.min.js'))
+ .pipe(Plugins.uglify())
+ .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
+ title: "Minify Fabric Component JS"
+ })))
+ .pipe(gulp.dest(Config.paths.distJS));
+});
+
+
+//
+// Rolled up Build tasks
+// ----------------------------------------------------------------------------
+
+var ComponentJSTasks = [
+ 'ComponentJS-copyLib',
+ 'ComponentJS-typescript',
+ 'ComponentJS-concatJS'
+];
+
+//Build Fabric Component Samples
+gulp.task('ComponentJS', ComponentJSTasks);
diff --git a/gulp/ComponentSamples.js b/gulp/ComponentSamples.js
index 1ca11259..40a39e9d 100644
--- a/gulp/ComponentSamples.js
+++ b/gulp/ComponentSamples.js
@@ -1,6 +1,7 @@
var gulp = require('gulp');
var fs = require('fs');
var Utilities = require('./modules/Utilities');
+var Banners = require('./modules/Banners');
var Config = require('./modules/Config');
var BuildConfig = require('./modules/BuildConfig');
var ConsoleHelper = require('./modules/ConsoleHelper');
@@ -51,24 +52,6 @@ gulp.task('ComponentSamples-copyAssets', function() {
.pipe(gulp.dest(Config.paths.distSamples + '/Components'));
});
-gulp.task('ComponentSamples-moveJS', function() {
- var paths;
- var newPaths;
- paths = Utilities.setIgnoreFlagOnFiles(Config.ignoreComponentJSLinting);
- newPaths = paths.concat([Config.paths.componentsPath + '/**/*.js']);
-
- return gulp.src(newPaths)
- .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
- .pipe(Plugins.jshint())
- .pipe(ErrorHandling.JSHintErrors())
- .pipe(Plugins.changed(Config.paths.distSamples + '/Components'))
- .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
- title: "Copying Component Assets"
- })))
- .pipe(Plugins.fileinclude())
- .pipe(gulp.dest(Config.paths.distSamples + '/Components'));
-});
-
gulp.task('ComponentSamples-styleHinting', function() {
return gulp.src(Config.paths.componentsPath + '/**/*.scss')
@@ -131,12 +114,7 @@ gulp.task('ComponentSamples-build', function() {
var filesArray = manifest.fileOrder;
var componentPipe;
var fileGlob = Utilities.getManifestFileList(filesArray, Config.paths.componentsPath + '/' + folderName);
- var jsFiles = Utilities.getFilesByExtension(srcFolderName, '.js');
- var jsLinks = '';
-
- for (var x = 0; x < jsFiles.length; x++) {
- jsLinks += '' + "\r\n";
- }
+
componentPipe = gulp.src(fileGlob)
.pipe(Plugins.plumber(ErrorHandling.oneErrorInPipe))
.pipe(Plugins.gulpif(manifest.wrapBranches, Plugins.wrap('
<%= contents %>
')))
@@ -148,9 +126,6 @@ gulp.task('ComponentSamples-build', function() {
},
{
componentName: folderName
- },
- {
- jsLinks: jsLinks
}
))
.pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
@@ -178,7 +153,7 @@ var ComponentSamplesTasks = [
'ComponentSamples-build',
'ComponentSamples-copyAssets',
'ComponentSamples-buildStyles',
- 'ComponentSamples-moveJS',
+ 'ComponentJS',
'ComponentSamples-copyIgnoredFiles'
// 'ComponentSamples-styleHinting' Commented out until warnings are resolved
];
diff --git a/gulp/FabricComponents.js b/gulp/FabricComponents.js
index 956417e1..2eed0f27 100644
--- a/gulp/FabricComponents.js
+++ b/gulp/FabricComponents.js
@@ -25,7 +25,7 @@ gulp.task('FabricComponents-nuke', function () {
gulp.task('FabricComponents-copyAssets', function () {
// Copy all Components files.
- return gulp.src([Config.paths.componentsPath + '/**', '!' + Config.paths.componentsPath + '/**/*.js'])
+ return gulp.src([Config.paths.componentsPath + '/**', '!' + Config.paths.componentsPath + '/**/*.js', '!' + Config.paths.componentsPath + '/**/*.ts'])
.pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
.pipe(Plugins.changed(Config.paths.distComponents))
.pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
@@ -34,18 +34,6 @@ gulp.task('FabricComponents-copyAssets', function () {
.pipe(gulp.dest(Config.paths.distComponents));
});
-gulp.task('FabricComponents-moveJs', function () {
- // Copy all Components files.
- return gulp.src([Config.paths.componentsPath + '/**/*.js'])
- .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
- .pipe(Plugins.changed(Config.paths.distComponents))
- .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
- title: "Moving Fabric Component Assets to Dist"
- })))
- .pipe(Plugins.fileinclude())
- .pipe(gulp.dest(Config.paths.distComponents));
-});
-
//
// Sass tasks
// ----------------------------------------------------------------------------
@@ -116,26 +104,6 @@ gulp.task('FabricComponents-buildStyles', function () {
});
});
-//
-// JS Only tasks
-// ----------------------------------------------------------------------------
-
-
-gulp.task('FabricComponents-moveJs', function() {
- return gulp.src(Config.paths.componentsPath + '/**/*.js')
- .pipe(Plugins.plumber(ErrorHandling.onErrorInPipe))
- .pipe(Plugins.concat('jquery.fabric.js'))
- .pipe(Plugins.header(Banners.getJSCopyRight()))
- .pipe(Plugins.changed(Config.paths.distJS))
- .pipe(Plugins.gulpif(Config.debugMode, Plugins.debug({
- title: "Moving Fabric Component JS"
- })))
- .pipe(gulp.dest(Config.paths.distJS))
- .pipe(Plugins.rename('jquery.fabric.min.js'))
- .pipe(Plugins.uglify())
- .pipe(gulp.dest(Config.paths.distJS));
-});
-
//
// Rolled up Build tasks
// ----------------------------------------------------------------------------
@@ -145,7 +113,7 @@ gulp.task('FabricComponents', [
'FabricComponents-buildAndCombineStyles',
'FabricComponents-buildStyles',
'FabricComponents-copyAssets',
- 'FabricComponents-moveJs'
+ 'ComponentJS'
]
);
diff --git a/gulp/modules/Config.js b/gulp/modules/Config.js
index 864f377f..f75e6660 100644
--- a/gulp/modules/Config.js
+++ b/gulp/modules/Config.js
@@ -1,5 +1,6 @@
var path = require('path');
var pkg = require('../../package.json');
+var Plugins = require('./Plugins');
/**
* Configuration class containing all properties to be used throughout the build
@@ -24,7 +25,9 @@ var Config = function() {
srcSamples: srcPath + '/samples',
srcSass: srcPath + '/sass',
componentsPath : 'src/components',
- templatePath : srcPath + '/templates'
+ templatePath : srcPath + '/templates',
+ srcLibPath: 'lib',
+ distLibPath: distPath + '/lib'
};
this.port = process.env.PORT || 2020;
this.projectURL = "http://localhost";
@@ -33,8 +36,23 @@ var Config = function() {
{
'urlPath': '/css',
'folderPath': '../css'
+ },
+ {
+ 'urlPath': '/js',
+ 'folderPath': '../js'
+ },
+ {
+ 'urlPath': '/lib',
+ 'folderPath': '../lib'
}
];
+ this.typescriptConfig = {
+ module: 'commonjs',
+ declaration: true,
+ target: 'ES5',
+ noEmitOnError: true
+ };
+ this.typescriptProject = Plugins.tsc.createProject(this.typescriptConfig);
this.nugetConfig = {
id: "OfficeUIFabric",
title: "Office UI Fabric",
diff --git a/gulp/modules/ErrorHandling.js b/gulp/modules/ErrorHandling.js
index 6ab738e6..d2e1566f 100644
--- a/gulp/modules/ErrorHandling.js
+++ b/gulp/modules/ErrorHandling.js
@@ -140,9 +140,12 @@ var ErrorHandling = function() {
case 'gulp-sass':
this.emit('end');
break;
+ case 'gulp-tslint':
+ this.emit('end');
+ break;
default:
- that.generateBuildError(error[0]);
- that.addError(error[0]);
+ that.generateBuildError(error);
+ that.addError(error);
break;
}
return;
diff --git a/gulp/modules/Plugins.js b/gulp/modules/Plugins.js
index c2460ac0..e1a72502 100644
--- a/gulp/modules/Plugins.js
+++ b/gulp/modules/Plugins.js
@@ -33,17 +33,19 @@ var Plugins = function() {
this.nugetpack = require('gulp-nuget-pack');
this.requireDir = require('require-dir');
this.debug = require('gulp-debug');
- this.gulpif = require('gulp-if');
- this.changed = require('gulp-changed');
- this.sass = require('gulp-sass');
- this.jshint = require('gulp-jshint');
- this.plumber = require('gulp-plumber');
- this.replace = require('gulp-replace');
- this.walkSync = require('walk-sync');
- this.size = require('gulp-size');
- this.fs = require('fs');
- this.sasslint = require('gulp-sass-lint');
- this.fileinclude = require('gulp-file-include');
+ this.gulpif = require('gulp-if');
+ this.changed = require('gulp-changed');
+ this.sass = require('gulp-sass');
+ this.jshint = require('gulp-jshint');
+ this.plumber = require('gulp-plumber');
+ this.replace = require('gulp-replace');
+ this.walkSync = require('walk-sync');
+ this.size = require('gulp-size');
+ this.fs = require('fs');
+ this.sasslint = require('gulp-sass-lint');
+ this.fileinclude = require('gulp-file-include');
+ this.tsc = require('gulp-typescript');
+ this.tslint = require("gulp-tslint");
};
module.exports = new Plugins();
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 03205083..22a431f3 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -9,6 +9,7 @@ var ErrorHandling = require('./gulp/modules/ErrorHandling');
var watchTasks = [
'Fabric',
+ 'ComponentJS',
'FabricComponents',
'ComponentSamples',
'Samples',
@@ -17,6 +18,7 @@ var watchTasks = [
var buildTasks = [
'Fabric',
+ 'ComponentJS',
'FabricComponents',
'ComponentSamples',
'Samples',
@@ -50,22 +52,22 @@ gulp.task('FabricServer', function() {
//
// Nuke Tasks
// ---------------------------------------------------------------------------
-gulp.task('nuke', ['Fabric-nuke', 'FabricComponents-nuke', 'ComponentSamples-nuke', 'Samples-nuke']);
+gulp.task('nuke', ['Fabric-nuke', 'ComponentJS-nuke', 'FabricComponents-nuke', 'ComponentSamples-nuke', 'Samples-nuke']);
//
// Watch Tasks
// ----------------------------------------------------------------------------
// Watch Sass
-gulp.task('watch-build', ['ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-server'], function () {
+gulp.task('watch-build', ['ComponentJS', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-server'], function () {
gulp.watch(Config.paths.srcPath + '/**/*', Plugins.batch(function (events, done) {
- Plugins.runSequence(['Fabric', 'FabricComponents', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-updated'], done);
+ Plugins.runSequence(['Fabric', 'ComponentJS', 'FabricComponents', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-updated'], done);
}));
});
gulp.task('watch', ['watch-build']);
-gulp.task('watch-debug-build', ['Fabric', 'FabricComponents', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-server'], function () {
+gulp.task('watch-debug-build', ['ComponentJS', 'Fabric', 'FabricComponents', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-server'], function () {
gulp.watch(Config.paths.srcPath + '/**/*', Plugins.batch(function (events, done) {
Plugins.runSequence(['Fabric', 'FabricComponents', 'ComponentSamples', 'Samples', 'FabricDemoPage', 'FabricServer', 'All-updated'], done);
}));
diff --git a/src/components/DatePicker/PickaDate.js b/lib/PickaDate.js
similarity index 100%
rename from src/components/DatePicker/PickaDate.js
rename to lib/PickaDate.js
diff --git a/package.json b/package.json
index f347defc..6600dff7 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,8 @@
"gulp-size": "^1.0.0",
"gulp-tap": "^0.1.3",
"gulp-template": "^3.0.0",
+ "gulp-tslint": "^4.3.2",
+ "gulp-typescript": "^2.10.0",
"gulp-uglify": "^1.5.2",
"gulp-util": "^3.0.1",
"gulp-wrap": "^0.11.0",
@@ -63,6 +65,8 @@
"run-sequence": "^1.1.0",
"swig": "^1.4.2",
"through2": "^2.0.0",
+ "tslint": "^3.3.0",
+ "typescript": "^1.7.5",
"walk-sync": "^0.2.6"
}
}
diff --git a/src/components/Breadcrumb/Breadcrumb.js b/src/components/Breadcrumb/Breadcrumb.js
deleted file mode 100644
index 8db08cb8..00000000
--- a/src/components/Breadcrumb/Breadcrumb.js
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Breadcrumb component
- *
- * Shows the user's current location in a hierarchy and provides a means of navigating upward.
- *
- */
-
-/**
- * @namespace fabric
- */
-var fabric = fabric || {};
-/**
- *
- * @param {HTMLElement} container - the target container for an instance of Breadcrumb
- * @constructor
- *
- * If dynamically populating a list run the constructor after the list has been populated
- * in the DOM.
- */
-fabric.Breadcrumb = function(container) {
- this.container = container;
- this.init();
-};
-
-fabric.Breadcrumb.prototype = (function() {
-
- //medium breakpoint
- var MEDIUM = 639;
-
- //cached DOM elements
- var _breadcrumb;
- var _listItems;
- var _contextMenu;
- var _overflowButton;
- var _overflowMenu;
- var _breadcrumbList;
-
- var _currentMaxItems = 0;
- var _itemCollection = [];
-
- /**
- * create internal model of list items from DOM
- */
- var _createItemCollection = function() {
- var length = _listItems.length;
- var i = 0;
- var item;
- var text;
- var link;
- var tabIndex;
-
- for(i; i < length; i++) {
- item = _listItems[i].querySelector('.ms-Breadcrumb-itemLink');
- text = item.textContent;
- link = item.getAttribute('href');
- tabIndex = parseInt(item.getAttribute('tabindex'), 10);
- _itemCollection.push({text: text, link: link, tabIndex: tabIndex});
- }
- };
-
- /**
- * Re-render lists on resize
- *
- */
- var _onResize = function() {
- _closeOverflow(null);
- _renderList();
- };
-
- /**
- * render breadcrumbs and overflow menus
- */
- var _renderList = function() {
- var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
-
- if(maxItems !== _currentMaxItems) {
- if(_itemCollection.length > maxItems) {
- _breadcrumb.className += ' is-overflow';
- } else {
- _removeClass(_breadcrumb, ' is-overflow');
- }
- _addBreadcrumbItems(maxItems);
- _addItemsToOverflow(maxItems);
- }
-
- _currentMaxItems = maxItems;
- };
-
- /**
- * creates the overflow menu
- */
- var _addItemsToOverflow = function(maxItems) {
- _resetList(_contextMenu);
- var end = _itemCollection.length - maxItems;
- var overflowItems = _itemCollection.slice(0, end);
-
- overflowItems.forEach(function(item) {
- var li = document.createElement('li');
- li.className = 'ms-ContextualMenu-item';
- if(!isNaN(item.tabIndex)) {
- li.setAttribute('tabindex', item.tabIndex);
- }
- var a = document.createElement('a');
- a.className = 'ms-ContextualMenu-link';
- if (item.link !== null) {
- a.setAttribute('href', item.link);
- }
- a.textContent = item.text;
- li.appendChild(a);
- _contextMenu.appendChild(li);
- });
- };
-
- /**
- * creates the breadcrumbs
- */
- var _addBreadcrumbItems = function(maxItems) {
- _resetList(_breadcrumbList);
- var i = _itemCollection.length - maxItems;
-
- if(i >= 0) {
- for(i; i < _itemCollection.length; i++) {
- var listItem = document.createElement('li');
- var item = _itemCollection[i];
- var a = document.createElement('a');
- var chevron = document.createElement('i');
- listItem.className = 'ms-Breadcrumb-listItem';
- a.className = 'ms-Breadcrumb-itemLink';
- if (item.link !== null) {
- a.setAttribute('href', item.link);
- }
- if(!isNaN(item.tabIndex)) {
- a.setAttribute('tabindex', item.tabIndex);
- }
- a.textContent = item.text;
- chevron.className = 'ms-Breadcrumb-chevron ms-Icon ms-Icon--chevronRight';
- listItem.appendChild(a);
- listItem.appendChild(chevron);
- _breadcrumbList.appendChild(listItem);
- }
- }
- };
-
- /**
- * resets a list by removing its children
- */
- var _resetList = function(list) {
- while (list.firstChild) {
- list.removeChild(list.firstChild);
- }
- };
-
- /**
- * opens the overflow menu
- */
- var _openOverflow = function(event) {
- if(_overflowMenu.className.indexOf(' is-open') === -1) {
- _overflowMenu.className += ' is-open';
- removeOutlinesOnClick(event);
- // force focus rect onto overflow button
- _overflowButton.focus();
- }
- };
-
- var _overflowKeyPress = function(event) {
- if(event.keyCode === 13) {
- _openOverflow(event);
- }
- };
-
- /**
- * closes the overflow menu
- */
- var _closeOverflow = function(event) {
- if(!event || event.target !== _overflowButton) {
- _removeClass(_overflowMenu, ' is-open');
- }
- };
-
- /**
- * utility that removes a class from an element
- */
- var _removeClass = function (element, value) {
- var index = element.className.indexOf(value);
- if(index > -1) {
- element.className = element.className.substring(0, index);
- }
- };
-
- /**
- * caches elements and values of the component
- */
- var _cacheDOM = function(context) {
- _breadcrumb = context.container;
- _breadcrumbList = _breadcrumb.querySelector('.ms-Breadcrumb-list');
- _listItems = _breadcrumb.querySelectorAll('.ms-Breadcrumb-listItem');
- _contextMenu = _breadcrumb.querySelector('.ms-ContextualMenu');
- _overflowButton = _breadcrumb.querySelector('.ms-Breadcrumb-overflowButton');
- _overflowMenu = _breadcrumb.querySelector('.ms-Breadcrumb-overflowMenu');
- };
-
- /**
- * sets handlers for resize and button click events
- */
- var _setListeners = function() {
- window.addEventListener('resize', _onResize);
- _overflowButton.addEventListener('click', _openOverflow, false);
- _overflowButton.addEventListener('keypress', _overflowKeyPress, false);
- document.addEventListener('click', _closeOverflow, false);
- _breadcrumbList.addEventListener('click', removeOutlinesOnClick, false);
- };
-
- /**
- * removes focus outlines so they don't linger after click
- */
- var removeOutlinesOnClick = function(event) {
- event.target.blur();
- };
-
- /**
- * initializes component
- */
- var init = function() {
- _cacheDOM(this);
- _setListeners();
- _createItemCollection();
- _onResize(null);
- };
-
- return {
- init: init
- };
-
-}());
diff --git a/src/components/Breadcrumb/Breadcrumb.ts b/src/components/Breadcrumb/Breadcrumb.ts
new file mode 100644
index 00000000..b81516ba
--- /dev/null
+++ b/src/components/Breadcrumb/Breadcrumb.ts
@@ -0,0 +1,235 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+
+/**
+ * @namespace fabric
+ */
+namespace fabric {
+ "use strict";
+
+ /**
+ * Breadcrumb component
+ *
+ * Shows the user"s current location in a hierarchy and provides a means of navigating upward.
+ *
+ */
+ export class Breadcrumb {
+ // medium breakpoint
+ private static MEDIUM: number = 639;
+
+ public container: HTMLElement;
+
+ // cached DOM elements
+ private _breadcrumb: HTMLElement;
+ private _listItems: NodeListOf;
+ private _contextMenu: HTMLElement;
+ private _overflowButton: HTMLElement;
+ private _overflowMenu: HTMLElement;
+ private _breadcrumbList: HTMLElement;
+
+ private _currentMaxItems: number = 0;
+ private _itemCollection: Array = [];
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Breadcrumb
+ * @constructor
+ *
+ * If dynamically populating a list run the constructor after the list has been populated
+ * in the DOM.
+ */
+ constructor(container: HTMLElement) {
+ this.container = container;
+ this.init();
+ }
+
+ /**
+ * removes focus outlines so they don"t linger after click
+ */
+ public removeOutlinesOnClick(): void {
+ this._breadcrumbList.blur();
+ }
+
+ /**
+ * initializes component
+ */
+ public init(): void {
+ this._cacheDOM();
+ this._setListeners();
+ this._createItemCollection();
+ this._onResize();
+ }
+
+ /**
+ * create internal model of list items from DOM
+ */
+ private _createItemCollection(): void {
+ let length = this._listItems.length;
+ let i = 0;
+ let item;
+ let text;
+ let link;
+ let tabIndex;
+
+ for (i; i < length; i++) {
+ item = this._listItems[i].querySelector(".ms-Breadcrumb-itemLink");
+ text = item.textContent;
+ link = item.getAttribute("href");
+ tabIndex = parseInt(item.getAttribute("tabindex"), 10);
+ this._itemCollection.push({link: link, tabIndex: tabIndex, text: text});
+ }
+ }
+
+ /**
+ * Re-render lists on resize
+ *
+ */
+ private _onResize(): void {
+ this._closeOverflow(null);
+ this._renderList();
+ }
+
+ /**
+ * render breadcrumbs and overflow menus
+ */
+ private _renderList(): void {
+ let maxItems = window.innerWidth > Breadcrumb.MEDIUM ? 4 : 2;
+
+ if (maxItems !== this._currentMaxItems) {
+ if (this._itemCollection.length > maxItems) {
+ this._breadcrumb.className += " is-overflow";
+ } else {
+ this._removeClass(this._breadcrumb, " is-overflow");
+ }
+ this._addBreadcrumbItems(maxItems);
+ this._addItemsToOverflow(maxItems);
+ }
+
+ this._currentMaxItems = maxItems;
+ }
+
+ /**
+ * creates the overflow menu
+ */
+ private _addItemsToOverflow(maxItems: number): void {
+ this._resetList(this._contextMenu);
+ let end = this._itemCollection.length - maxItems;
+ let overflowItems = this._itemCollection.slice(0, end);
+
+ overflowItems.forEach( (item) => {
+ let li = document.createElement("li");
+ li.className = "ms-ContextualMenu-item";
+ if (!isNaN(item.tabIndex)) {
+ li.setAttribute("tabindex", item.tabIndex);
+ }
+ let a = document.createElement("a");
+ a.className = "ms-ContextualMenu-link";
+ if (item.link !== null) {
+ a.setAttribute("href", item.link);
+ }
+ a.textContent = item.text;
+ li.appendChild(a);
+ this._contextMenu.appendChild(li);
+ });
+ }
+
+ /**
+ * creates the breadcrumbs
+ */
+ private _addBreadcrumbItems(maxItems: number): void {
+ this._resetList(this._breadcrumbList);
+ let i = this._itemCollection.length - maxItems;
+
+ i = i < 0 ? 0 : i;
+ if (i >= 0) {
+ for (i; i < this._itemCollection.length; i++) {
+ let listItem = document.createElement("li");
+ let item = this._itemCollection[i];
+ let a = document.createElement("a");
+ let chevron = document.createElement("i");
+ listItem.className = "ms-Breadcrumb-listItem";
+ a.className = "ms-Breadcrumb-itemLink";
+ if (item.link !== null) {
+ a.setAttribute("href", item.link);
+ }
+ if (!isNaN(item.tabIndex)) {
+ a.setAttribute("tabindex", item.tabIndex);
+ }
+ a.textContent = item.text;
+ chevron.className = "ms-Breadcrumb-chevron ms-Icon ms-Icon--chevronRight";
+ listItem.appendChild(a);
+ listItem.appendChild(chevron);
+ this._breadcrumbList.appendChild(listItem);
+ }
+ }
+ }
+
+ /**
+ * resets a list by removing its children
+ */
+ private _resetList(list: HTMLElement): void {
+ while (list.firstChild) {
+ list.removeChild(list.firstChild);
+ }
+ }
+
+ /**
+ * opens the overflow menu
+ */
+ private _openOverflow(event: KeyboardEvent): void {
+ if (this._overflowMenu.className.indexOf(" is-open") === -1) {
+ this._overflowMenu.className += " is-open";
+ this.removeOutlinesOnClick();
+ // force focus rect onto overflow button
+ this._overflowButton.focus();
+ }
+ }
+
+ private _overflowKeyPress(event: KeyboardEvent): void {
+ if (event.keyCode === 13) {
+ this._openOverflow(event);
+ }
+ }
+
+ /**
+ * closes the overflow menu
+ */
+ private _closeOverflow(event: Event): void {
+ if (!event || event.target !== this._overflowButton) {
+ this._removeClass(this._overflowMenu, " is-open");
+ }
+ }
+
+ /**
+ * utility that removes a class from an element
+ */
+ private _removeClass(element: HTMLElement, value: string): void {
+ let index = element.className.indexOf(value);
+ if (index > -1) {
+ element.className = element.className.substring(0, index);
+ }
+ }
+
+ /**
+ * caches elements and values of the component
+ */
+ private _cacheDOM(): void {
+ this._breadcrumb = this.container;
+ this._breadcrumbList = this._breadcrumb.querySelector(".ms-Breadcrumb-list");
+ this._listItems = >this._breadcrumb.querySelectorAll(".ms-Breadcrumb-listItem");
+ this._contextMenu = this._breadcrumb.querySelector(".ms-ContextualMenu");
+ this._overflowButton = this._breadcrumb.querySelector(".ms-Breadcrumb-overflowButton");
+ this._overflowMenu = this._breadcrumb.querySelector(".ms-Breadcrumb-overflowMenu");
+ }
+
+ /**
+ * sets handlers for resize and button click events
+ */
+ private _setListeners(): void {
+ window.addEventListener("resize", this._onResize.bind(this));
+ this._overflowButton.addEventListener("click", this._openOverflow.bind(this), false);
+ this._overflowButton.addEventListener("keypress", this._overflowKeyPress.bind(this), false);
+ document.addEventListener("click", this._closeOverflow.bind(this), false);
+ this._breadcrumbList.addEventListener("click", this.removeOutlinesOnClick, false);
+ }
+ }
+} // end fabric namespace
diff --git a/src/components/CommandBar/Jquery.CommandBar.js b/src/components/CommandBar/Jquery.CommandBar.js
deleted file mode 100644
index 5a63d928..00000000
--- a/src/components/CommandBar/Jquery.CommandBar.js
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Command Bar Plugin
- */
-
-(function ($) {
- $.fn.CommandBar = function () {
-
- var createMenuItem = function(text) {
- var item = '';
-
- return item;
- };
-
- var saveCommands = function($commands, $commandWidth, $commandarea) {
- var commands = [];
- $commands.each(function() {
- var $Item = $(this);
- var $rightOffset = ($Item.position().left + $Item.outerWidth() + $commandWidth + 10) - $commandarea.position().left; // Added padding of 10
- commands.push({ jquery: $Item, rightOffset: $rightOffset});
- });
-
- return commands;
- };
-
- var processCommands = function(commands, width, overflowwidth) {
- var overFlowCommands = [];
-
- for(var i=0; i < commands.length; i++) {
- var $Item = commands[i].jquery;
- var rightOffset = commands[i].rightOffset;
-
- // If the command is outside the right boundaries add to overflow items
- if(!$Item.hasClass('ms-CommandBarItem-overflow')) {
- if((rightOffset + overflowwidth) > width) {
- overFlowCommands.push($Item);
- } else {
- // Make sure item is displayed
- $Item.removeClass('is-hidden');
- }
- }
- }
- return overFlowCommands;
- };
-
- var processOverflow = function(overFlowCommands, $oCommand, $menu) {
- var overflowStrings = '';
-
- if(overFlowCommands.length > 0) {
- $oCommand.addClass("is-visible");
- // Empty menu
- $menu.html('');
-
- // Add overflowed commands to ContextualMenu
- for(var i = 0; i < overFlowCommands.length; i++) {
- var $Item = $(overFlowCommands[i]);
- // Hide Element in CommandBar
- $Item.addClass('is-hidden');
- var commandBarItemText = $Item.find('.ms-CommandBarItem-commandText').text();
- overflowStrings += createMenuItem(commandBarItemText);
- }
- $menu.html(overflowStrings);
- } else {
- $oCommand.removeClass("is-visible");
- }
- };
-
- /** Go through each CommandBar we've been given. */
- return this.each(function () {
- var $CommandBar = $(this);
- var $CommandMainArea = $CommandBar.find('.ms-CommandBar-mainArea');
- var $CommandBarItems = $CommandMainArea.find('.ms-CommandBarItem').not('.ms-CommandBarItem-overflow');
- var $OverflowCommand = $CommandBar.find('.ms-CommandBarItem-overflow');
- var $OverflowCommandWidth = $CommandBar.find('.ms-CommandBarItem-overflow').outerWidth();
- var $OverflowMenu = $CommandBar.find('.ms-CommandBar-overflowMenu');
- var $SearchBox = $CommandBar.find('.ms-CommandBarSearch');
- var mobileSwitch = false;
- var overFlowCommands;
- var allCommands;
-
- // Go through process and save commands
- allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
-
- // Initiate process commands and add commands to overflow on load
- overFlowCommands = processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
- processOverflow(overFlowCommands, $OverflowCommand, $OverflowMenu);
-
- // Set Search Behavior
- if($(window).width() < 640) {
-
- $('.ms-CommandBarSearch-iconSearchWrapper').click(function() {
- $(this).closest('.ms-CommandBarSearch').addClass('is-active');
- });
-
- }
-
- // Add resize event handler on commandBar
- $(window).resize(function() {
- var overFlowCommands;
-
- if($(window).width() < 640 && mobileSwitch === false) {
- // Go through process and save commands
- allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
-
- mobileSwitch = true;
-
- // Search Behavior
- $('.ms-CommandBarSearch-iconSearchWrapper').unbind();
- $('.ms-CommandBarSearch-iconSearchWrapper').click(function() {
- $(this).closest('.ms-CommandBarSearch').addClass('is-active');
- });
-
- } else if($(window).width() > 639 && mobileSwitch === true) {
- // Go through process and save commands
- allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
-
- mobileSwitch = false;
- $('.ms-CommandBarSearch').unbind();
-
- }
-
- // Initiate process commands and add commands to overflow on load
- overFlowCommands = processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
- processOverflow(overFlowCommands, $OverflowCommand, $OverflowMenu);
-
- });
-
- // Hook up contextual menu
- $OverflowCommand.click(function() {
- $OverflowMenu.toggleClass('is-open');
- });
-
- $OverflowCommand.focusout(function() {
- $OverflowMenu.removeClass('is-open');
- });
-
- $SearchBox.find('.ms-CommandBarSearch-input').click(function() {
- $(this).closest('.ms-CommandBarSearch').addClass('is-active');
- });
-
- $SearchBox.find('.ms-CommandBarSearch-input').on('focus', function() {
- $(this).closest('.ms-CommandBarSearch').addClass('is-active');
- });
-
- // When clicking the x clear the SearchBox and put state back to normal
- $SearchBox.find('.ms-CommandBarSearch-iconClearWrapper').click(function() {
- var $input = $(this).parent().find('.ms-CommandBarSearch-input');
- $input.val('');
- $input.parent().removeClass('is-active');
- });
-
- $SearchBox.parent().find('.ms-CommandBarSearch-input').blur(function() {
- var $input = $(this);
- $input.val('');
- $input.parent().removeClass('is-active');
- });
-
- });
- };
-})(jQuery);
\ No newline at end of file
diff --git a/src/components/CommandBar/Jquery.CommandBar.ts b/src/components/CommandBar/Jquery.CommandBar.ts
new file mode 100644
index 00000000..c06b502c
--- /dev/null
+++ b/src/components/CommandBar/Jquery.CommandBar.ts
@@ -0,0 +1,178 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+module fabric {
+
+ class CommandItem {
+ public jquery: JQuery;
+ public rightOffset: number;
+
+ constructor(jquery, rightOffset) {
+ this.jquery = jquery;
+ this.rightOffset = rightOffset;
+ }
+ }
+
+ /**
+ * Command Bar Plugin
+ */
+ export class CommandBar {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of CommandBar
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $CommandBar = $(container);
+ let $CommandMainArea = $CommandBar.find(".ms-CommandBar-mainArea");
+ let $CommandBarItems = $CommandMainArea.find(".ms-CommandBarItem").not(".ms-CommandBarItem-overflow");
+ let $OverflowCommand = $CommandBar.find(".ms-CommandBarItem-overflow");
+ let $OverflowCommandWidth = $CommandBar.find(".ms-CommandBarItem-overflow").outerWidth();
+ let $OverflowMenu = $CommandBar.find(".ms-CommandBar-overflowMenu");
+ let $SearchBox = $CommandBar.find(".ms-CommandBarSearch");
+ let mobileSwitch = false;
+ let overFlowCommands;
+ let allCommands;
+
+ // Go through process and save commands
+ allCommands = this._saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
+
+ // Initiate process commands and add commands to overflow on load
+ overFlowCommands = this._processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
+ this._processOverflow(overFlowCommands, $OverflowCommand, $OverflowMenu);
+
+ // Set Search Behavior
+ if ($(window).width() < 640) {
+
+ $(".ms-CommandBarSearch-iconSearchWrapper").click(function() {
+ $(this).closest(".ms-CommandBarSearch").addClass("is-active");
+ });
+
+ }
+
+ // Add resize event handler on commandBar
+ $(window).resize(() => {
+ if ($(window).width() < 640 && mobileSwitch === false) {
+ // Go through process and save commands
+ allCommands = this._saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
+
+ mobileSwitch = true;
+
+ // Search Behavior
+ $(".ms-CommandBarSearch-iconSearchWrapper").unbind();
+ $(".ms-CommandBarSearch-iconSearchWrapper").click(function() {
+ $(this).closest(".ms-CommandBarSearch").addClass("is-active");
+ });
+
+ } else if ($(window).width() > 639 && mobileSwitch === true) {
+ // Go through process and save commands
+ allCommands = this._saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
+
+ mobileSwitch = false;
+ $(".ms-CommandBarSearch").unbind();
+
+ }
+
+ // Initiate process commands and add commands to overflow on load
+ let newOverFlowCommands = this._processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
+ this._processOverflow(newOverFlowCommands, $OverflowCommand, $OverflowMenu);
+ });
+
+ // Hook up contextual menu
+ $OverflowCommand.click(function(): void {
+ $OverflowMenu.toggleClass("is-open");
+ });
+
+ $OverflowCommand.focusout(function(): void {
+ $OverflowMenu.removeClass("is-open");
+ });
+
+ $SearchBox.find(".ms-CommandBarSearch-input").click(function(): void {
+ $(this).closest(".ms-CommandBarSearch").addClass("is-active");
+ });
+
+ $SearchBox.find(".ms-CommandBarSearch-input").on("focus", function(): void {
+ $(this).closest(".ms-CommandBarSearch").addClass("is-active");
+ });
+
+ // When clicking the x clear the SearchBox and put state back to normal
+ $SearchBox.find(".ms-CommandBarSearch-iconClearWrapper").click(function(): void {
+ let $input = $(this).parent().find(".ms-CommandBarSearch-input");
+ $input.val("");
+ $input.parent().removeClass("is-active");
+ });
+
+ $SearchBox.parent().find(".ms-CommandBarSearch-input").blur(function(): void {
+ let $input = $(this);
+ $input.val("");
+ $input.parent().removeClass("is-active");
+ });
+ }
+
+ private _createMenuItem(text: string): string {
+ let item = "";
+ return item;
+ }
+
+ private _saveCommands($commands: JQuery, $commandWidth: number, $commandarea: JQuery): Array {
+ let commands = [];
+ $commands.each(function() {
+ let $Item = $(this);
+ // Added padding of 10
+ let $rightOffset = ($Item.position().left + $Item.outerWidth() + $commandWidth + 10) - $commandarea.position().left;
+ commands.push( new CommandItem( $Item, $rightOffset) );
+ });
+
+ return commands;
+ }
+
+ private _processCommands(commands: Array, width: number, overflowwidth: number): Array {
+ let overFlowCommands = [];
+
+ for (let i = 0; i < commands.length; i++) {
+ let $Item = commands[i].jquery;
+ let rightOffset = commands[i].rightOffset;
+
+ // If the command is outside the right boundaries add to overflow items
+ if (!$Item.hasClass("ms-CommandBarItem-overflow")) {
+ if ((rightOffset + overflowwidth) > width) {
+ overFlowCommands.push($Item);
+ } else {
+ // Make sure item is displayed
+ $Item.removeClass("is-hidden");
+ }
+ }
+ }
+ return overFlowCommands;
+ }
+
+ private _processOverflow(overFlowCommands: Array, $oCommand: JQuery, $menu: JQuery): void {
+ let overflowStrings = "";
+
+ if (overFlowCommands.length > 0) {
+ $oCommand.addClass("is-visible");
+ // Empty menu
+ $menu.html("");
+
+ // Add overflowed commands to ContextualMenu
+ for (let i = 0; i < overFlowCommands.length; i++) {
+ let $Item = $(overFlowCommands[i]);
+ // Hide Element in CommandBar
+ $Item.addClass("is-hidden");
+ let commandBarItemText = $Item.find(".ms-CommandBarItem-commandText").text();
+ overflowStrings += this._createMenuItem(commandBarItemText);
+ }
+ $menu.html(overflowStrings);
+ } else {
+ $oCommand.removeClass("is-visible");
+ }
+ }
+ } // end CommandBar
+} // end fabric namespace
diff --git a/src/components/ContextualMenu/Jquery.ContextualMenu.js b/src/components/ContextualMenu/Jquery.ContextualMenu.js
deleted file mode 100644
index 2a27de24..00000000
--- a/src/components/ContextualMenu/Jquery.ContextualMenu.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Contextual Menu Plugin
- */
-(function ($) {
- $.fn.ContextualMenu = function () {
-
- /** Go through each nav bar we've been given. */
- return this.each(function () {
-
- var $contextualMenu = $(this);
-
-
- // Set selected states.
- $contextualMenu.on('click', '.ms-ContextualMenu-link:not(.is-disabled)', function(event) {
- event.preventDefault();
-
- // Check if multiselect - set selected states
- if ( $contextualMenu.hasClass('ms-ContextualMenu--multiselect') ) {
-
- // If already selected, remove selection; if not, add selection
- if ( $(this).hasClass('is-selected') ) {
- $(this).removeClass('is-selected');
- }
- else {
- $(this).addClass('is-selected');
- }
-
- }
- // All other contextual menu variants
- else {
-
- // Deselect all of the items and close any menus.
- $('.ms-ContextualMenu-link')
- .removeClass('is-selected')
- .siblings('.ms-ContextualMenu')
- .removeClass('is-open');
-
- // Select this item.
- $(this).addClass('is-selected');
-
- // If this item has a menu, open it.
- if ($(this).hasClass('ms-ContextualMenu-link--hasMenu')) {
- $(this).siblings('.ms-ContextualMenu:first').addClass('is-open');
-
- // Open the menu without bubbling up the click event,
- // which can cause the menu to close.
- event.stopPropagation();
- }
-
- }
-
-
- });
-
- });
- };
-})(jQuery);
diff --git a/src/components/ContextualMenu/Jquery.ContextualMenu.ts b/src/components/ContextualMenu/Jquery.ContextualMenu.ts
new file mode 100644
index 00000000..0a424afe
--- /dev/null
+++ b/src/components/ContextualMenu/Jquery.ContextualMenu.ts
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+ /**
+ * Contextual Menu Plugin
+ */
+ export class ContextualMenu {
+
+ /**
+ *
+ * @param {HTMLDivElement} container - the target container for an instance of ContextualMenu
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $contextualMenu = $(container);
+ // Set selected states.
+ $contextualMenu.on("click", ".ms-ContextualMenu-link:not(.is-disabled)", function(event) {
+ event.preventDefault();
+
+ // Check if multiselect - set selected states
+ if ( $contextualMenu.hasClass("ms-ContextualMenu--multiselect") ) {
+
+ // If already selected, remove selection; if not, add selection
+ if ( $(this).hasClass("is-selected") ) {
+ $(this).removeClass("is-selected");
+ } else {
+ $(this).addClass("is-selected");
+ }
+ } else { // All other contextual menu variants
+ // Deselect all of the items and close any menus.
+ $(".ms-ContextualMenu-link")
+ .removeClass("is-selected")
+ .siblings(".ms-ContextualMenu")
+ .removeClass("is-open");
+
+ // Select this item.
+ $(this).addClass("is-selected");
+
+ // If this item has a menu, open it.
+ if ($(this).hasClass("ms-ContextualMenu-link--hasMenu")) {
+ $(this).siblings(".ms-ContextualMenu:first").addClass("is-open");
+
+ // Open the menu without bubbling up the click event,
+ // which can cause the menu to close.
+ event.stopPropagation();
+ }
+
+ }
+ });
+ }
+ }
+}
diff --git a/src/components/DatePicker/Jquery.DatePicker.js b/src/components/DatePicker/Jquery.DatePicker.js
deleted file mode 100644
index 74b4b674..00000000
--- a/src/components/DatePicker/Jquery.DatePicker.js
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-(function ($) {
-
- /**
- * DatePicker Plugin
- */
-
- $.fn.DatePicker = function (options) {
-
- return this.each(function () {
-
- /** Set up variables and run the Pickadate plugin. */
- var $datePicker = $(this);
- var $dateField = $datePicker.find('.ms-TextField-field').pickadate($.extend({
- // Strings and translations.
- weekdaysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
-
- // Don't render the buttons
- today: '',
- clear: '',
- close: '',
-
- // Events
- onStart: function() {
- initCustomView($datePicker);
- },
-
- // Classes
- klass: {
-
- // The element states
- input: 'ms-DatePicker-input',
- active: 'ms-DatePicker-input--active',
-
- // The root picker and states
- picker: 'ms-DatePicker-picker',
- opened: 'ms-DatePicker-picker--opened',
- focused: 'ms-DatePicker-picker--focused',
-
- // The picker holder
- holder: 'ms-DatePicker-holder',
-
- // The picker frame, wrapper, and box
- frame: 'ms-DatePicker-frame',
- wrap: 'ms-DatePicker-wrap',
- box: 'ms-DatePicker-dayPicker',
-
- // The picker header
- header: 'ms-DatePicker-header',
-
- // Month & year labels
- month: 'ms-DatePicker-month',
- year: 'ms-DatePicker-year',
-
- // Table of dates
- table: 'ms-DatePicker-table',
-
- // Weekday labels
- weekdays: 'ms-DatePicker-weekday',
-
- // Day states
- day: 'ms-DatePicker-day',
- disabled: 'ms-DatePicker-day--disabled',
- selected: 'ms-DatePicker-day--selected',
- highlighted: 'ms-DatePicker-day--highlighted',
- now: 'ms-DatePicker-day--today',
- infocus: 'ms-DatePicker-day--infocus',
- outfocus: 'ms-DatePicker-day--outfocus',
-
- }
- },options||{}));
- var $picker = $dateField.pickadate('picker');
-
- /** Respond to built-in picker events. */
- $picker.on({
- render: function() {
- updateCustomView($datePicker);
- },
- open: function() {
- scrollUp($datePicker);
- }
- });
-
- });
- };
-
- /**
- * After the Pickadate plugin starts, this function
- * adds additional controls to the picker view.
- */
- function initCustomView($datePicker) {
-
- /** Get some variables ready. */
- var $monthControls = $datePicker.find('.ms-DatePicker-monthComponents');
- var $goToday = $datePicker.find('.ms-DatePicker-goToday');
- var $monthPicker = $datePicker.find('.ms-DatePicker-monthPicker');
- var $yearPicker = $datePicker.find('.ms-DatePicker-yearPicker');
- var $pickerWrapper = $datePicker.find('.ms-DatePicker-wrap');
- var $picker = $datePicker.find('.ms-TextField-field').pickadate('picker');
-
- /** Move the month picker into position. */
- $monthControls.appendTo($pickerWrapper);
- $goToday.appendTo($pickerWrapper);
- $monthPicker.appendTo($pickerWrapper);
- $yearPicker.appendTo($pickerWrapper);
-
- /** Update the custom view. */
- updateCustomView($datePicker);
-
- /** Move back one month. */
- $monthControls.on('click', '.js-prevMonth', function(event) {
- event.preventDefault();
- var newMonth = $picker.get('highlight').month - 1;
- changeHighlightedDate($picker, null, newMonth, null);
- });
-
- /** Move ahead one month. */
- $monthControls.on('click', '.js-nextMonth', function(event) {
- event.preventDefault();
- var newMonth = $picker.get('highlight').month + 1;
- changeHighlightedDate($picker, null, newMonth, null);
- });
-
- /** Move back one year. */
- $monthPicker.on('click', '.js-prevYear', function(event) {
- event.preventDefault();
- var newYear = $picker.get('highlight').year - 1;
- changeHighlightedDate($picker, newYear, null, null);
- });
-
- /** Move ahead one year. */
- $monthPicker.on('click', '.js-nextYear', function(event) {
- event.preventDefault();
- var newYear = $picker.get('highlight').year + 1;
- changeHighlightedDate($picker, newYear, null, null);
- });
-
- /** Move back one decade. */
- $yearPicker.on('click', '.js-prevDecade', function(event) {
- event.preventDefault();
- var newYear = $picker.get('highlight').year - 10;
- changeHighlightedDate($picker, newYear, null, null);
- });
-
- /** Move ahead one decade. */
- $yearPicker.on('click', '.js-nextDecade', function(event) {
- event.preventDefault();
- var newYear = $picker.get('highlight').year + 10;
- changeHighlightedDate($picker, newYear, null, null);
- });
-
- /** Go to the current date, shown in the day picking view. */
- $goToday.click(function(event) {
- event.preventDefault();
-
- /** Select the current date, while keeping the picker open. */
- var now = new Date();
- $picker.set('select', [now.getFullYear(), now.getMonth(), now.getDate()]);
-
- /** Switch to the default (calendar) view. */
- $datePicker.removeClass('is-pickingMonths').removeClass('is-pickingYears');
-
- });
-
- /** Change the highlighted month. */
- $monthPicker.on('click', '.js-changeDate', function(event) {
- event.preventDefault();
-
- /** Get the requested date from the data attributes. */
- var newYear = $(this).attr('data-year');
- var newMonth = $(this).attr('data-month');
- var newDay = $(this).attr('data-day');
-
- /** Update the date. */
- changeHighlightedDate($picker, newYear, newMonth, newDay);
-
- /** If we've been in the "picking months" state on mobile, remove that state so we show the calendar again. */
- if ($datePicker.hasClass('is-pickingMonths')) {
- $datePicker.removeClass('is-pickingMonths');
- }
- });
-
- /** Change the highlighted year. */
- $yearPicker.on('click', '.js-changeDate', function(event) {
- event.preventDefault();
-
- /** Get the requested date from the data attributes. */
- var newYear = $(this).attr('data-year');
- var newMonth = $(this).attr('data-month');
- var newDay = $(this).attr('data-day');
-
- /** Update the date. */
- changeHighlightedDate($picker, newYear, newMonth, newDay);
-
- /** If we've been in the "picking years" state on mobile, remove that state so we show the calendar again. */
- if ($datePicker.hasClass('is-pickingYears')) {
- $datePicker.removeClass('is-pickingYears');
- }
- });
-
- /** Switch to the default state. */
- $monthPicker.on('click', '.js-showDayPicker', function() {
- $datePicker.removeClass('is-pickingMonths');
- $datePicker.removeClass('is-pickingYears');
- });
-
- /** Switch to the is-pickingMonths state. */
- $monthControls.on('click', '.js-showMonthPicker', function() {
- $datePicker.toggleClass('is-pickingMonths');
- });
-
- /** Switch to the is-pickingYears state. */
- $monthPicker.on('click', '.js-showYearPicker', function() {
- $datePicker.toggleClass('is-pickingYears');
- });
-
- }
-
- /** Change the highlighted date. */
- function changeHighlightedDate($picker, newYear, newMonth, newDay) {
-
- /** All letiables are optional. If not provided, default to the current value. */
- if (typeof newYear === "undefined" || newYear === null) {
- newYear = $picker.get("highlight").year;
- }
- if (typeof newMonth === "undefined" || newMonth === null) {
- newMonth = $picker.get("highlight").month;
- }
- if (typeof newDay === "undefined" || newDay === null) {
- newDay = $picker.get("highlight").date;
- }
-
- /** Update it. */
- $picker.set('highlight', [newYear, newMonth, newDay]);
-
- }
-
-
- /** Whenever the picker renders, do our own rendering on the custom controls. */
- function updateCustomView($datePicker) {
-
- /** Get some variables ready. */
- var $monthPicker = $datePicker.find('.ms-DatePicker-monthPicker');
- var $yearPicker = $datePicker.find('.ms-DatePicker-yearPicker');
- var $picker = $datePicker.find('.ms-TextField-field').pickadate('picker');
-
- /** Set the correct year. */
- $monthPicker.find('.ms-DatePicker-currentYear').text($picker.get('view').year);
-
- /** Highlight the current month. */
- $monthPicker.find('.ms-DatePicker-monthOption').removeClass('is-highlighted');
- $monthPicker.find('.ms-DatePicker-monthOption[data-month="' + $picker.get('highlight').month + '"]').addClass('is-highlighted');
-
- /** Generate the grid of years for the year picker view. */
-
- // Start by removing any existing generated output. */
- $yearPicker.find('.ms-DatePicker-currentDecade').remove();
- $yearPicker.find('.ms-DatePicker-optionGrid').remove();
-
- // Generate the output by going through the years.
- var startingYear = $picker.get('highlight').year - 11;
- var decadeText = startingYear + " - " + (startingYear + 11);
- var output = '' + decadeText + '
';
- output += '';
- for (var year = startingYear; year < (startingYear + 12); year++) {
- output += '' + year +' ';
- }
- output += '
';
-
- // Output the title and grid of years generated above.
- $yearPicker.append(output);
-
- /** Highlight the current year. */
- $yearPicker.find('.ms-DatePicker-yearOption').removeClass('is-highlighted');
- $yearPicker.find('.ms-DatePicker-yearOption[data-year="' + $picker.get('highlight').year + '"]').addClass('is-highlighted');
- }
-
- /** Scroll the page up so that the field the date picker is attached to is at the top. */
- function scrollUp($datePicker) {
- $('html, body').animate({
- scrollTop: $datePicker.offset().top
- }, 367);
- }
-
-})(jQuery);
diff --git a/src/components/DatePicker/Jquery.DatePicker.ts b/src/components/DatePicker/Jquery.DatePicker.ts
new file mode 100644
index 00000000..c2265d6e
--- /dev/null
+++ b/src/components/DatePicker/Jquery.DatePicker.ts
@@ -0,0 +1,286 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+///
+
+namespace fabric {
+ /**
+ * DatePicker Plugin
+ */
+ export class DatePicker {
+
+ constructor(container, options) {
+ /** Set up letiables and run the Pickadate plugin. */
+ let $datePicker = $(container);
+ let $dateField: any = $datePicker.find(".ms-TextField-field").pickadate($.extend({
+ // Strings and translations.
+ weekdaysShort: ["S", "M", "T", "W", "T", "F", "S"],
+
+ // Don't render the buttons
+ clear: "",
+ close: "",
+ today: "",
+
+ // Events
+ onStart: () => {
+ this.initCustomView($datePicker);
+ },
+
+ // Classes
+ klass: {
+
+ // The element states
+ input: "ms-DatePicker-input",
+ active: "ms-DatePicker-input--active",
+
+ // The root picker and states
+ picker: "ms-DatePicker-picker",
+ opened: "ms-DatePicker-picker--opened",
+ focused: "ms-DatePicker-picker--focused",
+
+ // The picker holder
+ holder: "ms-DatePicker-holder",
+
+ // The picker frame, wrapper, and box
+ frame: "ms-DatePicker-frame",
+ wrap: "ms-DatePicker-wrap",
+ box: "ms-DatePicker-dayPicker",
+
+ // The picker header
+ header: "ms-DatePicker-header",
+
+ // Month & year labels
+ month: "ms-DatePicker-month",
+ year: "ms-DatePicker-year",
+
+ // Table of dates
+ table: "ms-DatePicker-table",
+
+ // Weekday labels
+ weekdays: "ms-DatePicker-weekday",
+
+ // Day states
+ day: "ms-DatePicker-day",
+ disabled: "ms-DatePicker-day--disabled",
+ selected: "ms-DatePicker-day--selected",
+ highlighted: "ms-DatePicker-day--highlighted",
+ now: "ms-DatePicker-day--today",
+ infocus: "ms-DatePicker-day--infocus",
+ outfocus: "ms-DatePicker-day--outfocus",
+ },
+ }, options || {}));
+ let $picker = $dateField.pickadate("picker");
+
+ /** Respond to built-in picker events. */
+ $picker.on({
+ render: () => {
+ this.updateCustomView($datePicker);
+ },
+ open: () => {
+ this.scrollUp($datePicker);
+ },
+ });
+ }
+
+ /**
+ * After the Pickadate plugin starts, this function
+ * adds additional controls to the picker view.
+ */
+ public initCustomView($datePicker) {
+
+ /** Get some letiables ready. */
+ let $monthControls = $datePicker.find(".ms-DatePicker-monthComponents");
+ let $goToday = $datePicker.find(".ms-DatePicker-goToday");
+ let $monthPicker = $datePicker.find(".ms-DatePicker-monthPicker");
+ let $yearPicker = $datePicker.find(".ms-DatePicker-yearPicker");
+ let $pickerWrapper = $datePicker.find(".ms-DatePicker-wrap");
+ let $picker = $datePicker.find(".ms-TextField-field").pickadate("picker");
+
+ /** Move the month picker into position. */
+ $monthControls.appendTo($pickerWrapper);
+ $goToday.appendTo($pickerWrapper);
+ $monthPicker.appendTo($pickerWrapper);
+ $yearPicker.appendTo($pickerWrapper);
+
+ /** Update the custom view. */
+ this.updateCustomView($datePicker);
+
+ /** Move back one month. */
+ $monthControls.on("click", ".js-prevMonth", (event) => {
+ event.preventDefault();
+ let newMonth = $picker.get("highlight").month - 1;
+ this.changeHighlightedDate($picker, null, newMonth, null);
+ });
+
+ /** Move ahead one month. */
+ $monthControls.on("click", ".js-nextMonth", (event) => {
+ event.preventDefault();
+ let newMonth = $picker.get("highlight").month + 1;
+ this.changeHighlightedDate($picker, null, newMonth, null);
+ });
+
+ /** Move back one year. */
+ $monthPicker.on("click", ".js-prevYear", (event) => {
+ event.preventDefault();
+ let newYear = $picker.get("highlight").year - 1;
+ this.changeHighlightedDate($picker, newYear, null, null);
+ });
+
+ /** Move ahead one year. */
+ $monthPicker.on("click", ".js-nextYear", (event) => {
+ event.preventDefault();
+ let newYear = $picker.get("highlight").year + 1;
+ this.changeHighlightedDate($picker, newYear, null, null);
+ });
+
+ /** Move back one decade. */
+ $yearPicker.on("click", ".js-prevDecade", (event) => {
+ event.preventDefault();
+ let newYear = $picker.get("highlight").year - 10;
+ this.changeHighlightedDate($picker, newYear, null, null);
+ });
+
+ /** Move ahead one decade. */
+ $yearPicker.on("click", ".js-nextDecade", (event) => {
+ event.preventDefault();
+ let newYear = $picker.get("highlight").year + 10;
+ this.changeHighlightedDate($picker, newYear, null, null);
+ });
+
+ /** Go to the current date, shown in the day picking view. */
+ $goToday.click((event) => {
+ event.preventDefault();
+
+ /** Select the current date, while keeping the picker open. */
+ let now = new Date();
+ $picker.set("select", [now.getFullYear(), now.getMonth(), now.getDate()]);
+
+ /** Switch to the default (calendar) view. */
+ $datePicker.removeClass("is-pickingMonths").removeClass("is-pickingYears");
+
+ });
+
+ /** Change the highlighted month. */
+ $monthPicker.on("click", ".js-changeDate", (event) => {
+ event.preventDefault();
+
+ let $changeDate = $(event.toElement);
+
+ /** Get the requested date from the data attributes. */
+ let newYear = $changeDate.attr("data-year");
+ let newMonth = $changeDate.attr("data-month");
+ let newDay = $changeDate.attr("data-day");
+
+ /** Update the date. */
+ this.changeHighlightedDate($picker, newYear, newMonth, newDay);
+
+ /** If we"ve been in the "picking months" state on mobile, remove that state so we show the calendar again. */
+ if ($datePicker.hasClass("is-pickingMonths")) {
+ $datePicker.removeClass("is-pickingMonths");
+ }
+ });
+
+ /** Change the highlighted year. */
+ $yearPicker.on("click", ".js-changeDate", (event) => {
+ event.preventDefault();
+ let $changeDate = $(event.toElement);
+
+ /** Get the requested date from the data attributes. */
+ let newYear = $changeDate.attr("data-year");
+ let newMonth = $changeDate.attr("data-month");
+ let newDay = $changeDate.attr("data-day");
+
+ /** Update the date. */
+ this.changeHighlightedDate($picker, newYear, newMonth, newDay);
+
+ /** If we"ve been in the "picking years" state on mobile, remove that state so we show the calendar again. */
+ if ($datePicker.hasClass("is-pickingYears")) {
+ $datePicker.removeClass("is-pickingYears");
+ }
+ });
+
+ /** Switch to the default state. */
+ $monthPicker.on("click", ".js-showDayPicker", function() {
+ $datePicker.removeClass("is-pickingMonths");
+ $datePicker.removeClass("is-pickingYears");
+ });
+
+ /** Switch to the is-pickingMonths state. */
+ $monthControls.on("click", ".js-showMonthPicker", function() {
+ $datePicker.toggleClass("is-pickingMonths");
+ });
+
+ /** Switch to the is-pickingYears state. */
+ $monthPicker.on("click", ".js-showYearPicker", function() {
+ $datePicker.toggleClass("is-pickingYears");
+ });
+ }
+
+ /** Change the highlighted date. */
+ public changeHighlightedDate($picker, newYear, newMonth, newDay) {
+
+ /** All letiables are optional. If not provided, default to the current value. */
+ if (typeof newYear === "undefined" || newYear === null) {
+ newYear = $picker.get("highlight").year;
+ }
+ if (typeof newMonth === "undefined" || newMonth === null) {
+ newMonth = $picker.get("highlight").month;
+ }
+ if (typeof newDay === "undefined" || newDay === null) {
+ newDay = $picker.get("highlight").date;
+ }
+
+ /** Update it. */
+ $picker.set("highlight", [newYear, newMonth, newDay]);
+ }
+
+
+ /** Whenever the picker renders, do our own rendering on the custom controls. */
+ public updateCustomView($datePicker) {
+
+ /** Get some letiables ready. */
+ let $monthPicker = $datePicker.find(".ms-DatePicker-monthPicker");
+ let $yearPicker = $datePicker.find(".ms-DatePicker-yearPicker");
+ let $picker = $datePicker.find(".ms-TextField-field").pickadate("picker");
+
+ /** Set the correct year. */
+ $monthPicker.find(".ms-DatePicker-currentYear").text($picker.get("view").year);
+
+ /** Highlight the current month. */
+ $monthPicker.find(".ms-DatePicker-monthOption").removeClass("is-highlighted");
+ $monthPicker.find(".ms-DatePicker-monthOption[data-month='" + $picker.get("highlight").month + "']").addClass("is-highlighted");
+
+ /** Generate the grid of years for the year picker view. */
+
+ // Start by removing any existing generated output. */
+ $yearPicker.find(".ms-DatePicker-currentDecade").remove();
+ $yearPicker.find(".ms-DatePicker-optionGrid").remove();
+
+ // Generate the output by going through the years.
+ let startingYear = $picker.get("highlight").year - 11;
+ let decadeText = startingYear + " - " + (startingYear + 11);
+ let output = "" + decadeText + "
";
+ output += "";
+ for (let year = startingYear; year < (startingYear + 12); year++) {
+ output += "" + year + " ";
+ }
+ output += "
";
+
+ // Output the title and grid of years generated above.
+ $yearPicker.append(output);
+
+ /** Highlight the current year. */
+ $yearPicker.find(".ms-DatePicker-yearOption").removeClass("is-highlighted");
+ $yearPicker.find(".ms-DatePicker-yearOption[data-year='" + $picker.get("highlight").year + "']").addClass("is-highlighted");
+ }
+
+ /** Scroll the page up so that the field the date picker is attached to is at the top. */
+ public scrollUp($datePicker) {
+ $("html, body").animate({
+ scrollTop: $datePicker.offset().top,
+ }, 367);
+ }
+ }
+}
diff --git a/src/components/Dialog/jquery.Dialog.js b/src/components/Dialog/jquery.Dialog.js
deleted file mode 100644
index 0d647332..00000000
--- a/src/components/Dialog/jquery.Dialog.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Dialog Plugin
- *
- * Adds basic demonstration functionality to .ms-Dialog components.
- *
- * @param {jQuery Object} One or more .ms-Dialog components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.Dialog = function () {
-
- /** Iterate through the sample buttons, which can be used to open the Dialogs. */
- $(".js-DialogAction--open").each(function () {
- /** Open the associated dialog on click. */
- $(this).on('click', function () {
- var target = $(this).data("target");
- $(target).show();
- });
- });
-
-
- return this.each(function () {
- var dialog = this;
-
- /** Have the dialogs hidden for their initial state */
- $(dialog).hide();
-
- /** Have the close buttons close the Dialog. */
- $(dialog).find(".js-DialogAction--close").each(function() {
- $(this).on('click', function () {
- $(dialog).hide();
- });
- });
-
- /** Have the action buttons close the Dialog, though you would usually do some specific action per button. */
- $(dialog).find(".ms-Dialog-action").on('click', function () {
- $(dialog).hide();
- });
-
- });
- };
-})(jQuery);
diff --git a/src/components/Dialog/jquery.Dialog.ts b/src/components/Dialog/jquery.Dialog.ts
new file mode 100644
index 00000000..d938d28e
--- /dev/null
+++ b/src/components/Dialog/jquery.Dialog.ts
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+ /**
+ * Dialog Plugin
+ *
+ * Adds basic demonstration functionality to .ms-Dialog components.
+ */
+ export class Dialog {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Dialog
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let dialog = container;
+
+ /** Have the dialogs hidden for their initial state */
+ $(dialog).hide();
+
+ /** Have the close buttons close the Dialog. */
+ $(dialog).find(".js-DialogAction--close").each(function() {
+ $(this).on("click", function () {
+ $(dialog).hide();
+ });
+ });
+
+ /** Have the action buttons close the Dialog, though you would usually do some specific action per button. */
+ $(dialog).find(".ms-Dialog-action").on("click", function () {
+ $(dialog).hide();
+ });
+ }
+ } // end Dialog
+} // end Fabric namespace
+
+
+/* presentation code for the samples -
+ configure any sample buttons so that they open the associated Dialog */
+$(document).ready(function() {
+ /** Iterate through the sample buttons, which can be used to open the Dialogs. */
+ $(".js-DialogAction--open").each(function () {
+ /** Open the associated dialog on click. */
+ $(this).on("click", function () {
+ let target = $(this).data("target");
+ $(target).show();
+ });
+ });
+});
diff --git a/src/components/Dropdown/Jquery.Dropdown.js b/src/components/Dropdown/Jquery.Dropdown.js
deleted file mode 100644
index 30b806c5..00000000
--- a/src/components/Dropdown/Jquery.Dropdown.js
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Dropdown Plugin
- *
- * Given .ms-Dropdown containers with generic elements inside, this plugin hides the original
- * dropdown and creates a new "fake" dropdown that can more easily be styled across browsers.
- *
- * @param {jQuery Object} One or more .ms-Dropdown containers, each with a dropdown (.ms-Dropdown-select)
- * @return {jQuery Object} The same containers (allows for chaining)
- */
-(function ($) {
- $.fn.Dropdown = function () {
-
- /** Go through each dropdown we've been given. */
- return this.each(function () {
-
- var $dropdownWrapper = $(this),
- $originalDropdown = $dropdownWrapper.children('.ms-Dropdown-select'),
- $originalDropdownOptions = $originalDropdown.children('option'),
- newDropdownTitle = '',
- newDropdownItems = '',
- newDropdownSource = '';
-
- /** Go through the options to fill up newDropdownTitle and newDropdownItems. */
- $originalDropdownOptions.each(function (index, option) {
-
- /** If the option is selected, it should be the new dropdown's title. */
- if (option.selected) {
- newDropdownTitle = option.text;
- }
-
- /** Add this option to the list of items. */
- newDropdownItems += '' + option.text + ' ';
-
- });
-
- /** Insert the replacement dropdown. */
- newDropdownSource = '' + newDropdownTitle + ' ';
- $dropdownWrapper.append(newDropdownSource);
-
- function _openDropdown(evt) {
- if (!$dropdownWrapper.hasClass('is-disabled')) {
-
- /** First, let's close any open dropdowns on this page. */
- $dropdownWrapper.find('.is-open').removeClass('is-open');
-
- /** Stop the click event from propagating, which would just close the dropdown immediately. */
- evt.stopPropagation();
-
- /** Before opening, size the items list to match the dropdown. */
- var dropdownWidth = $(this).parents(".ms-Dropdown").width();
- $(this).next(".ms-Dropdown-items").css('width', dropdownWidth + 'px');
-
- /** Go ahead and open that dropdown. */
- $dropdownWrapper.toggleClass('is-open');
- $('.ms-Dropdown').each(function(){
- if ($(this)[0] !== $dropdownWrapper[0]) {
- $(this).removeClass('is-open');
- }
- });
-
- /** Temporarily bind an event to the document that will close this dropdown when clicking anywhere. */
- $(document).bind("click.dropdown", function() {
- $dropdownWrapper.removeClass('is-open');
- $(document).unbind('click.dropdown');
- });
- }
- }
-
- /** Toggle open/closed state of the dropdown when clicking its title. */
- $dropdownWrapper.on('click', '.ms-Dropdown-title', function(event) {
- _openDropdown(event);
- });
-
- /** Keyboard accessibility */
- $dropdownWrapper.on('keyup', function(event) {
- var keyCode = event.keyCode || event.which;
- // Open dropdown on enter or arrow up or arrow down and focus on first option
- if (!$(this).hasClass('is-open')) {
- if (keyCode === 13 || keyCode === 38 || keyCode === 40) {
- _openDropdown(event);
- if (!$(this).find('.ms-Dropdown-item').hasClass('is-selected')) {
- $(this).find('.ms-Dropdown-item:first').addClass('is-selected');
- }
- }
- }
- else if ($(this).hasClass('is-open')) {
- // Up arrow focuses previous option
- if (keyCode === 38) {
- if ($(this).find('.ms-Dropdown-item.is-selected').prev().siblings().size() > 0) {
- $(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').prev().addClass('is-selected');
- }
- }
- // Down arrow focuses next option
- if (keyCode === 40) {
- if ($(this).find('.ms-Dropdown-item.is-selected').next().siblings().size() > 0) {
- $(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').next().addClass('is-selected');
- }
- }
- // Enter to select item
- if (keyCode === 13) {
- if (!$dropdownWrapper.hasClass('is-disabled')) {
-
- // Item text
- var selectedItemText = $(this).find('.ms-Dropdown-item.is-selected').text();
-
- $(this).find('.ms-Dropdown-title').html(selectedItemText);
-
- /** Update the original dropdown. */
- $originalDropdown.find("option").each(function(key, value) {
- if (value.text === selectedItemText) {
- $(this).prop('selected', true);
- } else {
- $(this).prop('selected', false);
- }
- });
- $originalDropdown.change();
-
- $(this).removeClass('is-open');
- }
- }
- }
-
- // Close dropdown on esc
- if (keyCode === 27) {
- $(this).removeClass('is-open');
- }
- });
-
- /** Select an option from the dropdown. */
- $dropdownWrapper.on('click', '.ms-Dropdown-item', function () {
- if (!$dropdownWrapper.hasClass('is-disabled') && !$(this).hasClass('is-disabled')) {
-
- /** Deselect all items and select this one. */
- $(this).siblings('.ms-Dropdown-item').removeClass('is-selected');
- $(this).addClass('is-selected');
-
- /** Update the replacement dropdown's title. */
- $(this).parents().siblings('.ms-Dropdown-title').html($(this).text());
-
- /** Update the original dropdown. */
- var selectedItemText = $(this).text();
- $originalDropdown.find("option").each(function(key, value) {
- if (value.text === selectedItemText) {
- $(this).prop('selected', true);
- } else {
- $(this).prop('selected', false);
- }
- });
- $originalDropdown.change();
- }
- });
-
- });
- };
-})(jQuery);
\ No newline at end of file
diff --git a/src/components/Dropdown/Jquery.Dropdown.ts b/src/components/Dropdown/Jquery.Dropdown.ts
new file mode 100644
index 00000000..49c79bcd
--- /dev/null
+++ b/src/components/Dropdown/Jquery.Dropdown.ts
@@ -0,0 +1,162 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+ /**
+ * Dropdown Plugin
+ *
+ * Given .ms-Dropdown containers with generic elements inside, this plugin hides the original
+ * dropdown and creates a new "fake" dropdown that can more easily be styled across browsers.
+ *
+ */
+ export class Dropdown {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Dropdown
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $dropdownWrapper = $(container),
+ $originalDropdown = $dropdownWrapper.children(".ms-Dropdown-select"),
+ $originalDropdownOptions = $originalDropdown.children("option"),
+ newDropdownTitle = "",
+ newDropdownItems = "",
+ newDropdownSource = "";
+
+ /** Go through the options to fill up newDropdownTitle and newDropdownItems. */
+ $originalDropdownOptions.each(function (index, option: any) {
+
+ /** If the option is selected, it should be the new dropdown's title. */
+ if (option.selected) {
+ newDropdownTitle = option.text;
+ }
+
+ /** Add this option to the list of items. */
+ newDropdownItems += "" + option.text + " ";
+ });
+
+ /** Insert the replacement dropdown. */
+ newDropdownSource = "" + newDropdownTitle + " ";
+ newDropdownSource += "";
+ $dropdownWrapper.append(newDropdownSource);
+
+ function _openDropdown(evt: Event): void {
+ if (!$dropdownWrapper.hasClass("is-disabled")) {
+
+ /** First, let"s close any open dropdowns on this page. */
+ $dropdownWrapper.find(".is-open").removeClass("is-open");
+
+ /** Stop the click event from propagating, which would just close the dropdown immediately. */
+ evt.stopPropagation();
+
+ /** Before opening, size the items list to match the dropdown. */
+ let dropdownWidth = $(this).parents(".ms-Dropdown").width();
+ $(this).next(".ms-Dropdown-items").css("width", dropdownWidth + "px");
+
+ /** Go ahead and open that dropdown. */
+ $dropdownWrapper.toggleClass("is-open");
+ $(".ms-Dropdown").each(function(){
+ if ($(this)[0] !== $dropdownWrapper[0]) {
+ $(this).removeClass("is-open");
+ }
+ });
+
+ /** Temporarily bind an event to the document that will close this dropdown when clicking anywhere. */
+ $(document).bind("click.dropdown", function() {
+ $dropdownWrapper.removeClass("is-open");
+ $(document).unbind("click.dropdown");
+ });
+ }
+ }
+
+ /** Toggle open/closed state of the dropdown when clicking its title. */
+ $dropdownWrapper.on("click", ".ms-Dropdown-title", function(event) {
+ _openDropdown(event);
+ });
+
+ /** Keyboard accessibility */
+ $dropdownWrapper.on("keyup", function(event) {
+ let keyCode = event.keyCode || event.which;
+ // Open dropdown on enter or arrow up or arrow down and focus on first option
+ if (!$(this).hasClass("is-open")) {
+ if (keyCode === 13 || keyCode === 38 || keyCode === 40) {
+ _openDropdown(event);
+ if (!$(this).find(".ms-Dropdown-item").hasClass("is-selected")) {
+ $(this).find(".ms-Dropdown-item:first").addClass("is-selected");
+ }
+ }
+ } else if ($(this).hasClass("is-open")) {
+ // Up arrow focuses previous option
+ if (keyCode === 38) {
+ if ($(this).find(".ms-Dropdown-item.is-selected").prev().siblings().length > 0) {
+ $(this).find(".ms-Dropdown-item.is-selected").removeClass("is-selected").prev().addClass("is-selected");
+ }
+ }
+ // Down arrow focuses next option
+ if (keyCode === 40) {
+ if ($(this).find(".ms-Dropdown-item.is-selected").next().siblings().length > 0) {
+ $(this).find(".ms-Dropdown-item.is-selected").removeClass("is-selected").next().addClass("is-selected");
+ }
+ }
+ // Enter to select item
+ if (keyCode === 13) {
+ if (!$dropdownWrapper.hasClass("is-disabled")) {
+
+ // Item text
+ let selectedItemText = $(this).find(".ms-Dropdown-item.is-selected").text();
+
+ $(this).find(".ms-Dropdown-title").html(selectedItemText);
+
+ /** Update the original dropdown. */
+ $originalDropdown.find("option").each(function(key, value: any) {
+ if (value.text === selectedItemText) {
+ $(this).prop("selected", true);
+ } else {
+ $(this).prop("selected", false);
+ }
+ });
+ $originalDropdown.change();
+
+ $(this).removeClass("is-open");
+ }
+ }
+ }
+
+ // Close dropdown on esc
+ if (keyCode === 27) {
+ $(this).removeClass("is-open");
+ }
+ });
+
+ /** Select an option from the dropdown. */
+ $dropdownWrapper.on("click", ".ms-Dropdown-item", function () {
+ if (!$dropdownWrapper.hasClass("is-disabled") && !$(this).hasClass("is-disabled")) {
+
+ /** Deselect all items and select this one. */
+ $(this).siblings(".ms-Dropdown-item").removeClass("is-selected");
+ $(this).addClass("is-selected");
+
+ /** Update the replacement dropdown's title. */
+ $(this).parents().siblings(".ms-Dropdown-title").html($(this).text());
+
+ /** Update the original dropdown. */
+ let selectedItemText = $(this).text();
+ $originalDropdown.find("option").each(function(key, value: any) {
+ if (value.text === selectedItemText) {
+ $(this).prop("selected", true);
+ } else {
+ $(this).prop("selected", false);
+ }
+ });
+ $originalDropdown.change();
+ }
+ });
+ }
+ }
+}
diff --git a/src/components/Facepile/Jquery.Facepile.js b/src/components/Facepile/Jquery.Facepile.js
deleted file mode 100644
index 37690540..00000000
--- a/src/components/Facepile/Jquery.Facepile.js
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Facepile Plugin
- *
- * Adds basic demonstration functionality to .ms-Facepile components.
- *
- * @param {jQuery Object} One or more .ms-Facepile components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.Facepile = function () {
-
- /** Iterate through each Facepile provided. */
- return this.each(function () {
- $('.ms-PeoplePicker').PeoplePicker();
- $('.ms-Panel').Panel();
-
- var $Facepile = $(this);
- var $membersList = $(".ms-Facepile-members");
- var $membersCount = $(".ms-Facepile-members > .ms-Facepile-itemBtn").length;
- var $panel = $('.ms-Facepile-panel.ms-Panel');
- var $panelMain = $panel.find(".ms-Panel-main");
- var $picker = $('.ms-PeoplePicker.ms-PeoplePicker--Facepile');
- var $pickerMembers = $picker.find('.ms-PeoplePicker-selectedPeople');
- var $personaCard = $('.ms-Facepile').find('.ms-PersonaCard');
-
-
- /** Increment member count and show/hide overflow text */
- var incrementMembers = function() {
- /** Increment person count by one */
- $membersCount += 1;
-
- /** Display a maxiumum of 5 people */
- $(".ms-Facepile-members").children(":gt(4)").hide();
-
- /** Display counter after 5 people are present */
- if ($membersCount > 5) {
- $(".ms-Facepile-itemBtn--overflow").addClass("is-active");
-
- var remainingMembers = $membersCount - 5;
- $(".ms-Facepile-overflowText").text("+" + remainingMembers);
- }
- };
-
- /** Open panel with people picker */
- $Facepile.on("click", ".js-addPerson", function() {
- $panelMain.css({display: "block"});
- $panel.toggleClass("is-open")
- .addClass("ms-Panel-animateIn")
- .removeClass('ms-Facepile-panel--overflow ms-Panel--right')
- .addClass('ms-Facepile-panel--addPerson');
-
- /** Close any open persona cards */
- $personaCard.removeClass('is-active').hide();
- });
-
- $panel.on("click", ".js-togglePanel", function() {
- $panel.toggleClass("is-open")
- .addClass("ms-Panel-animateIn");
- });
-
- /** Open oveflow panel with list of members */
- $Facepile.on("click", ".js-overflowPanel", function() {
- $panelMain.css({display: "block"});
- $panel.toggleClass("is-open")
- .addClass("ms-Panel-animateIn")
- .removeClass('ms-Facepile-panel--addPerson')
- .addClass('ms-Facepile-panel--overflow ms-Panel--right');
- });
-
- /** Display person count on page load */
- $(document).ready(function() {
- $(".ms-Facepile-overflowText").text("+" + $membersCount);
- });
-
- /** Show selected members from PeoplePicker in the Facepile */
- $('.ms-PeoplePicker-result').on('click', function() {
- var $this = $(this);
- var name = $this.find(".ms-Persona-primaryText").html();
- var title = $this.find(".ms-Persona-secondaryText").html();
- var selectedInitials = (function() {
- var nameArray = name.split(' ');
- var nameInitials = '';
- for (var i = 0; i < nameArray.length; i++) {
- nameInitials += nameArray[i].charAt(0);
- }
-
- return nameInitials.substring(0,2);
- })();
- var selectedClasses = $this.find('.ms-Persona-initials').attr('class');
- var selectedImage = (function() {
- if ($this.find('.ms-Persona-image').length) {
- var selectedImageSrc = $this.find('.ms-Persona-image').attr('src');
- return ' ';
- } else {
- return '';
- }
- })();
-
- var FacepileItem =
- '' +
- '' +
- '
' +
- '
' + selectedInitials + '
' +
- selectedImage +
- '
' +
- '
' +
- '
' +
- '
' + name + '
' +
- '
' + title + '
' +
- '
' +
- '
' +
- ' ';
-
- /** Add new item to members list in Facepile */
- $membersList.prepend(FacepileItem);
-
- /** Increment member count */
- incrementMembers();
- });
-
- /** Remove members in panel people picker */
- $pickerMembers.on('click', '.js-selectedRemove', function() {
- var memberText = $(this).parent().find('.ms-Persona-primaryText').text();
-
- var $FacepileMember = $membersList.find(".ms-Persona-primaryText:contains(" + memberText + ")").first();
-
- if ($FacepileMember) {
- $FacepileMember.parent().closest('.ms-Facepile-itemBtn').remove();
-
- $membersCount -= 1;
-
- /** Display a maxiumum of 5 people */
- $(".ms-Facepile-members").children(":lt(5)").show();
-
- /** Display counter after 5 people are present */
- if ($membersCount <= 5) {
- $(".ms-Facepile-itemBtn--overflow").removeClass("is-active");
- } else {
- var remainingMembers = $membersCount - 5;
- $(".ms-Facepile-overflowText").text("+" + remainingMembers);
- }
- }
- });
-
- /** Show persona card when selecting a Facepile item */
- $membersList.on('click', '.ms-Facepile-itemBtn', function() {
- var selectedName = $(this).find(".ms-Persona-primaryText").html();
- var selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
- var selectedInitials = (function() {
- var name = selectedName.split(' ');
- var nameInitials = '';
- for (var i = 0; i < name.length; i++) {
- nameInitials += name[i].charAt(0);
- }
-
- return nameInitials.substring(0,2);
- })();
- var selectedClasses = $(this).find('.ms-Persona-initials').attr('class');
- var selectedImage = $(this).find('.ms-Persona-image').attr('src');
- var $card = $('.ms-PersonaCard');
- var $cardName = $card.find('.ms-Persona-primaryText');
- var $cardTitle = $card.find('.ms-Persona-secondaryText');
- var $cardInitials = $card.find('.ms-Persona-initials');
- var $cardImage = $card.find('.ms-Persona-image');
-
- /** Close any open persona cards */
- $personaCard.removeClass('is-active');
-
- /** Add data to persona card */
- $cardName.text(selectedName);
- $cardTitle.text(selectedTitle);
- $cardInitials.text(selectedInitials);
- $cardInitials.removeClass();
- $cardInitials.addClass(selectedClasses);
- $cardImage.attr('src', selectedImage);
-
- /** Show persona card */
- setTimeout(function() { $personaCard.addClass('is-active'); }, 100);
-
- /** Align persona card on md and above screens */
- if ($(window).width() > 480) {
- var itemPosition = $(this).offset().left;
- var correctedPosition = itemPosition - 26;
-
- $personaCard.css({'left': correctedPosition});
- } else {
- $personaCard.css({'left': 0, 'top': 'auto', 'position': 'fixed'});
- }
- });
-
- /** Dismiss persona card when clicking on the document */
- $(document).on('click', function(e) {
- var $memberBtn = $('.ms-Facepile-itemBtn--member');
-
- if (!$memberBtn.is(e.target) && $memberBtn.has(e.target).length === 0 && !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
- $personaCard.removeClass('is-active');
- $personaCard.removeAttr('style');
- } else {
- $personaCard.addClass('is-active');
- }
- });
-
- });
- };
-})(jQuery);
\ No newline at end of file
diff --git a/src/components/Facepile/Jquery.Facepile.ts b/src/components/Facepile/Jquery.Facepile.ts
new file mode 100644
index 00000000..431a1aae
--- /dev/null
+++ b/src/components/Facepile/Jquery.Facepile.ts
@@ -0,0 +1,218 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+///
+///
+
+namespace fabric {
+
+
+ /**
+ * Facepile Plugin
+ *
+ * Adds basic demonstration functionality to .ms-Facepile components.
+ *
+ */
+ export class Facepile {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Facepile
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ new fabric.PeoplePicker(document.querySelector(".ms-PeoplePicker"));
+ new fabric.Panel(document.querySelector(".ms-Panel"));
+
+ let $Facepile = $(container);
+ let $membersList = $(".ms-Facepile-members");
+ let $membersCount = $(".ms-Facepile-members > .ms-Facepile-itemBtn").length;
+ let $panel = $(".ms-Facepile-panel.ms-Panel");
+ let $panelMain = $panel.find(".ms-Panel-main");
+ let $picker = $(".ms-PeoplePicker.ms-PeoplePicker--Facepile");
+ let $pickerMembers = $picker.find(".ms-PeoplePicker-selectedPeople");
+ let $personaCard = $(".ms-Facepile").find(".ms-PersonaCard");
+
+
+ /** Increment member count and show/hide overflow text */
+ let incrementMembers = function() {
+ /** Increment person count by one */
+ $membersCount += 1;
+
+ /** Display a maxiumum of 5 people */
+ $(".ms-Facepile-members").children(":gt(4)").hide();
+
+ /** Display counter after 5 people are present */
+ if ($membersCount > 5) {
+ $(".ms-Facepile-itemBtn--overflow").addClass("is-active");
+
+ let remainingMembers = $membersCount - 5;
+ $(".ms-Facepile-overflowText").text("+" + remainingMembers);
+ }
+ };
+
+ /** Open panel with people picker */
+ $Facepile.on("click", ".js-addPerson", function() {
+ $panelMain.css({display: "block"});
+ $panel.toggleClass("is-open")
+ .addClass("ms-Panel-animateIn")
+ .removeClass("ms-Facepile-panel--overflow ms-Panel--right")
+ .addClass("ms-Facepile-panel--addPerson");
+
+ /** Close any open persona cards */
+ $personaCard.removeClass("is-active").hide();
+ });
+
+ $panel.on("click", ".js-togglePanel", function() {
+ $panel.toggleClass("is-open")
+ .addClass("ms-Panel-animateIn");
+ });
+
+ /** Open oveflow panel with list of members */
+ $Facepile.on("click", ".js-overflowPanel", function() {
+ $panelMain.css({display: "block"});
+ $panel.toggleClass("is-open")
+ .addClass("ms-Panel-animateIn")
+ .removeClass("ms-Facepile-panel--addPerson")
+ .addClass("ms-Facepile-panel--overflow ms-Panel--right");
+ });
+
+ /** Display person count on page load */
+ $(document).ready(function() {
+ $(".ms-Facepile-overflowText").text("+" + $membersCount);
+ });
+
+ /** Show selected members from PeoplePicker in the Facepile */
+ $(".ms-PeoplePicker-result").on("click", function() {
+ let $this = $(this);
+ let name = $this.find(".ms-Persona-primaryText").html();
+ let title = $this.find(".ms-Persona-secondaryText").html();
+ let selectedInitials = (function() {
+ let nameArray = name.split(" ");
+ let nameInitials = "";
+ for (let i = 0; i < nameArray.length; i++) {
+ nameInitials += nameArray[i].charAt(0);
+ }
+
+ return nameInitials.substring(0, 2);
+ })();
+ let selectedClasses = $this.find(".ms-Persona-initials").attr("class");
+ let selectedImage = (function() {
+ if ($this.find(".ms-Persona-image").length) {
+ let selectedImageSrc = $this.find(".ms-Persona-image").attr("src");
+ return " ";
+ } else {
+ return "";
+ }
+ })();
+
+ let FacepileItem =
+ "" +
+ "" +
+ "
" +
+ "
" + selectedInitials + "
" +
+ selectedImage +
+ "
" +
+ "
" +
+ "
" +
+ "
" + name + "
" +
+ "
" + title + "
" +
+ "
" +
+ "
" +
+ " ";
+
+ /** Add new item to members list in Facepile */
+ $membersList.prepend(FacepileItem);
+
+ /** Increment member count */
+ incrementMembers();
+ });
+
+ /** Remove members in panel people picker */
+ $pickerMembers.on("click", ".js-selectedRemove", function() {
+ let memberText = $(this).parent().find(".ms-Persona-primaryText").text();
+
+ let $FacepileMember = $membersList.find(".ms-Persona-primaryText:contains(" + memberText + ")").first();
+
+ if ($FacepileMember) {
+ $FacepileMember.parent().closest(".ms-Facepile-itemBtn").remove();
+
+ $membersCount -= 1;
+
+ /** Display a maxiumum of 5 people */
+ $(".ms-Facepile-members").children(":lt(5)").show();
+
+ /** Display counter after 5 people are present */
+ if ($membersCount <= 5) {
+ $(".ms-Facepile-itemBtn--overflow").removeClass("is-active");
+ } else {
+ let remainingMembers = $membersCount - 5;
+ $(".ms-Facepile-overflowText").text("+" + remainingMembers);
+ }
+ }
+ });
+
+ /** Show persona card when selecting a Facepile item */
+ $membersList.on("click", ".ms-Facepile-itemBtn", function() {
+ let selectedName = $(this).find(".ms-Persona-primaryText").html();
+ let selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
+ let selectedInitials = (function() {
+ let name = selectedName.split(" ");
+ let nameInitials = "";
+ for (let i = 0; i < name.length; i++) {
+ nameInitials += name[i].charAt(0);
+ }
+
+ return nameInitials.substring(0, 2);
+ })();
+ let selectedClasses = $(this).find(".ms-Persona-initials").attr("class");
+ let selectedImage = $(this).find(".ms-Persona-image").attr("src");
+ let $card = $(".ms-PersonaCard");
+ let $cardName = $card.find(".ms-Persona-primaryText");
+ let $cardTitle = $card.find(".ms-Persona-secondaryText");
+ let $cardInitials = $card.find(".ms-Persona-initials");
+ let $cardImage = $card.find(".ms-Persona-image");
+
+ /** Close any open persona cards */
+ $personaCard.removeClass("is-active");
+
+ /** Add data to persona card */
+ $cardName.text(selectedName);
+ $cardTitle.text(selectedTitle);
+ $cardInitials.text(selectedInitials);
+ $cardInitials.removeClass();
+ $cardInitials.addClass(selectedClasses);
+ $cardImage.attr("src", selectedImage);
+
+ /** Show persona card */
+ setTimeout(function() { $personaCard.addClass("is-active"); }, 100);
+
+ /** Align persona card on md and above screens */
+ if ($(window).width() > 480) {
+ let itemPosition = $(this).offset().left;
+ let correctedPosition = itemPosition - 26;
+
+ $personaCard.css({"left": correctedPosition});
+ } else {
+ $personaCard.css({"left": 0, "top": "auto", "position": "fixed"});
+ }
+ });
+
+ /** Dismiss persona card when clicking on the document */
+ $(document).on("click", function(e) {
+ let $memberBtn = $(".ms-Facepile-itemBtn--member");
+
+ if (!$memberBtn.is(e.target) && $memberBtn.has(e.target).length === 0 &&
+ !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
+ $personaCard.removeClass("is-active");
+ $personaCard.removeAttr("style");
+ } else {
+ $personaCard.addClass("is-active");
+ }
+ });
+
+ }
+ }
+}
diff --git a/src/components/ListItem/Jquery.ListItem.js b/src/components/ListItem/Jquery.ListItem.js
deleted file mode 100644
index 8248bfc2..00000000
--- a/src/components/ListItem/Jquery.ListItem.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * List Item Plugin
- *
- * Adds basic demonstration functionality to .ms-ListItem components.
- *
- * @param {jQuery Object} One or more .ms-ListItem components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.ListItem = function () {
-
- /** Go through each panel we've been given. */
- return this.each(function () {
-
- var $listItem = $(this);
-
- /** Detect clicks on selectable list items. */
- $listItem.on('click', '.js-toggleSelection', function() {
- $(this).parents('.ms-ListItem').toggleClass('is-selected');
- });
-
- });
-
- };
-})(jQuery);
diff --git a/src/components/ListItem/Jquery.ListItem.ts b/src/components/ListItem/Jquery.ListItem.ts
new file mode 100644
index 00000000..6ac1b5bd
--- /dev/null
+++ b/src/components/ListItem/Jquery.ListItem.ts
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+ /**
+ * List Item Plugin
+ *
+ * Adds basic demonstration functionality to .ms-ListItem components.
+ *
+ */
+ export class ListItem {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of ListItem
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ /** Detect clicks on selectable list items. */
+ $(container).on("click", ".js-toggleSelection", function() {
+ $(this).parents(".ms-ListItem").toggleClass("is-selected");
+ });
+ }
+ }
+}
diff --git a/src/components/MessageBanner/MessageBanner.js b/src/components/MessageBanner/MessageBanner.js
deleted file mode 100644
index 71edf977..00000000
--- a/src/components/MessageBanner/MessageBanner.js
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * MessageBanner component
- *
- * A component to display error messages
- *
- */
-
-/**
- * @namespace fabric
- */
-var fabric = fabric || {};
-/**
- *
- * @param {HTMLElement} container - the target container for an instance of MessageBanner
- * @constructor
- */
-fabric.MessageBanner = function(container) {
- this.container = container;
- this.init();
-};
-
-fabric.MessageBanner.prototype = (function() {
-
- var _clipper;
- var _bufferSize;
- var _textContainerMaxWidth = 700;
- var _clientWidth;
- var _textWidth;
- var _initTextWidth;
- var _chevronButton;
- var _errorBanner;
- var _actionButton;
- var _closeButton;
- var _bufferElementsWidth = 88;
- var _bufferElementsWidthSmall = 35;
- var SMALL_BREAK_POINT = 480;
-
- /**
- * sets styles on resize
- */
- var _onResize = function() {
- _clientWidth = _errorBanner.offsetWidth;
- if(window.innerWidth >= SMALL_BREAK_POINT ) {
- _resizeRegular();
- } else {
- _resizeSmall();
- }
- };
-
- /**
- * resize above 480 pixel breakpoint
- */
- var _resizeRegular = function() {
- if ((_clientWidth - _bufferSize) > _initTextWidth && _initTextWidth < _textContainerMaxWidth) {
- _textWidth = "auto";
- _chevronButton.className = "ms-MessageBanner-expand";
- _collapse();
- } else {
- _textWidth = Math.min((_clientWidth - _bufferSize), _textContainerMaxWidth) + "px";
- if(_chevronButton.className.indexOf("is-visible") === -1) {
- _chevronButton.className += " is-visible";
- }
- }
- _clipper.style.width = _textWidth;
- };
-
- /**
- * resize below 480 pixel breakpoint
- */
- var _resizeSmall = function() {
- if (_clientWidth - (_bufferElementsWidthSmall + _closeButton.offsetWidth) > _initTextWidth) {
- _textWidth = "auto";
- _collapse();
- } else {
- _textWidth = (_clientWidth - (_bufferElementsWidthSmall + _closeButton.offsetWidth)) + "px";
- }
- _clipper.style.width = _textWidth;
- };
- /**
- * caches elements and values of the component
- */
- var _cacheDOM = function(context) {
- _errorBanner = context.container;
- _clipper = context.container.querySelector('.ms-MessageBanner-clipper');
- _chevronButton = context.container.querySelector('.ms-MessageBanner-expand');
- _actionButton = context.container.querySelector('.ms-MessageBanner-action');
- _bufferSize = _actionButton.offsetWidth + _bufferElementsWidth;
- _closeButton = context.container.querySelector('.ms-MessageBanner-close');
- };
-
- /**
- * expands component to show full error message
- */
- var _expand = function() {
- var icon = _chevronButton.querySelector('.ms-Icon');
- _errorBanner.className += " is-expanded";
- icon.className = "ms-Icon ms-Icon--chevronsUp";
- };
-
- /**
- * collapses component to only show truncated message
- */
- var _collapse = function() {
- var icon = _chevronButton.querySelector('.ms-Icon');
- _errorBanner.className = "ms-MessageBanner";
- icon.className = "ms-Icon ms-Icon--chevronsDown";
- };
-
- var _toggleExpansion = function() {
- if (_errorBanner.className.indexOf("is-expanded") > -1) {
- _collapse();
- } else {
- _expand();
- }
- };
-
- /**
- * hides banner when close button is clicked
- */
- var _hideBanner = function() {
- if(_errorBanner.className.indexOf("hide") === -1) {
- _errorBanner.className += " hide";
- setTimeout(function() {
- _errorBanner.className = "ms-MessageBanner is-hidden";
- }, 500);
- }
- };
-
- /**
- * shows banner if the banner is hidden
- */
- var _showBanner = function() {
- _errorBanner.className = "ms-MessageBanner";
- };
-
- /**
- * sets handlers for resize and button click events
- */
- var _setListeners = function() {
- window.addEventListener('resize', _onResize, false);
- _chevronButton.addEventListener("click", _toggleExpansion, false);
- _closeButton.addEventListener("click", _hideBanner, false);
- };
-
- /**
- * initializes component
- */
- var init = function() {
- _cacheDOM(this);
- _setListeners();
- _clientWidth = _errorBanner.offsetWidth;
- _initTextWidth = _clipper.offsetWidth;
- _onResize(null);
- };
-
- return {
- init: init,
- showBanner: _showBanner
- };
-}());
diff --git a/src/components/MessageBanner/MessageBanner.ts b/src/components/MessageBanner/MessageBanner.ts
new file mode 100644
index 00000000..f7936b3e
--- /dev/null
+++ b/src/components/MessageBanner/MessageBanner.ts
@@ -0,0 +1,163 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+
+/**
+ * @namespace fabric
+ */
+namespace fabric {
+ "use strict";
+
+ /**
+ * MessageBanner component
+ *
+ * A component to display error messages
+ *
+ */
+ export class MessageBanner {
+ public container: HTMLElement;
+
+ private _clipper: HTMLElement;
+ private _bufferSize: number;
+ private _textContainerMaxWidth: number = 700;
+ private _clientWidth: number;
+ private _textWidth: string;
+ private _initTextWidth: number;
+ private _chevronButton: HTMLElement;
+ private _errorBanner: HTMLElement;
+ private _actionButton: HTMLElement;
+ private _closeButton: HTMLElement;
+ private _bufferElementsWidth: number = 88;
+ private _bufferElementsWidthSmall: number = 35;
+ private SMALL_BREAK_POINT: number = 480;
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of MessageBanner
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ this.container = container;
+ this.init();
+ }
+
+ /**
+ * initializes component
+ */
+ public init(): void {
+ this._cacheDOM();
+ this._setListeners();
+ this._clientWidth = this._errorBanner.offsetWidth;
+ this._initTextWidth = this._clipper.offsetWidth;
+ this._onResize();
+ }
+
+ /**
+ * shows banner if the banner is hidden
+ */
+ public showBanner(): void {
+ this._errorBanner.className = "ms-MessageBanner";
+ }
+
+ /**
+ * sets styles on resize
+ */
+ private _onResize(): void {
+ this._clientWidth = this._errorBanner.offsetWidth;
+ if (window.innerWidth >= this.SMALL_BREAK_POINT ) {
+ this._resizeRegular();
+ } else {
+ this._resizeSmall();
+ }
+ }
+
+ /**
+ * resize above 480 pixel breakpoint
+ */
+ private _resizeRegular(): void {
+ if ((this._clientWidth - this._bufferSize) > this._initTextWidth && this._initTextWidth < this._textContainerMaxWidth) {
+ this._textWidth = "auto";
+ this._chevronButton.className = "ms-MessageBanner-expand";
+ this._collapse();
+ } else {
+ this._textWidth = Math.min((this._clientWidth - this._bufferSize), this._textContainerMaxWidth) + "px";
+ if (this._chevronButton.className.indexOf("is-visible") === -1) {
+ this._chevronButton.className += " is-visible";
+ }
+ }
+ this._clipper.style.width = this._textWidth;
+ }
+
+ /**
+ * resize below 480 pixel breakpoint
+ */
+ private _resizeSmall(): void {
+ if (this._clientWidth - (this._bufferElementsWidthSmall + this._closeButton.offsetWidth) > this._initTextWidth) {
+ this._textWidth = "auto";
+ this._collapse();
+ } else {
+ this._textWidth = (this._clientWidth - (this._bufferElementsWidthSmall + this._closeButton.offsetWidth)) + "px";
+ }
+ this._clipper.style.width = this._textWidth;
+ }
+
+ /**
+ * caches elements and values of the component
+ */
+ private _cacheDOM(): void {
+ this._errorBanner = this.container;
+ this._clipper = this.container.querySelector(".ms-MessageBanner-clipper");
+ this._chevronButton = this.container.querySelector(".ms-MessageBanner-expand");
+ this._actionButton = this.container.querySelector(".ms-MessageBanner-action");
+ this._bufferSize = this._actionButton.offsetWidth + this._bufferElementsWidth;
+ this._closeButton = this.container.querySelector(".ms-MessageBanner-close");
+ }
+
+ /**
+ * expands component to show full error message
+ */
+ private _expand(): void {
+ let icon = this._chevronButton.querySelector(".ms-Icon");
+ this._errorBanner.className += " is-expanded";
+ icon.className = "ms-Icon ms-Icon--chevronsUp";
+ }
+
+ /**
+ * collapses component to only show truncated message
+ */
+ private _collapse(): void {
+ let icon = this._chevronButton.querySelector(".ms-Icon");
+ this._errorBanner.className = "ms-MessageBanner";
+ icon.className = "ms-Icon ms-Icon--chevronsDown";
+ }
+
+ private _toggleExpansion(): void {
+ if (this._errorBanner.className.indexOf("is-expanded") > -1) {
+ this._collapse();
+ } else {
+ this._expand();
+ }
+ }
+
+ private _hideMessageBanner(): void {
+ this._errorBanner.className = "ms-MessageBanner is-hidden";
+ }
+
+ /**
+ * hides banner when close button is clicked
+ */
+ private _hideBanner(): void {
+ if (this._errorBanner.className.indexOf("hide") === -1) {
+ this._errorBanner.className += " hide";
+ setTimeout(this._hideMessageBanner.bind(this), 500);
+ }
+ }
+
+ /**
+ * sets handlers for resize and button click events
+ */
+ private _setListeners(): void {
+ window.addEventListener("resize", this._onResize.bind(this), false);
+ this._chevronButton.addEventListener("click", this._toggleExpansion.bind(this), false);
+ this._closeButton.addEventListener("click", this._hideBanner.bind(this), false);
+ }
+ }
+} // end fabric namespace
diff --git a/src/components/NavBar/Jquery.NavBar.js b/src/components/NavBar/Jquery.NavBar.js
deleted file mode 100644
index 10202242..00000000
--- a/src/components/NavBar/Jquery.NavBar.js
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Nav Bar Plugin
- */
-(function ($) {
- $.fn.NavBar = function () {
-
- /** Go through each nav bar we've been given. */
- return this.each(function () {
-
- var $navBar = $(this);
-
- // Open the nav bar on mobile.
- $navBar.on('click', '.js-openMenu', function(event) {
- event.stopPropagation();
- $navBar.toggleClass('is-open');
- });
-
- // Close the nav bar on mobile.
- $navBar.click(function() {
- if ($navBar.hasClass('is-open')) {
- $navBar.removeClass('is-open');
- }
- });
-
- // Set selected states and open/close menus.
- $navBar.on('click', '.ms-NavBar-item:not(.is-disabled)', function(event) {
- var $searchBox = $navBar.find('.ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field');
- event.stopPropagation();
-
- // Prevent default actions from firing if links are not found.
- if ($(this).children('.ms-NavBar-link').length === 0) {
- event.preventDefault();
- }
-
- // Deselect all of the items.
- $(this).siblings('.ms-NavBar-item').removeClass('is-selected');
-
- // Close and blur the search box if it doesn't have text.
- if ($searchBox.length > 0 && $searchBox.val().length === 0) {
- $('.ms-NavBar-item.ms-NavBar-item--search').removeClass('is-open').find('.ms-TextField-field').blur();
- }
-
- // Does the selected item have a menu?
- if ($(this).hasClass('ms-NavBar-item--hasMenu')) {
-
- // First, close any neighboring menus.
- $(this).siblings('.ms-NavBar-item--hasMenu').children('.ms-ContextualMenu:first').removeClass('is-open');
-
- // Toggle 'is-open' to open or close it.
- $(this).children('.ms-ContextualMenu:first').toggleClass('is-open');
-
- // Toggle 'is-selected' to indicate whether it is active.
- $(this).toggleClass('is-selected');
- } else {
- // Doesn't have a menu, so just select the item.
- $(this).addClass('is-selected');
-
- // Close the submenu and any open contextual menus.
- $navBar.removeClass('is-open').find('.ms-ContextualMenu').removeClass('is-open');
- }
-
- // Is this the search box? Open it up and focus on the search field.
- if ($(this).hasClass('ms-NavBar-item--search')) {
- $(this).addClass('is-open');
- $(this).find('.ms-TextField-field').focus();
-
- // Close any open menus.
- $navBar.find('.ms-ContextualMenu:first').removeClass('is-open');
- }
- });
-
- // Prevent contextual menus from being hidden when clicking on them.
- $navBar.on('click', '.ms-NavBar-item .ms-ContextualMenu', function(event) {
- event.stopPropagation();
-
- // Collapse the mobile "panel" for nav items.
- $(this).removeClass('is-open');
- $navBar.removeClass('is-open').find('.ms-NavBar-item--hasMenu').removeClass('is-selected');
- });
-
- // Hide any menus and close the search box when clicking anywhere in the document.
- $(document).on('click', 'html', function() {
- var $searchBox = $navBar.find('.ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field');
- $navBar.find('.ms-NavBar-item').removeClass('is-selected').find('.ms-ContextualMenu').removeClass('is-open');
-
- // Close and blur the search box if it doesn't have text.
- if ($searchBox.length > 0 && $searchBox.val().length === 0) {
- $navBar.find('.ms-NavBar-item.ms-NavBar-item--search').removeClass('is-open').find('.ms-TextField-field').blur();
- }
- });
- });
- };
-})(jQuery);
diff --git a/src/components/NavBar/Jquery.NavBar.ts b/src/components/NavBar/Jquery.NavBar.ts
new file mode 100644
index 00000000..903a076a
--- /dev/null
+++ b/src/components/NavBar/Jquery.NavBar.ts
@@ -0,0 +1,102 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+ /**
+ * Nav Bar Plugin
+ */
+ export class NavBar {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of NavBar
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $navBar = $(container);
+
+ // Open the nav bar on mobile.
+ $navBar.on("click", ".js-openMenu", function(event) {
+ event.stopPropagation();
+ $navBar.toggleClass("is-open");
+ });
+
+ // Close the nav bar on mobile.
+ $navBar.click(function() {
+ if ($navBar.hasClass("is-open")) {
+ $navBar.removeClass("is-open");
+ }
+ });
+
+ // Set selected states and open/close menus.
+ $navBar.on("click", ".ms-NavBar-item:not(.is-disabled)", function(event) {
+ let $searchBox = $navBar.find(".ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field");
+ event.stopPropagation();
+
+ // Prevent default actions from firing if links are not found.
+ if ($(this).children(".ms-NavBar-link").length === 0) {
+ event.preventDefault();
+ }
+
+ // Deselect all of the items.
+ $(this).siblings(".ms-NavBar-item").removeClass("is-selected");
+
+ // Close and blur the search box if it doesn't have text.
+ if ($searchBox.length > 0 && $searchBox.val().length === 0) {
+ $(".ms-NavBar-item.ms-NavBar-item--search").removeClass("is-open").find(".ms-TextField-field").blur();
+ }
+
+ // Does the selected item have a menu?
+ if ($(this).hasClass("ms-NavBar-item--hasMenu")) {
+
+ // First, close any neighboring menus.
+ $(this).siblings(".ms-NavBar-item--hasMenu").children(".ms-ContextualMenu:first").removeClass("is-open");
+
+ // Toggle "is-open" to open or close it.
+ $(this).children(".ms-ContextualMenu:first").toggleClass("is-open");
+
+ // Toggle "is-selected" to indicate whether it is active.
+ $(this).toggleClass("is-selected");
+ } else {
+ // Doesn't have a menu, so just select the item.
+ $(this).addClass("is-selected");
+
+ // Close the submenu and any open contextual menus.
+ $navBar.removeClass("is-open").find(".ms-ContextualMenu").removeClass("is-open");
+ }
+
+ // Is this the search box? Open it up and focus on the search field.
+ if ($(this).hasClass("ms-NavBar-item--search")) {
+ $(this).addClass("is-open");
+ $(this).find(".ms-TextField-field").focus();
+
+ // Close any open menus.
+ $navBar.find(".ms-ContextualMenu:first").removeClass("is-open");
+ }
+ });
+
+ // Prevent contextual menus from being hidden when clicking on them.
+ $navBar.on("click", ".ms-NavBar-item .ms-ContextualMenu", function(event) {
+ event.stopPropagation();
+
+ // Collapse the mobile "panel" for nav items.
+ $(this).removeClass("is-open");
+ $navBar.removeClass("is-open").find(".ms-NavBar-item--hasMenu").removeClass("is-selected");
+ });
+
+ // Hide any menus and close the search box when clicking anywhere in the document.
+ $(document).on("click", "html", function() {
+ let $searchBox = $navBar.find(".ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field");
+ $navBar.find(".ms-NavBar-item").removeClass("is-selected").find(".ms-ContextualMenu").removeClass("is-open");
+
+ // Close and blur the search box if it doesn't have text.
+ if ($searchBox.length > 0 && $searchBox.val().length === 0) {
+ $navBar.find(".ms-NavBar-item.ms-NavBar-item--search").removeClass("is-open").find(".ms-TextField-field").blur();
+ }
+ });
+ }
+ }
+}
diff --git a/src/components/Panel/Jquery.Panel.js b/src/components/Panel/Jquery.Panel.js
deleted file mode 100644
index 1bb22422..00000000
--- a/src/components/Panel/Jquery.Panel.js
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Panel Plugin
- *
- * Adds basic demonstration functionality to .ms-Panel components.
- *
- * @param {jQuery Object} One or more .ms-Panel components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.Panel = function () {
-
- var pfx = ["webkit", "moz", "MS", "o", ""];
-
- // Prefix function
- function prefixedEvent(element, type, callback) {
- for (var p = 0; p < pfx.length; p++) {
- if (!pfx[p]) { type = type.toLowerCase(); }
- element.addEventListener(pfx[p]+type, callback, false);
- }
- }
-
- /** Go through each panel we've been given. */
- return this.each(function () {
-
- var $panel = $(this);
- var $panelMain = $panel.find(".ms-Panel-main");
-
- /** Hook to open the panel. */
- $(".ms-PanelAction-close").on("click", function() {
-
- // Display Panel first, to allow animations
- $panel.addClass("ms-Panel-animateOut");
-
- });
-
- $(".ms-PanelAction-open").on("click", function() {
-
- // Display Panel first, to allow animations
- $panel.addClass("is-open");
-
- // Add animation class
- $panel.addClass("ms-Panel-animateIn");
-
- });
-
- prefixedEvent($panelMain[0], 'AnimationEnd', function(event) {
- if (event.animationName.indexOf('Out') > -1) {
-
- // Hide and Prevent ms-Panel-main from being interactive
- $panel.removeClass('is-open');
-
- // Remove animating classes for the next time we open panel
- $panel.removeClass('ms-Panel-animateIn ms-Panel-animateOut');
-
- }
- });
-
- // Pivots for sample page to show variant panel sizes
- $(".panelVariant-item").on("click", function() {
- var className = $(this).find('span').attr('class');
-
- $(".panelVariant-item").removeClass('is-selected');
- $(this).addClass('is-selected');
-
- switch (className) {
- case 'is-default':
- $('.ms-Panel').removeClass().addClass('ms-Panel');
- break;
- case 'is-left':
- $('.ms-Panel').removeClass().addClass('ms-Panel ms-Panel--left');
- break;
- case 'is-lightDismiss':
- $('.ms-Panel').removeClass().addClass('ms-Panel ms-Panel--lightDismiss');
- break;
- case 'is-md':
- $('.ms-Panel').removeClass().addClass('ms-Panel ms-Panel--md');
- break;
- case 'is-lg':
- $('.ms-Panel').removeClass().addClass('ms-Panel ms-Panel--lg');
- break;
- case 'is-xl':
- $('.ms-Panel').removeClass().addClass('ms-Panel ms-Panel--xl');
- break;
- }
- });
- });
-
- };
-})(jQuery);
diff --git a/src/components/Panel/Jquery.Panel.ts b/src/components/Panel/Jquery.Panel.ts
new file mode 100644
index 00000000..86475e11
--- /dev/null
+++ b/src/components/Panel/Jquery.Panel.ts
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+ let pfx = ["webkit", "moz", "MS", "o", ""];
+
+ // Prefix function
+ function prefixedEvent(element, type, callback) {
+ for (let p = 0; p < pfx.length; p++) {
+ if (!pfx[p]) { type = type.toLowerCase(); }
+ element.addEventListener(pfx[p] + type, callback, false);
+ }
+ }
+
+
+ /**
+ * Panel Plugin
+ *
+ * Adds basic demonstration functionality to .ms-Panel components.
+ *
+ */
+ export class Panel {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Panel
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $panel = $(container);
+ let $panelMain = $panel.find(".ms-Panel-main");
+
+ /** Hook to open the panel. */
+ $(".ms-PanelAction-close").on("click", function() {
+
+ // Display Panel first, to allow animations
+ $panel.addClass("ms-Panel-animateOut");
+
+ });
+
+ $(".ms-PanelAction-open").on("click", function() {
+
+ // Display Panel first, to allow animations
+ $panel.addClass("is-open");
+
+ // Add animation class
+ $panel.addClass("ms-Panel-animateIn");
+
+ });
+
+ prefixedEvent($panelMain[0], "AnimationEnd", function(event) {
+ if (event.animationName.indexOf("Out") > -1) {
+
+ // Hide and Prevent ms-Panel-main from being interactive
+ $panel.removeClass("is-open");
+
+ // Remove animating classes for the next time we open panel
+ $panel.removeClass("ms-Panel-animateIn ms-Panel-animateOut");
+
+ }
+ });
+
+ // Pivots for sample page to show letiant panel sizes
+ $(".panelVariant-item").on("click", function() {
+ let className = $(this).find("span").attr("class");
+
+ $(".panelVariant-item").removeClass("is-selected");
+ $(this).addClass("is-selected");
+
+ switch (className) {
+ case "is-default":
+ $(".ms-Panel").removeClass().addClass("ms-Panel");
+ break;
+ case "is-left":
+ $(".ms-Panel").removeClass().addClass("ms-Panel ms-Panel--left");
+ break;
+ case "is-lightDismiss":
+ $(".ms-Panel").removeClass().addClass("ms-Panel ms-Panel--lightDismiss");
+ break;
+ case "is-md":
+ $(".ms-Panel").removeClass().addClass("ms-Panel ms-Panel--md");
+ break;
+ case "is-lg":
+ $(".ms-Panel").removeClass().addClass("ms-Panel ms-Panel--lg");
+ break;
+ case "is-xl":
+ $(".ms-Panel").removeClass().addClass("ms-Panel ms-Panel--xl");
+ break;
+ }
+ });
+ }
+ }
+}
diff --git a/src/components/PeoplePicker/Jquery.PeoplePicker.js b/src/components/PeoplePicker/Jquery.PeoplePicker.js
deleted file mode 100644
index 5382cd63..00000000
--- a/src/components/PeoplePicker/Jquery.PeoplePicker.js
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-var fabric = fabric || {};
-
-/**
- * People Picker Plugin
- *
- * Adds basic demonstration functionality to .ms-PeoplePicker components.
- *
- * @param {jQuery Object} One or more .ms-PeoplePicker components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-
-(function ($) {
- $.fn.PeoplePicker = function () {
-
- /** Iterate through each people picker provided. */
- return this.each(function () {
-
- var $peoplePicker = $(this);
- var $searchField = $peoplePicker.find(".ms-PeoplePicker-searchField");
- var $results = $peoplePicker.find(".ms-PeoplePicker-results");
- var $selected = $peoplePicker.find('.ms-PeoplePicker-selected');
- var $selectedPeople = $peoplePicker.find(".ms-PeoplePicker-selectedPeople");
- var $selectedCount = $peoplePicker.find(".ms-PeoplePicker-selectedCount");
- var $peopleList = $peoplePicker.find(".ms-PeoplePicker-peopleList");
- var isActive = false;
- var spinner;
- var $personaCard = $('.ms-PeoplePicker').find('.ms-PersonaCard');
-
- // Run when focused or clicked
- function peoplePickerActive(event) {
- /** Scroll the view so that the people picker is at the top. */
- $('html, body').animate({
- scrollTop: $peoplePicker.offset().top
- }, 367);
-
- /** Start by closing any open people pickers. */
- if ( $peoplePicker.hasClass('is-active') ) {
- $peoplePicker.removeClass("is-active");
- }
-
- /** Display a maxiumum of 5 people in Facepile variant */
- if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile') && $searchField.val() === "") {
- $peopleList.children(":gt(4)").hide();
- }
-
- /** Animate results and members in Facepile variant. */
- if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
- // $results.addClass('ms-u-slideDownIn20');
- $selectedPeople.addClass('ms-u-slideDownIn20');
- setTimeout(function() { $results.removeClass('ms-u-slideDownIn20'); $selectedPeople.removeClass('ms-u-slideDownIn20');}, 1000);
- }
-
- isActive = true;
-
- /** Stop the click event from propagating, which would just close the dropdown immediately. */
- event.stopPropagation();
-
- /** Before opening, size the results panel to match the people picker. */
- if (!$peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
- $results.width($peoplePicker.width() - 2);
- }
-
- /** Show the $results by setting the people picker to active. */
- $peoplePicker.addClass("is-active");
-
- /** Temporarily bind an event to the document that will close the people picker when clicking anywhere. */
- $(document).bind("click.peoplepicker", function() {
- $peoplePicker.removeClass('is-active');
- if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
- $peoplePicker.removeClass('is-searching');
- $('.ms-PeoplePicker-selected').show();
- $('.ms-PeoplePicker-searchMore').removeClass('is-active');
- $searchField.val("");
- }
- $(document).unbind('click.peoplepicker');
- isActive = false;
- });
- }
-
- /** Set to active when focusing on the input. */
- $peoplePicker.on('focus', '.ms-PeoplePicker-searchField', function(event) {
- peoplePickerActive(event);
- });
-
- /** Set to active when clicking on the input. */
- $peoplePicker.on('click', '.ms-PeoplePicker-searchField', function(event) {
- peoplePickerActive(event);
- });
-
- /** Keep the people picker active when clicking within it. */
- $(this).click(function (event) {
- event.stopPropagation();
- });
-
- /** Add the selected person to the text field or selected list and close the people picker. */
- $results.on('click', '.ms-PeoplePicker-result', function () {
- var $this = $(this);
- var selectedName = $this.find(".ms-Persona-primaryText").html();
- var selectedTitle = $this.find(".ms-Persona-secondaryText").html();
- var selectedInitials = (function() {
- var name = selectedName.split(' ');
- var nameInitials = '';
-
- for (var i = 0; i < name.length; i++) {
- nameInitials += name[i].charAt(0);
- }
-
- return nameInitials.substring(0,2);
- })();
- var selectedClasses = $this.find('.ms-Persona-initials').attr('class');
- var selectedImage = (function() {
- if ($this.find('.ms-Persona-image').length) {
- var selectedImageSrc = $this.find('.ms-Persona-image').attr('src');
- return ' ';
- } else {
- return '';
- }
- })();
-
- /** Token html */
- var personaHTML = '' +
- '
' +
- '
' +
- '
' + selectedInitials + '
' +
- selectedImage +
- '
' +
- '
' +
- '
' +
- '
' + selectedName + '
' +
- '
' +
- '
' +
- '
' +
- ' ' +
- ' ' +
- '
';
- /** List item html */
- var personaListItem = '' +
- '' +
- '
' +
- '
' + selectedInitials + '
' +
- selectedImage +
- '
' +
- '
' +
- '
' +
- '
' + selectedName + '
' +
- '
' + selectedTitle + '
' +
- '
' +
- '
' +
- ' ' +
- ' ';
- /** Tokenize selected persona if not Facepile or memberslist variants */
- if (!$peoplePicker.hasClass('ms-PeoplePicker--Facepile') && !$peoplePicker.hasClass('ms-PeoplePicker--membersList') ) {
- $searchField.before(personaHTML);
- $peoplePicker.removeClass("is-active");
- resizeSearchField($peoplePicker);
- }
- /** Add selected persona to a list if Facepile or memberslist variants */
- else {
- if (!$selected.hasClass('is-active')) {
- $selected.addClass('is-active');
- }
- /** Prepend persona list item html to selected people list */
- $selectedPeople.prepend(personaListItem);
- /** Close the picker */
- $peoplePicker.removeClass("is-active");
- /** Get the total amount of selected personas and display that number */
- var count = $peoplePicker.find('.ms-PeoplePicker-selectedPerson').length;
- $selectedCount.html(count);
- /** Return picker back to default state:
- - Show only the first five results in the people list for when the picker is reopened
- - Make searchMore inactive
- - Clear any search field text
- */
- $peopleList.children().show();
- $peopleList.children(":gt(4)").hide();
-
- $('.ms-PeoplePicker-searchMore').removeClass('is-active');
- $searchField.val("");
- }
- });
-
- /** Remove the persona when clicking the personaRemove button. */
- $peoplePicker.on('click', '.ms-PeoplePicker-personaRemove', function() {
- $(this).parents('.ms-PeoplePicker-persona').remove();
-
- /** Make the search field 100% width if all personas have been removed */
- if ( $('.ms-PeoplePicker-persona').length === 0 ) {
- $peoplePicker.find('.ms-PeoplePicker-searchField').outerWidth('100%');
- } else {
- resizeSearchField($peoplePicker);
- }
- });
-
- /** Trigger additional searching when clicking the search more area. */
- $results.on('click', '.js-searchMore', function() {
- var $searchMore = $(this);
- var primaryLabel = $searchMore.find(".ms-PeoplePicker-searchMorePrimary");
- var originalPrimaryLabelText = primaryLabel.html();
- var searchFieldText = $searchField.val();
-
- /** Change to searching state. */
- $searchMore.addClass("is-searching");
- primaryLabel.html("Searching for " + searchFieldText);
-
- /** Attach Spinner */
- if (!spinner) {
- spinner = new fabric.Spinner($searchMore.get(0));
- } else {
- spinner.start();
- }
-
- /** Show all results in Facepile variant */
- if($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
- setTimeout(function() {$peopleList.children().show();}, 1500);
- }
-
- /** Return the original state. */
- setTimeout(function() {
- $searchMore.removeClass("is-searching");
- primaryLabel.html(originalPrimaryLabelText);
- spinner.stop();
- }, 1500);
- });
-
- /** Remove a result using the action icon. */
- $results.on('click', '.js-resultRemove', function(event) {
- event.stopPropagation();
- $(this).parent(".ms-PeoplePicker-result").remove();
- });
-
- /** Expand a result if more details are available. */
- $results.on('click', '.js-resultExpand', function(event) {
- event.stopPropagation();
- $(this).parent(".ms-PeoplePicker-result").toggleClass("is-expanded");
- });
-
- /** Remove a selected person using the action icon. */
- $selectedPeople.on('click', '.js-selectedRemove', function(event) {
- event.stopPropagation();
- $(this).parent(".ms-PeoplePicker-selectedPerson").remove();
- var count = $peoplePicker.find('.ms-PeoplePicker-selectedPerson').length;
- $selectedCount.html(count);
- if ($peoplePicker.find('.ms-PeoplePicker-selectedPerson').length === 0) {
- $selected.removeClass('is-active');
- }
- });
-
- var filterResults = function(results, currentSuggestion, currentValueExists) {
- return results.find('.ms-Persona-primaryText').filter(function() {
- if (currentValueExists) {
- return $(this).text().toLowerCase() === currentSuggestion;
- } else {
- return $(this).text().toLowerCase() !== currentSuggestion;
- }
- }).parents('.ms-PeoplePicker-peopleListItem');
- };
-
- /** Search people picker items */
- $peoplePicker.on('keyup', '.ms-PeoplePicker-searchField', function(evt) {
- var suggested = [];
- var newSuggestions = [];
- var $pickerResult = $results.find('.ms-Persona-primaryText');
-
- $peoplePicker.addClass('is-searching');
-
- /** Hide members */
- $selected.hide();
-
- /** Show 5 results */
- $peopleList.children(":lt(5)").show();
-
- /** Show searchMore button */
- $('.ms-PeoplePicker-searchMore').addClass('is-active');
-
- /** Get array of suggested people */
- $pickerResult.each(function() { suggested.push($(this).text()); });
-
- /** Iterate over array to find matches and show matching items */
- for (var i = 0; i < suggested.length; i++) {
- var currentPersona = suggested[i].toLowerCase();
- var currentValue = evt.target.value.toLowerCase();
- var currentSuggestion;
-
- if (currentPersona.indexOf(currentValue) > -1) {
- currentSuggestion = suggested[i].toLowerCase();
-
- newSuggestions.push(suggested[i]);
-
- filterResults($results, currentSuggestion, true).show();
- } else {
- filterResults($results, currentSuggestion, false).hide();
- }
- }
-
- /** Show members and hide searchmore when field is empty */
- if ($(this).val() === "") {
- $peoplePicker.removeClass('is-searching');
- $selected.show();
- $('.ms-PeoplePicker-searchMore').removeClass('is-active');
- $selectedPeople.addClass('ms-u-slideDownIn20');
- setTimeout(function() { $selectedPeople.removeClass('ms-u-slideDownIn20');}, 1000);
- $peopleList.children(":gt(4)").hide();
- }
- });
-
- /** Show persona card when clicking a persona in the members list */
- $selectedPeople.on('click', '.ms-Persona', function() {
- var selectedName = $(this).find(".ms-Persona-primaryText").html();
- var selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
- var selectedInitials = (function() {
- var name = selectedName.split(' ');
- var nameInitials = '';
-
- for (var i = 0; i < name.length; i++) {
- nameInitials += name[i].charAt(0);
- }
-
- return nameInitials.substring(0,2);
- })();
- var selectedClasses = $(this).find('.ms-Persona-initials').attr('class');
- var selectedImage = $(this).find('.ms-Persona-image').attr('src');
- var $card = $('.ms-PersonaCard');
- var $cardName = $card.find('.ms-Persona-primaryText');
- var $cardTitle = $card.find('.ms-Persona-secondaryText');
- var $cardInitials = $card.find('.ms-Persona-initials');
- var $cardImage = $card.find('.ms-Persona-image');
-
- /** Close any open persona cards */
- $personaCard.removeClass('is-active');
-
- /** Add data to persona card */
- $cardName.text(selectedName);
- $cardTitle.text(selectedTitle);
- $cardInitials.text(selectedInitials);
- $cardInitials.removeClass();
- $cardInitials.addClass(selectedClasses);
- $cardImage.attr('src', selectedImage);
-
- /** Show persona card */
- setTimeout(function() {
- $personaCard.addClass('is-active');
- setTimeout(function(){$personaCard.css({'animation-name': 'none'});}, 300);
- }, 100);
-
- /** Align persona card on md and above screens */
- if ($(window).width() > 480) {
- var itemPositionTop = $(this).offset().top;
- var correctedPositionTop = itemPositionTop + 10;
-
- $personaCard.css({'top': correctedPositionTop, 'left': 0});
- } else {
- $personaCard.css({'top': 'auto'});
- }
- });
-
- /** Dismiss persona card when clicking on the document */
- $(document).on('click', function(e) {
- var $memberBtn = $('.ms-PeoplePicker-selectedPerson').find('.ms-Persona');
-
- if (!$memberBtn.is(e.target) && !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
- $personaCard.removeClass('is-active');
- setTimeout(function(){$personaCard.removeAttr('style');}, 300);
- } else {
- $personaCard.addClass('is-active');
- }
- });
- });
- };
-
- /** Resize the search field to match the search box */
- function resizeSearchField($peoplePicker) {
- var $searchBox = $peoplePicker.find('.ms-PeoplePicker-searchBox');
-
- // Where is the right edge of the search box?
- var searchBoxLeftEdge = $searchBox.position().left;
- var searchBoxWidth = $searchBox.outerWidth();
- var searchBoxRightEdge = searchBoxLeftEdge + searchBoxWidth;
-
- // Where is the right edge of the last persona component?
- var $lastPersona = $searchBox.find('.ms-PeoplePicker-persona:last');
- var lastPersonaLeftEdge = $lastPersona.offset().left;
- var lastPersonaWidth = $lastPersona.outerWidth();
- var lastPersonaRightEdge = lastPersonaLeftEdge + lastPersonaWidth;
-
- // Adjust the width of the field to fit the remaining space.
- var newFieldWidth = searchBoxRightEdge - lastPersonaRightEdge - 7;
-
- // Don't let the field get too tiny.
- if (newFieldWidth < 100) {
- newFieldWidth = "100%";
- }
-
- // Set the width of the search field
- $peoplePicker.find('.ms-PeoplePicker-searchField').outerWidth(newFieldWidth);
- }
-})(jQuery);
diff --git a/src/components/PeoplePicker/Jquery.PeoplePicker.ts b/src/components/PeoplePicker/Jquery.PeoplePicker.ts
new file mode 100644
index 00000000..0af0cbc8
--- /dev/null
+++ b/src/components/PeoplePicker/Jquery.PeoplePicker.ts
@@ -0,0 +1,417 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+///
+
+namespace fabric {
+
+
+ /** Resize the search field to match the search box */
+ function resizeSearchField($peoplePicker) {
+ let $searchBox = $peoplePicker.find(".ms-PeoplePicker-searchBox");
+
+ // Where is the right edge of the search box?
+ let searchBoxLeftEdge = $searchBox.position().left;
+ let searchBoxWidth = $searchBox.outerWidth();
+ let searchBoxRightEdge = searchBoxLeftEdge + searchBoxWidth;
+
+ // Where is the right edge of the last persona component?
+ let $lastPersona = $searchBox.find(".ms-PeoplePicker-persona:last");
+ let lastPersonaLeftEdge = $lastPersona.offset().left;
+ let lastPersonaWidth = $lastPersona.outerWidth();
+ let lastPersonaRightEdge = lastPersonaLeftEdge + lastPersonaWidth;
+
+ // Adjust the width of the field to fit the remaining space.
+ let newFieldWidth: any = searchBoxRightEdge - lastPersonaRightEdge - 7;
+
+ // Don"t let the field get too tiny.
+ if (newFieldWidth < 100) {
+ newFieldWidth = "100%";
+ }
+
+ // Set the width of the search field
+ $peoplePicker.find(".ms-PeoplePicker-searchField").outerWidth(newFieldWidth);
+ }
+
+ /**
+ * People Picker Plugin
+ *
+ * Adds basic demonstration functionality to .ms-PeoplePicker components.
+ *
+ */
+ export class PeoplePicker {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of PeoplePicker
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+
+ let $peoplePicker = $(container);
+ let $searchField = $peoplePicker.find(".ms-PeoplePicker-searchField");
+ let $results = $peoplePicker.find(".ms-PeoplePicker-results");
+ let $selected = $peoplePicker.find(".ms-PeoplePicker-selected");
+ let $selectedPeople = $peoplePicker.find(".ms-PeoplePicker-selectedPeople");
+ let $selectedCount = $peoplePicker.find(".ms-PeoplePicker-selectedCount");
+ let $peopleList = $peoplePicker.find(".ms-PeoplePicker-peopleList");
+ let isActive = false;
+ let spinner;
+ let $personaCard = $(".ms-PeoplePicker").find(".ms-PersonaCard");
+
+ // Run when focused or clicked
+ function peoplePickerActive(event) {
+ /** Scroll the view so that the people picker is at the top. */
+ $("html, body").animate({
+ scrollTop: $peoplePicker.offset().top,
+ }, 367);
+
+ /** Start by closing any open people pickers. */
+ if ( $peoplePicker.hasClass("is-active") ) {
+ $peoplePicker.removeClass("is-active");
+ }
+
+ /** Display a maxiumum of 5 people in Facepile letiant */
+ if ($peoplePicker.hasClass("ms-PeoplePicker--Facepile") && $searchField.val() === "") {
+ $peopleList.children(":gt(4)").hide();
+ }
+
+ /** Animate results and members in Facepile letiant. */
+ if ($peoplePicker.hasClass("ms-PeoplePicker--Facepile")) {
+ // $results.addClass("ms-u-slideDownIn20");
+ $selectedPeople.addClass("ms-u-slideDownIn20");
+ setTimeout(function() {
+ $results.removeClass("ms-u-slideDownIn20");
+ $selectedPeople.removeClass("ms-u-slideDownIn20");
+ }, 1000);
+ }
+
+ isActive = true;
+
+ /** Stop the click event from propagating, which would just close the dropdown immediately. */
+ event.stopPropagation();
+
+ /** Before opening, size the results panel to match the people picker. */
+ if (!$peoplePicker.hasClass("ms-PeoplePicker--Facepile")) {
+ $results.width($peoplePicker.width() - 2);
+ }
+
+ /** Show the $results by setting the people picker to active. */
+ $peoplePicker.addClass("is-active");
+
+ /** Temporarily bind an event to the document that will close the people picker when clicking anywhere. */
+ $(document).bind("click.peoplepicker", function() {
+ $peoplePicker.removeClass("is-active");
+ if ($peoplePicker.hasClass("ms-PeoplePicker--Facepile")) {
+ $peoplePicker.removeClass("is-searching");
+ $(".ms-PeoplePicker-selected").show();
+ $(".ms-PeoplePicker-searchMore").removeClass("is-active");
+ $searchField.val("");
+ }
+ $(document).unbind("click.peoplepicker");
+ isActive = false;
+ });
+ }
+
+ /** Set to active when focusing on the input. */
+ $peoplePicker.on("focus", ".ms-PeoplePicker-searchField", function(event) {
+ peoplePickerActive(event);
+ });
+
+ /** Set to active when clicking on the input. */
+ $peoplePicker.on("click", ".ms-PeoplePicker-searchField", function(event) {
+ peoplePickerActive(event);
+ });
+
+ /** Keep the people picker active when clicking within it. */
+ $peoplePicker.click(function (event) {
+ event.stopPropagation();
+ });
+
+ /** Add the selected person to the text field or selected list and close the people picker. */
+ $results.on("click", ".ms-PeoplePicker-result", function () {
+ let $this = $(this);
+ let selectedName = $this.find(".ms-Persona-primaryText").html();
+ let selectedTitle = $this.find(".ms-Persona-secondaryText").html();
+ let selectedInitials = (function() {
+ let name = selectedName.split(" ");
+ let nameInitials = "";
+
+ for (let i = 0; i < name.length; i++) {
+ nameInitials += name[i].charAt(0);
+ }
+
+ return nameInitials.substring(0, 2);
+ })();
+ let selectedClasses = $this.find(".ms-Persona-initials").attr("class");
+ let selectedImage = (function() {
+ if ($this.find(".ms-Persona-image").length) {
+ let selectedImageSrc = $this.find(".ms-Persona-image").attr("src");
+ return " ";
+ } else {
+ return "";
+ }
+ })();
+
+ /** Token html */
+ let personaHTML = "" +
+ "
" +
+ "
" +
+ "
" + selectedInitials + "
" +
+ selectedImage +
+ "
" +
+ "
" +
+ "
" +
+ "
" + selectedName + "
" +
+ "
" +
+ "
" +
+ "
" +
+ " " +
+ " " +
+ "
";
+ /** List item html */
+ let personaListItem = "" +
+ "" +
+ "
" +
+ "
" + selectedInitials + "
" +
+ selectedImage +
+ "
" +
+ "
" +
+ "
" +
+ "
" + selectedName + "
" +
+ "
" + selectedTitle + "
" +
+ "
" +
+ "
" +
+ "" +
+ " " +
+ " " +
+ " ";
+ /** Tokenize selected persona if not Facepile or memberslist letiants */
+ if (!$peoplePicker.hasClass("ms-PeoplePicker--Facepile") && !$peoplePicker.hasClass("ms-PeoplePicker--membersList") ) {
+ $searchField.before(personaHTML);
+ $peoplePicker.removeClass("is-active");
+ resizeSearchField($peoplePicker);
+ } else {
+ /** Add selected persona to a list if Facepile or memberslist letiants */
+ if (!$selected.hasClass("is-active")) {
+ $selected.addClass("is-active");
+ }
+ /** Prepend persona list item html to selected people list */
+ $selectedPeople.prepend(personaListItem);
+ /** Close the picker */
+ $peoplePicker.removeClass("is-active");
+ /** Get the total amount of selected personas and display that number */
+ let count: any = $peoplePicker.find(".ms-PeoplePicker-selectedPerson").length;
+ $selectedCount.html(count);
+ /** Return picker back to default state:
+ - Show only the first five results in the people list for when the picker is reopened
+ - Make searchMore inactive
+ - Clear any search field text
+ */
+ $peopleList.children().show();
+ $peopleList.children(":gt(4)").hide();
+
+ $(".ms-PeoplePicker-searchMore").removeClass("is-active");
+ $searchField.val("");
+ }
+ });
+
+ /** Remove the persona when clicking the personaRemove button. */
+ $peoplePicker.on("click", ".ms-PeoplePicker-personaRemove", function() {
+ $(this).parents(".ms-PeoplePicker-persona").remove();
+
+ /** Make the search field 100% width if all personas have been removed */
+ if ( $(".ms-PeoplePicker-persona").length === 0 ) {
+ $peoplePicker.find(".ms-PeoplePicker-searchField").outerWidth("100%");
+ } else {
+ resizeSearchField($peoplePicker);
+ }
+ });
+
+ /** Trigger additional searching when clicking the search more area. */
+ $results.on("click", ".js-searchMore", function() {
+ let $searchMore = $(this);
+ let primaryLabel = $searchMore.find(".ms-PeoplePicker-searchMorePrimary");
+ let originalPrimaryLabelText = primaryLabel.html();
+ let searchFieldText = $searchField.val();
+
+ /** Change to searching state. */
+ $searchMore.addClass("is-searching");
+ primaryLabel.html("Searching for " + searchFieldText);
+
+ /** Attach Spinner */
+ if (!spinner) {
+ spinner = new fabric.Spinner($searchMore.get(0));
+ } else {
+ spinner.start();
+ }
+
+ /** Show all results in Facepile letiant */
+ if ($peoplePicker.hasClass("ms-PeoplePicker--Facepile")) {
+ setTimeout(function() {
+ $peopleList.children().show();
+ }, 1500);
+ }
+
+ /** Return the original state. */
+ setTimeout(function() {
+ $searchMore.removeClass("is-searching");
+ primaryLabel.html(originalPrimaryLabelText);
+ spinner.stop();
+ }, 1500);
+ });
+
+ /** Remove a result using the action icon. */
+ $results.on("click", ".js-resultRemove", function(event) {
+ event.stopPropagation();
+ $(this).parent(".ms-PeoplePicker-result").remove();
+ });
+
+ /** Expand a result if more details are available. */
+ $results.on("click", ".js-resultExpand", function(event) {
+ event.stopPropagation();
+ $(this).parent(".ms-PeoplePicker-result").toggleClass("is-expanded");
+ });
+
+ /** Remove a selected person using the action icon. */
+ $selectedPeople.on("click", ".js-selectedRemove", function(event) {
+ event.stopPropagation();
+ $(this).parent(".ms-PeoplePicker-selectedPerson").remove();
+ let count: any = $peoplePicker.find(".ms-PeoplePicker-selectedPerson").length;
+ $selectedCount.html(count);
+ if ($peoplePicker.find(".ms-PeoplePicker-selectedPerson").length === 0) {
+ $selected.removeClass("is-active");
+ }
+ });
+
+ let filterResults = function(results, currentSuggestion, currentValueExists) {
+ return results.find(".ms-Persona-primaryText").filter(function() {
+ if (currentValueExists) {
+ return $(this).text().toLowerCase() === currentSuggestion;
+ } else {
+ return $(this).text().toLowerCase() !== currentSuggestion;
+ }
+ }).parents(".ms-PeoplePicker-peopleListItem");
+ };
+
+ /** Search people picker items */
+ $peoplePicker.on("keyup", ".ms-PeoplePicker-searchField", function(evt) {
+ let suggested = [];
+ let newSuggestions = [];
+ let $pickerResult = $results.find(".ms-Persona-primaryText");
+
+ $peoplePicker.addClass("is-searching");
+
+ /** Hide members */
+ $selected.hide();
+
+ /** Show 5 results */
+ $peopleList.children(":lt(5)").show();
+
+ /** Show searchMore button */
+ $(".ms-PeoplePicker-searchMore").addClass("is-active");
+
+ /** Get array of suggested people */
+ $pickerResult.each(function() { suggested.push($(this).text()); });
+
+ /** Iterate over array to find matches and show matching items */
+ for (let i = 0; i < suggested.length; i++) {
+ let currentPersona = suggested[i].toLowerCase();
+ let currentValue = (evt.target).value.toLowerCase();
+ let currentSuggestion;
+
+ if (currentPersona.indexOf(currentValue) > -1) {
+ currentSuggestion = suggested[i].toLowerCase();
+
+ newSuggestions.push(suggested[i]);
+
+ filterResults($results, currentSuggestion, true).show();
+ } else {
+ filterResults($results, currentSuggestion, false).hide();
+ }
+ }
+
+ /** Show members and hide searchmore when field is empty */
+ if ($(this).val() === "") {
+ $peoplePicker.removeClass("is-searching");
+ $selected.show();
+ $(".ms-PeoplePicker-searchMore").removeClass("is-active");
+ $selectedPeople.addClass("ms-u-slideDownIn20");
+ setTimeout(function() {
+ $selectedPeople.removeClass("ms-u-slideDownIn20");
+ }, 1000);
+ $peopleList.children(":gt(4)").hide();
+ }
+ });
+
+ /** Show persona card when clicking a persona in the members list */
+ $selectedPeople.on("click", ".ms-Persona", function() {
+ let selectedName = $(this).find(".ms-Persona-primaryText").html();
+ let selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
+ let selectedInitials = (function() {
+ let name = selectedName.split(" ");
+ let nameInitials = "";
+
+ for (let i = 0; i < name.length; i++) {
+ nameInitials += name[i].charAt(0);
+ }
+
+ return nameInitials.substring(0, 2);
+ })();
+ let selectedClasses = $(this).find(".ms-Persona-initials").attr("class");
+ let selectedImage = $(this).find(".ms-Persona-image").attr("src");
+ let $card = $(".ms-PersonaCard");
+ let $cardName = $card.find(".ms-Persona-primaryText");
+ let $cardTitle = $card.find(".ms-Persona-secondaryText");
+ let $cardInitials = $card.find(".ms-Persona-initials");
+ let $cardImage = $card.find(".ms-Persona-image");
+
+ /** Close any open persona cards */
+ $personaCard.removeClass("is-active");
+
+ /** Add data to persona card */
+ $cardName.text(selectedName);
+ $cardTitle.text(selectedTitle);
+ $cardInitials.text(selectedInitials);
+ $cardInitials.removeClass();
+ $cardInitials.addClass(selectedClasses);
+ $cardImage.attr("src", selectedImage);
+
+ /** Show persona card */
+ setTimeout(function() {
+ $personaCard.addClass("is-active");
+ setTimeout(function(){
+ $personaCard.css({"animation-name": "none"});
+ }, 300);
+ }, 100);
+
+ /** Align persona card on md and above screens */
+ if ($(window).width() > 480) {
+ let itemPositionTop = $(this).offset().top;
+ let correctedPositionTop = itemPositionTop + 10;
+
+ $personaCard.css({"top": correctedPositionTop, "left": 0});
+ } else {
+ $personaCard.css({"top": "auto"});
+ }
+ });
+
+ /** Dismiss persona card when clicking on the document */
+ $(document).on("click", function(e) {
+ let $memberBtn = $(".ms-PeoplePicker-selectedPerson").find(".ms-Persona");
+
+ if (!$memberBtn.is(e.target) && !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
+ $personaCard.removeClass("is-active");
+ setTimeout(function(){
+ $personaCard.removeAttr("style");
+ }, 300);
+ } else {
+ $personaCard.addClass("is-active");
+ }
+ });
+
+ }
+ }
+}
diff --git a/src/components/PeoplePicker/PeoplePicker.json b/src/components/PeoplePicker/PeoplePicker.json
index 61d741ac..daff3bab 100644
--- a/src/components/PeoplePicker/PeoplePicker.json
+++ b/src/components/PeoplePicker/PeoplePicker.json
@@ -9,7 +9,8 @@
"Label",
"Overlay",
"Persona",
- "PersonaCard"
+ "PersonaCard",
+ "Spinner"
],
"wrapBranches": true,
"fileOrder": [
diff --git a/src/components/PersonaCard/Jquery.PersonaCard.js b/src/components/PersonaCard/Jquery.PersonaCard.js
deleted file mode 100644
index 588a8dde..00000000
--- a/src/components/PersonaCard/Jquery.PersonaCard.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Persona Card Plugin
- *
- * Adds basic demonstration functionality to .ms-PersonaCard components.
- *
- * @param {jQuery Object} One or more .ms-PersonaCard components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.PersonaCard = function () {
-
- /** Go through each file picker we've been given. */
- return this.each(function () {
-
- var $personaCard = $(this);
-
- /** When selecting an action, show its details. */
- $personaCard.on('click', '.ms-PersonaCard-action', function() {
-
- /** Select the correct tab. */
- $personaCard.find('.ms-PersonaCard-action').removeClass('is-active');
- $(this).addClass('is-active');
-
- /** Function for switching selected item into view by adding a class to ul. */
- var updateForItem = function(wrapper, item) {
- var previousItem = wrapper.className + "";
- var detail = item.charAt(0).toUpperCase() + item.slice(1);
- var nextItem = "ms-PersonaCard-detail" + detail;
- if (previousItem !== nextItem){
- wrapper.classList.remove(previousItem);
- wrapper.classList.add(nextItem);
- }
- };
-
- /** Get id of selected item */
- var el = $(this).attr('id');
- /** Add detail class to ul to switch it into view. */
- updateForItem($(this).parent().next().find('#detailList')[0], el);
-
- /** Display the corresponding details. */
- var requestedAction = $(this).attr('id');
- $personaCard.find('.ms-PersonaCard-actionDetails').removeClass('is-active');
- $personaCard.find('#' + requestedAction + '.ms-PersonaCard-actionDetails').addClass('is-active');
-
- });
-
- /** Toggle more details. */
- $personaCard.on('click', '.ms-PersonaCard-detailExpander', function() {
- $(this).parent('.ms-PersonaCard-actionDetails').toggleClass('is-collapsed');
- });
-
- });
-
- };
-})(jQuery);
diff --git a/src/components/PersonaCard/Jquery.PersonaCard.ts b/src/components/PersonaCard/Jquery.PersonaCard.ts
new file mode 100644
index 00000000..2e7d0487
--- /dev/null
+++ b/src/components/PersonaCard/Jquery.PersonaCard.ts
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+ /**
+ * Persona Card Plugin
+ *
+ * Adds basic demonstration functionality to .ms-PersonaCard components.
+ *
+ */
+ export class PersonaCard {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of PersonaCard
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $personaCard = $(container);
+
+ /** When selecting an action, show its details. */
+ $personaCard.on("click", ".ms-PersonaCard-action", function() {
+
+ /** Select the correct tab. */
+ $personaCard.find(".ms-PersonaCard-action").removeClass("is-active");
+ $(this).addClass("is-active");
+
+ /** Function for switching selected item into view by adding a class to ul. */
+ let updateForItem = function(wrapper, item) {
+ let previousItem = wrapper.className + "";
+ let detail = item.charAt(0).toUpperCase() + item.slice(1);
+ let nextItem = "ms-PersonaCard-detail" + detail;
+ if (previousItem !== nextItem) {
+ wrapper.classList.remove(previousItem);
+ wrapper.classList.add(nextItem);
+ }
+ };
+
+ /** Get id of selected item */
+ let el = $(this).attr("id");
+ /** Add detail class to ul to switch it into view. */
+ updateForItem($(this).parent().next().find("#detailList")[0], el);
+
+ /** Display the corresponding details. */
+ let requestedAction = $(this).attr("id");
+ $personaCard.find(".ms-PersonaCard-actionDetails").removeClass("is-active");
+ $personaCard.find("#" + requestedAction + ".ms-PersonaCard-actionDetails").addClass("is-active");
+
+ });
+
+ /** Toggle more details. */
+ $personaCard.on("click", ".ms-PersonaCard-detailExpander", function() {
+ $(this).parent(".ms-PersonaCard-actionDetails").toggleClass("is-collapsed");
+ });
+ }
+ }
+}
diff --git a/src/components/Pivot/jquery.Pivot.js b/src/components/Pivot/jquery.Pivot.js
deleted file mode 100644
index e5e44bb0..00000000
--- a/src/components/Pivot/jquery.Pivot.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Pivot Plugin
- *
- * Adds basic demonstration functionality to .ms-Pivot components.
- *
- * @param {jQuery Object} One or more .ms-Pivot components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.Pivot = function () {
-
- /** Go through each pivot we've been given. */
- return this.each(function () {
-
- var $pivotContainer = $(this);
-
- /** When clicking/tapping a link, select it. */
- $pivotContainer.on('click', '.ms-Pivot-link', function(event) {
- event.preventDefault();
- /** Check if current selection has elipses child element **/
- var $elipsisCheck = $(this).find('.ms-Pivot-ellipsis');
-
- /** Only execute when no elipses element can be found **/
- if($elipsisCheck.length === 0){
-
- $(this).siblings('.ms-Pivot-link').removeClass('is-selected');
- $(this).addClass('is-selected');
- }
-
- });
-
- });
-
- };
-})(jQuery);
diff --git a/src/components/Pivot/jquery.Pivot.ts b/src/components/Pivot/jquery.Pivot.ts
new file mode 100644
index 00000000..dcf30a6f
--- /dev/null
+++ b/src/components/Pivot/jquery.Pivot.ts
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+ /**
+ * Pivot Plugin
+ *
+ * Adds basic demonstration functionality to .ms-Pivot components.
+ *
+ */
+ export class Pivot {
+
+ /**
+ *
+ * @param {HTMLElement} container - the target container for an instance of Pivot
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $pivotContainer = $(container);
+
+ /** When clicking/tapping a link, select it. */
+ $pivotContainer.on("click", ".ms-Pivot-link", function(event) {
+ event.preventDefault();
+ /** Check if current selection has elipses child element **/
+ let $elipsisCheck = $(this).find(".ms-Pivot-ellipsis");
+
+ /** Only execute when no elipses element can be found **/
+ if ($elipsisCheck.length === 0) {
+
+ $(this).siblings(".ms-Pivot-link").removeClass("is-selected");
+ $(this).addClass("is-selected");
+ }
+ });
+ }
+ }
+}
diff --git a/src/components/ProgressIndicator/ProgressIndicator.js b/src/components/ProgressIndicator/ProgressIndicator.js
deleted file mode 100644
index d70504b1..00000000
--- a/src/components/ProgressIndicator/ProgressIndicator.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * ProgressIndicator component
- *
- * A component for outputting determinate progress
- *
- */
-
-/**
- * @namespace fabric
- */
-var fabric = fabric || {};
-/**
- *
- * @param {HTMLDivElement} container - the target container for an instance of ProgressIndicator
- * @constructor
- */
-fabric.ProgressIndicator = function(container) {
- this.container = container;
- this.cacheDOM();
-};
-
-fabric.ProgressIndicator.prototype = (function() {
-
- var _progress;
- var _width;
- var _itemName;
- var _total;
- var _itemDescription;
- var _progressBar;
-
- /**
- * Sets the progress percentage for a determinate
- * operation. Either use this or setProgress
- * and setTotal as setProgressPercent assumes
- * you've done a percentage calculation before
- * injecting it into the function
- * @param {number} percent - a floating point number from 0 to 1
- */
- var setProgressPercent = function(percent) {
- _progressBar.style.width = Math.round(_width * percent) + "px";
- };
-
- /**
- * Sets the progress for a determinate operation.
- * Use this in combination with setTotal.
- * @param {number} progress
- */
- var setProgress = function(progress) {
- _progress = progress;
- var percentage = _progress / _total;
- this.setProgressPercent(percentage);
- };
-
- /**
- * Sets the total file size, etc. for a
- * determinate operation. Use this in
- * combination with setProgress
- * @param {number} total
- */
- var setTotal = function(total) {
- _total = total;
- };
-
- /**
- * Sets the text for the title or label
- * of an instance
- * @param {string} name
- */
- var setName = function(name) {
- _itemName.innerHTML = name;
- };
-
- /**
- * Sets the text for a description
- * of an instance
- * @param {string} name
- */
- var setDescription = function(description) {
- _itemDescription.innerHTML = description;
- };
-
- /**
- * caches elements and values of the component
- *
- */
- var cacheDOM = function() {
- _itemName = this.container.querySelector('.ms-ProgressIndicator-itemName') || null; //an itemName element is optional
- _itemDescription = this.container.querySelector('.ms-ProgressIndicator-itemDescription') || null; //an itemDescription element is optional
- _progressBar = this.container.querySelector('.ms-ProgressIndicator-progressBar');
- _width = this.container.querySelector('.ms-ProgressIndicator-itemProgress').offsetWidth;
- };
-
- return {
- setProgressPercent: setProgressPercent,
- setName: setName,
- setDescription: setDescription,
- setProgress: setProgress,
- setTotal: setTotal,
- cacheDOM: cacheDOM
- };
-}());
diff --git a/src/components/ProgressIndicator/ProgressIndicator.ts b/src/components/ProgressIndicator/ProgressIndicator.ts
new file mode 100644
index 00000000..77bd370b
--- /dev/null
+++ b/src/components/ProgressIndicator/ProgressIndicator.ts
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+
+/**
+ * @namespace fabric
+ */
+namespace fabric {
+ "use strict";
+
+ /**
+ * ProgressIndicator component
+ *
+ * A component for outputting determinate progress
+ *
+ */
+ export class ProgressIndicator {
+
+ public container: HTMLElement;
+
+ private _progress: number;
+ private _width: number;
+ private _itemName: HTMLElement;
+ private _total: number;
+ private _itemDescription: HTMLElement;
+ private _progressBar: HTMLElement;
+
+ /**
+ *
+ * @param {HTMLDivElement} container - the target container for an instance of ProgressIndicator
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ this.container = container;
+ this.cacheDOM();
+ }
+
+ /**
+ * Sets the progress percentage for a determinate
+ * operation. Either use this or setProgress
+ * and setTotal as setProgressPercent assumes
+ * you've done a percentage calculation before
+ * injecting it into the function
+ * @param {number} percent - a floating point number from 0 to 1
+ */
+ public setProgressPercent(percent: number): void {
+ this._progressBar.style.width = Math.round(this._width * percent) + "px";
+ }
+
+ /**
+ * Sets the progress for a determinate operation.
+ * Use this in combination with setTotal.
+ * @param {number} progress
+ */
+ public setProgress(progress: number): void {
+ this._progress = progress;
+ let percentage = this._progress / this._total;
+ this.setProgressPercent(percentage);
+ }
+
+ /**
+ * Sets the total file size, etc. for a
+ * determinate operation. Use this in
+ * combination with setProgress
+ * @param {number} total
+ */
+ public setTotal(total: number): void {
+ this._total = total;
+ }
+
+ /**
+ * Sets the text for the title or label
+ * of an instance
+ * @param {string} name
+ */
+ public setName(name: string): void {
+ this._itemName.innerHTML = name;
+ }
+
+ /**
+ * Sets the text for a description
+ * of an instance
+ * @param {string} name
+ */
+ public setDescription(description: string): void {
+ this._itemDescription.innerHTML = description;
+ }
+
+ /**
+ * caches elements and values of the component
+ *
+ */
+ public cacheDOM(): void {
+ // an itemName element is optional
+ this._itemName = this.container.querySelector(".ms-ProgressIndicator-itemName") || null;
+ // an itemDescription element is optional
+ this._itemDescription = this.container.querySelector(".ms-ProgressIndicator-itemDescription") || null;
+ this._progressBar = this.container.querySelector(".ms-ProgressIndicator-progressBar");
+ let itemProgress = this.container.querySelector(".ms-ProgressIndicator-itemProgress");
+ this._width = itemProgress.offsetWidth;
+ }
+ }
+} // end fabric namespace
diff --git a/src/components/SearchBox/Jquery.SearchBox.js b/src/components/SearchBox/Jquery.SearchBox.js
deleted file mode 100644
index c95c6029..00000000
--- a/src/components/SearchBox/Jquery.SearchBox.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * SearchBox Plugin
- *
- * Adds basic demonstration functionality to .ms-SearchBox components.
- *
- * @param {jQuery Object} One or more .ms-SearchBox components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.SearchBox = function () {
-
- /** Iterate through each text field provided. */
- return this.each(function () {
- // Set cancel to false
- var cancel = false;
- var $searchField = $(this).find('.ms-SearchBox-field');
-
- /** SearchBox focus - hide label and show cancel button */
- $searchField.on('focus', function() {
- /** Hide the label on focus. */
- $(this).siblings('.ms-SearchBox-label').hide();
- // Show cancel button by adding is-active class
- $(this).parent('.ms-SearchBox').addClass('is-active');
- });
-
- /** 'hovering' class allows for more fine grained control of hover state */
- $searchField.on('mouseover', function() {
- $searchField.addClass('hovering');
- });
-
- $searchField.on('mouseout', function() {
- $searchField.removeClass('hovering');
- });
-
- // If cancel button is selected, change cancel value to true
- $(this).find('.ms-SearchBox-closeButton').on('mousedown', function() {
- cancel = true;
- });
-
- /** Show the label again when leaving the field. */
- $(this).find('.ms-SearchBox-field').on('blur', function() {
-
- // If cancel button is selected remove the text and show the label
- if (cancel) {
- $(this).val('');
- $searchField.addClass('hovering');
- }
-
- var $searchBox = $(this).parent('.ms-SearchBox');
- // Prevents inputfield from gaining focus too soon
- setTimeout(function() {
- // Remove is-active class - hides cancel button
- $searchBox.removeClass('is-active');
- }, 10);
-
- /** Only do this if no text was entered. */
- if ($(this).val().length === 0 ) {
- $(this).siblings('.ms-SearchBox-label').show();
- }
-
- // Reset cancel to false
- cancel = false;
- });
- });
-
- };
-})(jQuery);
diff --git a/src/components/SearchBox/Jquery.SearchBox.ts b/src/components/SearchBox/Jquery.SearchBox.ts
new file mode 100644
index 00000000..77f67270
--- /dev/null
+++ b/src/components/SearchBox/Jquery.SearchBox.ts
@@ -0,0 +1,77 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+
+ /**
+ * SearchBox Plugin
+ *
+ * Adds basic demonstration functionality to .ms-SearchBox components.
+ */
+ export class SearchBox {
+
+ /**
+ *
+ * @param {HTMLDivElement} container - the target container for an instance of SearchBox
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+
+ let $searchBox = $(container);
+
+ // Set cancel to false
+ let cancel = false;
+ let $searchField = $searchBox.find(".ms-SearchBox-field");
+
+ /** SearchBox focus - hide label and show cancel button */
+ $searchField.on("focus", function() {
+ /** Hide the label on focus. */
+ $(this).siblings(".ms-SearchBox-label").hide();
+ // Show cancel button by adding is-active class
+ $(this).parent(".ms-SearchBox").addClass("is-active");
+ });
+
+ /** "hovering" class allows for more fine grained control of hover state */
+ $searchField.on("mouseover", function() {
+ $searchField.addClass("hovering");
+ });
+
+ $searchField.on("mouseout", function() {
+ $searchField.removeClass("hovering");
+ });
+
+ // If cancel button is selected, change cancel value to true
+ $searchBox.find(".ms-SearchBox-closeButton").on("mousedown", function() {
+ cancel = true;
+ });
+
+ /** Show the label again when leaving the field. */
+ $searchBox.find(".ms-SearchBox-field").on("blur", function() {
+
+ // If cancel button is selected remove the text and show the label
+ if (cancel) {
+ $(this).val("");
+ $searchField.addClass("hovering");
+ }
+
+ // Prevents inputfield from gaining focus too soon
+ setTimeout(function() {
+ // Remove is-active class - hides cancel button
+ $searchBox.removeClass("is-active");
+ }, 10);
+
+ /** Only do this if no text was entered. */
+ if ($(this).val().length === 0 ) {
+ $(this).siblings(".ms-SearchBox-label").show();
+ }
+
+ // Reset cancel to false
+ cancel = false;
+ });
+ }
+ }
+}
diff --git a/src/components/Spinner/Spinner.js b/src/components/Spinner/Spinner.js
deleted file mode 100644
index 1c4364d7..00000000
--- a/src/components/Spinner/Spinner.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Spinner Component
- *
- * An animating activity indicator.
- *
- */
-
-/**
- * @namespace fabric
- */
-var fabric = fabric || {};
-
-/**
- * @param {HTMLDOMElement} target - The element the Spinner will attach itself to.
- */
-
-fabric.Spinner = function(target) {
-
- var _target = target;
- var eightSize = 0.2;
- var circleObjects = [];
- var animationSpeed = 90;
- var interval;
- var spinner;
- var numCircles;
- var offsetSize;
- var fadeIncrement = 0;
- var parentSize = 20;
-
- /**
- * @function start - starts or restarts the animation sequence
- * @memberOf fabric.Spinner
- */
- function start() {
- stop();
- interval = setInterval(function() {
- var i = circleObjects.length;
- while(i--) {
- _fade(circleObjects[i]);
- }
- }, animationSpeed);
- }
-
- /**
- * @function stop - stops the animation sequence
- * @memberOf fabric.Spinner
- */
- function stop() {
- clearInterval(interval);
- }
-
- //private methods
-
- function _init() {
- _setTargetElement();
- _setPropertiesForSize();
- _createCirclesAndArrange();
- _initializeOpacities();
- start();
- }
-
- function _initializeOpacities() {
- var i = 0;
- var j = 1;
- var opacity;
- fadeIncrement = 1 / numCircles;
-
- for (i; i < numCircles; i++) {
- var circleObject = circleObjects[i];
- opacity = (fadeIncrement * j++);
- _setOpacity(circleObject.element, opacity);
- }
- }
-
- function _fade(circleObject) {
- var opacity = _getOpacity(circleObject.element) - fadeIncrement;
-
- if (opacity <= 0) {
- opacity = 1;
- }
-
- _setOpacity(circleObject.element, opacity);
- }
-
- function _getOpacity(element) {
- return parseFloat(window.getComputedStyle(element).getPropertyValue("opacity"));
- }
-
- function _setOpacity(element, opacity) {
- element.style.opacity = opacity;
- }
-
- function _createCircle() {
- var circle = document.createElement('div');
- circle.className = "ms-Spinner-circle";
- circle.style.width = circle.style.height = parentSize * offsetSize + "px";
- return circle;
- }
-
- function _createCirclesAndArrange() {
-
- var angle = 0;
- var offset = parentSize * offsetSize;
- var step = (2 * Math.PI) / numCircles;
- var i = numCircles;
- var circleObject;
- var radius = (parentSize - offset) * 0.5;
-
- while (i--) {
- var circle = _createCircle();
- var x = Math.round(parentSize * 0.5 + radius * Math.cos(angle) - circle.clientWidth * 0.5) - offset * 0.5;
- var y = Math.round(parentSize * 0.5 + radius * Math.sin(angle) - circle.clientHeight * 0.5) - offset * 0.5;
- spinner.appendChild(circle);
- circle.style.left = x + 'px';
- circle.style.top = y + 'px';
- angle += step;
- circleObject = { element:circle, j:i };
- circleObjects.push(circleObject);
- }
- }
-
- function _setPropertiesForSize() {
- if (spinner.className.indexOf("large") > -1) {
- parentSize = 28;
- eightSize = 0.179;
- }
-
- offsetSize = eightSize;
- numCircles = 8;
- }
-
- function _setTargetElement() {
- //for backwards compatibility
- if (_target.className.indexOf("ms-Spinner") === -1) {
- spinner = document.createElement("div");
- spinner.className = "ms-Spinner";
- _target.appendChild(spinner);
- } else {
- spinner = _target;
- }
- }
-
- _init();
-
- return {
- start:start,
- stop:stop
- };
-};
diff --git a/src/components/Spinner/Spinner.ts b/src/components/Spinner/Spinner.ts
new file mode 100644
index 00000000..08328b73
--- /dev/null
+++ b/src/components/Spinner/Spinner.ts
@@ -0,0 +1,159 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+
+/**
+ * @namespace fabric
+ */
+namespace fabric {
+
+ class CircleObject {
+ public element: HTMLElement;
+ public j: number;
+
+ constructor(element, j) {
+ this.element = element;
+ this.j = j;
+ }
+ }
+
+ /**
+ * Spinner Component
+ *
+ * An animating activity indicator.
+ *
+ */
+ export class Spinner {
+
+ public eightSize: number = 0.2;
+ public animationSpeed: number = 90;
+ public interval: number;
+ public spinner: HTMLElement;
+ public numCircles: number;
+ public offsetSize: number;
+ public parentSize: number = 20;
+ public fadeIncrement: number = 0;
+
+ private circleObjects: Array = [];
+ private _target: HTMLElement;
+
+ /**
+ * @param {HTMLDOMElement} target - The element the Spinner will attach itself to.
+ */
+ constructor(container: HTMLElement) {
+ this._target = container;
+ this._init();
+ }
+
+ /**
+ * @function start - starts or restarts the animation sequence
+ * @memberOf fabric.Spinner
+ */
+ public start(): void {
+ this.stop();
+ this.interval = setInterval(() => {
+ let i = this.circleObjects.length;
+ while (i--) {
+ this._fade(this.circleObjects[i]);
+ }
+ }, this.animationSpeed);
+ }
+
+ /**
+ * @function stop - stops the animation sequence
+ * @memberOf fabric.Spinner
+ */
+ public stop(): void {
+ clearInterval(this.interval);
+ }
+
+ // private methods
+
+ private _init(): void {
+ this._setTargetElement();
+ this._setPropertiesForSize();
+ this._createCirclesAndArrange();
+ this._initializeOpacities();
+ this.start();
+ }
+
+ private _setPropertiesForSize(): void {
+ if (this.spinner.className.indexOf("large") > -1) {
+ this.parentSize = 28;
+ this.eightSize = 0.179;
+ }
+
+ this.offsetSize = this.eightSize;
+ this.numCircles = 8;
+ }
+
+ private _setTargetElement(): void {
+ // for backwards compatibility
+ if (this._target.className.indexOf("ms-Spinner") === -1) {
+ this.spinner = document.createElement("div");
+ this.spinner.className = "ms-Spinner";
+ this._target.appendChild(this.spinner);
+ } else {
+ this.spinner = this._target;
+ }
+ }
+
+ private _initializeOpacities(): void {
+ let i = 0;
+ let j = 1;
+ let opacity;
+ this.fadeIncrement = 1 / this.numCircles;
+
+ for (i; i < this.numCircles; i++) {
+ let circleObject = this.circleObjects[i];
+ opacity = (this.fadeIncrement * j++);
+ this._setOpacity(circleObject.element, opacity);
+ }
+ }
+
+ private _fade(circleObject: CircleObject): void {
+ let opacity = this._getOpacity(circleObject.element) - this.fadeIncrement;
+
+ if (opacity <= 0) {
+ opacity = 1;
+ }
+
+ this._setOpacity(circleObject.element, opacity);
+ }
+
+ private _getOpacity(element: HTMLElement): number {
+ return parseFloat(window.getComputedStyle(element).getPropertyValue("opacity"));
+ }
+
+ private _setOpacity(element: HTMLElement, opacity: number): void {
+ element.style.opacity = opacity.toString();
+ }
+
+ private _createCircle(): HTMLElement {
+ let circle = document.createElement("div");
+ circle.className = "ms-Spinner-circle";
+ circle.style.width = circle.style.height = this.parentSize * this.offsetSize + "px";
+ return circle;
+ }
+
+ private _createCirclesAndArrange(): void {
+
+ let angle = 0;
+ let offset = this.parentSize * this.offsetSize;
+ let step = (2 * Math.PI) / this.numCircles;
+ let i = this.numCircles;
+ let circleObject;
+ let radius = (this.parentSize - offset) * 0.5;
+
+ while (i--) {
+ let circle = this._createCircle();
+ let x = Math.round(this.parentSize * 0.5 + radius * Math.cos(angle) - circle.clientWidth * 0.5) - offset * 0.5;
+ let y = Math.round(this.parentSize * 0.5 + radius * Math.sin(angle) - circle.clientHeight * 0.5) - offset * 0.5;
+ this.spinner.appendChild(circle);
+ circle.style.left = x + "px";
+ circle.style.top = y + "px";
+ angle += step;
+ circleObject = new CircleObject(circle, i);
+ this.circleObjects.push(circleObject);
+ }
+ }
+ }
+}
diff --git a/src/components/TextField/Jquery.TextField.js b/src/components/TextField/Jquery.TextField.js
deleted file mode 100644
index 4b7094c2..00000000
--- a/src/components/TextField/Jquery.TextField.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
-
-/**
- * Text Field Plugin
- *
- * Adds basic demonstration functionality to .ms-TextField components.
- *
- * @param {jQuery Object} One or more .ms-TextField components
- * @return {jQuery Object} The same components (allows for chaining)
- */
-(function ($) {
- $.fn.TextField = function () {
-
- /** Iterate through each text field provided. */
- return this.each(function () {
-
- /** Does it have a placeholder? */
- if ($(this).hasClass("ms-TextField--placeholder")) {
-
- /** Hide the label on click. */
- $(this).on('click', function () {
- $(this).find('.ms-Label').hide();
- });
-
- /** Show the label again when leaving the field. */
- $(this).find('.ms-TextField-field').on('blur', function () {
-
- /** Only do this if no text was entered. */
- if ($(this).val().length === 0) {
- $(this).siblings('.ms-Label').show();
- }
- });
- }
-
- /** Underlined - adding/removing a focus class */
- if ($(this).hasClass('ms-TextField--underlined')) {
-
- /** Add is-active class - changes border color to theme primary */
- $(this).find('.ms-TextField-field').on('focus', function() {
- $(this).parent('.ms-TextField--underlined').addClass('is-active');
- });
-
- /** Remove is-active on blur of textfield */
- $(this).find('.ms-TextField-field').on('blur', function() {
- $(this).parent('.ms-TextField--underlined').removeClass('is-active');
- });
- }
-
- });
- };
-})(jQuery);
diff --git a/src/components/TextField/Jquery.TextField.ts b/src/components/TextField/Jquery.TextField.ts
new file mode 100644
index 00000000..2e47d348
--- /dev/null
+++ b/src/components/TextField/Jquery.TextField.ts
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
+// @TODO - we can add this once jquery is removed
+// "use strict";
+
+///
+
+namespace fabric {
+
+ /**
+ * Text Field Plugin
+ *
+ * Adds basic demonstration functionality to .ms-TextField components.
+ */
+ export class TextField {
+
+ /**
+ *
+ * @param {HTMLDivElement} container - the target container for an instance of TextField
+ * @constructor
+ */
+ constructor(container: HTMLElement) {
+ let $textField = $(container);
+
+ /** Does it have a placeholder? */
+ if ($textField.hasClass("ms-TextField--placeholder")) {
+
+ /** Hide the label on click. */
+ $textField.on("click", function () {
+ $textField.find(".ms-Label").hide();
+ });
+
+ /** Show the label again when leaving the field. */
+ $textField.find(".ms-TextField-field").on("blur", function () {
+
+ /** Only do this if no text was entered. */
+ if ($textField.val().length === 0) {
+ $(this).siblings(".ms-Label").show();
+ }
+ });
+ }
+
+ /** Underlined - adding/removing a focus class */
+ if ($textField.hasClass("ms-TextField--underlined")) {
+
+ /** Add is-active class - changes border color to theme primary */
+ $textField.find(".ms-TextField-field").on("focus", function() {
+ $(this).parent(".ms-TextField--underlined").addClass("is-active");
+ });
+
+ /** Remove is-active on blur of textfield */
+ $textField.find(".ms-TextField-field").on("blur", function() {
+ $(this).parent(".ms-TextField--underlined").removeClass("is-active");
+ });
+ }
+ }
+ }
+}
diff --git a/src/templates/componentSampleTemplate.html b/src/templates/componentSampleTemplate.html
index a8ce9911..df99d254 100644
--- a/src/templates/componentSampleTemplate.html
+++ b/src/templates/componentSampleTemplate.html
@@ -11,22 +11,11 @@
-
+
+
+
- <%= jsLinks %>
-