Add vue-identicon (#178)

* Add vue-identicon

* Remove generated file

* Add links to reactnative & vue identicons

* Update package.json

* Update Jdenticon.vue

* Update Polkadot.vue

* Move deps around

* Empty on error

* Build to build

* ... typo

* Fix vue-identicon doc generation

* Ok, I give up... vuepress and vue packages, no luck

* Swap to TypeScript components (aligning with polkadot-js)

* Expand template with build

* Adjust vue examples

* debump gh-pages dep

* Expand doc. desc.

* Fix vuepress docs generation

* Address CC complexity

* eslint fix (babel config)

* Add Bechball
This commit is contained in:
Jaco Greeff
2019-08-06 13:15:10 +02:00
committed by GitHub
parent 32d03bdfa8
commit 85a8a3a0ee
58 changed files with 883 additions and 129 deletions
+41
View File
@@ -0,0 +1,41 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue, { VNode } from 'vue';
import Identicon from './index';
interface Data {
address: string;
size: number;
}
/**
* @name Demo
* @description Demo component
*/
const Demo = Vue.extend({
template: `
<div id="demo">
<Identicon :size="size" :theme="'polkadot'" :value="address" />
<Identicon :size="size" :theme="'substrate'" :value="address" />
<Identicon :size="size" :theme="'beachball'" :value="address" />
<Identicon :size="size" :theme="'empty'" />
</div>
`,
name: 'Demo',
data: function (): Data {
return {
address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
size: 128
};
},
components: {
Identicon
}
});
new Vue({
render: (h): VNode => h(Demo)
}).$mount('#demo');
+78
View File
@@ -0,0 +1,78 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue from 'vue';
import { isHex, isU8a, u8aToHex } from '@polkadot/util';
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
import { Beachball, Empty, Jdenticon, Polkadot } from './icons';
interface Data {
address: string;
iconSize: number;
publicKey: string;
type: 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate';
}
const DEFAULT_SIZE = 64;
/**
* @name Identicon
* @description The main Identicon component, taking a number of properties
* @example
* ```html
* <Identicon :size="128" :theme="polkadot" :value="..." />
* ```
*/
export const Identicon = Vue.extend({
// FIXME These nested divs are not correct, would like a different way
// here so we don't create a div wrapped for the div wrapper of the icon
template: `
<div v-if="type === 'empty' || address === ''">
<Empty :size="iconSize" />
</div>
<div v-else-if="type === 'beachball'">
<Beachball :address="address" :size="iconSize" />
</div>
<div v-else-if="type === 'polkadot'">
<Polkadot :address="address" :size="iconSize" />
</div>
<div v-else>
<Jdenticon :publicKey="publicKey" :size="iconSize" />
</div>
`,
props: ['prefix', 'size', 'theme', 'value'],
components: {
Beachball,
Empty,
Jdenticon,
Polkadot
},
data: function (): Data {
return {
address: '',
iconSize: DEFAULT_SIZE,
publicKey: '0x',
type: 'empty'
};
},
created: function (): void {
this.createData();
},
methods: {
createData: function (): void {
this.iconSize = this.size || DEFAULT_SIZE;
try {
this.address = isU8a(this.value) || isHex(this.value)
? encodeAddress(this.value as string, this.prefix)
: this.value;
this.publicKey = u8aToHex(decodeAddress(this.address, false, this.prefix));
this.type = this.theme;
} catch (error) {
this.address = '';
}
}
}
});
@@ -0,0 +1,32 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue from 'vue';
import generate from '@polkadot/ui-shared/beachballIcon';
interface Data {
html: string;
}
/**
* @name Beachball
* @description The Beachball identicon
*/
export const Beachball = Vue.extend({
template: `<div v-html="html" />`,
props: ['address', 'size'],
data: function (): Data {
return {
html: `<div />`
};
},
created: function (): void {
this.createHtml();
},
methods: {
createHtml: function (): void {
this.html = generate(this.address, this.size).outerHTML;
}
}
});
+18
View File
@@ -0,0 +1,18 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue from 'vue';
/**
* @name Empty
* @description An empty identicon
*/
export const Empty = Vue.extend({
template: `
<svg :height="size" :width="size" viewBox="0 0 64 64">
<circle cx="50%" cy="50%" fill="#eee" r="50%" />
</svg>
`,
props: ['size']
});
@@ -0,0 +1,32 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue from 'vue';
import jdenticon from 'jdenticon';
interface Data {
svgHtml: string;
}
/**
* @name Jdenticon
* @description The substrate default via Jdenticon
*/
export const Jdenticon = Vue.extend({
template: `<div v-html="svgHtml" />`,
props: ['publicKey', 'size'],
data: function (): Data {
return {
svgHtml: `<svg viewBox="0 0 64 64" />`
};
},
created: function (): void {
this.createSvgHtml();
},
methods: {
createSvgHtml: function (): void {
this.svgHtml = jdenticon.toSvg(this.publicKey.substr(2), this.size);
}
}
});
@@ -0,0 +1,36 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Vue from 'vue';
import generateIcon from '@polkadot/ui-shared/polkadotIcon';
interface Data {
svgHtml: string;
}
/**
* @name Polkadot
* @description The Polkadot default identicon
*/
export const Polkadot = Vue.extend({
template: `<div v-html="svgHtml" />`,
props: ['address', 'size'],
data: function (): Data {
return {
svgHtml: `<svg viewBox="0 0 64 64" />`
};
},
created: function (): void {
this.createSvgHtml();
},
methods: {
createSvgHtml: function (): void {
const circles = generateIcon(this.address).map(({ cx, cy, fill, r }): string =>
`<circle cx=${cx} cy=${cy} fill="${fill}" r=${r} />`
).join('');
this.svgHtml = `<svg height=${this.size} viewBox='0 0 64 64' width=${this.size}>${circles}</svg>`;
}
}
});
@@ -0,0 +1,8 @@
// Copyright 2017-2019 @polkadot/reactnative-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './Beachball';
export * from './Empty';
export * from './Jdenticon';
export * from './Polkadot';
+7
View File
@@ -0,0 +1,7 @@
// Copyright 2017-2019 @polkadot/vue-identicon authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Identicon } from './Identicon';
export default Identicon;