Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mlaursen/vim-react-snippets
Useful snippets for developing in React (Javascript and Typescript)
https://github.com/mlaursen/vim-react-snippets
javascript proptypes react snippets typescript
Last synced: about 1 month ago
JSON representation
Useful snippets for developing in React (Javascript and Typescript)
- Host: GitHub
- URL: https://github.com/mlaursen/vim-react-snippets
- Owner: mlaursen
- License: apache-2.0
- Created: 2015-05-30T17:36:41.000Z (over 9 years ago)
- Default Branch: main
- Last Pushed: 2024-04-26T13:30:59.000Z (5 months ago)
- Last Synced: 2024-05-22T11:35:08.533Z (4 months ago)
- Topics: javascript, proptypes, react, snippets, typescript
- Language: Lua
- Homepage:
- Size: 445 KB
- Stars: 231
- Watchers: 5
- Forks: 21
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# vim-react-snippets
A collection of common Javascript and Typescript vim snippets for developing
[React] applications. The snippets within this repo rely on [LuaSnip] or
[UltiSnips] as the snippet provider.## Typescript Example
https://user-images.githubusercontent.com/3920850/167317421-45035822-9ced-40ec-8d85-9b3db5d42651.mov
## Previewing Snippets with [coc-snippets](https://github.com/neoclide/coc-snippets)
https://user-images.githubusercontent.com/3920850/167317372-6165c118-99da-4a31-88e6-57b6c7086ed5.mov
## Using Log Helpers
https://user-images.githubusercontent.com/3920850/167317795-63e74576-f0e6-4787-817f-b699e88d10e7.mov
## Writing Tests
https://user-images.githubusercontent.com/3920850/167318157-70692488-b126-47b2-9eab-ee3dc79771e9.mov
## Installation
With [lazy.nvim] and [LuaSnip]:
```diff
{
"hrsh7th/nvim-cmp",
dependencies = {
"L3MON4D3/LuaSnip",
"saadparwaiz1/cmp_luasnip",
+ "mlaursen/vim-react-snippets",
},
---@param opts cmp.ConfigSchema
opts = function()
vim.api.nvim_set_hl(0, "CmpGhostText", { link = "Comment", default = true })
+ require("vim-react-snippets").lazy_load()
local cmp = require("cmp")
local luasnip = require("luasnip")
local compare = cmp.config.compare
``````vim
call plug#begin('~/.vim/plugged')
Plug 'SirVer/ultisnips'
Plug 'mlaursen/vim-react-snippets'
call plug#end()
```> NOTE: I no longer use UltiSnips so the snippets might be different. Check out
> the [UltiSnips folder] to see available snippets.## Cheatsheet
Most of the available snippets will be listed below to showcase the generated
code. Tabstops will be indicated with `$TABSTOP` or `$NAME` where `$NAME` is
replaceable. `$CFN` or `$CFN_` will indicate a snippet that uses the current
file name to generate the code.Some snippets support an "inline" version as where the `const whatever = ` will
be omitted. These snippets will be marked with ✨.> Javascript snippets are not shown since I really only use Typescript now, but
> they are generally the same without the type definitions included.## Table of Contents
- [Function Components](#function-components)
- [Function Component Export](#function-component-export)
- [Function Component Default Export](#function-component-default-export)
- [Simple Function Component Export](#simple-function-component-export)
- [Simple Function Component Default Export](#simple-function-component-default-export)
- [Forwarded Function Component Export](#forwarded-function-component-export)
- [Forwarded Function Component Default Export](#forwarded-function-component-default-export)
- [Hooks and Effects](#hooks-and-effects)
- [useState](#usestate)
- [useReducer](#usereducer)
- [useEffect](#useeffect)
- [useContext ✨](#usecontext-)
- [useCallback ✨](#usecallback-)
- [useMemo ✨](#usememo-)
- [useMemo return (manual return required) ✨](#usememo-return-manual-return-required-)
- [useRef ✨](#useref-)
- [Create Context Provider](#create-context-provider)
- [Redux](#redux)
- [useAppDispatch ✨](#useappdispatch-)
- [useSelector ✨](#useselector-)
- [useAppSelector ✨](#useappselector-)
- [Common](#common)
- [Destructured Const](#destructured-const)
- [Export Destructured Const](#export-destructured-const)
- [if](#if)
- [else](#else)
- [switch](#switch)
- [for loop](#for-loop)
- [reduce](#reduce)
- [noop](#noop)
- [interface](#interface)
- [JSDoc/TSDoc](#jsdoctsdoc)
- [Block Comment](#block-comment)
- [@example](#example)
- [@defaultValue](#defaultvalue)
- [@since](#since)
- [Logging](#logging)
- [Importing](#importing)
- [Exporting](#exporting)
- [NODE_ENV](#node_env)
- [Tests](#tests)
- [Describe a test](#describe-a-test)
- [it should...](#it-should)
- [it should (async)...](#it-should-async)
- [Test Expect](#test-expect)
- [Test Queries ✨](#test-queries-)
- [React Testing](#react-testing)
- [React Test File](#react-test-file)
- [React Test File (ESM)](#react-test-file-esm)
- [Global Test File](#global-test-file)
- [Global Test File (ESM)](#global-test-file-esm)
- [User Event Test](#user-event-test)
- [waitFor](#waitfor)* [SCSS Snippets](#scss-snippets)
* [Contributing](#contributing)
- [LuaSnip Template](#luasnip-template)### Function Components
#### Function Component Export
`fce` ->
```tsx
import { type ReactElement, type ReactNode } from "react"export interface $CFN_Props {
$TABSTOP
children: ReactNode
}export function $CFN(props: $CFN_Props): ReactElement {
return <>>
}
```#### Function Component Default Export
`fcde` ->
```tsx
import { type ReactElement, type ReactNode } from "react"export interface $CFN_Props {
$TABSTOP
children: ReactNode
}export default function $CFN(props: $CFN_Props): ReactElement {
return <>>
}
```#### Simple Function Component Export
`sfce` ->
```tsx
import { type ReactElement } from "react"export function $CFN(): ReactElement {
return <>>
}
```#### Simple Function Component Default Export
`sfcde` ->
```tsx
import { type ReactElement } from "react"export default function $CFN(): ReactElement {
return <>>
}
```#### Forwarded Function Component Export
`ffce` ->
```tsx
import { forwardRef, type ReactNode } from "react"export interface $CFNProps {
$TABSTOP
children: ReactNode
}export const $CFN = forwardRef(
function $CFN(props, ref) {
return
}
)
```#### Forwarded Function Component Default Export
`ffcde` ->
```tsx
import { forwardRef, type ReactNode } from "react"export interface $CFNProps {
$TABSTOP
children: ReactNode
}export default forwardRef(
function $CFN(props, ref) {
return
}
)
```### Hooks and Effects
#### useState
`useS` ->
```ts
const [$STATE, set$STATE] = useState$TABSTOP($TABSTOP)
```#### useReducer
`useRed` ->
```tsx
const [$STATE, $DISPATCH] = useReducer(function reducer(state: $STATE, action: $ACTION): $STATE {
switch (action.type):
default:
return state
}, $INITIAL_STATE)
```#### useEffect
`useE` ->
```ts
useEffect(() => {
$TABSTOP
}, [])
```#### useContext ✨
`useC` ->
```ts
const context = useContext($TABSTOP)
```#### useCallback ✨
`useCB` ->
```ts
const $CALLBACK = useCallback(($TABSTOP) => {
$TABSTOP
}, [])
```#### useMemo ✨
`useM` ->
```ts
const $MEMOIZED = useMemo(() => ({
$TABSTOP
}), [])
```#### useMemo return (manual return required) ✨
`useMR` ->
```ts
const $MEMOIZED = useMemo(() => {
$TABSTOP
}, [])
```#### useRef ✨
`useR` ->
```ts
const $REF = useRef$TABSTOP(TABSTOP)
```#### Create Context Provider
`ccp` ->
```tsx
import { createContext, useContext } from "react"export interface $CFN_Context {}
const context = createContext<$CFN_Context | null>(null)
const { Provider } = contextexport function use$CFN_Context(): $CFN_Context {
const value = useContext(context)
if (!value) {
throw new Error("$CFN_Context must be initialized.")
}return value
}
```### Redux
#### useAppDispatch ✨
`useD` ->
```ts
const dispatch = useAppDispatch()
```#### useSelector ✨
`useSL` ->
```ts
const $VALUE = useSelector(($STATE: AppState) => $SELECTOR)
```#### useAppSelector ✨
`useAS` ->
```ts
const $VALUE = useAppSelector(($STATE) => $SELECTOR)
```### Common
#### Destructured Const
`dc` ->
```ts
const { $TABSTOP } = $PROPS
``````ts
dcuseSomeHook()
^ trigger completion hereconst { $TABSTOP } = useSomeHook()
```#### Export Destructured Const
`edc` ->
```ts
const { $TABSTOP } = $PROPS
```#### if
`if` ->
```ts
if ($CONDITION) {
$TABSTOP
}
```#### else
`else` ->
```ts
else $TABSTOP{
$TABSTOP
}
```The `if` snippet can be triggered from the first tabstop to generate:
```ts
else if{
$TABSTOP
}
```into:
```ts
else if ($CONDITION) {
$TABSTOP
}
```#### switch
`switch` ->
```ts
switch ($KEY) {
case $VALUE:
$TABSTOP
break
default:
$TABSTOP
}
```#### for loop
`for` ->
```ts
for (let $I = $0, $I < $LIST.length; $I++) {
const $ITEM = $LIST[$I]
$TABSTOP
}
```#### reduce
`reduce` ->
```ts
const $VALUE = $LIST.reduce<$TYPE_DEF>(($result, $item) => {
$TABSTOP
return $RESULT
}, $INITIAL)
```#### noop
`noop` ->
```ts
const noop = (): void => {
// do nothing
}
```#### interface
`intf` ->
```ts
export interface $CFN_$TABSTOP {
$TABSTOP
}
```### JSDoc/TSDoc
#### Block Comment
`/**` ->
```ts
/**
* $TABSTOP
*/
```#### @example
`@e` ->
```ts
@example $EXAMPLE_NAME
\`\`\`$TSX
$TABSTOP
\`\`\`
```#### @defaultValue
`@d` ->
```ts
@defaultValue \`$TABSTOP\`
```#### @since
`@s` ->
```ts
@since $MAJOR.$MINOR.$PATCH
```### Logging
| Shortcut | Nane | Expands to |
| -------- | ---------------------- | --------------------------------------- |
| `cl` | Console Log | `console.log($TABSTOP)` |
| `clv` | Console Log Variable | `console.log("$TABSTOP: ", $TABSTOP)` |
| `ce` | Console Error | `console.error($TABSTOP)` |
| `cev` | Console Error Variable | `console.error("$TABSTOP: ", $TABSTOP)` |
| `cw` | Console Warn | `console.warn($TABSTOP)` |
| `cwv` | Console Warn Variable | `console.warn("$TABSTOP: ", $TABSTOP)` |
| `ct` | Console Table | `console.table($TABSTOP)` |
| `cd` | Console Debug | `console.debug($TABSTOP)` |
| `cdv` | Console Debug Variable | `console.debug("$TABSTOP: ", $TABSTOP)` |> Note: The logging commands that end in a `v` will have the cursor at the
> second `$TABSTOP` instead of the first so that autocompletion will work.### Importing
| Shortcut | Name | Expands to |
| -------- | -------------------- | ------------------------------------------------ |
| `imp` | Import | `import packageName from "package-name"` |
| `impf` | Import File | `import File from "./File"` |
| `impd` | Import Destructured | `import { destructured } from "package-or/path"` |
| `impp` | Import (Please?) | `import "./file"` |
| `icn` | Import Classnames | `import cn from "classnames"` |
| `icnb` | Import Cnbuilder | `import { cnb } from "cnbuilder"` |
| `ism` | Import Styles Module | `import styles from "./$CFN.module.scss"` |### Exporting
| Shortcut | Name | Expands to |
| -------- | ------------------- | --------------------------------------- |
| `exp` | Export | `export { default } from "./$CFN"` |
| `expf` | Export File | `export $TABSTOP from "./$TABSTOP"` |
| `expd` | Export Destructured | `export { $TABSTOP } from "./$TABSTOP"` |
| `expa` | Export All | `export * from "$TABSTOP"` |### NODE_ENV
| Shortcut | Expands to |
| -------- | --------------------------------------- |
| `dev` | `process.env.NODE_ENV !== "production"` |
| `prod` | `process.env.NODE_ENV === "production"` |### Tests
#### Describe a test
`desc` ->
```ts
describe('$CFN', () => {
it('should $TABSTOP', () => {
$TABSTOP
)}
})
```#### it should...
`it` ->
```ts
it("should $TABSTOP", () => {
$TABSTOP
})
```#### it should (async)...
`ita` ->
```ts
it("should $TABSTOP", async () => {
$TABSTOP
})
```#### Test Expect
| Shortcut | Name | Expands to |
| -------- | ------------------- | -------------------------------------------------- |
| `es` | Expect Snapshot | `expect(${container}).toMatchSnapshot()` |
| `ett` | Expect To Throw | `expect(() => $TABSTOP).toThrow()` |
| `entt` | Expect Not To Throw | `expect(() => $TABSTOP).not.toThrow()` |
| `enc` | Expect Not Called | `expect($TABSTOP).not.toHaveBeenCalled()` |
| `ecw` | Expect Called With | `expect($TABSTOP).toHaveBeenCalledWith($TABSTOP)` |
| `ect` | Expect Called Times | `expect($TABSTOP).toHaveBeenCalledTimes($TABSTOP)` |#### Test Queries ✨
| Shortcut | Name | Expands to |
| -------- | ----------------------------- | ----------------------------------------------------------------------------- |
| `sgbr` | Screen Get By Role | `const $TABSTOP = screen.getByRole("${button}", { name: "$TABSTOP" })` |
| `sgbru` | Screen Get By Role (Unnamed) | `const $TABSTOP = screen.getByRole("${progressbar}")` |
| `sgbi` | Screen Get By testId | `const $TABSTOP = screen.getByTestId("$TABSTOP")` |
| `sgbt` | Screen Get By Text | `const $TABSTOP = screen.getByText("$TABSTOP")` |
| `sfbr` | Screen Find By Role | `const $TABSTOP = await screen.findByRole("${button}", { name: "$TABSTOP" })` |
| `sfbru` | Screen Find By Role (Unnamed) | `const $TABSTOP = await screen.findByRole("${progressbar}")` |
| `fbi` | Screen Find By testId | `const $TABSTOP = await screen.findByTestId("$TABSTOP")` |
| `fbt` | Screen Find By Text | `const $TABSTOP = await screen.findByText("$TABSTOP")` |
| `gbr` | Get By Role | `const $TABSTOP = getByRole("${button}", { name: "$TABSTOP" })` |
| `gbru` | Get By Role (Unnamed) | `const $TABSTOP = getByRole("${progressbar}")` |
| `gbi` | Get By testId | `const $TABSTOP = getByTestId("$TABSTOP")` |
| `gbt` | Get By Text | `const $TABSTOP = getByText("$TABSTOP")` |
| `fbr` | Find By Role | `const $TABSTOP = await findByRole("${button}", { name: "$TABSTOP" })` |
| `fbru` | Find By Role (Unnamed) | `const $TABSTOP = await findByRole("${progressbar}")` |
| `fbi` | Find By testId | `const $TABSTOP = await findByTestId("$TABSTOP")` |
| `fbt` | Find By Text | `const $TABSTOP = await findByText("$TABSTOP")` |### React Testing
#### React Test File
`rtf` ->
```tsx
import { render, screen, userEvent } from "${@testing-library/react}"import { $CFN } from "../$CFN"
describe("$CFN", () => {
it("should $TABSTOP", () => {
$TABSTOP
})
})
```#### React Test File (ESM)
`rtfe` ->
```tsx
import { render, screen, userEvent } from "${@testing-library/react}"import { $CFN } from "../$CFN.js"
describe("$CFN", () => {
it("should $TABSTOP", () => {
$TABSTOP
})
})
```#### Global Test File
`gtf` ->
```tsx
import { describe, expect, it } from "${@jest/globals}"
import { render, screen, userEvent } from "${@testing-library/react}"import { $CFN } from "../$CFN"
describe("$CFN", () => {
it("should $TABSTOP", () => {
$TABSTOP
})
})
```#### Global Test File (ESM)
`gtfe` ->
```tsx
import { describe, expect, it } from "${@jest/globals}"
import { render, screen, userEvent } from "${@testing-library/react}"import { $CFN } from "../$CFN.js"
describe("$CFN", () => {
it("should $TABSTOP", () => {
$TABSTOP
})
})
```#### User Event Test
`uet` ->
```tsx
it("should $TABSTOP", async () => {
const user = userEvent.setup()
$TABSTOPexpect(true).toBe(true)
})
```#### waitFor
`wf` ->
```tsx
await waitFor(() => {
$TABSTOP
})
```## SCSS Snippets
| Shortcut | Name | Expands to |
| -------- | ------- | -------------------------------------- |
| `use` | Use | `@use "$TABSTOP";` |
| `use*` | Use \* | `@use "$TABSTOP" as *;` |
| `forw` | Forward | `@forward "$TABSTOP" with ($TABSTOP);` |## Contributing
### LuaSnip Template
```lua
local ls = require("luasnip")
local s = ls.snippet
local sn = ls.snippet_node
local isn = ls.indent_snippet_node
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local r = ls.restore_node
local events = require("luasnip.util.events")
local ai = require("luasnip.nodes.absolute_indexer")
local extras = require("luasnip.extras")
local l = extras.lambda
local rep = extras.rep
local p = extras.partial
local m = extras.match
local n = extras.nonempty
local dl = extras.dynamic_lambda
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local conds = require("luasnip.extras.expand_conditions")
local postfix = require("luasnip.extras.postfix").postfix
local types = require("luasnip.util.types")
local parse = require("luasnip.util.parser").parse_snippet
local ms = ls.multi_snippet
local k = require("luasnip.nodes.key_indexer").new_key
```[react]: https://reactjs.org/
[ultisnips]: https://github.com/SirVer/ultisnips
[ultisnips folder]:
https://github.com/mlaursen/vim-react-snippets/tree/main/UltiSnips
[luasnip]: https://github.com/L3MON4D3/LuaSnip
[lazy.nvim]: https://github.com/folke/lazy.nvim