Skip to content

Commit

Permalink
feat(ui): suggestions animation
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume Chau committed Jun 15, 2018
1 parent 959ea07 commit 82836f5
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 102 deletions.
116 changes: 14 additions & 102 deletions packages/@vue/cli-ui/src/components/SuggestionBar.vue
Expand Up @@ -33,98 +33,31 @@
/>

<template slot-scope="{ result: { data } }" v-if="data">
<VueDropdown
v-for="suggestion of withBuiltins(data.suggestions)"
:key="suggestion.id"
:disabled="!suggestion.message && !suggestion.link"
class="suggestion"
placement="bottom-end"
>
<VueButton
slot="trigger"
:label="$t(suggestion.label)"
:loading="suggestion.busy"
class="round"
v-tooltip="$t('components.suggestion-bar.suggestion')"
@click="if (!suggestion.message && !suggestion.link) activate(suggestion)"
<transition-group name="suggestion" class="suggestions">
<SuggestionBarItem
v-for="suggestion of withBuiltins(data.suggestions)"
:key="suggestion.id"
:suggestion="suggestion"
/>

<div class="suggestion-details">
<div class="info label">
{{ $t(suggestion.label) }}
</div>

<div
v-if="suggestion.message"
class="info message"
v-html="$t(suggestion.message)"
/>

<div
v-if="suggestion.image"
class="info image"
>
<img :src="suggestion.image" alt="image">
</div>

<div class="actions-bar">
<VueButton
:href="suggestion.link"
:label="$t('components.list-item-info.more-info')"
target="_blank"
class="flat"
icon-right="open_in_new"
/>
<div class="vue-ui-spacer"/>
<VueButton
:label="$t('components.suggestion-bar.modal.cancel')"
icon-left="close"
v-close-popover
/>
<VueButton
class="primary"
:label="$t('components.suggestion-bar.modal.continue')"
icon-left="done"
v-close-popover
@click="activate(suggestion)"
/>
</div>
</div>
</VueDropdown>
</transition-group>
</template>
</ApolloQuery>
</template>

<script>
import SUGGESTION_ACTIVATE from '../graphql/suggestionActivate.gql'
export default {
data () {
return {
forceDevtoolsSuggestion: false
}
},
methods: {
async activate (suggestion) {
if (suggestion.actionLink) {
const win = window.open(
suggestion.actionLink,
'_blank'
)
win.focus()
} else {
await this.$apollo.mutate({
mutation: SUGGESTION_ACTIVATE,
variables: {
input: {
id: suggestion.id
}
}
})
}
},
// Builtin suggestions
withBuiltins (suggestions) {
let list = suggestions
// Install devtools
if (!Object.prototype.hasOwnProperty.call(window, '__VUE_DEVTOOLS_GLOBAL_HOOK__')) {
if (this.forceDevtoolsSuggestion || !Object.prototype.hasOwnProperty.call(window, '__VUE_DEVTOOLS_GLOBAL_HOOK__')) {
let devtoolsLink = null
if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)) {
devtoolsLink = 'https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd'
Expand Down Expand Up @@ -157,27 +90,6 @@ export default {
<style lang="stylus" scoped>
@import "~@/style/imports"
.suggestion
&:not(:first-child)
margin-left $padding-item
.suggestion-details
padding ($padding-item * 2 - 8px) ($padding-item * 2)
box-sizing border-box
width 440px
.label
font-size 20px
.actions-bar
padding 0
margin-top ($padding-item * 3)
.info
&:not(:last-child)
margin-bottom $padding-item
&.image
>>> img
max-width 100%
.suggestions
h-box()
</style>
160 changes: 160 additions & 0 deletions packages/@vue/cli-ui/src/components/SuggestionBarItem.vue
@@ -0,0 +1,160 @@
<template>
<div
class="suggestion-bar-item"
v-set-size="'.wrapper'"
>
<div class="wrapper">
<VueDropdown
:disabled="!suggestion.message && !suggestion.link"
placement="bottom-end"
class="dropdown"
>
<VueButton
slot="trigger"
:label="$t(suggestion.label)"
:loading="suggestion.busy"
class="round"
v-tooltip="$t('components.suggestion-bar.suggestion')"
@click="onTriggerClick()"
/>

<div class="suggestion-details">
<div class="info label">
{{ $t(suggestion.label) }}
</div>

<div
v-if="suggestion.message"
class="info message"
v-html="$t(suggestion.message)"
/>

<div
v-if="suggestion.image"
class="info image"
>
<img :src="suggestion.image" alt="image">
</div>

<div class="actions-bar">
<VueButton
:href="suggestion.link"
:label="$t('components.list-item-info.more-info')"
target="_blank"
class="flat"
icon-right="open_in_new"
/>
<div class="vue-ui-spacer"/>
<VueButton
:label="$t('components.suggestion-bar.modal.cancel')"
icon-left="close"
v-close-popover
/>
<VueButton
class="primary"
:label="$t('components.suggestion-bar.modal.continue')"
icon-left="done"
v-close-popover
@click="activate(suggestion)"
/>
</div>
</div>
</VueDropdown>
</div>
</div>
</template>

<script>
import SUGGESTION_ACTIVATE from '../graphql/suggestionActivate.gql'
export default {
props: {
suggestion: {
type: Object,
required: true
}
},
methods: {
onTriggerClick () {
if (!this.suggestion.message && !this.suggestion.link) {
this.activate(this.suggestion)
}
},
async activate (suggestion) {
if (suggestion.actionLink) {
const win = window.open(
suggestion.actionLink,
'_blank'
)
win.focus()
} else {
await this.$apollo.mutate({
mutation: SUGGESTION_ACTIVATE,
variables: {
input: {
id: suggestion.id
}
}
})
}
}
}
}
</script>

<style lang="stylus" scoped>
@import "~@/style/imports"
.suggestion-details
padding ($padding-item * 2 - 8px) ($padding-item * 2)
box-sizing border-box
width 440px
.label
font-size 20px
.actions-bar
padding 0
margin-top ($padding-item * 3)
.info
&:not(:last-child)
margin-bottom $padding-item
&.image
>>> img
max-width 100%
.suggestion-bar-item
margin-left $padding-item
h-box()
box-center()
.wrapper
width max-content
box-sizing border-box
.suggestion-enter-active,
.suggestion-leave-active
transition all 1.5s cubic-bezier(0.075, 0.820, 0.165, 1.000)
>>> .vue-ui-button
transition all 1.5s cubic-bezier(0.075, 0.820, 0.165, 1.000)
.content
transition all .2s
.suggestion-enter-active
>>> .vue-ui-button
.content
transition-delay .5s
.suggestion-enter,
.suggestion-leave-to
width 0 !important
opacity 0
margin-left 0
>>> .vue-ui-button
transform scale(0)
.content
opacity 0
</style>
3 changes: 3 additions & 0 deletions packages/@vue/cli-ui/src/main.js
Expand Up @@ -15,6 +15,7 @@ import SharedData from './util/shared-data'
import PluginAction from './util/plugin-action'
import gql from 'graphql-tag'
import ClientState from './mixins/ClientState'
import SetSize from './util/set-size'

window.gql = gql

Expand Down Expand Up @@ -47,6 +48,8 @@ for (const key in Filters) {

Vue.mixin(ClientState)

Vue.directive('set-size', SetSize)

Vue.config.productionTip = false

// For client addons
Expand Down
12 changes: 12 additions & 0 deletions packages/@vue/cli-ui/src/util/set-size.js
@@ -0,0 +1,12 @@
export default {
bind (el, { value }) {
if (typeof value === 'string') {
value = el.querySelector(value)
}
requestAnimationFrame(() => {
const bounds = value.getBoundingClientRect()
el.style.width = `${bounds.width}px`
el.style.height = `${bounds.height}px`
})
}
}

0 comments on commit 82836f5

Please sign in to comment.