Skip to content
This repository has been archived by the owner on Nov 5, 2020. It is now read-only.

Commit

Permalink
feat: Add case conversion option
Browse files Browse the repository at this point in the history
  • Loading branch information
pocka committed Dec 11, 2019
1 parent f9ab4e2 commit ce482d5
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 23 deletions.
52 changes: 41 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,47 @@ For more details, see [live examples].

## Options

| Name | Data type | Default value | Description |
| ------------------ | ------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `header` | `boolean` | `true` | Whether to show header or not. |
| `source` | `boolean` | `true` | Whether to show source(usage) or not. |
| `wrapperComponent` | `Component` | [default wrapper](src/components/Wrapper/index.vue) | Override inline docs component. |
| `previewClassName` | `string` | `undefined` | Class name passed down to preview container. |
| `previewStyle` | Style object | `undefined` | Style passed down to preview container. |
| `summary` | `string` | `''` | Summary for the story. Accepts Markdown. |
| `components` | `{ [name: string]: Component }\|null` | `null` | Display info for these components. Same type as component's `components` property. |
| `docsInPanel` | `boolean` | `true` | Whether to show docs in addon panel. |
| `useDocgen` | `boolean` | `true` | Whether to use result of vue-docgen-api. |
| Name | Data type | Default value | Description |
| ------------------ | --------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `header` | `boolean` | `true` | Whether to show header or not. |
| `source` | `boolean` | `true` | Whether to show source(usage) or not. |
| `wrapperComponent` | `Component` | [default wrapper](src/components/Wrapper/index.vue) | Override inline docs component. |
| `previewClassName` | `string` | `undefined` | Class name passed down to preview container. |
| `previewStyle` | Style object | `undefined` | Style passed down to preview container. |
| `summary` | `string` | `''` | Summary for the story. Accepts Markdown. |
| `components` | `{ [name: string]: Component }\|null` | `null` | Display info for these components. Same type as component's `components` property. |
| `docsInPanel` | `boolean` | `true` | Whether to show docs in addon panel. |
| `useDocgen` | `boolean` | `true` | Whether to use result of vue-docgen-api. |
| `casing` | `"kebab" \| "camel" \| "pascal" \| undefined` | `undefined` | Which case to use. For detailed usage, see below. |

### Valid `casing` options

```js
{
// Don't convert names
casing: undefined
}

{
// Show names in kebab-case
casing 'kebab'
}

{
// Show prop names in camelCase and
// Show component names in PascalCase
casing: 'camel' // or 'pascal'
}

{
// Show prop names in camelCase and
// Show component names in kebab-case
casing: {
props: 'camel',
component: 'kebab'
}
}
```

In addition to addon options, we have a component option.

Expand Down
8 changes: 1 addition & 7 deletions example/.storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,4 @@ Vue.use(VueI18n)

addDecorator(withInfo)

const req = require.context('../stories', true, /\.stories\.js$/)

function loadStories() {
req.keys().forEach(req)
}

configure(loadStories, module)
configure(require.context('../stories', true, /\.stories\.js$/), module)
14 changes: 14 additions & 0 deletions example/stories/issues/122/camel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script>
export default {
props: {
tooLongCamelProps: {
type: String,
default: 'foo'
}
}
}
</script>

<template>
<p>camelCase</p>
</template>
80 changes: 80 additions & 0 deletions example/stories/issues/122/index.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import CamelComponent from './camel.vue'
import KebabComponent from './kebab.vue'
import MixedComponent from './mixed.vue'

export default {
title: 'Issues/#122'
}

export const camelToKebab = () => {
return {
components: { CamelComponent },
template: '<CamelComponent />'
}
}
camelToKebab.story = {
title: 'Convert camelCase to kebab-case',
parameters: {
info: {
casing: 'kebab'
}
}
}

export const kebabToCamel = () => {
return {
components: { KebabComponent },
template: '<kebab-component />'
}
}
kebabToCamel.story = {
title: 'Convert kebab-case to camelCase',
parameters: {
info: {
casing: 'camel'
}
}
}

export const mixedToKebab = () => {
return {
components: { MixedComponent },
template: '<mixed-component/>'
}
}
mixedToKebab.story = {
title: 'Convert to kebab-case (mixed)',
parameters: {
info: {
casing: 'kebab'
}
}
}

export const mixedToCamel = () => {
return {
components: { MixedComponent },
template: '<mixed-component/>'
}
}
mixedToCamel.story = {
title: 'Convert to camelCase (mixed)',
parameters: {
info: {
casing: 'camel'
}
}
}

export const preserve = () => {
return {
components: { MixedComponent },
template: '<mixed-component/>'
}
}
preserve.story = {
title: 'Preserve casing when undefined',
parameters: {
info: {}
}
}
14 changes: 14 additions & 0 deletions example/stories/issues/122/kebab.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script>
export default {
props: {
'too-long-kebab-props': {
type: String,
default: 'foo'
}
}
}
</script>

<template>
<p>kebab-case</p>
</template>
18 changes: 18 additions & 0 deletions example/stories/issues/122/mixed.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script>
export default {
props: {
tooLongCamelProps: {
type: String,
default: 'foo'
},
'too-long-kebab-props': {
type: String,
default: 'foo'
}
}
}
</script>

<template>
<p>mIxeD-CaSE</p>
</template>
29 changes: 27 additions & 2 deletions src/components/Component/index.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import { paramCase, camelCase, pascalCase } from 'change-case'
import XTable from '../Table/index.vue'
export default {
Expand All @@ -11,11 +12,35 @@ export default {
component: {
type: Object,
required: true
},
/**
* Case conversion
* See components/Wrapper/index.vue
*/
casing: {
type: Object,
required: true
}
},
computed: {
title() {
return `# <${this.component.name}/>`
return `# <${this.normalizeCase(this.component.name, 'component')}/>`
}
},
methods: {
normalizeCase(name, attr) {
switch (this.casing[attr]) {
case void 0:
return name
case 'kebab':
case 'kebab-case':
return paramCase(name)
case 'camel':
case 'camelCase':
case 'pascalCase':
case 'PascalCase':
return attr === 'component' ? pascalCase(name) : camelCase(name)
}
}
}
}
Expand All @@ -36,7 +61,7 @@ export default {
<tbody>
<tr v-for="prop in component.props" :key="prop.name">
<td>
{{ prop.name }}
{{ normalizeCase(prop.name, 'props') }}
<sup v-if="prop.required" :class="$style.required">*</sup>
</td>
<td>{{ prop.type }}</td>
Expand Down
21 changes: 20 additions & 1 deletion src/components/Wrapper/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ export default {
type: Object,
required: true
}
},
computed: {
casing() {
return {
component:
typeof this.options.casing === 'string' || !this.options.casing
? this.options.casing
: this.options.casing.component,
props:
typeof this.options.casing === 'string' || !this.options.casing
? this.options.casing
: this.options.casing.props
}
}
}
}
</script>
Expand All @@ -51,7 +65,12 @@ export default {
:lang="info.jsxStory ? 'jsx' : 'html'"
/>
<x-separator />
<x-component v-for="c in info.components" :key="c.name" :component="c" />
<x-component
v-for="c in info.components"
:key="c.name"
:component="c"
:casing="casing"
/>
</x-docs>
</template>

Expand Down
2 changes: 1 addition & 1 deletion src/extract/decideTargets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Vue, { ComponentOptions } from 'vue'
import { paramCase } from 'change-case'
import Vue, { ComponentOptions } from 'vue'

import { InfoAddonOptions } from '../options'
import { ComponentRegistory } from '../types/vue'
Expand Down
19 changes: 18 additions & 1 deletion src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ export const defaultOptions: InfoAddonOptions = {
components: null,
wrapperComponent: DefaultWrapper,
docsInPanel: true,
useDocgen: true
useDocgen: true,
casing: undefined
}

type Casing =
| undefined
| 'camel'
| 'camelCase'
| 'kebab'
| 'kebab-case'
| 'pascal'
| 'PascalCase'

/**
* Addon options
*/
Expand Down Expand Up @@ -53,4 +63,11 @@ export interface InfoAddonOptions {
* Whether to use component infomation generated by vue-docgen-api
*/
useDocgen: boolean

casing:
| Casing
| {
props: Casing
component: Casing
}
}

0 comments on commit ce482d5

Please sign in to comment.