feat: 初始化仓库

This commit is contained in:
NICE CODE BY DEV 2024-05-16 10:31:01 +08:00
commit dbdf7d0033
33 changed files with 3598 additions and 0 deletions

282
.eslintrc.js Normal file
View File

@ -0,0 +1,282 @@
const path = require('path');
module.exports = {
env: {
es6: true,
browser: true,
node: true,
},
parserOptions: {
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
extends: ['eslint-config-prettier'],
plugins: [
'babel',
'eslint-comments',
'import',
'prettier',
'simple-import-sort',
],
rules: {
'array-callback-return': 'error',
'babel/no-invalid-this': 'error',
'babel/valid-typeof': 'error',
'constructor-super': 'error',
'default-case': ['error', { commentPattern: '^no default$' }],
'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
'eslint-comments/no-aggregating-enable': 'error',
'eslint-comments/no-duplicate-disable': 'error',
'eslint-comments/no-unlimited-disable': 'error',
'eslint-comments/no-unused-disable': 'error',
'eslint-comments/no-unused-enable': 'error',
'for-direction': 'error',
'getter-return': 'error',
'import/export': 'error',
'import/extensions': 'off',
'import/imports-first': 'error',
'import/named': 'off',
'import/no-amd': 'error',
'import/no-commonjs': 'error',
'import/no-duplicates': 'error',
'import/no-extraneous-dependencies': 'error',
'import/no-self-import': 'error',
'new-parens': 'error',
'no-array-constructor': 'error',
'no-caller': 'error',
'no-case-declarations': 'error',
'no-class-assign': 'error',
'no-compare-neg-zero': 'error',
'no-cond-assign': ['error', 'except-parens'],
'no-const-assign': 'error',
'no-constant-condition': 'error',
'no-control-regex': 'error',
'no-delete-var': 'error',
'no-dupe-args': 'error',
'no-dupe-class-members': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-empty': 'error',
'no-empty-character-class': 'error',
'no-empty-pattern': 'error',
'no-eval': 'error',
'no-ex-assign': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-extra-boolean-cast': 'error',
'no-extra-label': 'error',
'no-extra-semi': 'error',
'no-fallthrough': 'error',
'no-func-assign': 'error',
'no-global-assign': 'error',
'no-implied-eval': 'error',
'no-inner-declarations': 'error',
'no-invalid-regexp': 'error',
'no-iterator': 'error',
'no-label-var': 'error',
'no-labels': ['error', { allowLoop: true, allowSwitch: false }],
'no-lone-blocks': 'error',
'no-loop-func': 'error',
'no-misleading-character-class': 'error',
'no-multi-str': 'error',
'no-new-func': 'error',
'no-new-object': 'error',
'no-new-symbol': 'error',
'no-new-wrappers': 'error',
'no-obj-calls': 'error',
'no-octal': 'error',
'no-octal-escape': 'error',
'no-redeclare': 'error',
'no-regex-spaces': 'error',
'no-self-assign': 'error',
'no-self-compare': 'error',
'no-shadow-restricted-names': 'error',
'no-sparse-arrays': 'error',
'no-this-before-super': 'error',
'no-throw-literal': 'error',
'no-undef': 'error',
'no-unexpected-multiline': 'error',
'no-unreachable': 'error',
'no-unsafe-finally': 'error',
'no-unsafe-negation': 'error',
'no-unused-labels': 'error',
'no-unused-vars': 'error',
'no-use-before-define': [
'error',
{ functions: false, classes: false, variables: false },
],
'no-useless-computed-key': 'error',
'no-useless-concat': 'error',
'no-useless-constructor': 'error',
'no-useless-escape': 'error',
'no-useless-rename': 'error',
'no-with': 'error',
'require-yield': 'error',
'simple-import-sort/exports': 'error',
'unicode-bom': 'error',
'use-isnan': 'error',
eqeqeq: ['error', 'smart'],
'import/no-unresolved': [
'error',
{ caseSensitive: false, ignore: ['vscode'] },
],
'prettier/prettier': [
'error',
{
bracketSameLine: false,
bracketSpacing: true,
printWidth: 80,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'all',
useTabs: false,
endOfLine: 'auto',
},
],
'simple-import-sort/imports': [
'error',
{ groups: [['^\\u0000'], ['^@?\\w'], ['^~/'], ['^../'], ['^./']] },
],
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: require.resolve('@typescript-eslint/parser'),
plugins: ['@typescript-eslint/eslint-plugin'],
settings: {
'import/extensions': ['.js', '.ts', '.tsx'],
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
node: {
extensions: ['.js', '.ts', '.tsx'],
},
},
},
rules: {
'@typescript-eslint/adjacent-overload-signatures': 'error',
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/consistent-type-assertions': [
'error',
{ assertionStyle: 'as' },
],
'@typescript-eslint/member-delimiter-style': 'error',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-dynamic-delete': 'error',
'@typescript-eslint/no-empty-interface': [
'error',
{ allowSingleExtends: true },
],
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
],
'@typescript-eslint/no-use-before-define': [
'error',
{
functions: false,
classes: false,
variables: false,
typedefs: false,
},
],
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unified-signatures': 'error',
'default-case': 'off',
'no-dupe-class-members': 'off',
'no-undef': 'off',
'no-unused-vars': 'off',
'no-array-constructor': 'off',
'no-use-before-define': 'off',
},
},
{
plugins: ['jest'],
files: ['*.{spec,test}.{js,ts,tsx}', '**/__tests__/**/*.{js,ts,tsx}'],
env: {
jest: true,
},
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
'jest/consistent-test-it': ['error', { fn: 'test' }],
'jest/expect-expect': [
'error',
{ assertFunctionNames: ['expect', 'element'] },
],
'jest/no-disabled-tests': 'error',
'jest/no-duplicate-hooks': 'error',
'jest/no-export': 'error',
'jest/no-focused-tests': 'error',
'jest/no-identical-title': 'error',
'jest/no-jasmine-globals': 'error',
'jest/no-test-prefixes': 'error',
'jest/no-test-return-statement': 'error',
'jest/prefer-todo': 'error',
'jest/require-to-throw-message': 'error',
'jest/valid-describe-callback': 'error',
'jest/valid-expect-in-promise': 'error',
'jest/valid-expect': 'error',
'jest/valid-title': 'error',
'jest/no-restricted-matchers': [
'error',
{
toBeTruthy: 'Avoid `toBeTruthy`',
toBeFalsy: 'Avoid `toBeFalsy`',
},
],
},
},
{
files: ['*.js'],
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
requireConfigFile: false,
},
rules: {
'import/default': 'error',
'import/namespace': 'error',
'import/no-named-as-default': 'error',
'import/no-named-as-default-member': 'error',
'import/no-cycle': 'error',
'import/no-deprecated': 'error',
},
},
{
files: ['*.config.js', '.*rc.js'],
env: {
node: true,
},
rules: {
'import/no-commonjs': 'off',
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
},
},
],
globals: {
jasmine: true,
},
};

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
*.vsix

12
.vscodeignore Normal file
View File

@ -0,0 +1,12 @@
**/*.ts
**/tsconfig.json
node_modules
!file.ts
src
**/tsconfig.json
*.ts
.github/**
.gitignore
.vscode/**
docs/**
src/**

13
CHANGELOG.md Normal file
View File

@ -0,0 +1,13 @@
# nicecode-snippets
## 0.2.1
### Patch Changes
- 初始化仓库,发个小版本
## 0.2.0
### Minor Changes
- feat: 初始化

107
README.md Normal file
View File

@ -0,0 +1,107 @@
## 下载应用
> 在 **vscode** 应用商店搜索并下载 **nicecode-react-js-ts-snippets** 即可。
## javascript-snippets
> `imp` => `import xx from xx`
> `imd` => `import { XX } from 'XX'`
> `ime` => `import * as XX from 'XX'`
> `exp` => `export default XX`
> `clg` => `console.log(XX)`
> `deas` => `const { XX } = XX`
## react-snippets
> `imr` => `import React, {} from 'react'`
> `useState` => `const [xx, setXX] = useState(XX)`
> `useEffect` => `useEffect(() => { XX }, [XX])`
> `useDispatch` => `const dispatch = useDispatch()`
> `useSelector` => `const XX = useSelector(state => state.XX)`
...more
## umi-snippets
`tsx -> 生成`
```jsx | pure
import { FC } from 'react'
import { connect, ConnectProps } from 'umi'
import styles from './index.less'
interface I${1:component} extends ConnectProps {
}
const $1: FC<I${1:component}> = (props) => {",
return (
<div className={styles.${1:component}}>${1:component}</div>
)
}
export default connect(({}: {}) => ({
}))(${1:component})
```
`mts -> 生成`
```js | pure
// 2022-08-26 - by dev
import { ImmerReducer, Effect } from 'umi';
import { SubscriptionsMapObject } from 'dva';
export interface XXModelState {
}
export interface XXModelType {
namespace: 'XX';
state: XXModelState;
effects: {
};
reducers: {
save: ImmerReducer<XXModelState>;
reset: ImmerReducer<XXModelState>;
};
subscriptions: SubscriptionsMapObject;
}
const initialState: XXModelState = {
}
const XXModel: XXModelType = {
namespace: 'XX',
state: initialState,
effects: {
},
reducers: {
save(state, { payload }: any) {
return { ...state, ...payload }
},
reset(state, { payload }: any) {
return { ...initialState }
}
},
subscriptions: {}
};
export default XXModel;
```
## join us
[Nicecoders Team](https://github.com/nicecoders/nicecode)

BIN
images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

128
package.json Normal file
View File

@ -0,0 +1,128 @@
{
"name": "nicecode-snippets",
"displayName": "nicecode-react-js-ts-snippets",
"version": "0.2.1",
"description": "Extensions for React, React-Native and Redux in JS/TS with ES7+ syntax",
"publisher": "devlifestyle",
"icon": "images/logo.png",
"keywords": [
"snippets",
"flow",
"work",
"nicecode"
],
"author": "dev <710328466@qq.com>",
"main": "./lib/src/index.js",
"homepage": "https://nicecoders.github.io/nicecode/#/snippets",
"scripts": {
"builder": "vsce package --no-dependencies",
"vscode:prepublish": "yarn compile",
"compile": "rm -rf lib; tsc -p ./ --noEmit false --module commonjs --outDir lib",
"compile:dev": "rm -rf lib; tsc -p ./ --noEmit false --module commonjs --outDir lib",
"lint": "eslint --ext .js,.ts,.tsx ./src/",
"watch": "tsc -watch -p ./",
"typescript": "tsc --noEmit"
},
"engines": {
"vscode": "^1.64.0"
},
"license": "MIT",
"categories": [
"Snippets"
],
"contributes": {
"commands": [
{
"command": "nicecodeSnippets.search",
"title": "nicecode search"
}
],
"keybindings": [
{
"command": "nicecodeSnippets.search",
"key": "ctrl+alt+r",
"mac": "shift+cmd+r",
"when": "editorTextFocus"
}
],
"configuration": {
"title": "ES React/React-Native/Redux snippets",
"properties": {
"nicecodeSnippets.settings.prettierEnabled": {
"type": "boolean",
"markdownDescription": "[EXPERIMENTAL: MIGHT NOT WORK]: Integrate prettier settings with code generated from snippets.",
"default": false
},
"nicecodeSnippets.settings.languageScopes": {
"type": "string",
"markdownDescription": "defines the language scopes for which the snippets will be available.\nUse comma separated values.\nFor example: `typescript,typescriptreact,javascript,javascriptreact`",
"default": "typescript,typescriptreact,javascript,javascriptreact"
}
}
},
"snippets": [
{
"language": "javascript",
"path": "./snippets/snippets.json"
},
{
"language": "javascriptreact",
"path": "./snippets/snippets.json"
},
{
"language": "typescript",
"path": "./snippets/snippets.json"
},
{
"language": "typescriptreact",
"path": "./snippets/snippets.json"
}
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/nicecoders/nicecoders.github.io.git"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
},
"bugs": {
"url": "https://github.com/nicecoders/nicecoders.github.io/issues"
},
"dependencies": {
"prettier": "2.5.1"
},
"devDependencies": {
"@babel/cli": "7.17.0",
"@babel/eslint-parser": "7.17.0",
"@babel/preset-typescript": "7.16.7",
"@types/node": "17.0.16",
"@types/prettier": "2.4.3",
"@types/vscode": "^1.60.0",
"@typescript-eslint/eslint-plugin": "5.11.0",
"@typescript-eslint/parser": "5.11.0",
"eslint": "8.8.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-babel": "5.3.1",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-jest": "26.1.0",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-simple-import-sort": "7.0.0",
"prettier": "2.5.1",
"typescript": "^4.8.3"
},
"prettier": {
"bracketSameLine": false,
"bracketSpacing": true,
"printWidth": 80,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false,
"endOfLine": "auto"
},
"gitHead": "143fba48314ad1f175de7fed5b83325215ff7380"
}

225
snippets.json Normal file
View File

@ -0,0 +1,225 @@
{
"import": {
"prefix": "imp",
"body": ["import ${2:moduleName} from '${1:module}'"],
"description": "normal import"
},
"import module": {
"prefix": "imd",
"body": ["import { $2 } from '${1:module}'"],
"description": "importDestructing"
},
"import everything": {
"prefix": "ime",
"body": ["import * as ${2:alias} from '${1:module}'"],
"description": "importEverything"
},
"exportDefault": {
"prefix": "exp",
"body": ["export default $1"],
"description": "export default"
},
"consoleLog": {
"prefix": "clg",
"body": ["console.log(${1:data})"],
"description": "console log"
},
"destructuringAssignment": {
"prefix": "deas",
"body": ["const { ${2:prop} } = ${1:object}"],
"description": "destructuring assignment"
},
"import React": {
"prefix": "imr",
"body": ["import React, {} from 'react'"],
"description": "import React"
},
"useState": {
"prefix": "useState",
"body": [
"const [${1:state}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:initialState})"
],
"description": "useState"
},
"useEffect": {
"prefix": "useEffect",
"body": ["useEffect(() => {\n\t${1:effect}\n}, [${2:dep}])"],
"description": "useEffect"
},
"useContext": {
"prefix": "useContext",
"body": ["const ${1:context} = useContext(${2:ContextValue})"],
"description": "useContext"
},
"reduxActionCreator": {
"prefix": "rxaction",
"body": ["export const ${1:actionName} = (payload) => ({\n\ttype: ${2:type},\n\tpayload\n})"],
"description": "reduxActionCreator"
},
"useDispatch": {
"prefix": "useDispatch",
"body": ["const dispatch = useDispatch()"],
"description": "useDispatch"
},
"useSelector": {
"prefix": "useSelector",
"body": ["const ${1:state} = useSelector(state => state.$1)"],
"description": "useSelector"
},
"useMount": {
"prefix": "useMount",
"body": ["useMount(() => {\n\t${1:fn}\n})"],
"description": "useMount"
},
"useUnmount": {
"prefix": "useUnmount",
"body": ["useUnmount(() => {\n\t${1:fn}\n})"],
"description": "useUnmount"
},
"useSetState": {
"prefix": "useSetState",
"body": [
"const [state, setState] = useSetState(${1:initialState})"
],
"description": "useSetState"
},
"useBoolean": {
"prefix": "useBoolean",
"body": [
"const [${1}, { toggle, setTrue, setFalse }] = useBoolean(${2)"
],
"description": "useBoolean"
},
"useToggle": {
"prefix": "useToggle",
"body": [
"const [${1}, { toggle, set, setLeft, setRight }] = useToggle(${2}, ${3})"
],
"description": "useToggle"
},
"useCookieState": {
"prefix": "useCookieState",
"body": [
"const [${1}, set${1}] = useCookieState('${3:key}')"
],
"description": "useCookieState"
},
"useLocalStorageState": {
"prefix": "useLocalStorageState",
"body": [
"const [${1}, set${1}] = useLocalStorageState('${3:key}')"
],
"description": "useLocalStorageState"
},
"useSessionStorageState": {
"prefix": "useSessionStorageState",
"body": [
"const [${1}, set${1}] = useSessionStorageState('${3:key}')"
],
"description": "useSessionStorageState"
},
"useDebounce": {
"prefix": "useDebounce",
"body": [
"const ${2:debounceVal} = useDebounce(${1:value}, { wait: 1000 })"
],
"description": "useDebounce"
},
"useDebounceFn": {
"prefix": "useDebounceFn",
"body": [
"const { run, cancel, flush } = useDebounceFn(() => {\n\t${1:fn}\n},, { wait: 1000 })"
],
"description": "useDebounceFn"
},
"useThrottle": {
"prefix": "useThrottle",
"body": [
"const ${2} = useThrottle(${1}, { wait: 1000 })"
],
"description": "useThrottle"
},
"useThrottleFn": {
"prefix": "useThrottleFn",
"body": [
"const { run, cancel, flush } = useThrottleFn(() => {\n\t${1:fn}\n},, { wait: 1000 })"
],
"description": "useThrottleFn"
},
"functionComponentWithUmi": {
"prefix": "tsx",
"body": [
"// $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE - by dev",
"\n",
"import { FC } from 'react'",
"import { connect, ConnectProps } from 'umi'",
"import styles from './index.less'",
"\n",
"interface I${1:component} extends ConnectProps {",
"}",
"\n",
"const ${1:component}: FC<I${1:component}> = (props) => {",
" return (",
" <div className={styles.${1:component}}>${1:component}</div>",
" )",
" }",
"\n",
"export default connect(({}: {}) => ({",
"}))(${1:component})"
],
"description": "umi 函数组件模板"
},
"umiModel": {
"prefix": "mts",
"body": [
"// $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE - by dev",
"import { ImmerReducer, Effect } from 'umi';",
"import { SubscriptionsMapObject } from 'dva';",
"\n",
"export interface ${1:component}ModelState {",
"}",
"\n",
"export interface ${1:component}ModelType {",
" namespace: '${1:component}';",
" state: ${1:component}ModelState;",
" effects: {",
" };",
" reducers: {",
" save: ImmerReducer<${1:component}ModelState>;",
" reset: ImmerReducer<${1:component}ModelState>;",
" };",
" subscriptions: SubscriptionsMapObject;",
"}",
"\n",
"const initialState: ${1:component}ModelState = {",
"}",
"\n",
"const ${1:component}Model: ${1:component}ModelType = {",
" namespace: '${1:component}',",
" state: initialState,",
" effects: {",
" // *demo({ payload }, { call, put }) {",
" // const response = yield call(getCaseForm, payload);",
" // yield put({",
" // type: 'save',",
" // payload: response,",
" // });",
" //},",
" },",
" reducers: {",
" save(state, { payload }: any) {",
" return { ...state, ...payload }",
" },",
" reset(state, { payload }: any) {",
" return { ...initialState }",
" }",
" },",
" subscriptions: {}",
"};",
"\n",
"export default ${1:component}Model;"
]
}
}

View File

@ -0,0 +1,16 @@
import { workspace } from 'vscode';
export type ExtensionSettings = {
languageScopes: string;
prettierEnabled: boolean;
importReactOnTop: boolean;
typescript: boolean;
typescriptPropsStatePrefix: 'type' | 'interface';
};
const extensionConfig = () =>
workspace.getConfiguration(
'reactSnippets.settings',
) as unknown as ExtensionSettings;
export default extensionConfig;

22
src/helpers/formatters.ts Normal file
View File

@ -0,0 +1,22 @@
import prettier from 'prettier';
import extensionConfig from './extensionConfig';
import getPrettierConfig from './getPrettierConfig';
import {
replaceSnippetPlaceholders,
revertSnippetPlaceholders,
} from './snippetPlaceholders';
export const formatSnippet = (snippetString: string) => {
return extensionConfig().prettierEnabled
? prettier.format(snippetString, getPrettierConfig())
: snippetString;
};
export const parseSnippet = (body: string | string[]) => {
const snippetBody = typeof body === 'string' ? body : body.join('\n');
return replaceSnippetPlaceholders(
formatSnippet(revertSnippetPlaceholders(snippetBody)),
);
};

View File

@ -0,0 +1,94 @@
import { writeFile } from 'fs';
import componentsSnippets, {
ComponentsSnippet,
} from '../sourceSnippets/components';
import consoleSnippets, { ConsoleSnippet } from '../sourceSnippets/console';
import hooksSnippets, { HooksSnippet } from '../sourceSnippets/hooks';
import importsSnippets, { ImportsSnippet } from '../sourceSnippets/imports';
import othersSnippets, { OthersSnippet } from '../sourceSnippets/others';
import propTypesSnippets, {
PropTypesSnippet,
} from '../sourceSnippets/propTypes';
import reactNativeSnippets, {
ReactNativeSnippet,
} from '../sourceSnippets/reactNative';
import reduxSnippets, { ReduxSnippet } from '../sourceSnippets/redux';
import testsSnippets, { TestsSnippet } from '../sourceSnippets/tests';
import typescriptSnippets, {
TypescriptSnippet,
} from '../sourceSnippets/typescript';
import extensionConfig from './extensionConfig';
import parseSnippetToBody from './parseSnippetToBody';
import { replaceSnippetPlaceholders } from './snippetPlaceholders';
export type SnippetKeys =
| OthersSnippet['key']
| HooksSnippet['key']
| ImportsSnippet['key']
| ReactNativeSnippet['key']
| TypescriptSnippet['key']
| ReduxSnippet['key']
| ComponentsSnippet['key']
| ConsoleSnippet['key']
| PropTypesSnippet['key']
| TestsSnippet['key'];
export type Snippet =
| OthersSnippet
| HooksSnippet
| ImportsSnippet
| ReactNativeSnippet
| TypescriptSnippet
| ReduxSnippet
| ComponentsSnippet
| ConsoleSnippet
| PropTypesSnippet
| TestsSnippet;
export type Snippets = {
[key in SnippetKeys]: Snippet;
};
const getSnippets = () => {
const { typescript, languageScopes } = extensionConfig();
const snippets = [
...(typescript ? typescriptSnippets : []),
...componentsSnippets,
...consoleSnippets,
...hooksSnippets,
...importsSnippets,
...propTypesSnippets,
...reactNativeSnippets,
...reduxSnippets,
...testsSnippets,
...othersSnippets,
].reduce((acc, snippet) => {
acc[snippet.key] = Object.assign(snippet, {
body: parseSnippetToBody(snippet),
scope: languageScopes,
});
return acc;
}, {} as Snippets);
return replaceSnippetPlaceholders(JSON.stringify(snippets, null, 2));
};
const generateSnippets = () =>
new Promise((resolve) => {
const jsonSnippets = getSnippets();
writeFile(
__dirname + '/../snippets/generated.json',
jsonSnippets,
(error) => {
if (error) {
console.error(error);
}
return resolve(true);
},
);
});
export default generateSnippets;

View File

@ -0,0 +1,19 @@
import prettier, { Options } from 'prettier';
import extensionConfig from './extensionConfig';
let prettierConfig: prettier.Options | null;
prettier
.resolveConfig('', { editorconfig: true })
.then((config) => (prettierConfig = config));
const getPrettierConfig = (): Options => {
const { prettierEnabled } = extensionConfig();
return {
parser: 'typescript',
...(prettierEnabled && prettierConfig),
};
};
export default getPrettierConfig;

View File

@ -0,0 +1,23 @@
import extensionConfig from './extensionConfig';
import { formatSnippet } from './formatters';
import { Snippet } from './generateSnippets';
import replaceOrRemoveReactImport from './replaceOrRemoveReactImport';
const parseSnippetToBody = (snippet: Snippet) => {
const { importReactOnTop } = extensionConfig();
const body =
typeof snippet.body === 'string' ? snippet.body : snippet.body.join('\n');
const snippetBody = importReactOnTop
? body
: replaceOrRemoveReactImport({
prefix: snippet.prefix,
body: snippet.body,
});
const formattedSnippet = formatSnippet(snippetBody).split('\n');
return formattedSnippet;
};
export default parseSnippetToBody;

View File

@ -0,0 +1,64 @@
import { Snippet } from './generateSnippets';
const snippetWithReactImportPrefixes = [
'rfce',
'rfc',
'rfcp',
'rafce',
'rafc',
'rafcp',
'rnfe',
'rnfes',
'rnf',
'rnfs',
'stest',
'sntest',
'srtest',
'snrtest',
'hocredux',
'hoc',
'tsrafc',
'tsrafce',
'tsrcc',
'tsrcredux',
'tsrce',
'tsrpce',
'tsrpc',
'tsrfc',
'tsrfce',
'tsrnf',
'tsrnfs',
];
const replaceOrRemoveReactImport = ({
body,
prefix,
}: {
body: string[];
prefix: Snippet['prefix'];
}) => {
if (!snippetWithReactImportPrefixes.includes(prefix)) {
return body.join('\n');
}
let bodyCopy = [...body];
const reactImportIndex = bodyCopy.findIndex((line) =>
line.match(new RegExp(/import React/, 'g')),
);
if (reactImportIndex !== -1) {
const line = bodyCopy[reactImportIndex];
const newLine = line
.replace(new RegExp(/^import React .*$/, 'g'), '')
.replace(new RegExp(/^import React, /, 'g'), 'import ');
bodyCopy[reactImportIndex] = newLine;
if (!newLine.length) {
bodyCopy = bodyCopy.filter(Boolean);
}
}
return bodyCopy.join('\n');
};
export default replaceOrRemoveReactImport;

View File

@ -0,0 +1,43 @@
import { Mappings, Placeholders } from '../types';
import extensionConfig from './extensionConfig';
export const replaceSnippetPlaceholders = (snippetString: string) => {
const { typescriptPropsStatePrefix } = extensionConfig();
const propsPlaceholder =
typescriptPropsStatePrefix === 'type'
? Mappings.TypeProps
: Mappings.InterfaceProps;
const statePlaceholder =
typescriptPropsStatePrefix === 'type'
? Mappings.TypeState
: Mappings.InterfaceState;
return String(snippetString)
.replace(new RegExp(Placeholders.FileName, 'g'), '${1:${TM_FILENAME_BASE}}')
.replace(new RegExp(Placeholders.FirstTab, 'g'), '${1:first}')
.replace(new RegExp(Placeholders.SecondTab, 'g'), '${2:second}')
.replace(new RegExp(Placeholders.ThirdTab, 'g'), '${3:third}')
.replace(
new RegExp(Placeholders.Capitalize, 'g'),
'${1/(.*)/${1:/capitalize}/}',
)
.replace(new RegExp(Placeholders.TypeProps, 'g'), propsPlaceholder)
.replace(new RegExp(Placeholders.TypeState, 'g'), statePlaceholder);
};
export const revertSnippetPlaceholders = (snippetString: string) => {
return String(snippetString)
.replace(
new RegExp(/\${1:\${TM_FILENAME_BASE}}/, 'g'),
Placeholders.FileName,
)
.replace(new RegExp(/\${1:first}/, 'g'), Placeholders.FirstTab)
.replace(new RegExp(/\${2:second}/, 'g'), Placeholders.SecondTab)
.replace(new RegExp(/\${3:third}/, 'g'), Placeholders.ThirdTab)
.replace(
new RegExp(/\${1\/(.*)\/${1:\/capitalize}\/}/, 'g'),
Placeholders.Capitalize,
);
};
export default revertSnippetPlaceholders;

View File

@ -0,0 +1,41 @@
import { readFileSync } from 'fs';
import { SnippetString, window } from 'vscode';
import { parseSnippet } from './formatters';
import { Snippet } from './generateSnippets';
const snippetSearch = async () => {
const { showQuickPick, activeTextEditor } = window;
const snippets = readFileSync(
__dirname + '/../snippets/generated.json',
'utf8',
);
const snippetsArray = Object.entries(JSON.parse(snippets)) as [
string,
Snippet,
][];
const items = snippetsArray.map(
([shortDescription, { body, description, prefix: label }]) => ({
body,
description: description || shortDescription,
label,
}),
);
const rawSnippet = await showQuickPick(items, {
matchOnDescription: true,
matchOnDetail: true,
placeHolder: 'Search snippet by prefix or description',
});
const body = rawSnippet ? parseSnippet(rawSnippet.body) : '';
if (activeTextEditor) {
activeTextEditor.insertSnippet(new SnippetString(body));
}
};
export default snippetSearch;

15
src/index.d Normal file
View File

@ -0,0 +1,15 @@
---
nav:
title: 工具
path: /other
second:
title: 规范工具
order: 2
group:
title: snippets 代码片段
order: 4
---
# snippets 代码片段
<embed src="../README.md"></embed>

11
src/index.md Normal file
View File

@ -0,0 +1,11 @@
---
nav:
title: 工具
path: /other
group:
title: 其它
title: 代码片段
toc: content
---
<embed src="../README.md"></embed>

47
src/index.ts Normal file
View File

@ -0,0 +1,47 @@
import {
commands,
ConfigurationChangeEvent,
ExtensionContext,
window,
workspace,
} from 'vscode';
import generateSnippets from './helpers/generateSnippets';
import snippetSearch from './helpers/snippetSearch';
import generatedSnippets from '../snippets/snippets.json';
const showRestartMessage = async ({
affectsConfiguration,
}: ConfigurationChangeEvent) => {
if (affectsConfiguration('reactSnippets')) {
await generateSnippets();
setTimeout(() => {
window
.showWarningMessage(
'React Snippets: Please restart VS Code to apply snippet formatting changes',
'Restart VS Code',
'Ignore',
)
.then((action?: string) => {
if (action === 'Restart VS Code') {
commands.executeCommand('workbench.action.reloadWindow');
}
});
}, 1000);
}
};
export async function activate(context: ExtensionContext) {
workspace.onDidChangeConfiguration(showRestartMessage);
if (JSON.stringify(generatedSnippets).length < 10) {
await generateSnippets();
}
const snippetSearchCommand = commands.registerCommand(
'reactSnippets.search',
snippetSearch,
);
context.subscriptions.push(snippetSearchCommand);
}
export function deactivate() {}

View File

@ -0,0 +1,365 @@
import { Placeholders, SnippetMapping } from '../types';
import {
exportDefault,
innerComponent,
innerComponentReturn,
react,
reactComponent,
reactComponentWithReduxConnect,
reactPropTypes,
reactPureComponent,
reactWithMemo,
reactWithReduxConnect,
reduxComponentExport,
} from './sharedSnippets';
type ComponentMappings = {
reactArrowFunctionComponent: 'rafc';
reactArrowFunctionComponentWithPropTypes: 'rafcp';
reactArrowFunctionExportComponent: 'rafce';
reactClassComponentPropTypes: 'rccp';
reactClassComponentRedux: 'rcredux';
reactClassComponentReduxPropTypes: 'rcreduxp';
reactClassComponent: 'rcc';
reactClassExportComponent: 'rce';
reactClassExportComponentWithPropTypes: 'rcep';
reactClassExportPureComponent: 'rpce';
reactClassPureComponent: 'rpc';
reactClassPureComponentWithPropTypes: 'rpcp';
reactFunctionMemoComponent: 'rmc';
reactFunctionMemoComponentWithPropTypes: 'rmcp';
reactFunctionalComponentRedux: 'rfcredux';
reactFunctionalComponentReduxPropTypes: 'rfcreduxp';
reactFunctionalComponent: 'rfc';
reactFunctionalComponentWithPropTypes: 'rfcp';
reactFunctionalExportComponent: 'rfce';
};
export type ComponentsSnippet = SnippetMapping<ComponentMappings>;
const reactClassComponent: ComponentsSnippet = {
key: 'reactClassComponent',
prefix: 'rcc',
body: [
...reactComponent,
'',
`export default class ${Placeholders.FileName} extends Component {`,
...innerComponentReturn,
'}',
'',
],
description: 'Creates a React component class with ES7 module system',
};
const reactClassExportComponent: ComponentsSnippet = {
key: 'reactClassExportComponent',
prefix: 'rce',
body: [
...reactComponent,
'',
`export class ${Placeholders.FileName} extends Component {`,
...innerComponentReturn,
'}',
...exportDefault,
],
description: 'Creates a React component class with ES7 module system',
};
const reactFunctionalExportComponent: ComponentsSnippet = {
key: 'reactFunctionalExportComponent',
prefix: 'rfce',
body: [
...react,
'',
`function ${Placeholders.FileName}() {`,
...innerComponent,
'}',
...exportDefault,
],
description: 'Creates a React Functional Component with ES7 module system',
};
const reactFunctionalComponent: ComponentsSnippet = {
key: 'reactFunctionalComponent',
prefix: 'rfc',
body: [
...react,
'',
`export default function ${Placeholders.FileName}() {`,
...innerComponent,
'}',
'',
],
description: 'Creates a React Functional Component with ES7 module system',
};
const reactFunctionalComponentWithPropTypes: ComponentsSnippet = {
key: 'reactFunctionalComponentWithPropTypes',
prefix: 'rfcp',
body: [
...reactPropTypes,
'',
`function ${Placeholders.FileName}(props) {`,
...innerComponent,
'}',
'',
`${Placeholders.FileName}.propTypes = {}`,
...exportDefault,
'',
],
description:
'Creates a React Functional Component with ES7 module system with PropTypes',
};
const reactArrowFunctionExportComponent: ComponentsSnippet = {
key: 'reactArrowFunctionExportComponent',
prefix: 'rafce',
body: [
...react,
'',
`const ${Placeholders.FileName} = () => {`,
...innerComponent,
'}',
...exportDefault,
],
description:
'Creates a React Arrow Function Component with ES7 module system',
};
const reactArrowFunctionComponent: ComponentsSnippet = {
key: 'reactArrowFunctionComponent',
prefix: 'rafc',
body: [
...react,
'',
`export const ${Placeholders.FileName} = () => {`,
...innerComponent,
'}',
'',
],
description:
'Creates a React Arrow Function Component with ES7 module system',
};
const reactArrowFunctionComponentWithPropTypes: ComponentsSnippet = {
key: 'reactArrowFunctionComponentWithPropTypes',
prefix: 'rafcp',
body: [
...reactPropTypes,
'',
`const ${Placeholders.FileName} = props => {`,
...innerComponent,
'}',
'',
`${Placeholders.FileName}.propTypes = {}`,
...exportDefault,
],
description:
'Creates a React Arrow Function Component with ES7 module system with PropTypes',
};
const reactClassExportComponentWithPropTypes: ComponentsSnippet = {
key: 'reactClassExportComponentWithPropTypes',
prefix: 'rcep',
body: [
"import PropTypes from 'prop-types'",
...reactComponent,
'',
`export class ${Placeholders.FileName} extends Component {`,
' static propTypes = {}',
'',
...innerComponentReturn,
'}',
...exportDefault,
],
description: 'Creates a React component class with ES7 module system',
};
const reactClassPureComponent: ComponentsSnippet = {
key: 'reactClassPureComponent',
prefix: 'rpc',
body: [
...reactPureComponent,
'',
`export default class ${Placeholders.FileName} extends PureComponent {`,
...innerComponentReturn,
'}',
'',
],
description: 'Creates a React pure component class with ES7 module system',
};
const reactClassExportPureComponent: ComponentsSnippet = {
key: 'reactClassExportPureComponent',
prefix: 'rpce',
body: [
...reactPureComponent,
'',
`export class ${Placeholders.FileName} extends PureComponent {`,
...innerComponentReturn,
'}',
...exportDefault,
],
description:
'Creates a React pure component class with ES7 module system export',
};
const reactClassPureComponentWithPropTypes: ComponentsSnippet = {
key: 'reactClassPureComponentWithPropTypes',
prefix: 'rpcp',
body: [
"import PropTypes from 'prop-types'",
...reactPureComponent,
'',
`export default class ${Placeholders.FileName} extends PureComponent {`,
' static propTypes = {}',
'',
...innerComponentReturn,
'}',
'',
],
description: 'Creates a React component class with ES7 module system',
};
const reactFunctionMemoComponent: ComponentsSnippet = {
key: 'reactFunctionMemoComponent',
prefix: 'rmc',
body: [
...reactWithMemo,
'',
`const ${Placeholders.FileName} = memo(() => {`,
...innerComponent,
'})',
...exportDefault,
],
description: 'Creates a React Memo Function Component with ES7 module system',
};
const reactFunctionMemoComponentWithPropTypes: ComponentsSnippet = {
key: 'reactFunctionMemoComponentWithPropTypes',
prefix: 'rmcp',
body: [
"import PropTypes from 'prop-types'",
...reactWithMemo,
'',
`const ${Placeholders.FileName} = memo((props) => {`,
...innerComponent,
'})',
'',
`${Placeholders.FileName}.propTypes = {}`,
...exportDefault,
],
description:
'Creates a React Memo Function Component with ES7 module system with PropTypes',
};
const reactClassComponentPropTypes: ComponentsSnippet = {
key: 'reactClassComponentPropTypes',
prefix: 'rccp',
body: [
"import PropTypes from 'prop-types'",
...reactComponent,
'',
`export default class ${Placeholders.FileName} extends Component {`,
` static propTypes = {${Placeholders.SecondTab}: ${Placeholders.ThirdTab}}`,
'',
...innerComponentReturn,
'}',
'',
],
description:
'Creates a React component class with PropTypes and ES7 module system',
};
const reactClassComponentRedux: ComponentsSnippet = {
key: 'reactClassComponentRedux',
prefix: 'rcredux',
body: [
...reactComponentWithReduxConnect,
'',
`export class ${Placeholders.FileName} extends Component {`,
...innerComponentReturn,
'}',
...reduxComponentExport,
],
description:
'Creates a React component class with connected redux and ES7 module system',
};
const reactClassComponentReduxPropTypes: ComponentsSnippet = {
key: 'reactClassComponentReduxPropTypes',
prefix: 'rcreduxp',
body: [
"import PropTypes from 'prop-types'",
...reactComponentWithReduxConnect,
'',
`export class ${Placeholders.FileName} extends Component {`,
' static propTypes = {',
` ${Placeholders.SecondTab}: ${Placeholders.ThirdTab}`,
' }',
'',
...innerComponentReturn,
'}',
...reduxComponentExport,
],
description:
'Creates a React component class with PropTypes with connected redux and ES7 module system',
};
const reactFunctionalComponentRedux: ComponentsSnippet = {
key: 'reactFunctionalComponentRedux',
prefix: 'rfcredux',
body: [
...reactWithReduxConnect,
'',
`export const ${Placeholders.FileName} = (props) => {`,
...innerComponent,
'}',
...reduxComponentExport,
],
description:
'Creates a React functional component with connected redux and ES7 module system',
};
const reactFunctionalComponentReduxPropTypes: ComponentsSnippet = {
key: 'reactFunctionalComponentReduxPropTypes',
prefix: 'rfcreduxp',
body: [
"import PropTypes from 'prop-types'",
...reactWithReduxConnect,
'',
`export const ${Placeholders.FileName} = (props) => {`,
...innerComponent,
'}',
'',
`${Placeholders.FileName}.propTypes = {`,
` ${Placeholders.SecondTab}: PropTypes.${Placeholders.ThirdTab}`,
'}',
...reduxComponentExport,
],
description:
'DEPRECATED: Creates a React functional component with PropTypes with connected redux and ES7 module system',
};
export default [
reactArrowFunctionComponent,
reactArrowFunctionComponentWithPropTypes,
reactArrowFunctionExportComponent,
reactClassComponent,
reactClassComponentPropTypes,
reactClassComponentRedux,
reactClassComponentReduxPropTypes,
reactClassExportComponent,
reactClassExportComponentWithPropTypes,
reactClassExportPureComponent,
reactClassPureComponent,
reactClassPureComponentWithPropTypes,
reactFunctionMemoComponent,
reactFunctionMemoComponentWithPropTypes,
reactFunctionalComponent,
reactFunctionalComponentRedux,
reactFunctionalComponentReduxPropTypes,
reactFunctionalComponentWithPropTypes,
reactFunctionalExportComponent,
];

View File

@ -0,0 +1,162 @@
import { Placeholders, SnippetMapping } from '../types';
type ConsoleMapping = {
consoleAssert: 'cas';
consoleClear: 'ccl';
consoleCount: 'cco';
consoleDir: 'cdi';
consoleError: 'cer';
consoleGroup: 'cgr';
consoleGroupEnd: 'cge';
consoleLog: 'clg';
consoleTrace: 'ctr';
consoleLogObject: 'clo';
consoleLogJson: 'clj';
consoleTime: 'ctm';
consoleTimeEnd: 'cte';
consoleWarn: 'cwa';
consoleInfo: 'cin';
consoleTable: 'ctl';
};
export type ConsoleSnippet = SnippetMapping<ConsoleMapping>;
const consoleAssert: ConsoleSnippet = {
key: 'consoleAssert',
prefix: 'cas',
body: [`console.assert(${Placeholders.FirstTab}, ${Placeholders.SecondTab})`],
description:
'If the specified expression is false, the message is written to the console along with a stack trace',
};
const consoleClear: ConsoleSnippet = {
key: 'consoleClear',
prefix: 'ccl',
body: ['console.clear()'],
description: 'Clears the console',
};
const consoleCount: ConsoleSnippet = {
key: 'consoleCount',
prefix: 'cco',
body: [`console.count(${Placeholders.FirstTab})`],
description:
'Writes the the number of times that count() has been invoked at the same line and with the same label',
};
const consoleDir: ConsoleSnippet = {
key: 'consoleDir',
prefix: 'cdi',
body: [`console.dir(${Placeholders.FirstTab})`],
description: 'Prints a JavaScript representation of the specified object',
};
const consoleError: ConsoleSnippet = {
key: 'consoleError',
prefix: 'cer',
body: [`console.error(${Placeholders.FirstTab})`],
description:
'Displays a message in the console and also includes a stack trace from where the method was called',
};
const consoleGroup: ConsoleSnippet = {
key: 'consoleGroup',
prefix: 'cgr',
body: [`console.group('${Placeholders.FirstTab}')`],
description:
'Groups and indents all following output by an additional level, until console.groupEnd() is called.',
};
const consoleGroupEnd: ConsoleSnippet = {
key: 'consoleGroupEnd',
prefix: 'cge',
body: ['console.groupEnd()'],
description: 'Closes out the corresponding console.group().',
};
const consoleLog: ConsoleSnippet = {
key: 'consoleLog',
prefix: 'clg',
body: [`console.log(${Placeholders.FirstTab})`],
description: 'Displays a message in the console',
};
const consoleTrace: ConsoleSnippet = {
key: 'consoleTrace',
prefix: 'ctr',
body: [`console.trace(${Placeholders.FirstTab})`],
description:
'Prints a stack trace from the point where the method was called',
};
const consoleLogObject: ConsoleSnippet = {
key: 'consoleLogObject',
prefix: 'clo',
body: [`console.log('${Placeholders.FirstTab}', ${Placeholders.FirstTab})`],
description: 'Logs property with name.',
};
const consoleLogJson: ConsoleSnippet = {
key: 'consoleLogJson',
prefix: 'clj',
body: [
`console.log('${Placeholders.FirstTab}', JSON.stringify(${Placeholders.FirstTab}, null, 2))`,
],
description: 'Logs stringified JSON property with name.',
};
const consoleTime: ConsoleSnippet = {
key: 'consoleTime',
prefix: 'ctm',
body: [`console.time('${Placeholders.FirstTab}')`],
description: 'Console time wrapper',
};
const consoleTimeEnd: ConsoleSnippet = {
key: 'consoleTimeEnd',
prefix: 'cte',
body: [`console.timeEnd('${Placeholders.FirstTab}')`],
description: 'Console time end wrapper',
};
const consoleWarn: ConsoleSnippet = {
key: 'consoleWarn',
prefix: 'cwa',
body: [`console.warn(${Placeholders.FirstTab})`],
description:
'Displays a message in the console but also displays a yellow warning icon along with the logged message',
};
const consoleInfo: ConsoleSnippet = {
key: 'consoleInfo',
prefix: 'cin',
body: [`console.info(${Placeholders.FirstTab})`],
description:
'Displays a message in the console but also displays a blue information icon along with the logged message',
};
const consoleTable: ConsoleSnippet = {
key: 'consoleTable',
prefix: 'ctl',
body: [`console.table([${Placeholders.FirstTab}])`],
description: 'Logs table to console',
};
export default [
consoleAssert,
consoleClear,
consoleCount,
consoleDir,
consoleError,
consoleGroup,
consoleGroupEnd,
consoleLog,
consoleTrace,
consoleLogObject,
consoleLogJson,
consoleTime,
consoleTimeEnd,
consoleWarn,
consoleInfo,
consoleTable,
];

122
src/sourceSnippets/hooks.ts Normal file
View File

@ -0,0 +1,122 @@
import { Placeholders, SnippetMapping } from '../types';
type HookMappings = {
useState: 'useStateSnippet';
useCallback: 'useCallbackSnippet';
useContext: 'useContextSnippet';
useEffect: 'useEffectSnippet';
useImperativeHandle: 'useImperativeHandleSnippet';
useLayoutEffect: 'useLayoutEffectSnippet';
useMemo: 'useMemoSnippet';
useReducer: 'useReducerSnippet';
useRef: 'useRefSnippet';
};
export type HooksSnippet = SnippetMapping<HookMappings>;
const useEffect: HooksSnippet = {
key: 'useEffect',
prefix: 'useEffectSnippet',
body: [
'useEffect(() => {',
` ${Placeholders.FirstTab}`,
'',
' return () => {',
` ${Placeholders.SecondTab}`,
' }',
`}, [${Placeholders.ThirdTab}])`,
'',
],
};
const useContext: HooksSnippet = {
key: 'useContext',
prefix: 'useContextSnippet',
body: [
`const ${Placeholders.FirstTab} = useContext(${Placeholders.SecondTab})`,
],
};
const useState: HooksSnippet = {
key: 'useState',
prefix: 'useStateSnippet',
body: [
`const [${Placeholders.FirstTab}, set${Placeholders.Capitalize}] = useState(${Placeholders.SecondTab})`,
],
};
const useReducer: HooksSnippet = {
key: 'useReducer',
prefix: 'useReducerSnippet',
body: [
`const [state, dispatch] = useReducer(${Placeholders.FirstTab}, ${Placeholders.SecondTab}, ${Placeholders.ThirdTab})`,
],
};
const useCallback: HooksSnippet = {
key: 'useCallback',
prefix: 'useCallbackSnippet',
body: [
'useCallback(',
' () => {',
` ${Placeholders.FirstTab}`,
' },',
` [${Placeholders.SecondTab}],`,
')',
'',
],
};
const useMemo: HooksSnippet = {
key: 'useMemo',
prefix: 'useMemoSnippet',
body: [
`useMemo(() => ${Placeholders.FirstTab}, [${Placeholders.SecondTab}])`,
],
};
const useRef: HooksSnippet = {
key: 'useRef',
prefix: 'useRefSnippet',
body: [`const ${Placeholders.FirstTab} = useRef(${Placeholders.SecondTab})`],
};
const useImperativeHandle: HooksSnippet = {
key: 'useImperativeHandle',
prefix: 'useImperativeHandleSnippet',
body: [
'useImperativeHandle(',
` ${Placeholders.FirstTab},`,
' () => {',
` ${Placeholders.SecondTab}`,
' },',
` [${Placeholders.ThirdTab}],`,
')',
],
};
const useLayoutEffect: HooksSnippet = {
key: 'useLayoutEffect',
prefix: 'useLayoutEffectSnippet',
body: [
'useLayoutEffect(() => {',
` ${Placeholders.FirstTab}`,
'',
' return () => {',
` ${Placeholders.SecondTab}`,
' };',
`}, [${Placeholders.ThirdTab}])`,
],
};
export default [
useCallback,
useContext,
useEffect,
useImperativeHandle,
useLayoutEffect,
useMemo,
useReducer,
useRef,
useState,
];

View File

@ -0,0 +1,200 @@
import { Placeholders, SnippetMapping } from '../types';
import { reactWithMemo } from './sharedSnippets';
type ImportsMappings = {
import: 'imp';
importAs: 'ima';
importBrowserRouter: 'imbr';
importBrowserRouterWithRouteAndNavLink: 'imrr';
importDestructing: 'imd';
importEverything: 'ime';
importNoModuleName: 'imn';
importPropTypes: 'impt';
importReact: 'imr';
importReactDom: 'imrd';
importReactWithComponent: 'imrc';
importReactWithComponentAndPropTypes: 'imrcp';
importReactWithMemo: 'imrm';
importReactWithMemoAndPropTypes: 'imrmp';
importReactWithPureComponent: 'imrpc';
importReactWithPureComponentAndPropTypes: 'imrpcp';
importReduxConnect: 'redux';
importRouterLink: 'imbrl';
importRouterNavLink: 'imbrnl';
importRouterSetup: 'imbrc';
importRouterSwitch: 'imbrs';
};
export type ImportsSnippet = SnippetMapping<ImportsMappings>;
/**
* react, react-dom & prop-types
*/
const importReact: ImportsSnippet = {
key: 'importReact',
prefix: 'imr',
body: ["import React from 'react'"],
};
const importReactDom: ImportsSnippet = {
key: 'importReactDom',
prefix: 'imrd',
body: ["import ReactDOM from 'react-dom'"],
};
const importReactWithComponent: ImportsSnippet = {
key: 'importReactWithComponent',
prefix: 'imrc',
body: ["import React, { Component } from 'react'"],
};
const importReactWithComponentAndPropTypes: ImportsSnippet = {
key: 'importReactWithComponentAndPropTypes',
prefix: 'imrcp',
body: [
"import React, { Component } from 'react'",
"import PropTypes from 'prop-types'",
'',
],
};
const importReactWithPureComponent: ImportsSnippet = {
key: 'importReactWithPureComponent',
prefix: 'imrpc',
body: ["import React, { PureComponent } from 'react'"],
};
const importReactWithPureComponentAndPropTypes: ImportsSnippet = {
key: 'importReactWithPureComponentAndPropTypes',
prefix: 'imrpcp',
body: [
"import React, { PureComponent } from 'react'",
"import PropTypes from 'prop-types'",
'',
],
};
const importReactWithMemo: ImportsSnippet = {
key: 'importReactWithMemo',
prefix: 'imrm',
body: reactWithMemo,
};
const importReactWithMemoAndPropTypes: ImportsSnippet = {
key: 'importReactWithMemoAndPropTypes',
prefix: 'imrmp',
body: [...reactWithMemo, "import PropTypes from 'prop-types'", ''],
};
const importPropTypes: ImportsSnippet = {
key: 'importPropTypes',
prefix: 'impt',
body: ["import PropTypes from 'prop-types'"],
};
/**
* react-router
*/
const importBrowserRouter: ImportsSnippet = {
key: 'importBrowserRouter',
prefix: 'imbr',
body: ["import { BrowserRouter as Router } from 'react-router-dom'"],
};
const importBrowserRouterWithRouteAndNavLink: ImportsSnippet = {
key: 'importBrowserRouterWithRouteAndNavLink',
prefix: 'imrr',
body: [
"import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom'",
'',
],
};
const importRouterSetup: ImportsSnippet = {
key: 'importRouterSetup',
prefix: 'imbrc',
body: ["import { Route, Switch, NavLink, Link } from 'react-router-dom'"],
};
const importRouterSwitch: ImportsSnippet = {
key: 'importRouterSwitch',
prefix: 'imbrs',
body: ["import { Switch } from 'react-router-dom'"],
};
const importRouterLink: ImportsSnippet = {
key: 'importRouterLink',
prefix: 'imbrl',
body: ["import { Link } from 'react-router-dom'"],
};
const importRouterNavLink: ImportsSnippet = {
key: 'importRouterNavLink',
prefix: 'imbrnl',
body: ["import { NavLink } from 'react-router-dom'"],
};
/**
* Others
*/
const importSnippet: ImportsSnippet = {
key: 'import',
prefix: 'imp',
body: [`import ${Placeholders.SecondTab} from '${Placeholders.FirstTab}'`],
};
const importNoModuleName: ImportsSnippet = {
key: 'importNoModuleName',
prefix: 'imn',
body: [`import '${Placeholders.FirstTab}'`],
};
const importDestructing: ImportsSnippet = {
key: 'importDestructing',
prefix: 'imd',
body: [
`import { ${Placeholders.SecondTab} } from '${Placeholders.FirstTab}'`,
],
};
const importEverything: ImportsSnippet = {
key: 'importEverything',
prefix: 'ime',
body: [
`import * as ${Placeholders.SecondTab} from '${Placeholders.FirstTab}'`,
],
};
const importAs: ImportsSnippet = {
key: 'importAs',
prefix: 'ima',
body: [
`import { ${Placeholders.SecondTab} as ${Placeholders.ThirdTab} } from '${Placeholders.FirstTab}'`,
],
};
export default [
importAs,
importBrowserRouter,
importBrowserRouterWithRouteAndNavLink,
importDestructing,
importEverything,
importNoModuleName,
importPropTypes,
importReact,
importReactDom,
importReactWithComponent,
importReactWithComponentAndPropTypes,
importReactWithMemo,
importReactWithMemoAndPropTypes,
importReactWithPureComponent,
importReactWithPureComponentAndPropTypes,
importRouterLink,
importRouterNavLink,
importRouterSetup,
importRouterSwitch,
importSnippet,
];

View File

@ -0,0 +1,451 @@
import { Placeholders, SnippetMapping } from '../types';
type OthersMapping = {
commentBigBlock: 'cmmb';
anonymousFunction: 'anfn';
bindThis: 'bnd';
classConstructor: 'rconst';
componentDidMount: 'cdm';
componentDidUpdate: 'cdup';
componentProps: 'props';
componentSetStateFunc: 'ssf';
componentSetStateObject: 'sst';
componentState: 'state';
componentWillUnmount: 'cwun';
createContext: 'rcontext';
createRef: 'cref';
destructProps: 'cp';
destructState: 'cs';
destructingArray: 'dar';
destructingObject: 'dob';
emptyState: 'est';
exportAs: 'exa';
exportDefault: 'exp';
exportDefaultFunction: 'edf';
exportDefaultNamedFunction: 'ednf';
exportDestructing: 'exd';
exportNamedFunction: 'enf';
forEach: 'fre';
forIn: 'fin';
forOf: 'fof';
getDerivedStateFromProps: 'gdsfp';
getSnapshotBeforeUpdate: 'gsbu';
hocComponent: 'hoc';
hocComponentWithRedux: 'hocredux';
method: 'met';
namedFunction: 'nfn';
promise: 'prom';
propertyGet: 'pge';
propertySet: 'pse';
setInterval: 'sti';
setTimeOut: 'sto';
shouldComponentUpdate: 'scu';
typeofSnippet: 'tpf';
};
export type OthersSnippet = SnippetMapping<OthersMapping>;
const exportDefault: OthersSnippet = {
key: 'exportDefault',
prefix: 'exp',
body: [`export default ${Placeholders.FirstTab}`],
};
const exportDestructing: OthersSnippet = {
key: 'exportDestructing',
prefix: 'exd',
body: [
`export { ${Placeholders.SecondTab} } from '${Placeholders.FirstTab}'`,
],
};
const exportAs: OthersSnippet = {
key: 'exportAs',
prefix: 'exa',
body: [
`export { ${Placeholders.SecondTab} as ${Placeholders.ThirdTab} } from '${Placeholders.FirstTab}'`,
],
};
const exportNamedFunction: OthersSnippet = {
key: 'exportNamedFunction',
prefix: 'enf',
body: [
`export const ${Placeholders.FirstTab} = (${Placeholders.SecondTab}) => {${Placeholders.ThirdTab}}`,
],
description: 'Export named function',
};
const exportDefaultFunction: OthersSnippet = {
key: 'exportDefaultFunction',
prefix: 'edf',
body: [
`export default (${Placeholders.FirstTab}) => {${Placeholders.SecondTab}}`,
],
description: 'Export default function',
};
const exportDefaultNamedFunction: OthersSnippet = {
key: 'exportDefaultNamedFunction',
prefix: 'ednf',
body: [
`export default function ${Placeholders.FirstTab}(${Placeholders.SecondTab}) {${Placeholders.ThirdTab}}`,
],
description: 'Export default named function',
};
const method: OthersSnippet = {
key: 'method',
prefix: 'met',
body: [
`${Placeholders.FirstTab} = (${Placeholders.SecondTab}) => {${Placeholders.ThirdTab}}`,
],
description: 'Creates a method inside a class',
};
const propertyGet: OthersSnippet = {
key: 'propertyGet',
prefix: 'pge',
body: [
`get ${Placeholders.FirstTab}() {`,
` return this.${Placeholders.SecondTab}`,
'}',
],
description: 'Creates a getter property inside a class',
};
const propertySet: OthersSnippet = {
key: 'propertySet',
prefix: 'pse',
body: [
`set ${Placeholders.FirstTab}(${Placeholders.SecondTab}) {${Placeholders.ThirdTab}}`,
],
description: 'Creates a setter property inside a class',
};
const forEach: OthersSnippet = {
key: 'forEach',
prefix: 'fre',
body: [
`${Placeholders.FirstTab}.forEach(${Placeholders.SecondTab} => {${Placeholders.ThirdTab}})`,
],
description: 'Creates a forEach statement',
};
const forOf: OthersSnippet = {
key: 'forOf',
prefix: 'fof',
body: [
`for(let ${Placeholders.FirstTab} of ${Placeholders.SecondTab}) {${Placeholders.ThirdTab}}`,
],
description: 'Iterating over property names of iterable objects',
};
const forIn: OthersSnippet = {
key: 'forIn',
prefix: 'fin',
body: [
`for(let ${Placeholders.FirstTab} in ${Placeholders.SecondTab}) {${Placeholders.ThirdTab}}`,
],
description: 'Iterating over property values of iterable objects',
};
const anonymousFunction: OthersSnippet = {
key: 'anonymousFunction',
prefix: 'anfn',
body: [`(${Placeholders.FirstTab}) => { ${Placeholders.SecondTab} }`],
description: 'Creates an anonymous function',
};
const namedFunction: OthersSnippet = {
key: 'namedFunction',
prefix: 'nfn',
body: [
`const ${Placeholders.FirstTab} = (${Placeholders.SecondTab}) => { ${Placeholders.ThirdTab} }`,
],
description: 'Creates a named function',
};
const destructingObject: OthersSnippet = {
key: 'destructingObject',
prefix: 'dob',
body: [`const {${Placeholders.SecondTab}} = ${Placeholders.FirstTab}`],
description: 'Creates and assigns a local variable using object destructing',
};
const destructingArray: OthersSnippet = {
key: 'destructingArray',
prefix: 'dar',
body: [`const [${Placeholders.SecondTab}] = ${Placeholders.FirstTab}`],
description: 'Creates and assigns a local variable using array destructing',
};
const setInterval: OthersSnippet = {
key: 'setInterval',
prefix: 'sti',
body: [
`setInterval(() => { ${Placeholders.FirstTab} }, ${Placeholders.SecondTab})`,
],
description: 'Executes the given function at specified intervals',
};
const setTimeOut: OthersSnippet = {
key: 'setTimeOut',
prefix: 'sto',
body: [
`setTimeout(() => { ${Placeholders.FirstTab} }, ${Placeholders.SecondTab})`,
],
description: 'Executes the given function after the specified delay',
};
const promise: OthersSnippet = {
key: 'promise',
prefix: 'prom',
body: [
`return new Promise((resolve, reject) => { ${Placeholders.FirstTab} })`,
],
description: 'Creates and returns a new Promise in the standard ES7 syntax',
};
const destructProps: OthersSnippet = {
key: 'destructProps',
prefix: 'cp',
body: [`const { ${Placeholders.FirstTab} } = this.props`],
description: 'Creates and assigns a local variable using props destructing',
};
const destructState: OthersSnippet = {
key: 'destructState',
prefix: 'cs',
body: [`const { ${Placeholders.FirstTab} } = this.state`],
description: 'Creates and assigns a local variable using state destructing',
};
const classConstructor: OthersSnippet = {
key: 'classConstructor',
prefix: 'rconst',
body: [
'constructor(props) {',
' super(props)',
'',
' this.state = {',
` ${Placeholders.FirstTab}`,
' }',
'}',
],
description:
"Adds a default constructor for it('', () => {})the class that contains props as arguments",
};
const emptyState: OthersSnippet = {
key: 'emptyState',
prefix: 'est',
body: [`state = { ${Placeholders.FirstTab} }`],
description: 'Creates empty state object. To be used in a constructor.',
};
const componentDidMount: OthersSnippet = {
key: 'componentDidMount',
prefix: 'cdm',
body: [`componentDidMount() { ${Placeholders.FirstTab} }`],
description:
'Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.',
};
const shouldComponentUpdate: OthersSnippet = {
key: 'shouldComponentUpdate',
prefix: 'scu',
body: [
`shouldComponentUpdate(nextProps, nextState) { ${Placeholders.FirstTab} }`,
],
description:
'Invoked before rendering when new props or state are being received. ',
};
const componentDidUpdate: OthersSnippet = {
key: 'componentDidUpdate',
prefix: 'cdup',
body: [
`componentDidUpdate(prevProps, prevState) { ${Placeholders.FirstTab}} `,
],
description:
"Invoked immediately after the component's updates are flushed to the DOM.",
};
const componentWillUnmount: OthersSnippet = {
key: 'componentWillUnmount',
prefix: 'cwun',
body: [`componentWillUnmount() {${Placeholders.FirstTab} }`],
description:
'Invoked immediately before a component is unmounted from the DOM.',
};
const getDerivedStateFromProps: OthersSnippet = {
key: 'getDerivedStateFromProps',
prefix: 'gdsfp',
body: [
`static getDerivedStateFromProps(props, state) {${Placeholders.FirstTab}}`,
],
description:
'Invoked right before calling the render method, both on the initial mount and on subsequent updates.',
};
const getSnapshotBeforeUpdate: OthersSnippet = {
key: 'getSnapshotBeforeUpdate',
prefix: 'gsbu',
body: [
`getSnapshotBeforeUpdate = (prevProps, prevState) => {${Placeholders.FirstTab}}`,
],
description:
'Called right before mutations are made (e.g. before the DOM is updated)',
};
const createContext: OthersSnippet = {
key: 'createContext',
prefix: 'rcontext',
body: [`const ${Placeholders.FirstTab} = React.createContext()`],
description: 'Create React context',
};
const createRef: OthersSnippet = {
key: 'createRef',
prefix: 'cref',
body: [`this.${Placeholders.FirstTab}Ref = React.createRef()`],
description: 'Create ref statement used inside constructor',
};
const componentSetStateObject: OthersSnippet = {
key: 'componentSetStateObject',
prefix: 'sst',
body: [`this.setState({${Placeholders.FirstTab}})`],
description: 'Performs a shallow merge of nextState into current state',
};
const componentSetStateFunc: OthersSnippet = {
key: 'componentSetStateFunc',
prefix: 'ssf',
body: [
`this.setState((state, props) => { return { ${Placeholders.FirstTab} }})`,
],
description: 'Performs a shallow merge of nextState into current state',
};
const componentProps: OthersSnippet = {
key: 'componentProps',
prefix: 'props',
body: [`this.props.${Placeholders.FirstTab}`],
description: "Access component's props",
};
const componentState: OthersSnippet = {
key: 'componentState',
prefix: 'state',
body: [`this.state.${Placeholders.FirstTab}`],
};
const bindThis: OthersSnippet = {
key: 'bindThis',
prefix: 'bnd',
body: [
`this.${Placeholders.FirstTab} = this.${Placeholders.FirstTab}.bind(this)`,
],
description: 'Binds this to a method',
};
const commentBigBlock: OthersSnippet = {
key: 'commentBigBlock',
prefix: 'cmmb',
body: ['/**', ` * ${Placeholders.FirstTab}`, ' */'],
};
const hocComponentWithRedux: OthersSnippet = {
key: 'hocComponentWithRedux',
prefix: 'hocredux',
body: [
"import React from 'react'",
"import { connect } from 'react-redux'",
"import PropTypes from 'prop-types'",
'',
'export const mapStateToProps = state => ({})',
'',
'export const mapDispatchToProps = {}',
'',
`export const ${Placeholders.FirstTab} = (WrappedComponent) => {`,
' const hocComponent = ({ ...props }) => <WrappedComponent {...props} />',
'',
' hocComponent.propTypes = {}',
'',
' return hocComponent',
'}',
'',
`export default WrapperComponent => connect(mapStateToProps, mapDispatchToProps)(${Placeholders.FirstTab}(WrapperComponent))`,
'',
],
};
const hocComponent: OthersSnippet = {
key: 'hocComponent',
prefix: 'hoc',
body: [
"import React from 'react'",
"import PropTypes from 'prop-types'",
'',
'export default (WrappedComponent) => {',
' const hocComponent = ({ ...props }) => <WrappedComponent {...props} />',
'',
' hocComponent.propTypes = {}',
'',
' return hocComponent',
'}',
'',
],
};
const typeofSnippet: OthersSnippet = {
key: 'typeofSnippet',
prefix: 'tpf',
body: [`typeof ${Placeholders.FirstTab}`],
};
export default [
exportDefault,
exportDestructing,
exportAs,
exportNamedFunction,
exportDefaultFunction,
exportDefaultNamedFunction,
method,
propertyGet,
propertySet,
forEach,
forOf,
forIn,
anonymousFunction,
namedFunction,
destructingObject,
destructingArray,
setInterval,
setTimeOut,
promise,
destructProps,
destructState,
classConstructor,
emptyState,
componentDidMount,
shouldComponentUpdate,
componentDidUpdate,
componentWillUnmount,
getDerivedStateFromProps,
getSnapshotBeforeUpdate,
createContext,
createRef,
componentSetStateObject,
componentSetStateFunc,
componentProps,
componentState,
bindThis,
commentBigBlock,
hocComponentWithRedux,
hocComponent,
typeofSnippet,
];

View File

@ -0,0 +1,291 @@
import { SnippetMapping } from '../types';
type PropTypesMapping = {
propTypeAny: 'ptany';
propTypeArray: 'pta';
propTypeArrayOf: 'ptao';
propTypeArrayOfRequired: 'ptaor';
propTypeArrayRequired: 'ptar';
propTypeBool: 'ptb';
propTypeBoolRequired: 'ptbr';
propTypeElement: 'ptel';
propTypeElementRequired: 'ptelr';
propTypeEnum: 'pte';
propTypeEnumRequired: 'pter';
propTypeExact: 'ptex';
propTypeExactRequired: 'ptexr';
propTypeFunc: 'ptf';
propTypeFuncRequired: 'ptfr';
propTypeInstanceOf: 'pti';
propTypeInstanceOfRequired: 'ptir';
propTypeNode: 'ptnd';
propTypeNodeRequired: 'ptndr';
propTypeNumber: 'ptn';
propTypeNumberRequired: 'ptnr';
propTypeObject: 'pto';
propTypeObjectOf: 'ptoo';
propTypeObjectOfRequired: 'ptoor';
propTypeObjectRequired: 'ptor';
propTypeOneOfType: 'ptet';
propTypeOneOfTypeRequired: 'ptetr';
propTypeShape: 'ptsh';
propTypeShapeRequired: 'ptshr';
propTypeString: 'pts';
propTypeStringRequired: 'ptsr';
};
export type PropTypesSnippet = SnippetMapping<PropTypesMapping>;
const propTypeArray: PropTypesSnippet = {
key: 'propTypeArray',
prefix: 'pta',
body: ['PropTypes.array'],
description: 'Array prop type',
};
const propTypeArrayRequired: PropTypesSnippet = {
key: 'propTypeArrayRequired',
prefix: 'ptar',
body: ['PropTypes.array.isRequired'],
description: 'Array prop type required',
};
const propTypeBool: PropTypesSnippet = {
key: 'propTypeBool',
prefix: 'ptb',
body: ['PropTypes.bool'],
description: 'Bool prop type',
};
const propTypeBoolRequired: PropTypesSnippet = {
key: 'propTypeBoolRequired',
prefix: 'ptbr',
body: ['PropTypes.bool.isRequired'],
description: 'Bool prop type required',
};
const propTypeFunc: PropTypesSnippet = {
key: 'propTypeFunc',
prefix: 'ptf',
body: ['PropTypes.func'],
description: 'Func prop type',
};
const propTypeFuncRequired: PropTypesSnippet = {
key: 'propTypeFuncRequired',
prefix: 'ptfr',
body: ['PropTypes.func.isRequired'],
description: 'Func prop type required',
};
const propTypeNumber: PropTypesSnippet = {
key: 'propTypeNumber',
prefix: 'ptn',
body: ['PropTypes.number'],
description: 'Number prop type',
};
const propTypeNumberRequired: PropTypesSnippet = {
key: 'propTypeNumberRequired',
prefix: 'ptnr',
body: ['PropTypes.number.isRequired'],
description: 'Number prop type required',
};
const propTypeObject: PropTypesSnippet = {
key: 'propTypeObject',
prefix: 'pto',
body: ['PropTypes.object'],
description: 'Object prop type',
};
const propTypeObjectRequired: PropTypesSnippet = {
key: 'propTypeObjectRequired',
prefix: 'ptor',
body: ['PropTypes.object.isRequired'],
description: 'Object prop type required',
};
const propTypeString: PropTypesSnippet = {
key: 'propTypeString',
prefix: 'pts',
body: ['PropTypes.string'],
description: 'String prop type',
};
const propTypeStringRequired: PropTypesSnippet = {
key: 'propTypeStringRequired',
prefix: 'ptsr',
body: ['PropTypes.string.isRequired'],
description: 'String prop type required',
};
const propTypeNode: PropTypesSnippet = {
key: 'propTypeNode',
prefix: 'ptnd',
body: ['PropTypes.node'],
description:
'Anything that can be rendered: numbers, strings, elements or an array',
};
const propTypeNodeRequired: PropTypesSnippet = {
key: 'propTypeNodeRequired',
prefix: 'ptndr',
body: ['PropTypes.node.isRequired'],
description:
'Anything that can be rendered: numbers, strings, elements or an array required',
};
const propTypeElement: PropTypesSnippet = {
key: 'propTypeElement',
prefix: 'ptel',
body: ['PropTypes.element'],
description: 'React element prop type',
};
const propTypeElementRequired: PropTypesSnippet = {
key: 'propTypeElementRequired',
prefix: 'ptelr',
body: ['PropTypes.element.isRequired'],
description: 'React element prop type required',
};
const propTypeInstanceOf: PropTypesSnippet = {
key: 'propTypeInstanceOf',
prefix: 'pti',
body: ['PropTypes.instanceOf($0)'],
description: 'Is an instance of a class prop type',
};
const propTypeInstanceOfRequired: PropTypesSnippet = {
key: 'propTypeInstanceOfRequired',
prefix: 'ptir',
body: ['PropTypes.instanceOf($0).isRequired'],
description: 'Is an instance of a class prop type required',
};
const propTypeEnum: PropTypesSnippet = {
key: 'propTypeEnum',
prefix: 'pte',
body: ["PropTypes.oneOf(['$0'])"],
description: 'Prop type limited to specific values by treating it as an enum',
};
const propTypeEnumRequired: PropTypesSnippet = {
key: 'propTypeEnumRequired',
prefix: 'pter',
body: ["PropTypes.oneOf(['$0']).isRequired"],
description:
'Prop type limited to specific values by treating it as an enum required',
};
const propTypeOneOfType: PropTypesSnippet = {
key: 'propTypeOneOfType',
prefix: 'ptet',
body: ['PropTypes.oneOfType([', ' $0', '])'],
description: 'An object that could be one of many types',
};
const propTypeOneOfTypeRequired: PropTypesSnippet = {
key: 'propTypeOneOfTypeRequired',
prefix: 'ptetr',
body: ['PropTypes.oneOfType([', ' $0', ']).isRequired'],
description: 'An object that could be one of many types required',
};
const propTypeArrayOf: PropTypesSnippet = {
key: 'propTypeArrayOf',
prefix: 'ptao',
body: ['PropTypes.arrayOf($0)'],
description: 'An array of a certain type',
};
const propTypeArrayOfRequired: PropTypesSnippet = {
key: 'propTypeArrayOfRequired',
prefix: 'ptaor',
body: ['PropTypes.arrayOf($0).isRequired'],
description: 'An array of a certain type required',
};
const propTypeObjectOf: PropTypesSnippet = {
key: 'propTypeObjectOf',
prefix: 'ptoo',
body: ['PropTypes.objectOf($0)'],
description: 'An object with property values of a certain type',
};
const propTypeObjectOfRequired: PropTypesSnippet = {
key: 'propTypeObjectOfRequired',
prefix: 'ptoor',
body: ['PropTypes.objectOf($0).isRequired'],
description: 'An object with property values of a certain type required',
};
const propTypeShape: PropTypesSnippet = {
key: 'propTypeShape',
prefix: 'ptsh',
body: ['PropTypes.shape({', ' $0', '})'],
description: 'An object taking on a particular shape',
};
const propTypeShapeRequired: PropTypesSnippet = {
key: 'propTypeShapeRequired',
prefix: 'ptshr',
body: ['PropTypes.shape({', ' $0', '}).isRequired'],
description: 'An object taking on a particular shape required',
};
const propTypeExact: PropTypesSnippet = {
key: 'propTypeExact',
prefix: 'ptex',
body: ['PropTypes.exact({', ' $0', '})'],
description: 'An object with warnings on extra properties',
};
const propTypeExactRequired: PropTypesSnippet = {
key: 'propTypeExactRequired',
prefix: 'ptexr',
body: ['PropTypes.exact({', ' $0', '}).isRequired'],
description: 'An object with warnings on extra properties required',
};
const propTypeAny: PropTypesSnippet = {
key: 'propTypeAny',
prefix: 'ptany',
body: ['PropTypes.any'],
description: 'Any prop type',
};
export default [
propTypeArray,
propTypeArrayRequired,
propTypeBool,
propTypeBoolRequired,
propTypeFunc,
propTypeFuncRequired,
propTypeNumber,
propTypeNumberRequired,
propTypeObject,
propTypeObjectRequired,
propTypeString,
propTypeStringRequired,
propTypeNode,
propTypeNodeRequired,
propTypeElement,
propTypeElementRequired,
propTypeInstanceOf,
propTypeInstanceOfRequired,
propTypeEnum,
propTypeEnumRequired,
propTypeOneOfType,
propTypeOneOfTypeRequired,
propTypeArrayOf,
propTypeArrayOfRequired,
propTypeObjectOf,
propTypeObjectOfRequired,
propTypeShape,
propTypeShapeRequired,
propTypeExact,
propTypeExactRequired,
propTypeAny,
];

View File

@ -0,0 +1,196 @@
import { Placeholders, SnippetMapping } from '../types';
import {
exportDefault,
react,
reactComponent,
reactPureComponent,
} from './sharedSnippets';
type ReactNativeMapping = {
reactNativeImport: 'imrn';
reactNativeStyles: 'rnstyle';
reactNativeComponent: 'rnc';
reactNativeComponentWithStyles: 'rncs';
reactNativeComponentExport: 'rnce';
reactNativePureComponent: 'rnpc';
reactNativePureComponentExport: 'rnpce';
reactNativeFunctionalExportComponent: 'rnfe';
reactNativeFunctionalExportComponentWithStyles: 'rnfes';
reactNativeFunctionalComponent: 'rnf';
reactNativeFunctionalComponentWithStyles: 'rnfs';
};
export type ReactNativeSnippet = SnippetMapping<ReactNativeMapping>;
const reactNativeStylesSnippet = ['const styles = StyleSheet.create({})'];
const reactNativeComponentReturn = [
' render() {',
' return (',
' <View>',
` <Text>${Placeholders.FirstTab}</Text>`,
' </View>',
' )',
' }',
];
const reactNativeReturn = [
' return (',
' <View>',
` <Text>${Placeholders.FirstTab}</Text>`,
' </View>',
' )',
];
const reactNativeImport: ReactNativeSnippet = {
key: 'reactNativeImport',
prefix: 'imrn',
body: [`import { ${Placeholders.FirstTab} } from 'react-native'`],
};
const reactNativeStyles: ReactNativeSnippet = {
key: 'reactNativeStyles',
prefix: 'rnstyle',
body: [`const styles = StyleSheet.create({${Placeholders.FirstTab}})`],
};
const reactNativeComponent: ReactNativeSnippet = {
key: 'reactNativeComponent',
prefix: 'rnc',
body: [
"import { Text, View } from 'react-native'",
...reactComponent,
'',
`export default class ${Placeholders.FileName} extends Component {`,
...reactNativeComponentReturn,
'}',
],
};
const reactNativeComponentWithStyles: ReactNativeSnippet = {
key: 'reactNativeComponentWithStyles',
prefix: 'rncs',
body: [
"import { Text, StyleSheet, View } from 'react-native'",
...reactComponent,
'',
`export default class ${Placeholders.FileName} extends Component {`,
...reactNativeComponentReturn,
'}',
'',
...reactNativeStylesSnippet,
],
};
const reactNativeComponentExport: ReactNativeSnippet = {
key: 'reactNativeComponentExport',
prefix: 'rnce',
body: [
"import { Text, View } from 'react-native'",
...reactComponent,
'',
`export class ${Placeholders.FileName} extends Component {`,
...reactNativeComponentReturn,
'}',
...exportDefault,
],
};
const reactNativePureComponent: ReactNativeSnippet = {
key: 'reactNativePureComponent',
prefix: 'rnpc',
body: [
"import { Text, View } from 'react-native'",
...reactPureComponent,
'',
`export default class ${Placeholders.FileName} extends PureComponent {`,
...reactNativeComponentReturn,
'}',
],
};
const reactNativePureComponentExport: ReactNativeSnippet = {
key: 'reactNativePureComponentExport',
prefix: 'rnpce',
body: [
"import { Text, View } from 'react-native'",
...reactPureComponent,
'',
`export class ${Placeholders.FileName} extends PureComponent {`,
...reactNativeComponentReturn,
'}',
...exportDefault,
],
};
const reactNativeFunctionalExportComponent: ReactNativeSnippet = {
key: 'reactNativeFunctionalExportComponent',
prefix: 'rnfe',
body: [
"import { View, Text } from 'react-native'",
...react,
'',
`const ${Placeholders.FileName} = () => {`,
...reactNativeReturn,
'}',
...exportDefault,
],
};
const reactNativeFunctionalExportComponentWithStyles: ReactNativeSnippet = {
key: 'reactNativeFunctionalExportComponentWithStyles',
prefix: 'rnfes',
body: [
"import { StyleSheet, Text, View } from 'react-native'",
...react,
'',
`const ${Placeholders.FileName} = () => {`,
...reactNativeReturn,
'}',
...exportDefault,
'',
...reactNativeStylesSnippet,
],
};
const reactNativeFunctionalComponent: ReactNativeSnippet = {
key: 'reactNativeFunctionalComponent',
prefix: 'rnf',
body: [
"import { View, Text } from 'react-native'",
...react,
'',
`export default function ${Placeholders.FileName}() {`,
...reactNativeReturn,
'}',
],
};
const reactNativeFunctionalComponentWithStyles: ReactNativeSnippet = {
key: 'reactNativeFunctionalComponentWithStyles',
prefix: 'rnfs',
body: [
"import { StyleSheet, Text, View } from 'react-native'",
...react,
'',
`export default function ${Placeholders.FileName}() {`,
...reactNativeReturn,
'}',
'',
...reactNativeStylesSnippet,
],
};
export default [
reactNativeComponent,
reactNativeComponentExport,
reactNativeComponentWithStyles,
reactNativeFunctionalComponent,
reactNativeFunctionalComponentWithStyles,
reactNativeFunctionalExportComponent,
reactNativeFunctionalExportComponentWithStyles,
reactNativeImport,
reactNativePureComponent,
reactNativePureComponentExport,
reactNativeStyles,
];

109
src/sourceSnippets/redux.ts Normal file
View File

@ -0,0 +1,109 @@
import { Placeholders, SnippetMapping } from '../types';
type ReduxMapping = {
importReduxConnect: 'redux';
reduxAction: 'rxaction';
reduxConst: 'rxconst';
reduxReducer: 'rxreducer';
reduxSelector: 'rxselect';
reduxSlice: 'rxslice';
mappingToProps: 'reduxmap';
};
export type ReduxSnippet = SnippetMapping<ReduxMapping>;
const importReduxConnect: ReduxSnippet = {
key: 'importReduxConnect',
prefix: 'redux',
body: ["import { connect } from 'react-redux'"],
};
const reduxAction: ReduxSnippet = {
key: 'reduxAction',
prefix: 'rxaction',
body: [
`export const ${Placeholders.FirstTab} = (payload) => ({`,
` type: ${Placeholders.SecondTab},`,
' payload',
'})',
'',
],
};
const reduxConst: ReduxSnippet = {
key: 'reduxConst',
prefix: 'rxconst',
body: [`export const ${Placeholders.FirstTab} = '${Placeholders.FirstTab}'`],
};
const reduxReducer: ReduxSnippet = {
key: 'reduxReducer',
prefix: 'rxreducer',
body: [
'const initialState = {}',
'',
'export default (state = initialState, { type, payload }) => {',
' switch (type) {',
'',
` case ${Placeholders.FirstTab}:`,
' return { ...state, ...payload }',
'',
' default:',
' return state',
' }',
'}',
'',
],
};
const reduxSelector: ReduxSnippet = {
key: 'reduxSelector',
prefix: 'rxselect',
body: [
"import { createSelector } from 'reselect'",
'',
`export const ${Placeholders.FirstTab} = state => state.${Placeholders.SecondTab}`,
],
};
const reduxSlice: ReduxSnippet = {
key: 'reduxSlice',
prefix: 'rxslice',
body: [
"import { createSlice } from '@reduxjs/toolkit'",
'',
'const initialState = {',
'',
'}',
'',
`const ${Placeholders.FileName} = createSlice({`,
` name: ${Placeholders.SecondTab},`,
' initialState,',
' reducers: {}',
'});',
'',
`export const {} = ${Placeholders.FileName}.actions`,
'',
`export default ${Placeholders.FileName}.reducer`,
],
};
const mappingToProps: ReduxSnippet = {
key: 'mappingToProps',
prefix: 'reduxmap',
body: [
'const mapStateToProps = (state) => ({})',
'',
'const mapDispatchToProps = {}',
],
};
export default [
importReduxConnect,
reduxAction,
reduxConst,
reduxReducer,
reduxSelector,
reduxSlice,
mappingToProps,
];

View File

@ -0,0 +1,55 @@
import { Placeholders } from '../types';
export const reactComponent = ["import React, { Component } from 'react'"];
export const react = ["import React from 'react'"];
export const reactPureComponent = [
"import React, { PureComponent } from 'react'",
];
export const reactPropTypes = [
"import React from 'react'",
"import PropTypes from 'prop-types'",
];
export const reactWithReduxConnect = [
"import React from 'react'",
"import { connect } from 'react-redux'",
];
export const reactComponentWithReduxConnect = [
"import React, { Component } from 'react'",
"import { connect } from 'react-redux'",
];
export const reactWithMemo = ["import React, { memo } from 'react'"];
export const reduxComponentExport = [
'',
'const mapStateToProps = (state) => ({})',
'',
'const mapDispatchToProps = {}',
'',
`export default connect(mapStateToProps, mapDispatchToProps)(${Placeholders.FileName})`,
];
export const innerComponent = [
' return (',
` <div>${Placeholders.FirstTab}</div>`,
' )',
];
export const innerComponentReturn = [
' render() {',
' return (',
` <div>${Placeholders.FirstTab}</div>`,
' )',
' }',
];
export const exportDefault = ['', `export default ${Placeholders.FileName}`];
export const propsTypeInterface = [Placeholders.TypeProps, ''];
export const stateTypeInterface = [Placeholders.TypeState, ''];
export const propsStateInterface = [
...propsTypeInterface,
...stateTypeInterface,
];

159
src/sourceSnippets/tests.ts Normal file
View File

@ -0,0 +1,159 @@
import { Placeholders, SnippetMapping } from '../types';
type TestMapping = {
describeBlock: 'desc';
itAsyncBlock: 'tita';
itBlock: 'tit';
setupReactComponentTestWithRedux: 'srtest';
setupReactNativeTest: 'sntest';
setupReactNativeTestWithRedux: 'snrtest';
setupReactTest: 'stest';
testAsyncBlock: 'testa';
testBlock: 'test';
};
export type TestsSnippet = SnippetMapping<TestMapping>;
const describeBlock: TestsSnippet = {
key: 'describeBlock',
prefix: 'desc',
body: [
`describe('${Placeholders.FirstTab}', () => { ${Placeholders.SecondTab} })`,
],
description: 'Testing `describe` block',
};
const testBlock: TestsSnippet = {
key: 'testBlock',
prefix: 'test',
body: [
`test('should ${Placeholders.FirstTab}', () => { ${Placeholders.SecondTab} })`,
],
description: 'Testing `test` block',
};
const testAsyncBlock: TestsSnippet = {
key: 'testAsyncBlock',
prefix: 'testa',
body: [
`test('should ${Placeholders.FirstTab}', async () => { ${Placeholders.SecondTab} })`,
],
description: 'Testing `asynchronous test` block',
};
const itBlock: TestsSnippet = {
key: 'itBlock',
prefix: 'tit',
body: [
`it('should ${Placeholders.FirstTab}', () => { ${Placeholders.SecondTab} })`,
],
description: 'Testing `it` block',
};
const itAsyncBlock: TestsSnippet = {
key: 'itAsyncBlock',
prefix: 'tita',
body: [
`it('should ${Placeholders.FirstTab}', async () => { ${Placeholders.SecondTab} })`,
],
description: 'Testing asynchronous `it` block',
};
const setupReactTest: TestsSnippet = {
key: 'setupReactTest',
prefix: 'stest',
body: [
"import React from 'react'",
"import renderer from 'react-test-renderer'",
'',
`import { ${Placeholders.FileName} } from '../${Placeholders.FileName}'`,
'',
`describe('<${Placeholders.FileName} />', () => {`,
' const defaultProps = {}',
` const wrapper = renderer.create(<${Placeholders.FileName} {...defaultProps} />)`,
'',
" test('render', () => {",
' expect(wrapper).toMatchSnapshot()',
' })',
'})',
],
};
const setupReactNativeTest: TestsSnippet = {
key: 'setupReactNativeTest',
prefix: 'sntest',
body: [
"import 'react-native'",
"import React from 'react'",
"import renderer from 'react-test-renderer'",
'',
`import ${Placeholders.FileName} from '../${Placeholders.FileName}'`,
'',
`describe('<${Placeholders.FileName} />', () => {`,
' const defaultProps = {}',
` const wrapper = renderer.create(<${Placeholders.FileName} {...defaultProps} />)`,
'',
" test('render', () => {",
' expect(wrapper).toMatchSnapshot()',
' })',
'})',
],
};
const setupReactComponentTestWithRedux: TestsSnippet = {
key: 'setupReactComponentTestWithRedux',
prefix: 'srtest',
body: [
"import React from 'react'",
"import renderer from 'react-test-renderer'",
"import { Provider } from 'react-redux'",
'',
"import store from '~/store'",
`import { ${Placeholders.FileName} } from '../${Placeholders.FileName}'`,
'',
`describe('<${Placeholders.FileName} />', () => {`,
' const defaultProps = {}',
' const wrapper = renderer.create(',
' <Provider store={store}>',
` <${Placeholders.FileName} {...defaultProps} />`,
' </Provider>,',
' )',
'',
" test('render', () => {",
' expect(wrapper).toMatchSnapshot()',
' })',
'})',
],
description: 'Create test component',
};
const setupReactNativeTestWithRedux: TestsSnippet = {
key: 'setupReactNativeTestWithRedux',
prefix: 'snrtest',
body: [
"import 'react-native'",
"import React from 'react'",
"import renderer from 'react-test-renderer'",
"import { Provider } from 'react-redux'",
'',
"import store from '~/store'",
`import ${Placeholders.FileName} from '../${Placeholders.FileName}'`,
'',
`describe('<${Placeholders.FileName} />', () => {`,
' const defaultProps = {}',
' const wrapper = renderer.create(',
' <Provider store={store}>',
` <${Placeholders.FileName} {...defaultProps} />`,
' </Provider>,',
' )',
'',
" test('render', () => {",
' expect(wrapper).toMatchSnapshot()',
' })',
'})',
],
};
export default [
describeBlock,
itAsyncBlock,
itBlock,
setupReactComponentTestWithRedux,
setupReactNativeTest,
setupReactNativeTestWithRedux,
setupReactTest,
testAsyncBlock,
testBlock,
];

View File

@ -0,0 +1,253 @@
import { Placeholders, SnippetMapping } from '../types';
import {
exportDefault,
innerComponent,
innerComponentReturn,
propsStateInterface,
propsTypeInterface,
react,
reactComponent,
reactPureComponent,
reduxComponentExport,
} from './sharedSnippets';
type TypescriptMappings = {
exportInterface: 'expint';
exportType: 'exptp';
typescriptReactArrowFunctionComponent: 'tsrafc';
typescriptReactArrowFunctionExportComponent: 'tsrafce';
typescriptReactClassComponent: 'tsrcc';
typescriptReactClassComponentRedux: 'tsrcredux';
typescriptReactClassExportComponent: 'tsrce';
typescriptReactClassExportPureComponent: 'tsrpce';
typescriptReactClassPureComponent: 'tsrpc';
typescriptReactFunctionalComponent: 'tsrfc';
typescriptReactFunctionalExportComponent: 'tsrfce';
typescriptReactNativeArrowFunctionComponent: 'tsrnf';
typescriptReactNativeArrowFunctionComponentWithStyles: 'tsrnfs';
};
export type TypescriptSnippet = SnippetMapping<TypescriptMappings>;
const exportType: TypescriptSnippet = {
body: [`export type ${Placeholders.FirstTab} = {${Placeholders.SecondTab}}`],
key: 'exportType',
prefix: 'exptp',
};
const exportInterface: TypescriptSnippet = {
key: 'exportInterface',
prefix: 'expint',
body: [
`export interface ${Placeholders.FirstTab} {${Placeholders.SecondTab}}`,
],
};
const typescriptReactClassComponent: TypescriptSnippet = {
key: 'typescriptReactClassComponent',
prefix: 'tsrcc',
description:
'Creates a React component class with ES7 module system and TypeScript interfaces',
body: [
...reactComponent,
'',
...propsStateInterface,
`export default class ${Placeholders.FileName} extends Component<Props, State> {`,
' state = {}',
'',
...innerComponentReturn,
'}',
],
};
const typescriptReactClassExportComponent: TypescriptSnippet = {
key: 'typescriptReactClassExportComponent',
prefix: 'tsrce',
body: [
...reactComponent,
'',
...propsStateInterface,
`class ${Placeholders.FileName} extends Component<Props, State> {`,
' state = {}',
'',
...innerComponentReturn,
'}',
...exportDefault,
],
description:
'Creates a React component class with ES7 module system and TypeScript interfaces',
};
const typescriptReactFunctionalExportComponent: TypescriptSnippet = {
key: 'typescriptReactFunctionalExportComponent',
prefix: 'tsrfce',
body: [
...react,
'',
...propsTypeInterface,
`function ${Placeholders.FileName}({}: Props) {`,
...innerComponent,
'}',
...exportDefault,
],
description:
'Creates a React Functional Component with ES7 module system and TypeScript interface',
};
const typescriptReactFunctionalComponent: TypescriptSnippet = {
key: 'typescriptReactFunctionalComponent',
prefix: 'tsrfc',
body: [
...react,
'',
...propsTypeInterface,
`export default function ${Placeholders.FileName}({}: Props) {`,
...innerComponent,
'}',
],
description:
'Creates a React Functional Component with ES7 module system and TypeScript interface',
};
const typescriptReactArrowFunctionExportComponent: TypescriptSnippet = {
key: 'typescriptReactArrowFunctionExportComponent',
prefix: 'tsrafce',
body: [
...react,
'',
...propsTypeInterface,
`const ${Placeholders.FileName} = (props: Props) => {`,
...innerComponent,
'}',
...exportDefault,
],
description:
'Creates a React Arrow Function Component with ES7 module system and TypeScript interface',
};
const typescriptReactArrowFunctionComponent: TypescriptSnippet = {
key: 'typescriptReactArrowFunctionComponent',
prefix: 'tsrafc',
body: [
...react,
'',
...propsTypeInterface,
`const ${Placeholders.FileName} = (props: Props) => {`,
...innerComponent,
'}',
],
description:
'Creates a React Arrow Function Component with ES7 module system and TypeScript interface',
};
const typescriptReactClassPureComponent: TypescriptSnippet = {
key: 'typescriptReactClassPureComponent',
prefix: 'tsrpc',
body: [
...reactPureComponent,
'',
...propsTypeInterface,
`export default class ${Placeholders.FileName} extends PureComponent<Props> {`,
...innerComponentReturn,
'}',
],
description:
'Creates a React pure component class with ES7 module system and TypeScript interface',
};
const typescriptReactClassExportPureComponent: TypescriptSnippet = {
key: 'typescriptReactClassExportPureComponent',
prefix: 'tsrpce',
body: [
...reactPureComponent,
'',
...propsTypeInterface,
`class ${Placeholders.FileName} extends PureComponent<Props> {`,
...innerComponentReturn,
'}',
...exportDefault,
],
description:
'Creates a React pure component class with ES7 module system and TypeScript interface',
};
const typescriptReactClassComponentRedux: TypescriptSnippet = {
key: 'typescriptReactClassComponentRedux',
prefix: 'tsrcredux',
body: [
"import { connect } from 'react-redux'",
...reactComponent,
'',
...propsStateInterface,
`export class ${Placeholders.FileName} extends Component<Props, State> {`,
' state = {}',
'',
...innerComponentReturn,
'}',
...reduxComponentExport,
],
description:
'Creates a React component class with connected redux and ES7 module system and TypeScript interfaces',
};
const typescriptReactNativeArrowFunctionComponent: TypescriptSnippet = {
key: 'typescriptReactNativeArrowFunctionComponent',
prefix: 'tsrnf',
body: [
"import { View, Text } from 'react-native'",
...react,
'',
...propsTypeInterface,
`const ${Placeholders.FileName} = (props: Props) => {`,
' return (',
' <View>',
` <Text>${Placeholders.FirstTab}</Text>`,
' </View>',
' )',
'}',
...exportDefault,
],
description:
'Creates a React Native Arrow Function Component with ES7 module system in TypeScript',
};
const typescriptReactNativeArrowFunctionComponentWithStyles: TypescriptSnippet =
{
key: 'typescriptReactNativeArrowFunctionComponentWithStyles',
prefix: 'tsrnfs',
body: [
"import { StyleSheet, Text, View } from 'react-native'",
...react,
'',
...propsTypeInterface,
`const ${Placeholders.FileName} = (props: Props) => {`,
' return (',
' <View>',
` <Text>${Placeholders.FirstTab}</Text>`,
' </View>',
' )',
'}',
...exportDefault,
'',
'const styles = StyleSheet.create({})',
],
description:
'Creates a React Native Arrow Function Component with ES7 module system, TypeScript interface and StyleSheet',
};
export default [
exportType,
exportInterface,
typescriptReactClassComponent,
typescriptReactClassExportComponent,
typescriptReactFunctionalExportComponent,
typescriptReactFunctionalComponent,
typescriptReactArrowFunctionExportComponent,
typescriptReactArrowFunctionComponent,
typescriptReactClassPureComponent,
typescriptReactClassExportPureComponent,
typescriptReactClassComponentRedux,
typescriptReactNativeArrowFunctionComponent,
typescriptReactNativeArrowFunctionComponentWithStyles,
];

21
src/test.ts Normal file
View File

@ -0,0 +1,21 @@
import { writeFile } from 'fs';
const generateSnippets = () =>
new Promise((resolve) => {
const jsonSnippets = `{}`;
writeFile(
__dirname + '/../snippets/generated.json',
jsonSnippets,
(error) => {
if (error) {
console.error(error);
}
return resolve(true);
},
);
});
generateSnippets()
export default generateSnippets;

28
src/types.ts Normal file
View File

@ -0,0 +1,28 @@
export type SnippetMapping<T> = {
key: keyof T;
prefix: T[keyof T];
body: string[];
description?: string;
};
export const Placeholders = {
FileName: 'file',
FirstTab: 'first',
SecondTab: 'second',
ThirdTab: 'third',
Capitalize: 'capitalize',
TypeProps: 'typeProps',
TypeState: 'typeState',
} as const;
export const Mappings = {
FileName: '${1:${TM_FILENAME_BASE}}',
FirstTab: '${1:first}',
SecondTab: '${2:second}',
ThirdTab: '${3:third}',
Capitalize: '${1/(.*)/${1:/capitalize}/}',
TypeProps: 'type Props = {}',
TypeState: 'type State = {}',
InterfaceProps: 'interface Props {}',
InterfaceState: 'interface State {}',
} as const;

22
tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": "amd",
"moduleResolution": "Node",
"noEmit": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"target": "ESNext"
},
"exclude": ["node_modules", "jest", "**/__tests__/*"],
"compileOnSave": false
}