2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-06 00:32:23 +03:00

feat: add components proposal

This commit is contained in:
pimlie
2019-06-12 14:57:34 +02:00
parent 02237e0176
commit 118c293a43
14 changed files with 4651 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
{
"name": "vue-app",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"test": "jest"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@vue/server-test-utils": "^1.0.0-beta.29",
"babel-jest": "^24.8.0",
"jest": "^24.8.0"
}
}
@@ -0,0 +1,16 @@
import { createComponent, variantProps } from '../utils'
export const charset = {
functional: true,
props: {
value: String
},
render(h, { data, props }) {
data.attrs = {
...data.attrs,
charset: props.value
}
return h('meta', data)
}
}
@@ -0,0 +1,37 @@
import { createComponent, variantProps } from '../utils'
export function createDescriptionComponent({ namePrefix = '', nameAttribute = 'name' } = {}) {
return createComponent({
valueAttribute: 'content',
attrs: {
[nameAttribute]: `${namePrefix}${namePrefix ? ':' : ''}description`
}
})
}
export const htmlDescription = createDescriptionComponent()
export const ogDescription = createDescriptionComponent({ namePrefix: 'og' })
export const twitterDescription = createDescriptionComponent({ namePrefix: 'twitter' })
export const websiteDescription = createDescriptionComponent({ nameAttribute: 'itemprop' })
export const variants = {
html: htmlDescription,
og: ogDescription,
twitter: twitterDescription,
website: websiteDescription
}
export const description = {
...createComponent(),
render(h, { data, props }) {
return Object.keys(variantProps)
.filter(variant => props[variant] && !!variants[variant])
.map(variant => h(variants[variant], {
...data,
props: { ...props }
}))
}
}
+40
View File
@@ -0,0 +1,40 @@
import { createComponent, variantProps } from '../utils'
function createTitleComponent({ tag = 'meta', namePrefix = '', nameAttribute = 'name' } = {}) {
const isHtmlTitle = tag === 'title'
return createComponent({
tag,
valueAttribute: isHtmlTitle ? undefined : 'content',
attrs: isHtmlTitle ? undefined : {
[nameAttribute]: `${namePrefix}${namePrefix ? ':' : ''}title`
}
})
}
export const htmlTitle = createTitleComponent({ tag: 'title' })
export const ogTitle = createTitleComponent({ namePrefix: 'og' })
export const twitterTitle = createTitleComponent({ namePrefix: 'twitter' })
export const websiteTitle = createTitleComponent({ nameAttribute: 'itemprop' })
export const variants = {
html: htmlTitle,
og: ogTitle,
twitter: twitterTitle,
website: websiteTitle
}
export const title = {
...createComponent(),
render(h, { data, props }) {
return Object.keys(variantProps)
.filter(variant => props[variant] && !!variants[variant])
.map(variant => h(variants[variant], {
...data,
props: { ...props }
}))
}
}
+1
View File
@@ -0,0 +1 @@
+48
View File
@@ -0,0 +1,48 @@
export const variantProps = {
html: {
type: Boolean,
default: true
},
og: Boolean,
twitter: Boolean,
website: Boolean
}
export function createComponent({
tag = 'meta',
attrs = {},
valueAttribute
} = {}) {
return {
functional: true,
props: {
value: String,
...variantProps
},
render(h, { data, props }) {
let vAttr = null
if (valueAttribute) {
vAttr = { [valueAttribute]: props.value }
}
data.attrs = {
...data.attrs,
...attrs,
...vAttr
}
return h(tag, data, valueAttribute ? undefined : props.value)
}
}
}
export function createMetaComponent(options) {
if (!options.hasOwnProperty('valueAttribute')) {
options.valueAttribute = 'content'
}
return createComponent({
...options,
tag: 'meta'
})
}
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`charset 1`] = `"<meta charset=\\"utf-8\\" data-server-rendered=\\"true\\">"`;
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`description 1`] = `"<meta name=\\"description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`description:html 1`] = `"<meta name=\\"description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`description:og 1`] = `"<meta name=\\"og:description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`description:twitter 1`] = `"<meta name=\\"twitter:description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`description:website 1`] = `"<meta itemprop=\\"description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`og-description 1`] = `"<meta name=\\"og:description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`twitter-description 1`] = `"<meta name=\\"twitter:description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`website-description 1`] = `"<meta itemprop=\\"description\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`og-title 1`] = `"<meta name=\\"og:title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`title 1`] = `"<title data-server-rendered=\\"true\\">test</title>"`;
exports[`title:html 1`] = `"<title data-server-rendered=\\"true\\">test</title>"`;
exports[`title:og 1`] = `"<meta name=\\"og:title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`title:twitter 1`] = `"<meta name=\\"twitter:title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`title:website 1`] = `"<meta itemprop=\\"title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`twitter-title 1`] = `"<meta name=\\"twitter:title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
exports[`website-title 1`] = `"<meta itemprop=\\"title\\" content=\\"test\\" data-server-rendered=\\"true\\">"`;
+13
View File
@@ -0,0 +1,13 @@
import { renderToString } from '@vue/server-test-utils'
import { charset } from '../src/elements/charset'
const renderOptions = {
propsData: {
value: 'utf-8'
}
}
test('charset', async () => {
const str = await renderToString(charset, renderOptions)
expect(str).toMatchSnapshot()
})
@@ -0,0 +1,75 @@
import { renderToString } from '@vue/server-test-utils'
import * as descriptions from '../src/elements/description'
const renderOptions = {
propsData: {
value: 'test'
}
}
test('description', async () => {
const str = await renderToString(descriptions.htmlDescription, renderOptions)
expect(str).toMatchSnapshot()
})
test('og-description', async () => {
const str = await renderToString(descriptions.ogDescription, renderOptions)
expect(str).toMatchSnapshot()
})
test('twitter-description', async () => {
const str = await renderToString(descriptions.twitterDescription, renderOptions)
expect(str).toMatchSnapshot()
})
test('website-description', async () => {
const str = await renderToString(descriptions.websiteDescription, renderOptions)
expect(str).toMatchSnapshot()
})
test('description:html', async () => {
const str = await renderToString(descriptions.description, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: true
}
})
expect(str).toMatchSnapshot()
})
test('description:og', async () => {
const str = await renderToString(descriptions.description, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
og: true
}
})
expect(str).toMatchSnapshot()
})
test('description:twitter', async () => {
const str = await renderToString(descriptions.description, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
twitter: true
}
})
expect(str).toMatchSnapshot()
})
test('description:website', async () => {
const str = await renderToString(descriptions.description, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
website: true
}
})
expect(str).toMatchSnapshot()
})
+75
View File
@@ -0,0 +1,75 @@
import { renderToString } from '@vue/server-test-utils'
import * as titles from '../src/elements/title'
const renderOptions = {
propsData: {
value: 'test'
}
}
test('title', async () => {
const str = await renderToString(titles.htmlTitle, renderOptions)
expect(str).toMatchSnapshot()
})
test('og-title', async () => {
const str = await renderToString(titles.ogTitle, renderOptions)
expect(str).toMatchSnapshot()
})
test('twitter-title', async () => {
const str = await renderToString(titles.twitterTitle, renderOptions)
expect(str).toMatchSnapshot()
})
test('website-title', async () => {
const str = await renderToString(titles.websiteTitle, renderOptions)
expect(str).toMatchSnapshot()
})
test('title:html', async () => {
const str = await renderToString(titles.title, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: true
}
})
expect(str).toMatchSnapshot()
})
test('title:og', async () => {
const str = await renderToString(titles.title, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
og: true
}
})
expect(str).toMatchSnapshot()
})
test('title:twitter', async () => {
const str = await renderToString(titles.title, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
twitter: true
}
})
expect(str).toMatchSnapshot()
})
test('title:website', async () => {
const str = await renderToString(titles.title, {
...renderOptions,
propsData: {
...renderOptions.propsData,
html: false,
website: true
}
})
expect(str).toMatchSnapshot()
})
File diff suppressed because it is too large Load Diff