385 lines
10 KiB
JSON
385 lines
10 KiB
JSON
{
|
|
"WRN page": {
|
|
"prefix": ["wrn-page", "page"],
|
|
"description": "Create a WRN page",
|
|
"body": [
|
|
"page ${1:PageName} {",
|
|
" layout = \"${2:default}\"",
|
|
"",
|
|
" seo {",
|
|
" title = \"${3:Page title}\"",
|
|
" description = \"${4:Page description}\"",
|
|
" }",
|
|
"",
|
|
" view {",
|
|
" <main>",
|
|
" <h1>${5:Page heading}</h1>",
|
|
" </main>",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN dynamic page": {
|
|
"prefix": ["wrn-dynamic-page", "dynamic-page"],
|
|
"description": "Create a WRN page using a route parameter",
|
|
"body": [
|
|
"page ${1:DynamicPage} {",
|
|
" layout = \"${2:default}\"",
|
|
"",
|
|
" state ${3:id} = ctx.params.${3:id}",
|
|
"",
|
|
" view {",
|
|
" <main>",
|
|
" <h1>{${3:id}}</h1>",
|
|
" </main>",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN component": {
|
|
"prefix": ["wrn-component", "component"],
|
|
"description": "Create a reusable WRN component",
|
|
"body": [
|
|
"component ${1:ComponentName} {",
|
|
" props {",
|
|
" ${2:title} = \"${3:Title}\"",
|
|
" }",
|
|
"",
|
|
" state ${4:ready} = false",
|
|
"",
|
|
" view {",
|
|
" <div>",
|
|
" <h2>{${2:title}}</h2>",
|
|
" </div>",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN reactive component": {
|
|
"prefix": ["wrn-reactive-component", "reactive-component"],
|
|
"description": "Create a component with functions, lifecycle hooks, and a watcher",
|
|
"body": [
|
|
"component ${1:ComponentName} {",
|
|
" state ${2:active} = false",
|
|
"",
|
|
" functions {",
|
|
" function ${3:updateState}() {",
|
|
" ${2:active} = true",
|
|
" }",
|
|
" }",
|
|
"",
|
|
" lifecycle {",
|
|
" mount {",
|
|
" ${3:updateState}()",
|
|
" }",
|
|
"",
|
|
" unmount {",
|
|
" $0",
|
|
" }",
|
|
" }",
|
|
"",
|
|
" watch ${2:active} {",
|
|
" console.log(value, previous)",
|
|
" }",
|
|
"",
|
|
" view {",
|
|
" <div>{${2:active}}</div>",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN layout": {
|
|
"prefix": ["wrn-layout", "layout"],
|
|
"description": "Create a reusable WRN layout",
|
|
"body": [
|
|
"layout ${1:LayoutName} {",
|
|
" view {",
|
|
" <main>",
|
|
" {content}",
|
|
" </main>",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN state": {
|
|
"prefix": ["wrn-state", "state"],
|
|
"description": "Create reactive state",
|
|
"body": ["state ${1:name} = ${2:\"value\"}"]
|
|
},
|
|
|
|
"WRN functions block": {
|
|
"prefix": ["wrn-functions", "functions"],
|
|
"description": "Create a browser-side functions block",
|
|
"body": ["functions {", " function ${1:handler}(${2}) {", " $0", " }", "}"]
|
|
},
|
|
|
|
"WRN function": {
|
|
"prefix": ["wrn-function", "function"],
|
|
"description": "Create a function inside a functions block",
|
|
"body": ["function ${1:name}(${2}) {", " $0", "}"]
|
|
},
|
|
|
|
"WRN async function": {
|
|
"prefix": ["wrn-async-function", "async-function"],
|
|
"description": "Create an asynchronous component function",
|
|
"body": ["async function ${1:name}(${2}) {", " $0", "}"]
|
|
},
|
|
|
|
"WRN lifecycle": {
|
|
"prefix": ["wrn-lifecycle", "lifecycle"],
|
|
"description": "Create mount, update, and unmount lifecycle hooks",
|
|
"body": [
|
|
"lifecycle {",
|
|
" mount {",
|
|
" ${1}",
|
|
" }",
|
|
"",
|
|
" update {",
|
|
" ${2}",
|
|
" }",
|
|
"",
|
|
" unmount {",
|
|
" $0",
|
|
" }",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN mount hook": {
|
|
"prefix": ["wrn-mount", "mount"],
|
|
"description": "Create a component mount lifecycle hook",
|
|
"body": ["mount {", " $0", "}"]
|
|
},
|
|
|
|
"WRN update hook": {
|
|
"prefix": ["wrn-update", "update-hook"],
|
|
"description": "Create a batched component update lifecycle hook",
|
|
"body": ["update {", " $0", "}"]
|
|
},
|
|
|
|
"WRN unmount hook": {
|
|
"prefix": ["wrn-unmount", "unmount"],
|
|
"description": "Create a component unmount lifecycle hook",
|
|
"body": ["unmount {", " $0", "}"]
|
|
},
|
|
|
|
"WRN watcher": {
|
|
"prefix": ["wrn-watch", "watch"],
|
|
"description": "Watch a declared state value",
|
|
"body": ["watch ${1:stateName} {", " console.log(value, previous)", " $0", "}"]
|
|
},
|
|
|
|
"WRN watcher with condition": {
|
|
"prefix": ["wrn-watch-if", "watch-if"],
|
|
"description": "Watch state and react to a specific value",
|
|
"body": ["watch ${1:stateName} {", " if (value === ${2:true}) {", " $0", " }", "}"]
|
|
},
|
|
|
|
"WRN SEO block": {
|
|
"prefix": ["wrn-seo", "seo"],
|
|
"description": "Create SEO metadata",
|
|
"body": [
|
|
"seo {",
|
|
" title = \"${1:Page title}\"",
|
|
" description = \"${2:Page description}\"",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN form": {
|
|
"prefix": ["wrn-form", "form"],
|
|
"description": "Create a POST form",
|
|
"body": [
|
|
"<form",
|
|
" method=\"post\"",
|
|
" action=\"${1:/api/action}\"",
|
|
">",
|
|
" ${2}",
|
|
"",
|
|
" <button type=\"submit\">",
|
|
" ${3:Submit}",
|
|
" </button>",
|
|
"</form>"
|
|
]
|
|
},
|
|
|
|
"WRN input": {
|
|
"prefix": ["wrn-input", "input"],
|
|
"description": "Create a labeled input",
|
|
"body": [
|
|
"<label>",
|
|
" <span>${1:Label}</span>",
|
|
"",
|
|
" <input",
|
|
" type=\"${2|text,email,password,tel,url,number,date|}\"",
|
|
" name=\"${3:name}\"",
|
|
" value=\"${4}\"",
|
|
" ${5:required}",
|
|
" />",
|
|
"</label>"
|
|
]
|
|
},
|
|
|
|
"WRN conditional class": {
|
|
"prefix": ["wrn-class-if", "class-if"],
|
|
"description": "Add a conditional class directive",
|
|
"body": ["class:${1:border-indigo-500}=\"${2:condition}\""]
|
|
},
|
|
|
|
"WRN conditional class pair": {
|
|
"prefix": ["wrn-class-toggle", "class-toggle"],
|
|
"description": "Toggle two classes from one condition",
|
|
"body": ["class:${1:opacity-100}=\"${3:visible}\"", "class:${2:opacity-0}=\"!${3:visible}\""]
|
|
},
|
|
|
|
"WRN click event": {
|
|
"prefix": ["wrn-click", "click"],
|
|
"description": "Add a click event handler",
|
|
"body": ["@click=\"${1:handler()}\""]
|
|
},
|
|
|
|
"WRN window scroll event": {
|
|
"prefix": ["wrn-window-scroll", "window-scroll"],
|
|
"description": "Add a window scroll event handler",
|
|
"body": ["@window:scroll=\"${1:handler()}\""]
|
|
},
|
|
|
|
"WRN window resize event": {
|
|
"prefix": ["wrn-window-resize", "window-resize"],
|
|
"description": "Add a window resize event handler",
|
|
"body": ["@window:resize=\"${1:handler()}\""]
|
|
},
|
|
|
|
"WRN document event": {
|
|
"prefix": ["wrn-document-event", "document-event"],
|
|
"description": "Add a document-level event handler",
|
|
"body": ["@document:${1:click}=\"${2:handler()}\""]
|
|
},
|
|
|
|
"WRN show directive": {
|
|
"prefix": ["wrn-show", "show"],
|
|
"description": "Conditionally show an element",
|
|
"body": ["data-show=\"${1:condition}\""]
|
|
},
|
|
|
|
"WRN loop": {
|
|
"prefix": ["wrn-for", "for"],
|
|
"description": "Create a reactive list loop",
|
|
"body": ["<div data-for=\"${1:item} in ${2:items}\">", " <span>{${1:item}}</span>", "</div>"]
|
|
},
|
|
|
|
"WRN dynamic link": {
|
|
"prefix": ["wrn-route-link", "route-link"],
|
|
"description": "Create a link using route state",
|
|
"body": ["<a href=\"/${1:resource}/{${2:id}}\">", " ${3:Open}", "</a>"]
|
|
},
|
|
|
|
"WRN API GET": {
|
|
"prefix": ["wrn-api-get", "api-get"],
|
|
"description": "Create a GET API route",
|
|
"body": [
|
|
"api GET ${1:/api/resource} {",
|
|
" return Response.json({",
|
|
" ${2:success}: true",
|
|
" })",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN API POST": {
|
|
"prefix": ["wrn-api-post", "api-post"],
|
|
"description": "Create a POST API route",
|
|
"body": [
|
|
"api POST ${1:/api/resource} {",
|
|
" const body = await ctx.request.json()",
|
|
"",
|
|
" return Response.json({",
|
|
" success: true,",
|
|
" data: body",
|
|
" })",
|
|
"}"
|
|
]
|
|
},
|
|
|
|
"WRN loading state": {
|
|
"prefix": ["wrn-loading", "loading-state"],
|
|
"description": "Create loading state and a reactive button",
|
|
"body": [
|
|
"state loading = false",
|
|
"",
|
|
"<button",
|
|
" type=\"submit\"",
|
|
" class:opacity-50=\"loading\"",
|
|
" class:cursor-not-allowed=\"loading\"",
|
|
" disabled=\"{loading}\"",
|
|
">",
|
|
" {loading ? \"Loading...\" : \"${1:Submit}\"}",
|
|
"</button>"
|
|
]
|
|
},
|
|
|
|
"WRN BackToTop component": {
|
|
"prefix": ["wrn-back-to-top", "back-to-top"],
|
|
"description": "Create an optimized BackToTop component using lifecycle cleanup",
|
|
"body": [
|
|
"component BackToTop {",
|
|
" state visible = false",
|
|
"",
|
|
" functions {",
|
|
" function updateBackToTopVisibility() {",
|
|
" visible = window.scrollY > ${1:500}",
|
|
" }",
|
|
"",
|
|
" function scrollToTop() {",
|
|
" window.scrollTo({",
|
|
" top: 0,",
|
|
" behavior: \"smooth\"",
|
|
" })",
|
|
" }",
|
|
" }",
|
|
"",
|
|
" lifecycle {",
|
|
" mount {",
|
|
" updateBackToTopVisibility()",
|
|
"",
|
|
" window.addEventListener(",
|
|
" \"scroll\",",
|
|
" updateBackToTopVisibility,",
|
|
" { passive: true }",
|
|
" )",
|
|
" }",
|
|
"",
|
|
" unmount {",
|
|
" window.removeEventListener(",
|
|
" \"scroll\",",
|
|
" updateBackToTopVisibility",
|
|
" )",
|
|
" }",
|
|
" }",
|
|
"",
|
|
" view {",
|
|
" <button",
|
|
" type=\"button\"",
|
|
" @click=\"scrollToTop()\"",
|
|
" aria-label=\"Back to top\"",
|
|
" class=\"fixed bottom-5 right-5\"",
|
|
" class:pointer-events-none=\"!visible\"",
|
|
" class:translate-y-4=\"!visible\"",
|
|
" class:opacity-0=\"!visible\"",
|
|
" class:pointer-events-auto=\"visible\"",
|
|
" class:translate-y-0=\"visible\"",
|
|
" class:opacity-100=\"visible\"",
|
|
" >",
|
|
" ${2:Back to top}",
|
|
" </button>",
|
|
" }",
|
|
"}"
|
|
]
|
|
}
|
|
}
|