Skip to content

Commit

Permalink
Merge pull request #5 from juntossomosmais/feat/vuetify-wrapper
Browse files Browse the repository at this point in the history
feat(Vuetify): creating vuetify wrapper generator
  • Loading branch information
schirrel authored Mar 31, 2022
2 parents 6df4288 + 355ac17 commit b2e7fff
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 18 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.4.0] - 2022-03-31

### Added
- Create Vuetify wrapper Option
## [0.3.0] - 2022-03-30

### Added
Expand Down Expand Up @@ -40,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Creating extensions

[unreleased]: https://github.com/juntossomosmais/jsm-component-generator/compare/.3.0...HEAD
[unreleased]: https://github.com/juntossomosmais/jsm-component-generator/compare/0.4.0...HEAD
[0.4.0]: https://github.com/juntossomosmais/jsm-component-generator/releases/tag/0.4.0
[0.3.0]: https://github.com/juntossomosmais/jsm-component-generator/releases/tag/0.3.0
[0.2.2]: https://github.com/juntossomosmais/jsm-component-generator/releases/tag/0.2.2
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "JS+ Generator",
"description": "Create components folder and files with JS+ style",
"license": "Apache-2.0",
"version": "0.3.0",
"version": "0.4.0",
"publisher": "juntossomosmais",
"icon": "resource/logo.png",
"repository": {
Expand All @@ -23,6 +23,7 @@
],
"activationEvents": [
"onCommand:jsm-generator.generateVue",
"onCommand:jsm-generator.generateVuetify",
"onCommand:jsm-generator.generateReact",
"onCommand:jsm-generator.generateReactJS"
],
Expand All @@ -33,6 +34,10 @@
"command": "jsm-generator.generateVue",
"title": "JS+ Generator: Generate Vue Component"
},
{
"command": "jsm-generator.generateVuetify",
"title": "JS+ Generator: Generate Vuetify Wrapper Component"
},
{
"command": "jsm-generator.generateReact",
"title": "JS+ Generator: Generate React Component"
Expand All @@ -49,6 +54,11 @@
"command": "jsm-generator.generateVue",
"title": "JS+ Generator: Vue Component"
},
{
"group": "JS+ Generator",
"command": "jsm-generator.generateVuetify",
"title": "JS+ Generator: Generate Vuetify Wrapper Component"
},
{
"group": "JS+ Generator",
"command": "jsm-generator.generateReact",
Expand Down
4 changes: 3 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# JS+ Generator
A VSCode extension to generate components as the way we do at Juntos Somos Mais

### Options
### Available Options

- JS+ Generator: Vue Component
- JS+ Generator: Vuetify Component
- Use only the name of Vuetify component in PascalCase without the initial V
- JS+ Generator: Generate React Component
- JS+ Generator: Generate React Component with JavaScript

Expand Down
2 changes: 1 addition & 1 deletion src/builders/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { createVueComponent } from './vue'
export { createVueComponent, createVuetifyComponent } from './vue'
export { createReactComponent } from './react'
49 changes: 39 additions & 10 deletions src/builders/vue/createFiles.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,59 @@
import { workspace, Uri } from 'vscode'

import { TEMPLATES } from './templates'
import { TEMPLATES, VueTemplates } from './templates'
import { VUETIFY_TEMPLATES } from './vuetify/templates'

export function createVue(
storePath: string,
name: string,
templateFactory?: (name: string) => VueTemplates
) {
const TEMPLATE = templateFactory || TEMPLATES

export function createVue(storePath: string, name: string) {
workspace.fs.writeFile(
Uri.file(`${storePath}/${name}.vue`),
Buffer.from(TEMPLATES(name).vue)
Buffer.from(TEMPLATE(name).vue)
)
}

export function createScss(storePath: string, name: string) {
export function createScss(
storePath: string,
name: string,
templateFactory?: (name: string) => VueTemplates
) {
const TEMPLATE = templateFactory || TEMPLATES

workspace.fs.writeFile(
Uri.file(`${storePath}/${name}.scss`),
Buffer.from(TEMPLATES(name).scss)
Buffer.from(TEMPLATE(name).scss)
)
}

export function createTest(storePath: string, name: string) {
export function createTest(
storePath: string,
name: string,
templateFactory?: (name: string) => VueTemplates
) {
const TEMPLATE = templateFactory || TEMPLATES

workspace.fs.writeFile(
Uri.file(`${storePath}/__tests__/${name}.spec.ts`),
Buffer.from(TEMPLATES(name).test)
Buffer.from(TEMPLATE(name).test)
)
}

export const createFiles = (storePath: string, name: string) => {
createVue(storePath, name)
createScss(storePath, name)
export const createFiles = (
storePath: string,
name: string,
templateFactory?: (name: string) => VueTemplates
) => {
createVue(storePath, name, templateFactory)
createScss(storePath, name, templateFactory)
createTest(storePath, name, templateFactory)
}

export const createVuetifyFiles = (storePath: string, name: string) => {
createVue(storePath, name, VUETIFY_TEMPLATES)
createScss(storePath, name, VUETIFY_TEMPLATES)
createTest(storePath, name)
}
13 changes: 12 additions & 1 deletion src/builders/vue/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { window } from 'vscode'

import { createComponentDirectory } from './createDirectory'
import { createFiles } from './createFiles'
import { createFiles, createVuetifyFiles } from './createFiles'

export async function createVueComponent(path: string, fileName: string) {
createComponentDirectory(path, fileName)
Expand All @@ -13,3 +13,14 @@ export async function createVueComponent(path: string, fileName: string) {
`Component ${fileName} successfully created in ${path}`
)
}

export async function createVuetifyComponent(path: string, fileName: string) {
createComponentDirectory(path, fileName)

const FULL_PATH = `${path}/${fileName}`
createVuetifyFiles(FULL_PATH, fileName)

window.showInformationMessage(
`Vuetify Wrapper ${fileName} successfully created in ${path}`
)
}
10 changes: 8 additions & 2 deletions src/builders/vue/templates.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
const camelCaseName = (name: string) => {
export interface VueTemplates {
vue: string
scss: string
test: string
}

export const camelCaseName = (name: string) => {
name = name.charAt(0).toLowerCase() + name.slice(1)
name = name.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase())

return name
}

export const TEMPLATES = (name: string) => {
export const TEMPLATES = (name: string): VueTemplates => {
return {
vue: `<template>
<div class="${camelCaseName(name)}" data-testid="${camelCaseName(
Expand Down
60 changes: 60 additions & 0 deletions src/builders/vue/vuetify/templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { camelCaseName, VueTemplates } from '../templates'

const className = (name: string): string => {
return `${camelCaseName(name)}__wrapper`
}

export const VUETIFY_TEMPLATES = (name: string): VueTemplates => {
return {
vue: `<template>
<!-- If you want to use v-model add ':value="value" @input="update" @change="update"' to wrapper tag -->
<V${name} class="${className(
name
)}" v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
<template v-for="(_, scopedSlotName) in $scopedSlots"#[scopedSlotName]="slotData">
<slot :name="scopedSlotName" v-bind="slotData" />
</template>
<template v-for="(_, slotName) in $slots" #[slotName]>
<slot :name="slotName" />
</template>
</V${name}>
</template>
<script lang="ts">
// Remember to add V${name} import on '/plugins/vuetify/index.ts
import Vue from 'vue'
export default Vue.extend({
name: '${name}',
// uncomment lines below if your wrapper uses v-model
/*
props: {
value: {},
},
methods: {
update(newValue) {
this.$emit('input', newValue)
this.$emit('change', newValue)
},
},
*/
})
</script>
<style lang="scss" src="./${name}.scss" scoped />`,
scss: `// ${name}.scss
.${className(name)} {
} `,
test: `import { mount } from '@vue/test-utils'
import ${name} from '../${name}.vue'
describe('${name}.vue', () => {
const wrapper = mount(${name})
it('Should render component', () => {
expect(wrapper.exists()).toBeTruthy()
})
})`,
}
}
22 changes: 21 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { commands, ExtensionContext, window } from 'vscode'

import { createVueComponent, createReactComponent } from './builders'
import {
createVueComponent,
createVuetifyComponent,
createReactComponent,
} from './builders'

const EXTENSION_NAME = 'jsm-generator'
const generateVue = commands.registerCommand(
`${EXTENSION_NAME}.generateVue`,
handleCreateVueComponent
)
const generateVuetify = commands.registerCommand(
`${EXTENSION_NAME}.generateVuetify`,
handleCreateVuetifyComponent
)
const generateReact = commands.registerCommand(
`${EXTENSION_NAME}.generateReact`,
handleCreateReactComponent
Expand All @@ -17,6 +25,7 @@ const generateReactJS = commands.registerCommand(
handleCreateReactComponentJS
)
export function activate({ subscriptions }: ExtensionContext) {
subscriptions.push(generateVuetify)
subscriptions.push(generateVue)
subscriptions.push(generateReact)
subscriptions.push(generateReactJS)
Expand All @@ -36,6 +45,17 @@ async function handleCreateVueComponent({ path }: { path: string }) {

return window.showErrorMessage('Something went wrong!')
}
async function handleCreateVuetifyComponent({ path }: { path: string }) {
const fileName = await window.showInputBox({
title: 'Enter the name of the Vuetify Component without initial V',
placeHolder: 'TextField (for VTextField)',
})
if (path && fileName) {
return await createVuetifyComponent(path, fileName)
}

return window.showErrorMessage('Something went wrong!')
}

async function handleCreateReactComponent({ path }: { path: string }) {
const fileName = await window.showInputBox({
Expand Down

0 comments on commit b2e7fff

Please sign in to comment.