React twitter (#1118)

* React Twitter Timeline web part

* typo in readme
This commit is contained in:
Alex Terentiev 2020-02-10 01:34:03 -08:00 committed by GitHub
parent cead35f5db
commit d7d473f3ee
27 changed files with 18712 additions and 0 deletions

View File

@ -0,0 +1,25 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# change these settings to your own preference
indent_style = space
indent_size = 2
# we recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[{package,bower}.json]
indent_style = space
indent_size = 2

32
samples/react-twitter/.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# Logs
logs
*.log
npm-debug.log*
# Dependency directories
node_modules
# Build generated files
dist
lib
solution
temp
*.sppkg
# Coverage directory used by tools like istanbul
coverage
# OSX
.DS_Store
# Visual Studio files
.ntvs_analysis.dat
.vs
bin
obj
# Resx Generated Code
*.resx.ts
# Styles Generated Code
*.scss.ts

View File

@ -0,0 +1,12 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": true,
"environment": "spo",
"version": "1.10.0",
"libraryName": "react-twitter",
"libraryId": "8c0ef02c-7f7d-4600-9ed0-b7620062c4ef",
"packageManager": "npm",
"isDomainIsolated": false,
"componentType": "webpart"
}
}

View File

@ -0,0 +1,52 @@
# React Twitter Timeline
Sample web part to display Twitter timeline
![Twitter timeline](./assets/twitter-timeline.png)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-1.10.0-green.svg)
## Applies to
* [SharePoint Framework](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
## Solution
Solution|Author(s)
--------|---------
react-twitter-client-side-solution|[AJIXuMuK](https://github.com/AJIXuMuK)
## Version history
Version|Date|Comments
-------|----|--------
1.0|January 20, 2020|Initial release
## Disclaimer
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
---
## Minimal Path to Awesome
* clone this repo
* move to right folder
* in the command line run:
* `npm install`
* `gulp bundle --ship`
* `gulp package-solution --ship`
* from the _sharepoint/solution_ folder, deploy the .sppkg file to the App catalog in your tenant
* in the site where you want to test this solution
* add the app named _page-sections-navigation-client-side-solution_
* edit a page
* add _Page Sections Navigation_ web part
* add as much _Page Sections Navigation Anchor_ web parts as you want - each anchor adds an item to the navigation
* configure web parts
## Features
This sample illustrates how to use [react-twitter-embed](https://www.npmjs.com/package/react-twitter-embed) module to display Twitter timeline of specific profile, likes, list, collection or url.
It also uses [PnP React Controls](https://github.com/SharePoint/sp-dev-fx-controls-react) and [PnP Property Controls](https://github.com/SharePoint/sp-dev-fx-property-controls) for rich web part and property pane components.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -0,0 +1,20 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"twitter-feed-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/twitterFeed/TwitterFeedWebPart.js",
"manifest": "./src/webparts/twitterFeed/TwitterFeedWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"TwitterFeedWebPartStrings": "lib/webparts/twitterFeed/loc/{locale}.js",
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js",
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -0,0 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "react-twitter",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "react-twitter-client-side-solution",
"id": "8c0ef02c-7f7d-4600-9ed0-b7620062c4ef",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false
},
"paths": {
"zippedPackage": "solution/react-twitter.sppkg"
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"port": 4321,
"https": true,
"initialPage": "https://localhost:5432/workbench",
"api": {
"port": 5432,
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}

7
samples/react-twitter/gulpfile.js vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
build.initialize(require('gulp'));

17781
samples/react-twitter/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
{
"name": "react-twitter",
"version": "0.0.1",
"private": true,
"main": "lib/index.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.10.0",
"@microsoft/sp-lodash-subset": "1.10.0",
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
"@microsoft/sp-property-pane": "1.10.0",
"@microsoft/sp-webpart-base": "1.10.0",
"@pnp/spfx-controls-react": "1.16.0",
"@pnp/spfx-property-controls": "1.16.0",
"@types/es6-promise": "0.0.33",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@types/webpack-env": "1.13.1",
"office-ui-fabric-react": "5.131.0",
"react": "16.8.5",
"react-dom": "16.8.5",
"react-twitter-embed": "^2.0.4"
},
"resolutions": {
"@types/react": "16.8.8"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.10.0",
"@microsoft/sp-tslint-rules": "1.10.0",
"@microsoft/sp-module-interfaces": "1.10.0",
"@microsoft/sp-webpart-workbench": "1.10.0",
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
"gulp": "~3.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2"
}
}

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -0,0 +1,83 @@
export type SourceType = 'profile' | 'likes' | 'list' | 'collection' | 'url';
export type Theme = 'dark' | 'light';
/**
* Twitter timeline settings
* See: https://developer.twitter.com/en/docs/twitter-for-websites/timelines/overview
*/
export interface ITwittweTimelineSettings {
/**
* Timeline source type
*/
sourceType: SourceType;
/**
* Twitter public profile name to be used with 'profile' or 'likes' timeline
*/
screenName?: string;
/**
* Twitter public profile user id to be used with 'profile' or 'likes' timeline
*/
userId?: string;
/**
* List's owner name for 'list' timeline
*/
ownerScreenName?: string;
/**
* List's name. For 'list' timeline
*/
slug?: string;
/**
* Unique list id for 'list' timeline OR
* Unique collection id for 'collection' timeline
*/
id?: string;
/**
* Url source to show
*/
url?: string;
/**
* Calculate widget's heigh based on parent
*/
autoHeight?: boolean;
/**
* Widget's theme
*/
theme?: Theme;
/**
* Border color (hex)
*/
borderColor?: string;
/**
* Do not display header
*/
noHeader?: boolean;
/**
* Do not display footer
*/
noFooter?: boolean;
/**
* Do not display border
*/
noBorders?: boolean;
/**
* Do not display scrollbar
*/
noScrollbar?: boolean;
/**
* Custom language code to use.
* See https://developer.twitter.com/en/docs/twitter-for-websites/twitter-for-websites-supported-languages/overview.html
*/
lang?: string;
/**
* Custom width
*/
width?: number;
/**
* Custom height (for autoHeight set to false)
*/
height?: number;
/**
* Number of tweets to display. 1..20
*/
tweetLimit?: number;
}

View File

@ -0,0 +1,27 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "33a4cbd4-780c-4b4a-b9cd-f574c38d30d3",
"alias": "TwitterFeedWebPart",
"componentType": "WebPart",
// The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,
// If true, the component can only be installed on sites where Custom Script is allowed.
// Components that allow authors to embed arbitrary script code should set this to true.
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
"requiresCustomScript": false,
"supportedHosts": ["SharePointWebPart"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "Twitter Feed" },
"description": { "default": "Twitter Feed description" },
"officeFabricIconFontName": "Page",
"properties": {
"description": "Twitter Feed"
}
}]
}

View File

@ -0,0 +1,314 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version, DisplayMode } from '@microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneDropdown,
PropertyPaneToggle
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { PropertyFieldColorPicker, PropertyFieldColorPickerStyle } from '@pnp/spfx-property-controls/lib/PropertyFieldColorPicker';
import { PropertyFieldSpinButton } from '@pnp/spfx-property-controls/lib/PropertyFieldSpinButton';
import { Placeholder, IPlaceholderProps } from '@pnp/spfx-controls-react/lib/Placeholder';
import * as strings from 'TwitterFeedWebPartStrings';
import TwitterFeed from './components/TwitterFeed';
import { ITwitterFeedProps } from './components/ITwitterFeedProps';
import { ITwittweTimelineSettings } from '../model/ITwitterTimelineSettings';
export interface ITwitterFeedWebPartProps extends ITwittweTimelineSettings {
}
export default class TwitterFeedWebPart extends BaseClientSideWebPart<ITwitterFeedWebPartProps> {
public onInit(): Promise<void> {
if (!this.properties.sourceType) {
this.properties.sourceType = 'profile';
}
return super.onInit();
}
public render(): void {
const element: React.ReactElement<ITwitterFeedProps | IPlaceholderProps> = this.isConfigured() ? React.createElement(
TwitterFeed,
this.properties
) : React.createElement(
Placeholder,
{
iconName: 'Edit',
iconText: strings.Configure,
description: strings.ConfigureDescription,
buttonLabel: strings.ConfigureButton,
hideButton: this.displayMode === DisplayMode.Read,
onConfigure: () => {
this.context.propertyPane.open();
}
}
);
ReactDom.unmountComponentAtNode(this.domElement);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected onBeforeSerialize() {
const {
sourceType,
autoHeight,
noBorders
} = this.properties;
//
// removing properties based on source type selection
//
switch (sourceType) {
case 'profile':
case 'likes':
delete this.properties.ownerScreenName;
delete this.properties.slug;
delete this.properties.id;
delete this.properties.url;
break;
case 'list':
delete this.properties.screenName;
delete this.properties.id;
delete this.properties.url;
break;
case 'collection':
delete this.properties.screenName;
delete this.properties.ownerScreenName;
delete this.properties.slug;
delete this.properties.url;
break;
case 'url':
delete this.properties.screenName;
delete this.properties.ownerScreenName;
delete this.properties.slug;
delete this.properties.id;
break;
}
// we don't need to save height if autoHeight is set
if (autoHeight) {
delete this.properties.height;
}
// we don't need to save border color if borders are hidden
if (noBorders) {
delete this.properties.borderColor;
}
}
public get disableReactivePropertyChanges(): boolean {
return true;
}
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any) {
const value = newValue as number;
if (propertyPath === 'tweetLimit') {
if (value === 0) {
//super.onPropertyPaneFieldChanged(propertyPath, oldValue, undefined);
this.properties.tweetLimit = undefined;
return;
}
}
super.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
const {
sourceType,
screenName,
ownerScreenName,
slug,
id,
url,
autoHeight,
theme,
borderColor,
noHeader,
noFooter,
noBorders,
noScrollbar,
width,
height,
tweetLimit
} = this.properties;
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.SourceGroupName,
groupFields: [
PropertyPaneDropdown('sourceType', {
label: strings.SourceType,
selectedKey: sourceType || 'profile',
options: [{
key: 'profile',
text: strings.SourceTypeProfile
}, {
key: 'likes',
text: strings.SourceTypeLikes
}, {
key: 'list',
text: strings.SourceTypeList
}, {
key: 'collection',
text: strings.SourceTypeCollection
}, {
key: 'url',
text: strings.SourceTypeUrl
}]
}),
PropertyPaneTextField('screenName', {
label: strings.ScreenName,
value: screenName,
disabled: sourceType && sourceType !== 'profile' && sourceType !== 'likes'
}),
PropertyPaneTextField('ownerScreenName', {
label: strings.OwnerScreenName,
value: ownerScreenName,
disabled: sourceType !== 'list'
}),
PropertyPaneTextField('slug', {
label: strings.Slug,
value: slug,
disabled: sourceType !== 'list'
}),
PropertyPaneTextField('id', {
label: strings.CollectionId,
value: id,
disabled: sourceType !== 'collection'
}),
PropertyPaneTextField('url', {
label: strings.Url,
value: url,
disabled: sourceType !== 'url'
})
]
},
{
groupName: strings.LayoutGroupName,
groupFields: [
PropertyPaneDropdown('theme', {
label: strings.Theme,
selectedKey: theme || 'light',
options: [{
key: 'light',
text: strings.ThemeLight
}, {
key: 'dark',
text: strings.ThemeDark
}]
}),
PropertyPaneToggle('autoHeight', {
label: strings.AutoHeight,
onText: strings.Yes,
offText: strings.No,
checked: autoHeight
}),
PropertyPaneTextField('height', {
label: strings.Height,
value: height ? height.toString() : '',
disabled: autoHeight
}),
PropertyPaneTextField('width', {
label: strings.Width,
value: width ? width.toString() : ''
}),
PropertyPaneToggle('noHeader', {
label: strings.NoHeader,
onText: strings.Yes,
offText: strings.No,
checked: noHeader
}),
PropertyPaneToggle('noFooter', {
label: strings.NoFooter,
onText: strings.Yes,
offText: strings.No,
checked: noFooter
}),
PropertyPaneToggle('noScrollbar', {
label: strings.NoScrollbar,
onText: strings.Yes,
offText: strings.No,
checked: noScrollbar
}),
PropertyPaneToggle('noBorders', {
label: strings.NoBorders,
onText: strings.Yes,
offText: strings.No,
checked: noBorders
}),
PropertyFieldColorPicker('borderColor', {
key: 'borderColor',
label: strings.BorderColor,
selectedColor: borderColor,
disabled: noBorders,
style: PropertyFieldColorPickerStyle.Inline,
properties: this.properties,
onPropertyChange: this.onPropertyPaneFieldChanged
}),
PropertyFieldSpinButton('tweetLimit', {
key: 'tweetLimit',
label: strings.TweetLimit,
initialValue: tweetLimit,
min: 0,
max: 20,
step: 1,
decimalPlaces: 0,
properties: this.properties,
onPropertyChange: this.onPropertyPaneFieldChanged
})
]
}
]
}
]
};
}
private isConfigured(): boolean {
const {
sourceType,
screenName,
ownerScreenName,
slug,
id,
url
} = this.properties;
if (!sourceType) {
return false;
}
switch (sourceType) {
case 'profile':
case 'likes':
return !!screenName;
break;
case 'list':
return !!ownerScreenName && !!slug;
break;
case 'collection':
return !!id;
break;
case 'url':
return !!url;
break;
}
}
}

View File

@ -0,0 +1,4 @@
import { ITwittweTimelineSettings } from '../../model/ITwitterTimelineSettings';
export interface ITwitterFeedProps extends ITwittweTimelineSettings {
}

View File

@ -0,0 +1,74 @@
@import '~office-ui-fabric-react/dist/sass/References.scss';
.twitterFeed {
.container {
max-width: 700px;
margin: 0px auto;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.row {
@include ms-Grid-row;
@include ms-fontColor-white;
background-color: $ms-color-themeDark;
padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl8;
@include ms-xlPush2;
@include ms-lgPush1;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-l;
@include ms-fontColor-white;
}
.button {
// Our button
text-decoration: none;
height: 32px;
// Primary Button
min-width: 80px;
background-color: $ms-color-themePrimary;
border-color: $ms-color-themePrimary;
color: $ms-color-white;
// Basic Button
outline: transparent;
position: relative;
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
-webkit-font-smoothing: antialiased;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
border-width: 0;
text-align: center;
cursor: pointer;
display: inline-block;
padding: 0 16px;
.label {
font-weight: $ms-font-weight-semibold;
font-size: $ms-font-size-m;
height: 32px;
line-height: 32px;
margin: 0 4px;
vertical-align: top;
display: inline-block;
}
}
}

View File

@ -0,0 +1,55 @@
import * as React from 'react';
import styles from './TwitterFeed.module.scss';
import { ITwitterFeedProps } from './ITwitterFeedProps';
import { TwitterTimelineEmbed } from 'react-twitter-embed';
export default class TwitterFeed extends React.Component<ITwitterFeedProps, {}> {
public render(): React.ReactElement<ITwitterFeedProps> {
const {
sourceType,
screenName,
userId,
ownerScreenName,
slug,
id,
url,
autoHeight,
theme,
borderColor,
noHeader,
noFooter,
noBorders,
noScrollbar,
lang,
width,
height,
tweetLimit
} = this.props;
return (
<div className={ styles.twitterFeed }>
<TwitterTimelineEmbed
sourceType={sourceType}
screenName={screenName}
userId={userId}
ownerScreenName={ownerScreenName}
slug={slug}
id={id}
url={url}
autoHeight={autoHeight}
theme={theme}
borderColor={borderColor}
noHeader={noHeader}
noFooter={noFooter}
noBorders={noBorders}
noScrollbar={noScrollbar}
lang={lang || 'en'}
options={{
height: autoHeight ? undefined : height,
width: width,
tweetLimit: tweetLimit
}} />
</div>
);
}
}

View File

@ -0,0 +1,35 @@
define([], function () {
return {
"PropertyPaneDescription": "Twitter Timeline Setting",
"SourceGroupName": "Source",
"SourceType": "Source type",
"SourceTypeProfile": "Profile",
"SourceTypeList": "List",
"SourceTypeCollection": "Collection",
"SourceTypeLikes": "Likes",
"SourceTypeUrl": "Url",
"ScreenName": "Twitter handle",
"OwnerScreenName": "List owner Twitter handle",
"Slug": "List slug",
"CollectionId": "Collection Id",
"Url": "Source URL",
"LayoutGroupName": "Layout Options",
"Theme": "Theme",
"ThemeDark": "Dark",
"ThemeLight": "Light",
"AutoHeight": "Auto height",
"Height": "Specify custom height",
"Width": "Specify custom width",
"NoBorders": "Hide borders",
"NoHeader": "Hide header",
"NoFooter": "Hide footer",
"NoScrollbar": "Hide scrollbar",
"TweetLimit": "Limit number of displayed tweets (1 to 20, 0 - auto)",
"BorderColor": "Border color",
"Yes": "Yes",
"No": "No",
"Configure": "Configure Twitter source",
"ConfigureDescription": "You need to configure Twitter source to use the web part",
"ConfigureButton": "Configure"
}
});

View File

@ -0,0 +1,38 @@
declare interface ITwitterFeedWebPartStrings {
PropertyPaneDescription: string;
SourceGroupName: string;
SourceType: string;
SourceTypeProfile:string;
SourceTypeList: string;
SourceTypeCollection: string;
SourceTypeLikes: string;
SourceTypeUrl: string;
ScreenName: string;
OwnerScreenName: string;
Slug: string;
CollectionId: string;
Url: string;
LayoutGroupName: string;
Theme: string;
ThemeDark: string;
ThemeLight: string;
AutoHeight: string;
Height: string;
Width: string;
NoBorders: string;
NoHeader: string;
NoFooter: string;
NoScrollbar: string;
TweetLimit: string;
BorderColor: string;
Yes: string;
No: string;
Configure: string;
ConfigureDescription: string;
ConfigureButton: string;
}
declare module 'TwitterFeedWebPartStrings' {
const strings: ITwitterFeedWebPartStrings;
export = strings;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,38 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"outDir": "lib",
"inlineSources": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
],
"types": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

@ -0,0 +1,30 @@
{
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
"rules": {
"class-name": false,
"export-name": false,
"forin": false,
"label-position": false,
"member-access": true,
"no-arg": false,
"no-console": false,
"no-construct": false,
"no-duplicate-variable": true,
"no-eval": false,
"no-function-expression": true,
"no-internal-module": true,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-unnecessary-semicolons": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-with-statement": true,
"semicolon": true,
"trailing-comma": false,
"typedef": false,
"typedef-whitespace": false,
"use-named-parameter": true,
"variable-name": false,
"whitespace": false
}
}