diff --git a/README.md b/README.md
index 38808d5..0b1729d 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,3 @@
-[](https://vsmarketplacebadge.apphb.com/version-short/dsznajder.es7-react-js-snippets.svg)
-[](https://vsmarketplacebadge.apphb.com/installs-short/dsznajder.es7-react-js-snippets.svg)
-[](https://vsmarketplacebadge.apphb.com/downloads-short/dsznajder.es7-react-js-snippets.svg)
-[](https://vsmarketplacebadge.apphb.com/rating-short/dsznajder.es7-react-js-snippets.svg)
-
# VS Code ES7+ React/Redux/React-Native/JS snippets
JavaScript and React/Redux snippets in ES7+ with Babel plugin features for [VS Code](https://code.visualstudio.com/)
@@ -25,28 +20,21 @@ ext install dsznajder.es7-react-js-snippets
## Options
-From version 4 extension provides options to customize the behavior of the snippets:
-
-| Option | Description |
-| ---------------: | ---------------------------------------------------------------------------- |
-| languageScopes | list of supported languages / files recognition |
-| prettierEnabled | determines if snippets should be parsed with project prettier config |
-| importReactOnTop | If disabled, snippets won't contain `import React` on top. React 17+ support |
-| typescript | adds additional typescript snippets |
-
-# Sponsors
+| Option | Description |
+| ----------------------: | ------------------------------------------------------------------------------------------------------ |
+| languageScopes | Comma-separated list of language scopes where snippets are available (default: `typescript,typescriptreact,javascript,javascriptreact`) |
+| importReactOnTop | Adds `import React` at the top of component snippets. Enable for legacy projects pre-React 17 (default: `false`) |
+| typescript | Adds TypeScript-specific component snippets (default: `true`) |
+| typescriptPropsStatePrefix | Controls `type` vs `interface` for TypeScript Props/State (default: `type`) |
-
-Manage pull requests and conduct code reviews in your IDE with full source-tree context. Comment on any line, not just the diffs. Use jump-to-definition, your favorite keybindings, and code intelligence with more of your workflow.
Learn More
-
-
+**Note:** Changing settings requires a VS Code restart to take effect.
### Conquer of Completion
It is possible to use this package in your vim/neovim text editor, to make this possible, make sure you have the `coc.nvim` previously configured, then add this command to your `init.vim`
```shell
-Plug 'dsznajder/vscode-es7-javascript-react-snippets', { 'do': 'yarn install --frozen-lockfile && yarn compile' }
+Plug 'r5n-labs/vscode-react-javascript-snippets', { 'do': 'yarn install --frozen-lockfile && yarn compile' }
```
Update your vim / neovim settings with `:source %` and then install the new package with `:PlugInstall`
@@ -60,7 +48,7 @@ Note: This example uses `vim-plug` as a package manager, feel free to use some o
For use with packer the syntax is a little different. Just add in your `init.vim` or `init.lua`:
```shell
-use {'dsznajder/vscode-es7-javascript-react-snippets',
+use {'r5n-labs/vscode-react-javascript-snippets',
run = 'yarn install --frozen-lockfile && yarn compile'
}
```
diff --git a/docs/Snippets.md b/docs/Snippets.md
index 135e201..6198ae3 100644
--- a/docs/Snippets.md
+++ b/docs/Snippets.md
@@ -13,7 +13,24 @@ I.E. `tsrcc`
### React Hooks
-- Hooks from [official docs](https://reactjs.org/docs/hooks-reference.html) are added with hook name as prefix.
+| Prefix | Method |
+| ------------------------------: | ------------------------------------------------------------------------- |
+| `useStateSnippet→` | `const [state, setState] = useState(initialValue)` |
+| `useEffectSnippet→` | `useEffect` with cleanup function and dependency array |
+| `useContextSnippet→` | `const value = useContext(MyContext)` |
+| `useReducerSnippet→` | `const [state, dispatch] = useReducer(reducer, initial, init)` |
+| `useCallbackSnippet→` | `useCallback` with dependency array |
+| `useMemoSnippet→` | `useMemo` with dependency array |
+| `useRefSnippet→` | `const ref = useRef(initialValue)` |
+| `useImperativeHandleSnippet→` | `useImperativeHandle` with ref and factory |
+| `useLayoutEffectSnippet→` | `useLayoutEffect` with cleanup and dependency array |
+| `useIdSnippet→` | `const id = useId()` |
+| `useTransitionSnippet→` | `const [isPending, startTransition] = useTransition()` |
+| `useDeferredValueSnippet→` | `const deferred = useDeferredValue(value)` |
+| `useSnippet→` | `const value = use(resource)` (Promises or Context) |
+| `useActionStateSnippet→` | `useActionState` with async handler, returns `[state, action, isPending]` |
+| `useFormStatusSnippet→` | `const { pending, data, method, action } = useFormStatus()` (from `react-dom`) |
+| `useOptimisticSnippet→` | `useOptimistic` with state and updater function |
### Basic Methods
@@ -41,6 +58,9 @@ I.E. `tsrcc`
| `sti→` | `setInterval(() => { }, intervalTime` |
| `sto→` | `setTimeout(() => { }, delayTime` |
| `prom→` | `return new Promise((resolve, reject) => { }` |
+| `pge→` | `get propertyName() { }` |
+| `pse→` | `set propertyName(value) { }` |
+| `tpf→` | `typeof operand` |
| `cmmb→` | `comment block` |
| `cp→` | `const { } = this.props` |
| `cs→` | `const { } = this.state` |
@@ -51,19 +71,27 @@ I.E. `tsrcc`
| ----------: | --------------------------------------------------------------------------- |
| `imr→` | `import React from 'react'` |
| `imrd→` | `import ReactDOM from 'react-dom'` |
-| `imrc→` | `import React, { Component } from 'react'` |
-| `imrpc→` | `import React, { PureComponent } from 'react'` |
-| `imrm→` | `import React, { memo } from 'react'` |
+| `imrc→` | `import { Component } from 'react'` |
+| `imrcp→` | `import { Component } from 'react'` + `import PropTypes from 'prop-types'` |
+| `imrpc→` | `import { PureComponent } from 'react'` |
+| `imrpcp→` | `import { PureComponent } from 'react'` + `import PropTypes from 'prop-types'` |
+| `imrm→` | `import { memo } from 'react'` |
+| `imrmp→` | `import { memo } from 'react'` + `import PropTypes from 'prop-types'` |
+| `impt→` | `import PropTypes from 'prop-types'` |
| `imrr→` | `import { BrowserRouter as Router, Route, NavLink} from 'react-router-dom'` |
| `imbr→` | `import { BrowserRouter as Router} from 'react-router-dom'` |
-| `imbrc→` | `import { Route, Switch, NavLink, Link } from react-router-dom'` |
-| `imbrr→` | `import { Route } from 'react-router-dom'` |
-| `imbrs→` | `import { Switch } from 'react-router-dom'` |
+| `imbrc→` | `import { Routes, Route, NavLink, Link } from 'react-router-dom'` |
| `imbrl→` | `import { Link } from 'react-router-dom'` |
| `imbrnl→` | `import { NavLink } from 'react-router-dom'` |
-| `imrs→` | `import React, { useState } from 'react'` |
-| `imrse→` | `import React, { useState, useEffect } from 'react'` |
+| `imrrs→` | `import { Routes, Route } from 'react-router-dom'` |
+| `imcbr→` | `import { createBrowserRouter, RouterProvider } from 'react-router-dom'` |
+| `imnav→` | `import { useNavigate } from 'react-router-dom'` |
+| `impar→` | `import { useParams } from 'react-router-dom'` |
+| `imsp→` | `import { useSearchParams } from 'react-router-dom'` |
+| `imld→` | `import { useLoaderData } from 'react-router-dom'` |
+| `imfet→` | `import { useFetcher } from 'react-router-dom'` |
| `redux→` | `import { connect } from 'react-redux'` |
+| `rconst→` | `constructor(props) { }` with state initialization |
| `est→` | `this.state = { }` |
| `cdm→` | `componentDidMount = () => { }` |
| `scu→` | `shouldComponentUpdate = (nextProps, nextState) => { }` |
@@ -77,15 +105,23 @@ I.E. `tsrcc`
| `state→` | `this.state.stateName` |
| `rcontext→` | `const $1 = React.createContext()` |
| `cref→` | `this.$1Ref = React.createRef()` |
-| `fref→` | `const ref = React.createRef()` |
| `bnd→` | `this.methodName = this.methodName.bind(this)` |
### React Native
-| Prefix | Method |
-| ---------: | -------------------------------------- |
-| `imrn→` | `import { $1 } from 'react-native'` |
-| `rnstyle→` | `const styles = StyleSheet.create({})` |
+| Prefix | Method |
+| ---------: | ------------------------------------------------ |
+| `imrn→` | `import { $1 } from 'react-native'` |
+| `rnstyle→` | `const styles = StyleSheet.create({})` |
+| `rnc→` | React Native class component |
+| `rncs→` | React Native class component with StyleSheet |
+| `rnce→` | React Native class component with named export |
+| `rnpc→` | React Native PureComponent |
+| `rnpce→` | React Native PureComponent with named export |
+| `rnf→` | React Native functional component |
+| `rnfe→` | React Native functional component with named export |
+| `rnfs→` | React Native functional component with StyleSheet |
+| `rnfes→` | React Native functional component with StyleSheet and named export |
### Redux
@@ -96,6 +132,9 @@ I.E. `tsrcc`
| `rxreducer→` | `redux reducer template` |
| `rxselect→` | `redux selector template` |
| `rxslice→` | `redux slice template` |
+| `rxslicex→` | `redux slice with extraReducers (pending/fulfilled/rejected)` |
+| `rxthunk→` | `redux createAsyncThunk template` |
+| `rxapi→` | `RTK Query createApi with fetchBaseQuery` |
### PropTypes
@@ -129,8 +168,9 @@ I.E. `tsrcc`
| `ptoor→` | `PropTypes.objectOf(name).isRequired` |
| `ptsh→` | `PropTypes.shape({ })` |
| `ptshr→` | `PropTypes.shape({ }).isRequired` |
+| `ptex→` | `PropTypes.exact({ })` |
+| `ptexr→` | `PropTypes.exact({ }).isRequired` |
| `ptany→` | `PropTypes.any` |
-| `ptypes→` | `static propTypes = {}` |
### Console
@@ -151,17 +191,34 @@ I.E. `tsrcc`
| `ctr→` | `console.trace(object)` |
| `cwa→` | `console.warn` |
| `cin→` | `console.info` |
+| `ctl→` | `console.table` |
+
+### React 19 Directives
+
+| Prefix | Method |
+| -----: | -------------------------------- |
+| `usc` | `'use client'` directive |
+| `uss` | `'use server'` directive |
+
+### React Router v6 Setup
+
+| Prefix | Method |
+| ----------: | ----------------------------------------------------------------- |
+| `rtrsetup→` | Full `createBrowserRouter` setup with `RouterProvider` and routes |
+| `rtrla→` | Route module with `loader`, `action`, and `useLoaderData` |
### React Components
+> **Note:** Examples below show output with `importReactOnTop` set to `false` (default). When enabled, component snippets will include `import React from 'react'` at the top.
+
### `rcc`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
export default class FileName extends Component {
render() {
- return $2
+ return <>$2>
}
}
```
@@ -169,11 +226,11 @@ export default class FileName extends Component {
### `rce`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
export class FileName extends Component {
render() {
- return $2
+ return <>$2>
}
}
@@ -183,14 +240,14 @@ export default $1
### `rcep`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import PropTypes from 'prop-types'
export class FileName extends Component {
static propTypes = {}
render() {
- return $2
+ return <>$2>
}
}
@@ -200,11 +257,11 @@ export default $1
### `rpc`
```javascript
-import React, { PureComponent } from 'react'
+import { PureComponent } from 'react'
export default class FileName extends PureComponent {
render() {
- return $2
+ return <>$2>
}
}
```
@@ -212,14 +269,14 @@ export default class FileName extends PureComponent {
### `rpcp`
```javascript
-import React, { PureComponent } from 'react'
+import { PureComponent } from 'react'
import PropTypes from 'prop-types'
export default class FileName extends PureComponent {
static propTypes = {}
render() {
- return $2
+ return <>$2>
}
}
```
@@ -227,14 +284,14 @@ export default class FileName extends PureComponent {
### `rpce`
```javascript
-import React, { PureComponent } from 'react'
+import { PureComponent } from 'react'
import PropTypes from 'prop-types'
export class FileName extends PureComponent {
static propTypes = {}
render() {
- return $2
+ return <>$2>
}
}
@@ -244,7 +301,7 @@ export default FileName
### `rccp`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import PropTypes from 'prop-types'
export default class FileName extends Component {
@@ -253,7 +310,7 @@ export default class FileName extends Component {
}
render() {
- return $4
+ return <>$4>
}
}
```
@@ -261,11 +318,10 @@ export default class FileName extends Component {
### `rfcp`
```javascript
-import React from 'react'
import PropTypes from 'prop-types'
function $1(props) {
- return $0
+ return <>$0>
}
$1.propTypes = {}
@@ -276,20 +332,16 @@ export default $1
### `rfc`
```javascript
-import React from 'react'
-
export default function $1() {
- return $0
+ return <>$0>
}
```
### `rfce`
```javascript
-import React from 'react'
-
function $1() {
- return $0
+ return <>$0>
}
export default $1
@@ -298,11 +350,10 @@ export default $1
### `rafcp`
```javascript
-import React from 'react'
import PropTypes from 'prop-types'
const $1 = (props) => {
- return $0
+ return <>$0>
}
$1.propTypes = {}
@@ -313,20 +364,16 @@ export default $1
### `rafc`
```javascript
-import React from 'react'
-
export const $1 = () => {
- return $0
+ return <>$0>
}
```
### `rafce`
```javascript
-import React from 'react'
-
const $1 = () => {
- return $0
+ return <>$0>
}
export default $1
@@ -335,21 +382,21 @@ export default $1
### `rmc`
```javascript
-import React, { memo } from 'react'
+import { memo } from 'react'
export default memo(function $1() {
- return $0
+ return <>$0>
})
```
### `rmcp`
```javascript
-import React, { memo } from 'react'
+import { memo } from 'react'
import PropTypes from 'prop-types'
const $1 = memo(function $1(props) {
- return $0
+ return <>$0>
})
$1.propTypes = {}
@@ -360,12 +407,12 @@ export default $1
### `rcredux`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import { connect } from 'react-redux'
export class FileName extends Component {
render() {
- return $4
+ return <>$4>
}
}
@@ -379,7 +426,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(FileName)
### `rcreduxp`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
@@ -389,7 +436,7 @@ export class FileName extends Component {
}
render() {
- return $4
+ return <>$4>
}
}
@@ -403,11 +450,10 @@ export default connect(mapStateToProps, mapDispatchToProps)(FileName)
### `rfcredux`
```javascript
-import React, { Component } from 'react'
import { connect } from 'react-redux'
export const FileName = () => {
- return $4
+ return <>$4>
}
const mapStateToProps = (state) => ({})
@@ -417,42 +463,40 @@ const mapDispatchToProps = {}
export default connect(mapStateToProps, mapDispatchToProps)(FileName)
```
-### `rfreduxp`
+### `reduxmap`
```javascript
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
-
-export const FileName = () => {
- return $4
-}
-
-FileName.propTypes = {
- $2: $3,
-}
-
const mapStateToProps = (state) => ({})
const mapDispatchToProps = {}
-
-export default connect(mapStateToProps, mapDispatchToProps)(FileName)
```
-### `reduxmap`
+## TypeScript Components
-```javascript
-const mapStateToProps = (state) => ({})
+All TypeScript component snippets use `type` for Props/State by default. Change to `interface` via the `typescriptPropsStatePrefix` setting.
-const mapDispatchToProps = {}
-```
+| Prefix | Method |
+| ----------: | ------------------------------------------------------------ |
+| `exptp→` | `export type` definition |
+| `expint→` | `export interface` definition |
+| `tsrcc→` | TypeScript class component with Props/State |
+| `tsrce→` | TypeScript class component with named export |
+| `tsrfce→` | TypeScript functional component with named export |
+| `tsrfc→` | TypeScript functional component with default export |
+| `tsrafce→` | TypeScript arrow function component with named export |
+| `tsrafc→` | TypeScript arrow function component |
+| `tsrpc→` | TypeScript PureComponent |
+| `tsrpce→` | TypeScript PureComponent with named export |
+| `tsrcredux→`| TypeScript class component with Redux |
+| `tsrnf→` | TypeScript React Native arrow function component |
+| `tsrnfs→` | TypeScript React Native arrow function with StyleSheet |
## React Native Components
### `rnc`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import { Text, View } from 'react-native'
export default class FileName extends Component {
@@ -469,7 +513,6 @@ export default class FileName extends Component {
### `rnf`
```javascript
-import React from 'react'
import { View, Text } from 'react-native'
export default function $1() {
@@ -484,7 +527,6 @@ export default function $1() {
### `rnfs`
```javascript
-import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
export default function $1() {
@@ -501,7 +543,6 @@ const styles = StyleSheet.create({})
### `rnfe`
```javascript
-import React from 'react'
import { View, Text } from 'react-native'
const $1 = () => {
@@ -518,7 +559,6 @@ export default $1
### `rnfes`
```javascript
-import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
const $1 = () => {
@@ -537,7 +577,7 @@ const styles = StyleSheet.create({})
### `rncs`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import { Text, StyleSheet, View } from 'react-native'
export default class FileName extends Component {
@@ -556,7 +596,7 @@ const styles = StyleSheet.create({})
### `rnce`
```javascript
-import React, { Component } from 'react'
+import { Component } from 'react'
import { Text, View } from 'react-native'
export class FileName extends Component {
@@ -608,10 +648,25 @@ it('should $1', () => {
})
```
+### `tita`
+
+```javascript
+it('should $1', async () => {
+ $2
+})
+```
+
+### `testa`
+
+```javascript
+test('should $1', async () => {
+ $2
+})
+```
+
### `stest`
```javascript
-import React from 'react'
import renderer from 'react-test-renderer'
import { $1 } from '../$1'
@@ -629,7 +684,6 @@ describe('<$1 />', () => {
### `srtest`
```javascript
-import React from 'react'
import renderer from 'react-test-renderer'
import { Provider } from 'react-redux'
@@ -654,7 +708,6 @@ describe('<$1 />', () => {
```javascript
import 'react-native'
-import React from 'react'
import renderer from 'react-test-renderer'
import $1 from '../$1'
@@ -674,7 +727,6 @@ describe('<$1 />', () => {
```javascript
import 'react-native'
-import React from 'react'
import renderer from 'react-test-renderer'
import { Provider } from 'react-redux'
@@ -698,7 +750,6 @@ describe('<$1 />', () => {
### `hocredux`
```javascript
-import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
@@ -721,7 +772,6 @@ export default (WrapperComponent) =>
### `hoc`
```javascript
-import React from 'react'
import PropTypes from 'prop-types'
export default (WrappedComponent) => {
diff --git a/package.json b/package.json
index 12df135..912f2b3 100644
--- a/package.json
+++ b/package.json
@@ -40,9 +40,9 @@
},
"activationEvents": [
"onLanguage:typescript",
- "onLanguage:typescriptReact",
+ "onLanguage:typescriptreact",
"onLanguage:javascript",
- "onLanguage:javascriptReact",
+ "onLanguage:javascriptreact",
"onCommand:reactSnippets.search",
"onStartupFinished"
],
@@ -64,15 +64,10 @@
"configuration": {
"title": "ES React/React-Native/Redux snippets",
"properties": {
- "reactSnippets.settings.prettierEnabled": {
- "type": "boolean",
- "markdownDescription": "[EXPERIMENTAL: MIGHT NOT WORK]: Integrate prettier settings with code generated from snippets.",
- "default": false
- },
"reactSnippets.settings.importReactOnTop": {
"type": "boolean",
- "markdownDescription": "Controls if snippets should add `import React from 'react';` at the top of components.\nUse if you have React +17 and use jsx transform.",
- "default": true
+ "markdownDescription": "Controls if snippets should add `import React from 'react';` at the top of components.\nEnable for legacy projects (pre-React 17).",
+ "default": false
},
"reactSnippets.settings.typescript": {
"type": "boolean",
@@ -122,18 +117,11 @@
"watch": "tsc -watch -p ./",
"typescript": "tsc --noEmit"
},
- "dependencies": {
- "prettier": "2.5.1"
- },
- "peerDependencies": {
- "prettier": "^2"
- },
"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",
diff --git a/src/helpers/extensionConfig.ts b/src/helpers/extensionConfig.ts
index 5301a46..38f7621 100644
--- a/src/helpers/extensionConfig.ts
+++ b/src/helpers/extensionConfig.ts
@@ -2,15 +2,20 @@ 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;
+const extensionConfig = (): ExtensionSettings => {
+ const config = workspace.getConfiguration('reactSnippets.settings');
+
+ return {
+ languageScopes: config.get('languageScopes', 'typescript,typescriptreact,javascript,javascriptreact'),
+ importReactOnTop: config.get('importReactOnTop', false),
+ typescript: config.get('typescript', true),
+ typescriptPropsStatePrefix: config.get<'type' | 'interface'>('typescriptPropsStatePrefix', 'type'),
+ };
+};
export default extensionConfig;
diff --git a/src/helpers/formatters.ts b/src/helpers/formatters.ts
index 6188083..83c220b 100644
--- a/src/helpers/formatters.ts
+++ b/src/helpers/formatters.ts
@@ -1,22 +1,10 @@
-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)),
- );
+ return replaceSnippetPlaceholders(revertSnippetPlaceholders(snippetBody));
};
diff --git a/src/helpers/generateSnippets.ts b/src/helpers/generateSnippets.ts
index 579dbde..42f8339 100644
--- a/src/helpers/generateSnippets.ts
+++ b/src/helpers/generateSnippets.ts
@@ -1,4 +1,5 @@
-import { writeFile } from 'fs';
+import { writeFile } from 'fs/promises';
+import path from 'path';
import componentsSnippets, {
ComponentsSnippet,
@@ -19,10 +20,33 @@ import typescriptSnippets, {
TypescriptSnippet,
} from '../sourceSnippets/typescript';
+import { window } from 'vscode';
+
import extensionConfig from './extensionConfig';
import parseSnippetToBody from './parseSnippetToBody';
import { replaceSnippetPlaceholders } from './snippetPlaceholders';
+const VALID_LANGUAGE_SCOPES = [
+ 'typescript',
+ 'typescriptreact',
+ 'javascript',
+ 'javascriptreact',
+];
+
+const validateLanguageScopes = (scopes: string) => {
+ const requested = scopes.split(',').map((s) => s.trim()).filter(Boolean);
+ const valid = requested.filter((s) => VALID_LANGUAGE_SCOPES.includes(s));
+ const invalid = requested.filter((s) => !VALID_LANGUAGE_SCOPES.includes(s));
+
+ if (invalid.length > 0) {
+ window.showWarningMessage(
+ `React Snippets: Invalid language scopes ignored: ${invalid.join(', ')}. Valid values: ${VALID_LANGUAGE_SCOPES.join(', ')}`,
+ );
+ }
+
+ return valid.length > 0 ? valid.join(',') : VALID_LANGUAGE_SCOPES.join(',');
+};
+
export type SnippetKeys =
| OthersSnippet['key']
| HooksSnippet['key']
@@ -52,7 +76,8 @@ export type Snippets = {
};
const getSnippets = () => {
- const { typescript, languageScopes } = extensionConfig();
+ const { typescript, languageScopes: rawScopes } = extensionConfig();
+ const languageScopes = validateLanguageScopes(rawScopes);
const snippets = [
...(typescript ? typescriptSnippets : []),
@@ -66,7 +91,7 @@ const getSnippets = () => {
...testsSnippets,
...othersSnippets,
].reduce((acc, snippet) => {
- acc[snippet.key] = Object.assign(snippet, {
+ acc[snippet.key] = Object.assign({}, snippet, {
body: parseSnippetToBody(snippet),
scope: languageScopes,
});
@@ -76,19 +101,12 @@ const getSnippets = () => {
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);
- },
- );
- });
+const generateSnippets = async () => {
+ const jsonSnippets = getSnippets();
+ await writeFile(
+ path.join(__dirname, '..', 'snippets', 'generated.json'),
+ jsonSnippets,
+ );
+};
export default generateSnippets;
diff --git a/src/helpers/getPrettierConfig.ts b/src/helpers/getPrettierConfig.ts
deleted file mode 100644
index 30fc1bd..0000000
--- a/src/helpers/getPrettierConfig.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-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;
diff --git a/src/helpers/parseSnippetToBody.ts b/src/helpers/parseSnippetToBody.ts
index b8a7e7e..22a4774 100644
--- a/src/helpers/parseSnippetToBody.ts
+++ b/src/helpers/parseSnippetToBody.ts
@@ -1,5 +1,4 @@
import extensionConfig from './extensionConfig';
-import { formatSnippet } from './formatters';
import { Snippet } from './generateSnippets';
import replaceOrRemoveReactImport from './replaceOrRemoveReactImport';
@@ -10,14 +9,9 @@ const parseSnippetToBody = (snippet: Snippet) => {
const snippetBody = importReactOnTop
? body
- : replaceOrRemoveReactImport({
- prefix: snippet.prefix,
- body: snippet.body,
- });
+ : replaceOrRemoveReactImport(snippet.body);
- const formattedSnippet = formatSnippet(snippetBody).split('\n');
-
- return formattedSnippet;
+ return snippetBody.split('\n');
};
export default parseSnippetToBody;
diff --git a/src/helpers/replaceOrRemoveReactImport.ts b/src/helpers/replaceOrRemoveReactImport.ts
index 74d4e51..ac7b556 100644
--- a/src/helpers/replaceOrRemoveReactImport.ts
+++ b/src/helpers/replaceOrRemoveReactImport.ts
@@ -1,46 +1,4 @@
-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');
- }
-
+const replaceOrRemoveReactImport = (body: string[]) => {
let bodyCopy = [...body];
const reactImportIndex = bodyCopy.findIndex((line) =>
line.match(new RegExp(/import React/, 'g')),
diff --git a/src/helpers/snippetSearch.ts b/src/helpers/snippetSearch.ts
index bb2855a..ec88f20 100644
--- a/src/helpers/snippetSearch.ts
+++ b/src/helpers/snippetSearch.ts
@@ -1,5 +1,6 @@
-import { readFileSync } from 'fs';
-import { SnippetString, window } from 'vscode';
+import { readFile } from 'fs/promises';
+import path from 'path';
+import { commands, SnippetString, window } from 'vscode';
import { parseSnippet } from './formatters';
import { Snippet } from './generateSnippets';
@@ -7,15 +8,19 @@ 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,
- ][];
+ let snippetsArray: [string, Snippet][];
+ try {
+ const snippets = await readFile(
+ path.join(__dirname, '..', 'snippets', 'generated.json'),
+ 'utf8',
+ );
+ snippetsArray = Object.entries(JSON.parse(snippets)) as [string, Snippet][];
+ } catch {
+ window.showErrorMessage(
+ 'React Snippets: Failed to load snippets. Try regenerating via settings change.',
+ );
+ return;
+ }
const items = snippetsArray.map(
([shortDescription, { body, description, prefix: label }]) => ({
@@ -34,7 +39,8 @@ const snippetSearch = async () => {
const body = rawSnippet ? parseSnippet(rawSnippet.body) : '';
if (activeTextEditor) {
- activeTextEditor.insertSnippet(new SnippetString(body));
+ await activeTextEditor.insertSnippet(new SnippetString(body));
+ await commands.executeCommand('editor.action.formatDocument');
}
};
diff --git a/src/index.ts b/src/index.ts
index a111de3..066d574 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -15,26 +15,25 @@ const showRestartMessage = async ({
}: 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);
+ const action = await window.showWarningMessage(
+ 'React Snippets: Please restart VS Code to apply snippet formatting changes',
+ 'Restart VS Code',
+ 'Ignore',
+ );
+ if (action === 'Restart VS Code') {
+ commands.executeCommand('workbench.action.reloadWindow');
+ }
}
};
export async function activate(context: ExtensionContext) {
workspace.onDidChangeConfiguration(showRestartMessage);
- if (JSON.stringify(generatedSnippets).length < 10) {
- await generateSnippets();
+ if (Object.keys(generatedSnippets).length === 0) {
+ try {
+ await generateSnippets();
+ } catch (error) {
+ console.error(error);
+ }
}
const snippetSearchCommand = commands.registerCommand(
'reactSnippets.search',
diff --git a/src/snippets/generated.json b/src/snippets/generated.json
index d73bea5..9fb8969 100644
--- a/src/snippets/generated.json
+++ b/src/snippets/generated.json
@@ -1,6 +1,8 @@
{
"exportType": {
- "body": ["export type ${1:first} = {${2:second}}"],
+ "body": [
+ "export type ${1:first} = {${2:second}}"
+ ],
"key": "exportType",
"prefix": "exptp",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -8,7 +10,9 @@
"exportInterface": {
"key": "exportInterface",
"prefix": "expint",
- "body": ["export interface ${1:first} {${2:second}}"],
+ "body": [
+ "export interface ${1:first} {${2:second}}"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"typescriptReactClassComponent": {
@@ -16,7 +20,7 @@
"prefix": "tsrcc",
"description": "Creates a React component class with ES7 module system and TypeScript interfaces",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"type Props = {}",
"",
@@ -27,7 +31,7 @@
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}"
@@ -38,7 +42,7 @@
"key": "typescriptReactClassExportComponent",
"prefix": "tsrce",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"type Props = {}",
"",
@@ -49,7 +53,7 @@
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -63,16 +67,12 @@
"key": "typescriptReactFunctionalExportComponent",
"prefix": "tsrfce",
"body": [
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"function ${1:${TM_FILENAME_BASE}}({}: Props) {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Functional Component with ES7 module system and TypeScript interface",
@@ -82,13 +82,10 @@
"key": "typescriptReactFunctionalComponent",
"prefix": "tsrfc",
"body": [
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"export default function ${1:${TM_FILENAME_BASE}}({}: Props) {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}"
],
@@ -99,16 +96,12 @@
"key": "typescriptReactArrowFunctionExportComponent",
"prefix": "tsrafce",
"body": [
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"const ${1:${TM_FILENAME_BASE}} = (props: Props) => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Arrow Function Component with ES7 module system and TypeScript interface",
@@ -118,13 +111,10 @@
"key": "typescriptReactArrowFunctionComponent",
"prefix": "tsrafc",
"body": [
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"const ${1:${TM_FILENAME_BASE}} = (props: Props) => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}"
],
@@ -135,14 +125,14 @@
"key": "typescriptReactClassPureComponent",
"prefix": "tsrpc",
"body": [
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"type Props = {}",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}"
@@ -154,14 +144,14 @@
"key": "typescriptReactClassExportPureComponent",
"prefix": "tsrpce",
"body": [
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"type Props = {}",
"",
"class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -176,7 +166,7 @@
"prefix": "tsrcredux",
"body": [
"import { connect } from 'react-redux'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"type Props = {}",
"",
@@ -187,7 +177,7 @@
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -206,10 +196,7 @@
"prefix": "tsrnf",
"body": [
"import { View, Text } from 'react-native'",
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"const ${1:${TM_FILENAME_BASE}} = (props: Props) => {",
" return (",
" ",
@@ -217,7 +204,6 @@
" ",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Native Arrow Function Component with ES7 module system in TypeScript",
@@ -228,10 +214,7 @@
"prefix": "tsrnfs",
"body": [
"import { StyleSheet, Text, View } from 'react-native'",
- "import React from 'react'",
- "",
"type Props = {}",
- "",
"const ${1:${TM_FILENAME_BASE}} = (props: Props) => {",
" return (",
" ",
@@ -239,9 +222,7 @@
" ",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}",
- "",
"const styles = StyleSheet.create({})"
],
"description": "Creates a React Native Arrow Function Component with ES7 module system, TypeScript interface and StyleSheet",
@@ -251,14 +232,11 @@
"key": "reactArrowFunctionComponent",
"prefix": "rafc",
"body": [
- "import React from 'react'",
- "",
"export const ${1:${TM_FILENAME_BASE}} = () => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
- "}",
- ""
+ "}"
],
"description": "Creates a React Arrow Function Component with ES7 module system",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -267,17 +245,13 @@
"key": "reactArrowFunctionComponentWithPropTypes",
"prefix": "rafcp",
"body": [
- "import React from 'react'",
"import PropTypes from 'prop-types'",
- "",
"const ${1:${TM_FILENAME_BASE}} = props => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"${1:${TM_FILENAME_BASE}}.propTypes = {}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Arrow Function Component with ES7 module system with PropTypes",
@@ -287,14 +261,11 @@
"key": "reactArrowFunctionExportComponent",
"prefix": "rafce",
"body": [
- "import React from 'react'",
- "",
"const ${1:${TM_FILENAME_BASE}} = () => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Arrow Function Component with ES7 module system",
@@ -304,12 +275,12 @@
"key": "reactClassComponent",
"prefix": "rcc",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -323,14 +294,14 @@
"prefix": "rccp",
"body": [
"import PropTypes from 'prop-types'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends Component {",
" static propTypes = {${2:second}: ${3:third}}",
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -343,13 +314,13 @@
"key": "reactClassComponentRedux",
"prefix": "rcredux",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"import { connect } from 'react-redux'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -368,7 +339,7 @@
"prefix": "rcreduxp",
"body": [
"import PropTypes from 'prop-types'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"import { connect } from 'react-redux'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends Component {",
@@ -378,7 +349,7 @@
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -396,12 +367,12 @@
"key": "reactClassExportComponent",
"prefix": "rce",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -416,14 +387,14 @@
"prefix": "rcep",
"body": [
"import PropTypes from 'prop-types'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends Component {",
" static propTypes = {}",
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -437,12 +408,12 @@
"key": "reactClassExportPureComponent",
"prefix": "rpce",
"body": [
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -456,12 +427,12 @@
"key": "reactClassPureComponent",
"prefix": "rpc",
"body": [
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -475,14 +446,14 @@
"prefix": "rpcp",
"body": [
"import PropTypes from 'prop-types'",
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" static propTypes = {}",
"",
" render() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
" }",
"}",
@@ -495,11 +466,11 @@
"key": "reactFunctionMemoComponent",
"prefix": "rmc",
"body": [
- "import React, { memo } from 'react'",
+ "import { memo } from 'react'",
"",
"const ${1:${TM_FILENAME_BASE}} = memo(() => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"})",
"",
@@ -513,11 +484,11 @@
"prefix": "rmcp",
"body": [
"import PropTypes from 'prop-types'",
- "import React, { memo } from 'react'",
+ "import { memo } from 'react'",
"",
"const ${1:${TM_FILENAME_BASE}} = memo((props) => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"})",
"",
@@ -532,14 +503,11 @@
"key": "reactFunctionalComponent",
"prefix": "rfc",
"body": [
- "import React from 'react'",
- "",
"export default function ${1:${TM_FILENAME_BASE}}() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
- "}",
- ""
+ "}"
],
"description": "Creates a React Functional Component with ES7 module system",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -548,68 +516,31 @@
"key": "reactFunctionalComponentRedux",
"prefix": "rfcredux",
"body": [
- "import React from 'react'",
"import { connect } from 'react-redux'",
- "",
"export const ${1:${TM_FILENAME_BASE}} = (props) => {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"const mapStateToProps = (state) => ({})",
- "",
"const mapDispatchToProps = {}",
- "",
"export default connect(mapStateToProps, mapDispatchToProps)(${1:${TM_FILENAME_BASE}})"
],
"description": "Creates a React functional component with connected redux and ES7 module system",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
- "reactFunctionalComponentReduxPropTypes": {
- "key": "reactFunctionalComponentReduxPropTypes",
- "prefix": "rfcreduxp",
- "body": [
- "import PropTypes from 'prop-types'",
- "import React from 'react'",
- "import { connect } from 'react-redux'",
- "",
- "export const ${1:${TM_FILENAME_BASE}} = (props) => {",
- " return (",
- " ${1:first}
",
- " )",
- "}",
- "",
- "${1:${TM_FILENAME_BASE}}.propTypes = {",
- " ${2:second}: PropTypes.${3:third}",
- "}",
- "",
- "const mapStateToProps = (state) => ({})",
- "",
- "const mapDispatchToProps = {}",
- "",
- "export default connect(mapStateToProps, mapDispatchToProps)(${1:${TM_FILENAME_BASE}})"
- ],
- "description": "DEPRECATED: Creates a React functional component with PropTypes with connected redux and ES7 module system",
- "scope": "typescript,typescriptreact,javascript,javascriptreact"
- },
"reactFunctionalComponentWithPropTypes": {
"key": "reactFunctionalComponentWithPropTypes",
"prefix": "rfcp",
"body": [
- "import React from 'react'",
"import PropTypes from 'prop-types'",
- "",
"function ${1:${TM_FILENAME_BASE}}(props) {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"${1:${TM_FILENAME_BASE}}.propTypes = {}",
- "",
- "export default ${1:${TM_FILENAME_BASE}}",
- ""
+ "export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Functional Component with ES7 module system with PropTypes",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -618,14 +549,11 @@
"key": "reactFunctionalExportComponent",
"prefix": "rfce",
"body": [
- "import React from 'react'",
- "",
"function ${1:${TM_FILENAME_BASE}}() {",
" return (",
- " ${1:first}
",
+ " <>${1:first}>",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"description": "Creates a React Functional Component with ES7 module system",
@@ -634,115 +562,169 @@
"consoleAssert": {
"key": "consoleAssert",
"prefix": "cas",
- "body": ["console.assert(${1:first}, ${2:second})"],
+ "body": [
+ "console.assert(${1:first}, ${2:second})"
+ ],
"description": "If the specified expression is false, the message is written to the console along with a stack trace",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleClear": {
"key": "consoleClear",
"prefix": "ccl",
- "body": ["console.clear()"],
+ "body": [
+ "console.clear()"
+ ],
"description": "Clears the console",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleCount": {
"key": "consoleCount",
"prefix": "cco",
- "body": ["console.count(${1:first})"],
+ "body": [
+ "console.count(${1:first})"
+ ],
"description": "Writes the the number of times that count() has been invoked at the same line and with the same label",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleDir": {
"key": "consoleDir",
"prefix": "cdi",
- "body": ["console.dir(${1:first})"],
+ "body": [
+ "console.dir(${1:first})"
+ ],
"description": "Prints a JavaScript representation of the specified object",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleError": {
"key": "consoleError",
"prefix": "cer",
- "body": ["console.error(${1:first})"],
+ "body": [
+ "console.error(${1:first})"
+ ],
"description": "Displays a message in the console and also includes a stack trace from where the method was called",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleGroup": {
"key": "consoleGroup",
"prefix": "cgr",
- "body": ["console.group('${1:first}')"],
+ "body": [
+ "console.group('${1:first}')"
+ ],
"description": "Groups and indents all following output by an additional level, until console.groupEnd() is called.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleGroupEnd": {
"key": "consoleGroupEnd",
"prefix": "cge",
- "body": ["console.groupEnd()"],
+ "body": [
+ "console.groupEnd()"
+ ],
"description": "Closes out the corresponding console.group().",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleLog": {
"key": "consoleLog",
"prefix": "clg",
- "body": ["console.log(${1:first})"],
+ "body": [
+ "console.log(${1:first})"
+ ],
"description": "Displays a message in the console",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleTrace": {
"key": "consoleTrace",
"prefix": "ctr",
- "body": ["console.trace(${1:first})"],
+ "body": [
+ "console.trace(${1:first})"
+ ],
"description": "Prints a stack trace from the point where the method was called",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleLogObject": {
"key": "consoleLogObject",
"prefix": "clo",
- "body": ["console.log('${1:first}', ${1:first})"],
+ "body": [
+ "console.log('${1:first}', ${1:first})"
+ ],
"description": "Logs property with name.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleLogJson": {
"key": "consoleLogJson",
"prefix": "clj",
- "body": ["console.log('${1:first}', JSON.stringify(${1:first}, null, 2))"],
+ "body": [
+ "console.log('${1:first}', JSON.stringify(${1:first}, null, 2))"
+ ],
"description": "Logs stringified JSON property with name.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleTime": {
"key": "consoleTime",
"prefix": "ctm",
- "body": ["console.time('${1:first}')"],
+ "body": [
+ "console.time('${1:first}')"
+ ],
"description": "Console time wrapper",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleTimeEnd": {
"key": "consoleTimeEnd",
"prefix": "cte",
- "body": ["console.timeEnd('${1:first}')"],
+ "body": [
+ "console.timeEnd('${1:first}')"
+ ],
"description": "Console time end wrapper",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleWarn": {
"key": "consoleWarn",
"prefix": "cwa",
- "body": ["console.warn(${1:first})"],
+ "body": [
+ "console.warn(${1:first})"
+ ],
"description": "Displays a message in the console but also displays a yellow warning icon along with the logged message",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleInfo": {
"key": "consoleInfo",
"prefix": "cin",
- "body": ["console.info(${1:first})"],
+ "body": [
+ "console.info(${1:first})"
+ ],
"description": "Displays a message in the console but also displays a blue information icon along with the logged message",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"consoleTable": {
"key": "consoleTable",
"prefix": "ctl",
- "body": ["console.table([${1:first}])"],
+ "body": [
+ "console.table([${1:first}])"
+ ],
"description": "Logs table to console",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "use": {
+ "key": "use",
+ "prefix": "useSnippet",
+ "body": [
+ "const ${1:first} = use(${2:second})"
+ ],
+ "description": "Read a Promise or Context in render (React 19)",
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useActionState": {
+ "key": "useActionState",
+ "prefix": "useActionStateSnippet",
+ "body": [
+ "const [state, submitAction, isPending] = useActionState(",
+ " async (previousState, formData) => {",
+ " ${1:first}",
+ " },",
+ " ${2:second},",
+ ")"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"useCallback": {
"key": "useCallback",
"prefix": "useCallbackSnippet",
@@ -760,7 +742,17 @@
"useContext": {
"key": "useContext",
"prefix": "useContextSnippet",
- "body": ["const ${1:first} = useContext(${2:second})"],
+ "body": [
+ "const ${1:first} = useContext(${2:second})"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useDeferredValue": {
+ "key": "useDeferredValue",
+ "prefix": "useDeferredValueSnippet",
+ "body": [
+ "const ${1:first} = useDeferredValue(${2:second})"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"useEffect": {
@@ -778,6 +770,23 @@
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "useFormStatus": {
+ "key": "useFormStatus",
+ "prefix": "useFormStatusSnippet",
+ "body": [
+ "const { pending, data, method, action } = useFormStatus()"
+ ],
+ "description": "useFormStatus (import from react-dom)",
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useId": {
+ "key": "useId",
+ "prefix": "useIdSnippet",
+ "body": [
+ "const ${1:first} = useId()"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"useImperativeHandle": {
"key": "useImperativeHandle",
"prefix": "useImperativeHandleSnippet",
@@ -809,7 +818,20 @@
"useMemo": {
"key": "useMemo",
"prefix": "useMemoSnippet",
- "body": ["useMemo(() => ${1:first}, [${2:second}])"],
+ "body": [
+ "useMemo(() => ${1:first}, [${2:second}])"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useOptimistic": {
+ "key": "useOptimistic",
+ "prefix": "useOptimisticSnippet",
+ "body": [
+ "const [optimistic${1/(.*)/${1:/capitalize}/}, addOptimistic] = useOptimistic(",
+ " ${1:first},",
+ " (state, newValue) => [...state, newValue],",
+ ")"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"useReducer": {
@@ -823,7 +845,9 @@
"useRef": {
"key": "useRef",
"prefix": "useRefSnippet",
- "body": ["const ${1:first} = useRef(${2:second})"],
+ "body": [
+ "const ${1:first} = useRef(${2:second})"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"useState": {
@@ -834,16 +858,28 @@
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "useTransition": {
+ "key": "useTransition",
+ "prefix": "useTransitionSnippet",
+ "body": [
+ "const [isPending, startTransition] = useTransition()"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"importAs": {
"key": "importAs",
"prefix": "ima",
- "body": ["import { ${2:second} as ${3:third} } from '${1:first}'"],
+ "body": [
+ "import { ${2:second} as ${3:third} } from '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importBrowserRouter": {
"key": "importBrowserRouter",
"prefix": "imbr",
- "body": ["import { BrowserRouter as Router } from 'react-router-dom'"],
+ "body": [
+ "import { BrowserRouter as Router } from 'react-router-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importBrowserRouterWithRouteAndNavLink": {
@@ -858,50 +894,64 @@
"importDestructing": {
"key": "importDestructing",
"prefix": "imd",
- "body": ["import { ${2:second} } from '${1:first}'"],
+ "body": [
+ "import { ${2:second} } from '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importEverything": {
"key": "importEverything",
"prefix": "ime",
- "body": ["import * as ${2:second} from '${1:first}'"],
+ "body": [
+ "import * as ${2:second} from '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importNoModuleName": {
"key": "importNoModuleName",
"prefix": "imn",
- "body": ["import '${1:first}'"],
+ "body": [
+ "import '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importPropTypes": {
"key": "importPropTypes",
"prefix": "impt",
- "body": ["import PropTypes from 'prop-types'"],
+ "body": [
+ "import PropTypes from 'prop-types'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReact": {
"key": "importReact",
"prefix": "imr",
- "body": ["import React from 'react'"],
+ "body": [
+ ""
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReactDom": {
"key": "importReactDom",
"prefix": "imrd",
- "body": ["import ReactDOM from 'react-dom'"],
+ "body": [
+ "import ReactDOM from 'react-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReactWithComponent": {
"key": "importReactWithComponent",
"prefix": "imrc",
- "body": ["import React, { Component } from 'react'"],
+ "body": [
+ "import { Component } from 'react'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReactWithComponentAndPropTypes": {
"key": "importReactWithComponentAndPropTypes",
"prefix": "imrcp",
"body": [
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"import PropTypes from 'prop-types'",
""
],
@@ -910,14 +960,16 @@
"importReactWithMemo": {
"key": "importReactWithMemo",
"prefix": "imrm",
- "body": ["import React, { memo } from 'react'"],
+ "body": [
+ "import { memo } from 'react'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReactWithMemoAndPropTypes": {
"key": "importReactWithMemoAndPropTypes",
"prefix": "imrmp",
"body": [
- "import React, { memo } from 'react'",
+ "import { memo } from 'react'",
"import PropTypes from 'prop-types'",
""
],
@@ -926,263 +978,397 @@
"importReactWithPureComponent": {
"key": "importReactWithPureComponent",
"prefix": "imrpc",
- "body": ["import React, { PureComponent } from 'react'"],
+ "body": [
+ "import { PureComponent } from 'react'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReactWithPureComponentAndPropTypes": {
"key": "importReactWithPureComponentAndPropTypes",
"prefix": "imrpcp",
"body": [
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"import PropTypes from 'prop-types'",
""
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "importCreateBrowserRouter": {
+ "key": "importCreateBrowserRouter",
+ "prefix": "imcbr",
+ "body": [
+ "import { createBrowserRouter, RouterProvider } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"importRouterLink": {
"key": "importRouterLink",
"prefix": "imbrl",
- "body": ["import { Link } from 'react-router-dom'"],
+ "body": [
+ "import { Link } from 'react-router-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importRouterNavLink": {
"key": "importRouterNavLink",
"prefix": "imbrnl",
- "body": ["import { NavLink } from 'react-router-dom'"],
+ "body": [
+ "import { NavLink } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importRouterRoutes": {
+ "key": "importRouterRoutes",
+ "prefix": "imrrs",
+ "body": [
+ "import { Routes, Route } from 'react-router-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importRouterSetup": {
"key": "importRouterSetup",
"prefix": "imbrc",
- "body": ["import { Route, Switch, NavLink, Link } from 'react-router-dom'"],
- "scope": "typescript,typescriptreact,javascript,javascriptreact"
- },
- "importRouterSwitch": {
- "key": "importRouterSwitch",
- "prefix": "imbrs",
- "body": ["import { Switch } from 'react-router-dom'"],
+ "body": [
+ "import { Routes, Route, NavLink, Link } from 'react-router-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"import": {
"key": "import",
"prefix": "imp",
- "body": ["import ${2:second} from '${1:first}'"],
+ "body": [
+ "import ${2:second} from '${1:first}'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importUseFetcher": {
+ "key": "importUseFetcher",
+ "prefix": "imfet",
+ "body": [
+ "import { useFetcher } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importUseLoaderData": {
+ "key": "importUseLoaderData",
+ "prefix": "imld",
+ "body": [
+ "import { useLoaderData } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importUseNavigate": {
+ "key": "importUseNavigate",
+ "prefix": "imnav",
+ "body": [
+ "import { useNavigate } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importUseParams": {
+ "key": "importUseParams",
+ "prefix": "impar",
+ "body": [
+ "import { useParams } from 'react-router-dom'"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "importUseSearchParams": {
+ "key": "importUseSearchParams",
+ "prefix": "imsp",
+ "body": [
+ "import { useSearchParams } from 'react-router-dom'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeArray": {
"key": "propTypeArray",
"prefix": "pta",
- "body": ["PropTypes.array"],
+ "body": [
+ "PropTypes.array"
+ ],
"description": "Array prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeArrayRequired": {
"key": "propTypeArrayRequired",
"prefix": "ptar",
- "body": ["PropTypes.array.isRequired"],
+ "body": [
+ "PropTypes.array.isRequired"
+ ],
"description": "Array prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeBool": {
"key": "propTypeBool",
"prefix": "ptb",
- "body": ["PropTypes.bool"],
+ "body": [
+ "PropTypes.bool"
+ ],
"description": "Bool prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeBoolRequired": {
"key": "propTypeBoolRequired",
"prefix": "ptbr",
- "body": ["PropTypes.bool.isRequired"],
+ "body": [
+ "PropTypes.bool.isRequired"
+ ],
"description": "Bool prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeFunc": {
"key": "propTypeFunc",
"prefix": "ptf",
- "body": ["PropTypes.func"],
+ "body": [
+ "PropTypes.func"
+ ],
"description": "Func prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeFuncRequired": {
"key": "propTypeFuncRequired",
"prefix": "ptfr",
- "body": ["PropTypes.func.isRequired"],
+ "body": [
+ "PropTypes.func.isRequired"
+ ],
"description": "Func prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeNumber": {
"key": "propTypeNumber",
"prefix": "ptn",
- "body": ["PropTypes.number"],
+ "body": [
+ "PropTypes.number"
+ ],
"description": "Number prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeNumberRequired": {
"key": "propTypeNumberRequired",
"prefix": "ptnr",
- "body": ["PropTypes.number.isRequired"],
+ "body": [
+ "PropTypes.number.isRequired"
+ ],
"description": "Number prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeObject": {
"key": "propTypeObject",
"prefix": "pto",
- "body": ["PropTypes.object"],
+ "body": [
+ "PropTypes.object"
+ ],
"description": "Object prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeObjectRequired": {
"key": "propTypeObjectRequired",
"prefix": "ptor",
- "body": ["PropTypes.object.isRequired"],
+ "body": [
+ "PropTypes.object.isRequired"
+ ],
"description": "Object prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeString": {
"key": "propTypeString",
"prefix": "pts",
- "body": ["PropTypes.string"],
+ "body": [
+ "PropTypes.string"
+ ],
"description": "String prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeStringRequired": {
"key": "propTypeStringRequired",
"prefix": "ptsr",
- "body": ["PropTypes.string.isRequired"],
+ "body": [
+ "PropTypes.string.isRequired"
+ ],
"description": "String prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeNode": {
"key": "propTypeNode",
"prefix": "ptnd",
- "body": ["PropTypes.node"],
+ "body": [
+ "PropTypes.node"
+ ],
"description": "Anything that can be rendered: numbers, strings, elements or an array",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeNodeRequired": {
"key": "propTypeNodeRequired",
"prefix": "ptndr",
- "body": ["PropTypes.node.isRequired"],
+ "body": [
+ "PropTypes.node.isRequired"
+ ],
"description": "Anything that can be rendered: numbers, strings, elements or an array required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeElement": {
"key": "propTypeElement",
"prefix": "ptel",
- "body": ["PropTypes.element"],
+ "body": [
+ "PropTypes.element"
+ ],
"description": "React element prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeElementRequired": {
"key": "propTypeElementRequired",
"prefix": "ptelr",
- "body": ["PropTypes.element.isRequired"],
+ "body": [
+ "PropTypes.element.isRequired"
+ ],
"description": "React element prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeInstanceOf": {
"key": "propTypeInstanceOf",
"prefix": "pti",
- "body": ["PropTypes.instanceOf($0)"],
+ "body": [
+ "PropTypes.instanceOf($0)"
+ ],
"description": "Is an instance of a class prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeInstanceOfRequired": {
"key": "propTypeInstanceOfRequired",
"prefix": "ptir",
- "body": ["PropTypes.instanceOf($0).isRequired"],
+ "body": [
+ "PropTypes.instanceOf($0).isRequired"
+ ],
"description": "Is an instance of a class prop type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeEnum": {
"key": "propTypeEnum",
"prefix": "pte",
- "body": ["PropTypes.oneOf(['$0'])"],
+ "body": [
+ "PropTypes.oneOf(['$0'])"
+ ],
"description": "Prop type limited to specific values by treating it as an enum",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeEnumRequired": {
"key": "propTypeEnumRequired",
"prefix": "pter",
- "body": ["PropTypes.oneOf(['$0']).isRequired"],
+ "body": [
+ "PropTypes.oneOf(['$0']).isRequired"
+ ],
"description": "Prop type limited to specific values by treating it as an enum required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeOneOfType": {
"key": "propTypeOneOfType",
"prefix": "ptet",
- "body": ["PropTypes.oneOfType([", " $0", "])"],
+ "body": [
+ "PropTypes.oneOfType([",
+ " $0",
+ "])"
+ ],
"description": "An object that could be one of many types",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeOneOfTypeRequired": {
"key": "propTypeOneOfTypeRequired",
"prefix": "ptetr",
- "body": ["PropTypes.oneOfType([", " $0", "]).isRequired"],
+ "body": [
+ "PropTypes.oneOfType([",
+ " $0",
+ "]).isRequired"
+ ],
"description": "An object that could be one of many types required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeArrayOf": {
"key": "propTypeArrayOf",
"prefix": "ptao",
- "body": ["PropTypes.arrayOf($0)"],
+ "body": [
+ "PropTypes.arrayOf($0)"
+ ],
"description": "An array of a certain type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeArrayOfRequired": {
"key": "propTypeArrayOfRequired",
"prefix": "ptaor",
- "body": ["PropTypes.arrayOf($0).isRequired"],
+ "body": [
+ "PropTypes.arrayOf($0).isRequired"
+ ],
"description": "An array of a certain type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeObjectOf": {
"key": "propTypeObjectOf",
"prefix": "ptoo",
- "body": ["PropTypes.objectOf($0)"],
+ "body": [
+ "PropTypes.objectOf($0)"
+ ],
"description": "An object with property values of a certain type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeObjectOfRequired": {
"key": "propTypeObjectOfRequired",
"prefix": "ptoor",
- "body": ["PropTypes.objectOf($0).isRequired"],
+ "body": [
+ "PropTypes.objectOf($0).isRequired"
+ ],
"description": "An object with property values of a certain type required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeShape": {
"key": "propTypeShape",
"prefix": "ptsh",
- "body": ["PropTypes.shape({", " $0", "})"],
+ "body": [
+ "PropTypes.shape({",
+ " $0",
+ "})"
+ ],
"description": "An object taking on a particular shape",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeShapeRequired": {
"key": "propTypeShapeRequired",
"prefix": "ptshr",
- "body": ["PropTypes.shape({", " $0", "}).isRequired"],
+ "body": [
+ "PropTypes.shape({",
+ " $0",
+ "}).isRequired"
+ ],
"description": "An object taking on a particular shape required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeExact": {
"key": "propTypeExact",
"prefix": "ptex",
- "body": ["PropTypes.exact({", " $0", "})"],
+ "body": [
+ "PropTypes.exact({",
+ " $0",
+ "})"
+ ],
"description": "An object with warnings on extra properties",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeExactRequired": {
"key": "propTypeExactRequired",
"prefix": "ptexr",
- "body": ["PropTypes.exact({", " $0", "}).isRequired"],
+ "body": [
+ "PropTypes.exact({",
+ " $0",
+ "}).isRequired"
+ ],
"description": "An object with warnings on extra properties required",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propTypeAny": {
"key": "propTypeAny",
"prefix": "ptany",
- "body": ["PropTypes.any"],
+ "body": [
+ "PropTypes.any"
+ ],
"description": "Any prop type",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
@@ -1191,7 +1377,7 @@
"prefix": "rnc",
"body": [
"import { Text, View } from 'react-native'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
@@ -1210,7 +1396,7 @@
"prefix": "rnce",
"body": [
"import { Text, View } from 'react-native'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
@@ -1231,7 +1417,7 @@
"prefix": "rncs",
"body": [
"import { Text, StyleSheet, View } from 'react-native'",
- "import React, { Component } from 'react'",
+ "import { Component } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends Component {",
" render() {",
@@ -1252,8 +1438,6 @@
"prefix": "rnf",
"body": [
"import { View, Text } from 'react-native'",
- "import React from 'react'",
- "",
"export default function ${1:${TM_FILENAME_BASE}}() {",
" return (",
" ",
@@ -1269,8 +1453,6 @@
"prefix": "rnfs",
"body": [
"import { StyleSheet, Text, View } from 'react-native'",
- "import React from 'react'",
- "",
"export default function ${1:${TM_FILENAME_BASE}}() {",
" return (",
" ",
@@ -1278,7 +1460,6 @@
" ",
" )",
"}",
- "",
"const styles = StyleSheet.create({})"
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -1288,8 +1469,6 @@
"prefix": "rnfe",
"body": [
"import { View, Text } from 'react-native'",
- "import React from 'react'",
- "",
"const ${1:${TM_FILENAME_BASE}} = () => {",
" return (",
" ",
@@ -1297,7 +1476,6 @@
" ",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}"
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -1307,8 +1485,6 @@
"prefix": "rnfes",
"body": [
"import { StyleSheet, Text, View } from 'react-native'",
- "import React from 'react'",
- "",
"const ${1:${TM_FILENAME_BASE}} = () => {",
" return (",
" ",
@@ -1316,9 +1492,7 @@
" ",
" )",
"}",
- "",
"export default ${1:${TM_FILENAME_BASE}}",
- "",
"const styles = StyleSheet.create({})"
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
@@ -1326,7 +1500,9 @@
"reactNativeImport": {
"key": "reactNativeImport",
"prefix": "imrn",
- "body": ["import { ${1:first} } from 'react-native'"],
+ "body": [
+ "import { ${1:first} } from 'react-native'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"reactNativePureComponent": {
@@ -1334,7 +1510,7 @@
"prefix": "rnpc",
"body": [
"import { Text, View } from 'react-native'",
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"export default class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
@@ -1353,7 +1529,7 @@
"prefix": "rnpce",
"body": [
"import { Text, View } from 'react-native'",
- "import React, { PureComponent } from 'react'",
+ "import { PureComponent } from 'react'",
"",
"export class ${1:${TM_FILENAME_BASE}} extends PureComponent {",
" render() {",
@@ -1372,13 +1548,17 @@
"reactNativeStyles": {
"key": "reactNativeStyles",
"prefix": "rnstyle",
- "body": ["const styles = StyleSheet.create({${1:first}})"],
+ "body": [
+ "const styles = StyleSheet.create({${1:first}})"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"importReduxConnect": {
"key": "importReduxConnect",
"prefix": "redux",
- "body": ["import { connect } from 'react-redux'"],
+ "body": [
+ "import { connect } from 'react-redux'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"reduxAction": {
@@ -1393,10 +1573,44 @@
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "reduxApi": {
+ "key": "reduxApi",
+ "prefix": "rxapi",
+ "body": [
+ "import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'",
+ "",
+ "export const ${1:first}Api = createApi({",
+ " reducerPath: '${1:first}Api',",
+ " baseQuery: fetchBaseQuery({ baseUrl: '${2:second}' }),",
+ " endpoints: (builder) => ({",
+ " ${3:third}: builder.query({",
+ " query: () => '/',",
+ " }),",
+ " }),",
+ "})",
+ "",
+ "export const { } = ${1:first}Api"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "reduxAsyncThunk": {
+ "key": "reduxAsyncThunk",
+ "prefix": "rxthunk",
+ "body": [
+ "import { createAsyncThunk } from '@reduxjs/toolkit'",
+ "",
+ "export const ${1:first} = createAsyncThunk('${2:second}', async () => {",
+ " ${3:third}",
+ "})"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"reduxConst": {
"key": "reduxConst",
"prefix": "rxconst",
- "body": ["export const ${1:first} = '${1:first}'"],
+ "body": [
+ "export const ${1:first} = '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"reduxReducer": {
@@ -1451,6 +1665,41 @@
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
+ "reduxSliceWithExtraReducers": {
+ "key": "reduxSliceWithExtraReducers",
+ "prefix": "rxslicex",
+ "body": [
+ "import { createSlice } from '@reduxjs/toolkit'",
+ "",
+ "const initialState = {",
+ " ${1:first}",
+ " status: 'idle',",
+ "}",
+ "",
+ "const ${1:${TM_FILENAME_BASE}} = createSlice({",
+ " name: '${2:second}',",
+ " initialState,",
+ " reducers: {},",
+ " extraReducers: (builder) => {",
+ " builder",
+ " .addCase(${3:third}.pending, (state) => {",
+ " state.status = 'loading'",
+ " })",
+ " .addCase(${3:third}.fulfilled, (state, action) => {",
+ " state.status = 'succeeded'",
+ " })",
+ " .addCase(${3:third}.rejected, (state) => {",
+ " state.status = 'failed'",
+ " })",
+ " },",
+ "})",
+ "",
+ "export const {} = ${1:${TM_FILENAME_BASE}}.actions",
+ "",
+ "export default ${1:${TM_FILENAME_BASE}}.reducer"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
"mappingToProps": {
"key": "mappingToProps",
"prefix": "reduxmap",
@@ -1464,21 +1713,27 @@
"describeBlock": {
"key": "describeBlock",
"prefix": "desc",
- "body": ["describe('${1:first}', () => { ${2:second} })"],
+ "body": [
+ "describe('${1:first}', () => { ${2:second} })"
+ ],
"description": "Testing `describe` block",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"itAsyncBlock": {
"key": "itAsyncBlock",
"prefix": "tita",
- "body": ["it('should ${1:first}', async () => { ${2:second} })"],
+ "body": [
+ "it('should ${1:first}', async () => { ${2:second} })"
+ ],
"description": "Testing asynchronous `it` block",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"itBlock": {
"key": "itBlock",
"prefix": "tit",
- "body": ["it('should ${1:first}', () => { ${2:second} })"],
+ "body": [
+ "it('should ${1:first}', () => { ${2:second} })"
+ ],
"description": "Testing `it` block",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
@@ -1486,13 +1741,10 @@
"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 { ${1:${TM_FILENAME_BASE}} } from '../${1:${TM_FILENAME_BASE}}'",
- "",
"describe('<${1:${TM_FILENAME_BASE}} />', () => {",
" const defaultProps = {}",
" const wrapper = renderer.create(",
@@ -1500,7 +1752,6 @@
" <${1:${TM_FILENAME_BASE}} {...defaultProps} />",
" ,",
" )",
- "",
" test('render', () => {",
" expect(wrapper).toMatchSnapshot()",
" })",
@@ -1514,15 +1765,11 @@
"prefix": "sntest",
"body": [
"import 'react-native'",
- "import React from 'react'",
"import renderer from 'react-test-renderer'",
- "",
"import ${1:${TM_FILENAME_BASE}} from '../${1:${TM_FILENAME_BASE}}'",
- "",
"describe('<${1:${TM_FILENAME_BASE}} />', () => {",
" const defaultProps = {}",
" const wrapper = renderer.create(<${1:${TM_FILENAME_BASE}} {...defaultProps} />)",
- "",
" test('render', () => {",
" expect(wrapper).toMatchSnapshot()",
" })",
@@ -1535,13 +1782,10 @@
"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 ${1:${TM_FILENAME_BASE}} from '../${1:${TM_FILENAME_BASE}}'",
- "",
"describe('<${1:${TM_FILENAME_BASE}} />', () => {",
" const defaultProps = {}",
" const wrapper = renderer.create(",
@@ -1549,7 +1793,6 @@
" <${1:${TM_FILENAME_BASE}} {...defaultProps} />",
" ,",
" )",
- "",
" test('render', () => {",
" expect(wrapper).toMatchSnapshot()",
" })",
@@ -1561,15 +1804,11 @@
"key": "setupReactTest",
"prefix": "stest",
"body": [
- "import React from 'react'",
"import renderer from 'react-test-renderer'",
- "",
"import { ${1:${TM_FILENAME_BASE}} } from '../${1:${TM_FILENAME_BASE}}'",
- "",
"describe('<${1:${TM_FILENAME_BASE}} />', () => {",
" const defaultProps = {}",
" const wrapper = renderer.create(<${1:${TM_FILENAME_BASE}} {...defaultProps} />)",
- "",
" test('render', () => {",
" expect(wrapper).toMatchSnapshot()",
" })",
@@ -1580,158 +1819,206 @@
"testAsyncBlock": {
"key": "testAsyncBlock",
"prefix": "testa",
- "body": ["test('should ${1:first}', async () => { ${2:second} })"],
+ "body": [
+ "test('should ${1:first}', async () => { ${2:second} })"
+ ],
"description": "Testing `asynchronous test` block",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"testBlock": {
"key": "testBlock",
"prefix": "test",
- "body": ["test('should ${1:first}', () => { ${2:second} })"],
+ "body": [
+ "test('should ${1:first}', () => { ${2:second} })"
+ ],
"description": "Testing `test` block",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportDefault": {
"key": "exportDefault",
"prefix": "exp",
- "body": ["export default ${1:first}"],
+ "body": [
+ "export default ${1:first}"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportDestructing": {
"key": "exportDestructing",
"prefix": "exd",
- "body": ["export { ${2:second} } from '${1:first}'"],
+ "body": [
+ "export { ${2:second} } from '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportAs": {
"key": "exportAs",
"prefix": "exa",
- "body": ["export { ${2:second} as ${3:third} } from '${1:first}'"],
+ "body": [
+ "export { ${2:second} as ${3:third} } from '${1:first}'"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportNamedFunction": {
"key": "exportNamedFunction",
"prefix": "enf",
- "body": ["export const ${1:first} = (${2:second}) => {${3:third}}"],
+ "body": [
+ "export const ${1:first} = (${2:second}) => {${3:third}}"
+ ],
"description": "Export named function",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportDefaultFunction": {
"key": "exportDefaultFunction",
"prefix": "edf",
- "body": ["export default (${1:first}) => {${2:second}}"],
+ "body": [
+ "export default (${1:first}) => {${2:second}}"
+ ],
"description": "Export default function",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"exportDefaultNamedFunction": {
"key": "exportDefaultNamedFunction",
"prefix": "ednf",
- "body": ["export default function ${1:first}(${2:second}) {${3:third}}"],
+ "body": [
+ "export default function ${1:first}(${2:second}) {${3:third}}"
+ ],
"description": "Export default named function",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"method": {
"key": "method",
"prefix": "met",
- "body": ["${1:first} = (${2:second}) => {${3:third}}"],
+ "body": [
+ "${1:first} = (${2:second}) => {${3:third}}"
+ ],
"description": "Creates a method inside a class",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propertyGet": {
"key": "propertyGet",
"prefix": "pge",
- "body": ["get ${1:first}() {", " return this.${2:second}", "}"],
+ "body": [
+ "get ${1:first}() {",
+ " return this.${2:second}",
+ "}"
+ ],
"description": "Creates a getter property inside a class",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"propertySet": {
"key": "propertySet",
"prefix": "pse",
- "body": ["set ${1:first}(${2:second}) {${3:third}}"],
+ "body": [
+ "set ${1:first}(${2:second}) {${3:third}}"
+ ],
"description": "Creates a setter property inside a class",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"forEach": {
"key": "forEach",
"prefix": "fre",
- "body": ["${1:first}.forEach(${2:second} => {${3:third}})"],
+ "body": [
+ "${1:first}.forEach(${2:second} => {${3:third}})"
+ ],
"description": "Creates a forEach statement",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"forOf": {
"key": "forOf",
"prefix": "fof",
- "body": ["for(let ${1:first} of ${2:second}) {${3:third}}"],
+ "body": [
+ "for(let ${1:first} of ${2:second}) {${3:third}}"
+ ],
"description": "Iterating over property names of iterable objects",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"forIn": {
"key": "forIn",
"prefix": "fin",
- "body": ["for(let ${1:first} in ${2:second}) {${3:third}}"],
+ "body": [
+ "for(let ${1:first} in ${2:second}) {${3:third}}"
+ ],
"description": "Iterating over property values of iterable objects",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"anonymousFunction": {
"key": "anonymousFunction",
"prefix": "anfn",
- "body": ["(${1:first}) => { ${2:second} }"],
+ "body": [
+ "(${1:first}) => { ${2:second} }"
+ ],
"description": "Creates an anonymous function",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"namedFunction": {
"key": "namedFunction",
"prefix": "nfn",
- "body": ["const ${1:first} = (${2:second}) => { ${3:third} }"],
+ "body": [
+ "const ${1:first} = (${2:second}) => { ${3:third} }"
+ ],
"description": "Creates a named function",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"destructingObject": {
"key": "destructingObject",
"prefix": "dob",
- "body": ["const {${2:second}} = ${1:first}"],
+ "body": [
+ "const {${2:second}} = ${1:first}"
+ ],
"description": "Creates and assigns a local variable using object destructing",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"destructingArray": {
"key": "destructingArray",
"prefix": "dar",
- "body": ["const [${2:second}] = ${1:first}"],
+ "body": [
+ "const [${2:second}] = ${1:first}"
+ ],
"description": "Creates and assigns a local variable using array destructing",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"setInterval": {
"key": "setInterval",
"prefix": "sti",
- "body": ["setInterval(() => { ${1:first} }, ${2:second})"],
+ "body": [
+ "setInterval(() => { ${1:first} }, ${2:second})"
+ ],
"description": "Executes the given function at specified intervals",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"setTimeOut": {
"key": "setTimeOut",
"prefix": "sto",
- "body": ["setTimeout(() => { ${1:first} }, ${2:second})"],
+ "body": [
+ "setTimeout(() => { ${1:first} }, ${2:second})"
+ ],
"description": "Executes the given function after the specified delay",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"promise": {
"key": "promise",
"prefix": "prom",
- "body": ["return new Promise((resolve, reject) => { ${1:first} })"],
+ "body": [
+ "return new Promise((resolve, reject) => { ${1:first} })"
+ ],
"description": "Creates and returns a new Promise in the standard ES7 syntax",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"destructProps": {
"key": "destructProps",
"prefix": "cp",
- "body": ["const { ${1:first} } = this.props"],
+ "body": [
+ "const { ${1:first} } = this.props"
+ ],
"description": "Creates and assigns a local variable using props destructing",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"destructState": {
"key": "destructState",
"prefix": "cs",
- "body": ["const { ${1:first} } = this.state"],
+ "body": [
+ "const { ${1:first} } = this.state"
+ ],
"description": "Creates and assigns a local variable using state destructing",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
@@ -1753,42 +2040,54 @@
"emptyState": {
"key": "emptyState",
"prefix": "est",
- "body": ["state = { ${1:first} }"],
+ "body": [
+ "state = { ${1:first} }"
+ ],
"description": "Creates empty state object. To be used in a constructor.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentDidMount": {
"key": "componentDidMount",
"prefix": "cdm",
- "body": ["componentDidMount() { ${1:first} }"],
+ "body": [
+ "componentDidMount() { ${1:first} }"
+ ],
"description": "Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"shouldComponentUpdate": {
"key": "shouldComponentUpdate",
"prefix": "scu",
- "body": ["shouldComponentUpdate(nextProps, nextState) { ${1:first} }"],
+ "body": [
+ "shouldComponentUpdate(nextProps, nextState) { ${1:first} }"
+ ],
"description": "Invoked before rendering when new props or state are being received. ",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentDidUpdate": {
"key": "componentDidUpdate",
"prefix": "cdup",
- "body": ["componentDidUpdate(prevProps, prevState) { ${1:first}} "],
+ "body": [
+ "componentDidUpdate(prevProps, prevState) { ${1:first}} "
+ ],
"description": "Invoked immediately after the component's updates are flushed to the DOM.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentWillUnmount": {
"key": "componentWillUnmount",
"prefix": "cwun",
- "body": ["componentWillUnmount() {${1:first} }"],
+ "body": [
+ "componentWillUnmount() {${1:first} }"
+ ],
"description": "Invoked immediately before a component is unmounted from the DOM.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"getDerivedStateFromProps": {
"key": "getDerivedStateFromProps",
"prefix": "gdsfp",
- "body": ["static getDerivedStateFromProps(props, state) {${1:first}}"],
+ "body": [
+ "static getDerivedStateFromProps(props, state) {${1:first}}"
+ ],
"description": "Invoked right before calling the render method, both on the initial mount and on subsequent updates.",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
@@ -1804,79 +2103,89 @@
"createContext": {
"key": "createContext",
"prefix": "rcontext",
- "body": ["const ${1:first} = React.createContext()"],
+ "body": [
+ "const ${1:first} = React.createContext()"
+ ],
"description": "Create React context",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"createRef": {
"key": "createRef",
"prefix": "cref",
- "body": ["this.${1:first}Ref = React.createRef()"],
+ "body": [
+ "this.${1:first}Ref = React.createRef()"
+ ],
"description": "Create ref statement used inside constructor",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentSetStateObject": {
"key": "componentSetStateObject",
"prefix": "sst",
- "body": ["this.setState({${1:first}})"],
+ "body": [
+ "this.setState({${1:first}})"
+ ],
"description": "Performs a shallow merge of nextState into current state",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentSetStateFunc": {
"key": "componentSetStateFunc",
"prefix": "ssf",
- "body": ["this.setState((state, props) => { return { ${1:first} }})"],
+ "body": [
+ "this.setState((state, props) => { return { ${1:first} }})"
+ ],
"description": "Performs a shallow merge of nextState into current state",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentProps": {
"key": "componentProps",
"prefix": "props",
- "body": ["this.props.${1:first}"],
+ "body": [
+ "this.props.${1:first}"
+ ],
"description": "Access component's props",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"componentState": {
"key": "componentState",
"prefix": "state",
- "body": ["this.state.${1:first}"],
+ "body": [
+ "this.state.${1:first}"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"bindThis": {
"key": "bindThis",
"prefix": "bnd",
- "body": ["this.${1:first} = this.${1:first}.bind(this)"],
+ "body": [
+ "this.${1:first} = this.${1:first}.bind(this)"
+ ],
"description": "Binds this to a method",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"commentBigBlock": {
"key": "commentBigBlock",
"prefix": "cmmb",
- "body": ["/**", " * ${1:first}", " */"],
+ "body": [
+ "/**",
+ " * ${1:first}",
+ " */"
+ ],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"hocComponentWithRedux": {
"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 ${1:first} = (WrappedComponent) => {",
" const hocComponent = ({ ...props }) => ",
- "",
" hocComponent.propTypes = {}",
- "",
" return hocComponent",
"}",
- "",
- "export default WrapperComponent => connect(mapStateToProps, mapDispatchToProps)(${1:first}(WrapperComponent))",
- ""
+ "export default WrapperComponent => connect(mapStateToProps, mapDispatchToProps)(${1:first}(WrapperComponent))"
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
@@ -1884,24 +2193,98 @@
"key": "hocComponent",
"prefix": "hoc",
"body": [
- "import React from 'react'",
"import PropTypes from 'prop-types'",
- "",
"export default (WrappedComponent) => {",
" const hocComponent = ({ ...props }) => ",
- "",
" hocComponent.propTypes = {}",
- "",
" return hocComponent",
- "}",
- ""
+ "}"
],
"scope": "typescript,typescriptreact,javascript,javascriptreact"
},
"typeofSnippet": {
"key": "typeofSnippet",
"prefix": "tpf",
- "body": ["typeof ${1:first}"],
+ "body": [
+ "typeof ${1:first}"
+ ],
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "createBrowserRouterSetup": {
+ "key": "createBrowserRouterSetup",
+ "prefix": "rtrsetup",
+ "body": [
+ "import { createBrowserRouter, RouterProvider } from 'react-router-dom'",
+ "",
+ "const router = createBrowserRouter([",
+ " {",
+ " path: '/',",
+ " element: <${1:first} />,",
+ " children: [",
+ " {",
+ " path: '${2:second}',",
+ " element: <${3:third} />,",
+ " },",
+ " ],",
+ " },",
+ "])",
+ "",
+ "function App() {",
+ " return ",
+ "}",
+ "",
+ "export default App"
+ ],
+ "description": "React Router v6 createBrowserRouter setup",
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "routeWithLoaderAction": {
+ "key": "routeWithLoaderAction",
+ "prefix": "rtrla",
+ "body": [
+ "import { useLoaderData } from 'react-router-dom'",
+ "",
+ "async function loader({ request, params }) {",
+ " ${1:first}",
+ "}",
+ "",
+ "async function action({ request, params }) {",
+ " const formData = await request.formData()",
+ " ${2:second}",
+ "}",
+ "",
+ "function ${1:${TM_FILENAME_BASE}}() {",
+ " const data = useLoaderData()",
+ "",
+ " return (",
+ " <>${3:third}>",
+ " )",
+ "}",
+ "",
+ "export { loader, action }",
+ "export default ${1:${TM_FILENAME_BASE}}"
+ ],
+ "description": "React Router v6 route with loader and action",
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useClient": {
+ "key": "useClient",
+ "prefix": "usc",
+ "body": [
+ "'use client'",
+ ""
+ ],
+ "description": "React Client Component directive",
+ "scope": "typescript,typescriptreact,javascript,javascriptreact"
+ },
+ "useServer": {
+ "key": "useServer",
+ "prefix": "uss",
+ "body": [
+ "'use server'",
+ ""
+ ],
+ "description": "React Server Action directive",
"scope": "typescript,typescriptreact,javascript,javascriptreact"
}
-}
+}
\ No newline at end of file
diff --git a/src/sourceSnippets/components.ts b/src/sourceSnippets/components.ts
index 09ef578..62a44dd 100644
--- a/src/sourceSnippets/components.ts
+++ b/src/sourceSnippets/components.ts
@@ -30,7 +30,6 @@ type ComponentMappings = {
reactFunctionMemoComponent: 'rmc';
reactFunctionMemoComponentWithPropTypes: 'rmcp';
reactFunctionalComponentRedux: 'rfcredux';
- reactFunctionalComponentReduxPropTypes: 'rfcreduxp';
reactFunctionalComponent: 'rfc';
reactFunctionalComponentWithPropTypes: 'rfcp';
reactFunctionalExportComponent: 'rfce';
@@ -322,26 +321,6 @@ const reactFunctionalComponentRedux: ComponentsSnippet = {
'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,
@@ -359,7 +338,6 @@ export default [
reactFunctionMemoComponentWithPropTypes,
reactFunctionalComponent,
reactFunctionalComponentRedux,
- reactFunctionalComponentReduxPropTypes,
reactFunctionalComponentWithPropTypes,
reactFunctionalExportComponent,
];
diff --git a/src/sourceSnippets/hooks.ts b/src/sourceSnippets/hooks.ts
index d8a0377..8425070 100644
--- a/src/sourceSnippets/hooks.ts
+++ b/src/sourceSnippets/hooks.ts
@@ -1,15 +1,22 @@
import { Placeholders, SnippetMapping } from '../types';
type HookMappings = {
- useState: 'useStateSnippet';
+ use: 'useSnippet';
+ useActionState: 'useActionStateSnippet';
useCallback: 'useCallbackSnippet';
useContext: 'useContextSnippet';
+ useDeferredValue: 'useDeferredValueSnippet';
useEffect: 'useEffectSnippet';
+ useFormStatus: 'useFormStatusSnippet';
+ useId: 'useIdSnippet';
useImperativeHandle: 'useImperativeHandleSnippet';
useLayoutEffect: 'useLayoutEffectSnippet';
useMemo: 'useMemoSnippet';
+ useOptimistic: 'useOptimisticSnippet';
useReducer: 'useReducerSnippet';
useRef: 'useRefSnippet';
+ useState: 'useStateSnippet';
+ useTransition: 'useTransitionSnippet';
};
export type HooksSnippet = SnippetMapping;
@@ -109,14 +116,79 @@ const useLayoutEffect: HooksSnippet = {
],
};
+const useId: HooksSnippet = {
+ key: 'useId',
+ prefix: 'useIdSnippet',
+ body: [`const ${Placeholders.FirstTab} = useId()`],
+};
+
+const useTransition: HooksSnippet = {
+ key: 'useTransition',
+ prefix: 'useTransitionSnippet',
+ body: ['const [isPending, startTransition] = useTransition()'],
+};
+
+const useDeferredValue: HooksSnippet = {
+ key: 'useDeferredValue',
+ prefix: 'useDeferredValueSnippet',
+ body: [
+ `const ${Placeholders.FirstTab} = useDeferredValue(${Placeholders.SecondTab})`,
+ ],
+};
+
+const useActionState: HooksSnippet = {
+ key: 'useActionState',
+ prefix: 'useActionStateSnippet',
+ body: [
+ `const [state, submitAction, isPending] = useActionState(`,
+ ' async (previousState, formData) => {',
+ ` ${Placeholders.FirstTab}`,
+ ' },',
+ ` ${Placeholders.SecondTab},`,
+ ')',
+ ],
+};
+
+const useFormStatus: HooksSnippet = {
+ key: 'useFormStatus',
+ prefix: 'useFormStatusSnippet',
+ body: ['const { pending, data, method, action } = useFormStatus()'],
+ description: 'useFormStatus (import from react-dom)',
+};
+
+const useOptimistic: HooksSnippet = {
+ key: 'useOptimistic',
+ prefix: 'useOptimisticSnippet',
+ body: [
+ `const [optimistic${Placeholders.Capitalize}, addOptimistic] = useOptimistic(`,
+ ` ${Placeholders.FirstTab},`,
+ ` (state, newValue) => [...state, newValue],`,
+ ')',
+ ],
+};
+
+const useHook: HooksSnippet = {
+ key: 'use',
+ prefix: 'useSnippet',
+ body: [`const ${Placeholders.FirstTab} = use(${Placeholders.SecondTab})`],
+ description: 'Read a Promise or Context in render (React 19)',
+};
+
export default [
+ useHook,
+ useActionState,
useCallback,
useContext,
+ useDeferredValue,
useEffect,
+ useFormStatus,
+ useId,
useImperativeHandle,
useLayoutEffect,
useMemo,
+ useOptimistic,
useReducer,
useRef,
useState,
+ useTransition,
];
diff --git a/src/sourceSnippets/imports.ts b/src/sourceSnippets/imports.ts
index f28281b..120596b 100644
--- a/src/sourceSnippets/imports.ts
+++ b/src/sourceSnippets/imports.ts
@@ -22,8 +22,14 @@ type ImportsMappings = {
importReduxConnect: 'redux';
importRouterLink: 'imbrl';
importRouterNavLink: 'imbrnl';
+ importRouterRoutes: 'imrrs';
importRouterSetup: 'imbrc';
- importRouterSwitch: 'imbrs';
+ importCreateBrowserRouter: 'imcbr';
+ importUseLoaderData: 'imld';
+ importUseFetcher: 'imfet';
+ importUseNavigate: 'imnav';
+ importUseParams: 'impar';
+ importUseSearchParams: 'imsp';
};
export type ImportsSnippet = SnippetMapping;
@@ -115,13 +121,51 @@ const importBrowserRouterWithRouteAndNavLink: ImportsSnippet = {
const importRouterSetup: ImportsSnippet = {
key: 'importRouterSetup',
prefix: 'imbrc',
- body: ["import { Route, Switch, NavLink, Link } from 'react-router-dom'"],
+ body: ["import { Routes, Route, NavLink, Link } from 'react-router-dom'"],
};
-const importRouterSwitch: ImportsSnippet = {
- key: 'importRouterSwitch',
- prefix: 'imbrs',
- body: ["import { Switch } from 'react-router-dom'"],
+const importRouterRoutes: ImportsSnippet = {
+ key: 'importRouterRoutes',
+ prefix: 'imrrs',
+ body: ["import { Routes, Route } from 'react-router-dom'"],
+};
+
+const importUseNavigate: ImportsSnippet = {
+ key: 'importUseNavigate',
+ prefix: 'imnav',
+ body: ["import { useNavigate } from 'react-router-dom'"],
+};
+
+const importUseParams: ImportsSnippet = {
+ key: 'importUseParams',
+ prefix: 'impar',
+ body: ["import { useParams } from 'react-router-dom'"],
+};
+
+const importUseSearchParams: ImportsSnippet = {
+ key: 'importUseSearchParams',
+ prefix: 'imsp',
+ body: ["import { useSearchParams } from 'react-router-dom'"],
+};
+
+const importCreateBrowserRouter: ImportsSnippet = {
+ key: 'importCreateBrowserRouter',
+ prefix: 'imcbr',
+ body: [
+ "import { createBrowserRouter, RouterProvider } from 'react-router-dom'",
+ ],
+};
+
+const importUseLoaderData: ImportsSnippet = {
+ key: 'importUseLoaderData',
+ prefix: 'imld',
+ body: ["import { useLoaderData } from 'react-router-dom'"],
+};
+
+const importUseFetcher: ImportsSnippet = {
+ key: 'importUseFetcher',
+ prefix: 'imfet',
+ body: ["import { useFetcher } from 'react-router-dom'"],
};
const importRouterLink: ImportsSnippet = {
@@ -192,9 +236,15 @@ export default [
importReactWithMemoAndPropTypes,
importReactWithPureComponent,
importReactWithPureComponentAndPropTypes,
+ importCreateBrowserRouter,
importRouterLink,
importRouterNavLink,
+ importRouterRoutes,
importRouterSetup,
- importRouterSwitch,
importSnippet,
+ importUseFetcher,
+ importUseLoaderData,
+ importUseNavigate,
+ importUseParams,
+ importUseSearchParams,
];
diff --git a/src/sourceSnippets/others.ts b/src/sourceSnippets/others.ts
index 76bf1db..30cd186 100644
--- a/src/sourceSnippets/others.ts
+++ b/src/sourceSnippets/others.ts
@@ -41,6 +41,10 @@ type OthersMapping = {
setTimeOut: 'sto';
shouldComponentUpdate: 'scu';
typeofSnippet: 'tpf';
+ createBrowserRouterSetup: 'rtrsetup';
+ routeWithLoaderAction: 'rtrla';
+ useClient: 'usc';
+ useServer: 'uss';
};
export type OthersSnippet = SnippetMapping;
@@ -407,6 +411,77 @@ const typeofSnippet: OthersSnippet = {
body: [`typeof ${Placeholders.FirstTab}`],
};
+const createBrowserRouterSetup: OthersSnippet = {
+ key: 'createBrowserRouterSetup',
+ prefix: 'rtrsetup',
+ body: [
+ "import { createBrowserRouter, RouterProvider } from 'react-router-dom'",
+ '',
+ 'const router = createBrowserRouter([',
+ ' {',
+ ` path: '/',`,
+ ` element: <${Placeholders.FirstTab} />,`,
+ ' children: [',
+ ' {',
+ ` path: '${Placeholders.SecondTab}',`,
+ ` element: <${Placeholders.ThirdTab} />,`,
+ ' },',
+ ' ],',
+ ' },',
+ '])',
+ '',
+ 'function App() {',
+ ' return ',
+ '}',
+ '',
+ 'export default App',
+ ],
+ description: 'React Router v6 createBrowserRouter setup',
+};
+
+const routeWithLoaderAction: OthersSnippet = {
+ key: 'routeWithLoaderAction',
+ prefix: 'rtrla',
+ body: [
+ "import { useLoaderData } from 'react-router-dom'",
+ '',
+ `async function loader({ request, params }) {`,
+ ` ${Placeholders.FirstTab}`,
+ '}',
+ '',
+ `async function action({ request, params }) {`,
+ ' const formData = await request.formData()',
+ ` ${Placeholders.SecondTab}`,
+ '}',
+ '',
+ `function ${Placeholders.FileName}() {`,
+ ' const data = useLoaderData()',
+ '',
+ ' return (',
+ ` <>${Placeholders.ThirdTab}>`,
+ ' )',
+ '}',
+ '',
+ `export { loader, action }`,
+ `export default ${Placeholders.FileName}`,
+ ],
+ description: 'React Router v6 route with loader and action',
+};
+
+const useClient: OthersSnippet = {
+ key: 'useClient',
+ prefix: 'usc',
+ body: ["'use client'", ''],
+ description: 'React Client Component directive',
+};
+
+const useServer: OthersSnippet = {
+ key: 'useServer',
+ prefix: 'uss',
+ body: ["'use server'", ''],
+ description: 'React Server Action directive',
+};
+
export default [
exportDefault,
exportDestructing,
@@ -448,4 +523,8 @@ export default [
hocComponentWithRedux,
hocComponent,
typeofSnippet,
+ createBrowserRouterSetup,
+ routeWithLoaderAction,
+ useClient,
+ useServer,
];
diff --git a/src/sourceSnippets/redux.ts b/src/sourceSnippets/redux.ts
index 0315fc9..a2f9247 100644
--- a/src/sourceSnippets/redux.ts
+++ b/src/sourceSnippets/redux.ts
@@ -3,10 +3,13 @@ import { Placeholders, SnippetMapping } from '../types';
type ReduxMapping = {
importReduxConnect: 'redux';
reduxAction: 'rxaction';
+ reduxApi: 'rxapi';
+ reduxAsyncThunk: 'rxthunk';
reduxConst: 'rxconst';
reduxReducer: 'rxreducer';
reduxSelector: 'rxselect';
reduxSlice: 'rxslice';
+ reduxSliceWithExtraReducers: 'rxslicex';
mappingToProps: 'reduxmap';
};
@@ -88,6 +91,73 @@ const reduxSlice: ReduxSnippet = {
],
};
+const reduxSliceWithExtraReducers: ReduxSnippet = {
+ key: 'reduxSliceWithExtraReducers',
+ prefix: 'rxslicex',
+ body: [
+ "import { createSlice } from '@reduxjs/toolkit'",
+ '',
+ 'const initialState = {',
+ ` ${Placeholders.FirstTab}`,
+ ' status: \'idle\',',
+ '}',
+ '',
+ `const ${Placeholders.FileName} = createSlice({`,
+ ` name: '${Placeholders.SecondTab}',`,
+ ' initialState,',
+ ' reducers: {},',
+ ' extraReducers: (builder) => {',
+ ' builder',
+ ` .addCase(${Placeholders.ThirdTab}.pending, (state) => {`,
+ " state.status = 'loading'",
+ ' })',
+ ` .addCase(${Placeholders.ThirdTab}.fulfilled, (state, action) => {`,
+ " state.status = 'succeeded'",
+ ' })',
+ ` .addCase(${Placeholders.ThirdTab}.rejected, (state) => {`,
+ " state.status = 'failed'",
+ ' })',
+ ' },',
+ '})',
+ '',
+ `export const {} = ${Placeholders.FileName}.actions`,
+ '',
+ `export default ${Placeholders.FileName}.reducer`,
+ ],
+};
+
+const reduxAsyncThunk: ReduxSnippet = {
+ key: 'reduxAsyncThunk',
+ prefix: 'rxthunk',
+ body: [
+ "import { createAsyncThunk } from '@reduxjs/toolkit'",
+ '',
+ `export const ${Placeholders.FirstTab} = createAsyncThunk('${Placeholders.SecondTab}', async () => {`,
+ ` ${Placeholders.ThirdTab}`,
+ '})',
+ ],
+};
+
+const reduxApi: ReduxSnippet = {
+ key: 'reduxApi',
+ prefix: 'rxapi',
+ body: [
+ "import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'",
+ '',
+ `export const ${Placeholders.FirstTab}Api = createApi({`,
+ ` reducerPath: '${Placeholders.FirstTab}Api',`,
+ ` baseQuery: fetchBaseQuery({ baseUrl: '${Placeholders.SecondTab}' }),`,
+ ' endpoints: (builder) => ({',
+ ` ${Placeholders.ThirdTab}: builder.query({`,
+ " query: () => '/',",
+ ' }),',
+ ' }),',
+ '})',
+ '',
+ `export const { } = ${Placeholders.FirstTab}Api`,
+ ],
+};
+
const mappingToProps: ReduxSnippet = {
key: 'mappingToProps',
prefix: 'reduxmap',
@@ -101,9 +171,12 @@ const mappingToProps: ReduxSnippet = {
export default [
importReduxConnect,
reduxAction,
+ reduxApi,
+ reduxAsyncThunk,
reduxConst,
reduxReducer,
reduxSelector,
reduxSlice,
+ reduxSliceWithExtraReducers,
mappingToProps,
];
diff --git a/src/sourceSnippets/sharedSnippets.ts b/src/sourceSnippets/sharedSnippets.ts
index 6a199ac..3cb5a4a 100644
--- a/src/sourceSnippets/sharedSnippets.ts
+++ b/src/sourceSnippets/sharedSnippets.ts
@@ -33,14 +33,14 @@ export const reduxComponentExport = [
export const innerComponent = [
' return (',
- ` ${Placeholders.FirstTab}
`,
+ ` <>${Placeholders.FirstTab}>`,
' )',
];
export const innerComponentReturn = [
' render() {',
' return (',
- ` ${Placeholders.FirstTab}
`,
+ ` <>${Placeholders.FirstTab}>`,
' )',
' }',
];
diff --git a/src/sourceSnippets/typescript.ts b/src/sourceSnippets/typescript.ts
index d024a0c..5cc9c1d 100644
--- a/src/sourceSnippets/typescript.ts
+++ b/src/sourceSnippets/typescript.ts
@@ -133,7 +133,7 @@ const typescriptReactArrowFunctionComponent: TypescriptSnippet = {
...react,
'',
...propsTypeInterface,
- `const ${Placeholders.FileName} = (props: Props) => {`,
+ `export const ${Placeholders.FileName} = (props: Props) => {`,
...innerComponent,
'}',
],