Skip to content

Commit

Permalink
comp(MdAvatar): create avatar component (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosmoura committed Sep 6, 2017
1 parent 30923dc commit 5a6d2e0
Show file tree
Hide file tree
Showing 14 changed files with 363 additions and 5 deletions.
9 changes: 5 additions & 4 deletions build/new-component.js
Expand Up @@ -139,6 +139,11 @@ const writeToEndOfFile = (contents, file) => {
}

const [name] = process.argv.slice(2)

if (!name) {
exit('Please provide the file name. Example: npm new-component \'MdComponent\'')
}

const singleName = name.replace('Md', '')
const camelCasedName = toCamelCase(singleName.replace('Md', ''))
const rootDir = join(__dirname, '..')
Expand All @@ -149,10 +154,6 @@ const docsPath = 'docs/app/pages/components/' + singleName
const docsRoutePath = 'docs/app/routes.js'
const navPath = 'docs/app/template/MainNavContent.vue'

if (!name) {
exit('Please provide the file name. Example: npm new-component \'MdComponent\'')
}

if (!test('-e', componentsPath)) {
mkdir('-p', componentsPath)
cd(componentsPath)
Expand Down
3 changes: 3 additions & 0 deletions docs/app/i18n/en-US.js
Expand Up @@ -28,6 +28,9 @@ export default {
app: {
title: 'App'
},
avatar: {
title: 'Avatar'
},
card: {
title: 'Card'
},
Expand Down
75 changes: 75 additions & 0 deletions docs/app/pages/Components/Avatar/Avatar.vue
@@ -0,0 +1,75 @@
<example src="./examples/Regular.vue" />
<example src="./examples/Sizes.vue" />
<example src="./examples/Placeholder.vue" />

<template>
<page-container centered :title="$t('pages.avatar.title')">
<div class="page-container-section">
<p>Avatars can be used to represent people. When used with a specific logo, avatars can also be used to represent brand. They also can be a placeholder when there is no image to be shown, showing a initial letter of a name on contacts that have to picture yet, for example.</p>
</div>

<div class="page-container-section">
<h2>Avatar</h2>

<p>Avatars can show a single image by default but can also display a icon (using the <code>md-icon</code> component):</p>
<code-example title="Default" :component="examples['regular']" />
<api-item title="API - md-avatar">
<p>The following option can be applied to any avatar:</p>

<api-table :headings="regular.headings" :props="regular.props" slot="classes" />
</api-item>
</div>

<div class="page-container-section">
<h2>Letter as a placeholder</h2>

<p>Let's assume that you want to show a list of contacts, but some of them do not have a picture in your database. You can use a initial letter of the contact name as a placeholder. It can even show 2 letters (for compound names) without problem:</p>
<code-example title="Placeholder" :component="examples['placeholder']" />
</div>

<div class="page-container-section">
<h2>Multiple sizes</h2>

<p>You can specify three different sizes, if you want: Regular, Small or Large. By default the avatar have a regular size.</p>
<code-example title="Sizes" :component="examples['sizes']" />
<api-item title="API - md-avatar">
<p>The following options will change the size of a avatar:</p>

<api-table :headings="sizes.headings" :props="sizes.props" slot="classes" />
</api-item>
</div>
</page-container>
</template>

<script>
import examples from 'docs-mixins/docsExample'
export default {
name: 'Avatar',
mixins: [examples],
data: () => ({
regular: {
headings: ['Name', 'Description'],
props: [
{
name: 'md-avatar-icon',
description: 'Create a avatar that can show a icon.'
}
]
},
sizes: {
headings: ['Name', 'Description'],
props: [
{
name: 'md-small',
description: 'Make a small avatar, changing the size of image, icon or text.'
},
{
name: 'md-large',
description: 'Make a large avatar. Commonly used as the current user avatar inside a left md-drawer.'
}
]
}
})
}
</script>
41 changes: 41 additions & 0 deletions docs/app/pages/Components/Avatar/examples/Placeholder.vue
@@ -0,0 +1,41 @@
<template>
<div>
<div class="separator">
<md-avatar class="md-avatar-icon">A</md-avatar>
<md-avatar class="md-avatar-icon md-primary">A</md-avatar>
<md-avatar class="md-avatar-icon md-accent">A</md-avatar>
</div>

<div class="separator">
<md-avatar class="md-avatar-icon md-small">B</md-avatar>
<md-avatar class="md-avatar-icon md-small md-primary">B</md-avatar>
<md-avatar class="md-avatar-icon md-small md-accent">B</md-avatar>
</div>

<div class="separator">
<md-avatar class="md-avatar-icon md-large">
<md-ripple>CA</md-ripple>
</md-avatar>

<md-avatar class="md-avatar-icon md-large md-primary">
<md-ripple>CA</md-ripple>
</md-avatar>

<md-avatar class="md-avatar-icon md-large md-accent">
<md-ripple>CA</md-ripple>
</md-avatar>
</div>
</div>
</template>

<script>
export default {
name: 'Placeholder'
}
</script>

<style lang="scss" scoped>
.separator + .separator {
margin-top: 24px;
}
</style>
25 changes: 25 additions & 0 deletions docs/app/pages/Components/Avatar/examples/Regular.vue
@@ -0,0 +1,25 @@
<template>
<div>
<md-avatar>
<img src="assets/examples/avatar.png" alt="Avatar">
</md-avatar>

<md-avatar class="md-avatar-icon">
<md-icon>home</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-primary">
<md-icon>folder</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-accent">
<md-icon>favorite</md-icon>
</md-avatar>
</div>
</template>

<script>
export default {
name: 'Regular'
}
</script>
69 changes: 69 additions & 0 deletions docs/app/pages/Components/Avatar/examples/Sizes.vue
@@ -0,0 +1,69 @@
<template>
<div>
<div class="separator">
<md-avatar class="md-small">
<img src="assets/examples/avatar.jpg" alt="People">
</md-avatar>

<md-avatar class="md-avatar-icon md-small">
<md-icon>home</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-small md-primary">
<md-icon>folder</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-small md-accent">
<md-icon>favorite</md-icon>
</md-avatar>
</div>

<div class="separator">
<md-avatar>
<img src="assets/examples/avatar.png" alt="Avatar">
</md-avatar>

<md-avatar class="md-avatar-icon">
<md-icon>home</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-primary">
<md-icon>folder</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-accent">
<md-icon>favorite</md-icon>
</md-avatar>
</div>

<div class="separator">
<md-avatar class="md-large">
<img src="assets/examples/avatar-2.jpg" alt="People">
</md-avatar>

<md-avatar class="md-avatar-icon md-large">
<md-icon>home</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-large md-primary">
<md-icon>folder</md-icon>
</md-avatar>

<md-avatar class="md-avatar-icon md-large md-accent">
<md-icon>favorite</md-icon>
</md-avatar>
</div>
</div>
</template>

<script>
export default {
name: 'Sizes'
}
</script>

<style lang="scss" scoped>
.separator + .separator {
margin-top: 24px;
}
</style>
5 changes: 5 additions & 0 deletions docs/app/routes.js
Expand Up @@ -4,6 +4,11 @@ import VueRouter from 'vue-router'
Vue.use(VueRouter)

export const routes = [
{
path: '/components/avatar',
name: 'components/avatar',
component: () => import(/* webpackChunkName: "avatar" */ './pages/Components/Avatar/Avatar.vue')
},
{
path: '/components/speed-dial',
name: 'components/speed-dial',
Expand Down
1 change: 1 addition & 0 deletions docs/app/template/MainNavContent.vue
Expand Up @@ -6,6 +6,7 @@
<router-link to="/components">{{ $t('pages.components.title') }}</router-link>
<div class="main-nav-level">
<router-link to="/components/app">{{ $t('pages.app.title') }}</router-link>
<router-link to="/components/avatar">{{ $t('pages.avatar.title') }}</router-link>
<router-link to="/components/button">{{ $t('pages.button.title') }}</router-link>
<router-link to="/components/card">{{ $t('pages.card.title') }}</router-link>
<router-link to="/components/content">{{ $t('pages.content.title') }}</router-link>
Expand Down
17 changes: 17 additions & 0 deletions src/components/MdAvatar/MdAvatar.test.js
@@ -0,0 +1,17 @@
import mountTemplate from 'test/utils/mountTemplate'
import MdAvatar from './MdAvatar.vue'

test('should render the avatar', async () => {
const template = '<md-avatar>Lorem ipsum</md-avatar>'
const wrapper = await mountTemplate(MdAvatar, template)

expect(wrapper.hasClass('md-avatar')).toBe(true)
expect(wrapper.text()).toBe('Lorem ipsum')
})

test('should render the theme class', async () => {
const template = '<md-avatar md-theme="alt">Lorem ipsum</md-avatar>'
const wrapper = await mountTemplate(MdAvatar, template)

expect(wrapper.hasClass('md-theme-alt')).toBe(true)
})
85 changes: 85 additions & 0 deletions src/components/MdAvatar/MdAvatar.vue
@@ -0,0 +1,85 @@
<template>
<div class="md-avatar" :class="[$mdActiveTheme]">
<slot />
</div>
</template>

<script>
import MdComponent from 'core/MdComponent'
export default new MdComponent({
name: 'MdAvatar'
})
</script>

<style lang="scss">
@import "~components/MdAnimation/variables";
$md-avatar-size: 40px;
$md-avatar-large-size: 64px;
$md-avatar-large-icon: 40px;
$md-avatar-small-size: 24px;
$md-avatar-small-icon: 16px;
.md-avatar {
width: $md-avatar-size;
height: $md-avatar-size;
margin: auto;
display: inline-flex;
justify-content: center;
align-items: center;
overflow: hidden;
user-select: none;
position: relative;
border-radius: $md-avatar-size;
transition: $md-transition-default;
transition-property: color, background-color;
will-change: color, background-color;
font-size: 24px;
letter-spacing: -.03em;
vertical-align: middle;
&.md-large {
min-width: $md-avatar-large-size;
min-height: $md-avatar-large-size;
border-radius: $md-avatar-large-size;
font-size: $md-avatar-large-icon;
.md-icon {
font-size: $md-avatar-large-icon !important;
}
}
&.md-small {
width: $md-avatar-small-size;
height: $md-avatar-small-size;
border-radius: $md-avatar-small-size;
font-size: $md-avatar-small-icon - 2px;
.md-icon {
font-size: $md-avatar-small-icon !important;
}
}
.md-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
img {
width: 100%;
height: 100%;
display: block;
}
.md-ripple {
cursor: pointer;
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 50%;
}
}
</style>
7 changes: 7 additions & 0 deletions src/components/MdAvatar/index.js
@@ -0,0 +1,7 @@
import init from 'vue-material/material'
import MdAvatar from './MdAvatar'

export default Vue => {
init(Vue)
Vue.component(MdAvatar.name, MdAvatar)
}

0 comments on commit 5a6d2e0

Please sign in to comment.