Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(MdChips): feedback for duplicated chip #1281

Merged
merged 11 commits into from
Dec 19, 2017
14 changes: 14 additions & 0 deletions docs/app/pages/Components/Chips/Chips.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<example src="./examples/Static.vue" />
<example src="./examples/Editable.vue" />
<example src="./examples/ChipCustomTemplate.vue" />
<example src="./examples/DuplicatedFeedback.vue" />
<example src="./examples/Themed.vue" />

<template>
Expand Down Expand Up @@ -45,6 +46,13 @@
<code-example title="Scoped Slot" :component="examples['chip-custom-template']" />
</div>

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

<p>Chips would reject insertion while a chip was duplicated. You could customize feedback style of the duplicated chip:</p>
<code-example title="Duplicated Feedback" :component="examples['duplicated-feedback']" />
</div>

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

Expand Down Expand Up @@ -142,6 +150,12 @@ export default {
type: 'Number',
description: 'Blocks the chips to create items above the limit.',
defaults: 'false'
},
{
name: 'md-check-duplicated',
type: 'Boolean',
description: 'Always check if there is a duplicated chip while changing the input value, or check it only on insertion',
defaults: 'false'
}
]
},
Expand Down
59 changes: 59 additions & 0 deletions docs/app/pages/Components/Chips/examples/DuplicatedFeedback.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div>
<md-chips class="md-primary" v-model="chips" md-placeholder="Add genre...">
<div class="md-helper-text">Default</div>
</md-chips>
<md-chips class="md-primary shake-on-error" v-model="chips" md-placeholder="Add genre...">
<div class="md-helper-text">Shake duplicated chip on insertion</div>
</md-chips>
<md-chips class="md-primary pulse-on-error" v-model="chips" md-placeholder="Add genre..." md-check-duplicated>
<div class="md-helper-text">Always pulse duplicated chip</div>
</md-chips>
</div>
</template>

<script>
export default {
name: 'DuplicatedFeedback',
data: () => ({
chips: [
'Pop',
'Rock',
'Jazz',
'Metal'
]
})
}
</script>

<style lang="scss" scoped>
.shake-on-error /deep/ .md-duplicated {
animation-name: shake;
animation-duration: 0.5s;
}

@keyframes shake {
0% { transform: translate(15px); }
20% { transform: translate(-15px); }
40% { transform: translate(7px); }
60% { transform: translate(-7px); }
80% { transform: translate(3px); }
100% { transform: translate(0px); }
}
</style>

<style lang="css" scoped>
.pulse-on-error >>> .md-duplicated {
animation-name: pulse;
animation-duration: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out
}

@keyframes pulse {
0% { transform: scale(1.1, 1.1); }
100% { transform: scale(0.9, 0.9); }
}
</style>

9 changes: 7 additions & 2 deletions src/components/MdChips/MdChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,20 @@
props: {
mdDisabled: Boolean,
mdDeletable: Boolean,
mdClickable: Boolean
mdClickable: Boolean,
mdDuplicated: {
type: Boolean,
default: false
}
},
computed: {
chipClasses () {
return {
'md-disabled': this.mdDisabled,
'md-deletable': this.mdDeletable,
'md-clickable': this.mdClickable,
'md-focused': this.mdHasFocus
'md-focused': this.mdHasFocus,
'md-duplicated': this.mdDuplicated
}
}
}
Expand Down
49 changes: 41 additions & 8 deletions src/components/MdChips/MdChips.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

<md-chip
v-for="(chip, key) in value"
:key="key"
:key="chip"
:md-deletable="!mdStatic"
:md-clickable="!mdStatic"
:md-duplicated="duplicatedChip === chip"
@keydown.enter="$emit('md-click', chip, key)"
@click.native="$emit('md-click', chip, key)"
@md-delete.stop="removeChip(chip)">
Expand All @@ -21,6 +22,7 @@
:type="mdInputType"
:id="id"
:placeholder="mdPlaceholder"
@input="handleInput"
@keydown.enter="insertChip"
@keydown.8="handleBackRemove">
</md-input>
Expand Down Expand Up @@ -52,10 +54,15 @@
},
mdPlaceholder: [String, Number],
mdStatic: Boolean,
mdLimit: Number
mdLimit: Number,
mdCheckDuplicated: {
type: Boolean,
default: false
}
},
data: () => ({
inputValue: ''
inputValue: '',
duplicatedChip: null
}),
computed: {
chipsClasses () {
Expand All @@ -70,13 +77,19 @@
},
methods: {
insertChip ({ target }) {
if (
!this.inputValue ||
this.value.includes(this.inputValue) ||
!this.modelRespectLimit
) {
if (!this.inputValue || !this.modelRespectLimit) {
return
}

if (this.value.includes(this.inputValue)) {
this.duplicatedChip = null
// to trigger animate
this.$nextTick(() => {
this.duplicatedChip = this.inputValue
})
return
}

this.value.push(this.inputValue)
this.$emit('input', this.value)
this.$emit('md-insert', this.inputValue)
Expand All @@ -94,6 +107,26 @@
if (!this.inputValue) {
this.removeChip(this.value[this.value.length - 1])
}
},
handleInput () {
if (this.mdCheckDuplicated) {
this.checkDuplicated()
} else {
this.duplicatedChip = null
}
},
checkDuplicated () {
if (!this.value.includes(this.inputValue)) {
this.duplicatedChip = null
return
}
if (!this.mdCheckDuplicated) return
this.duplicatedChip = this.inputValue
}
},
watch: {
value () {
this.checkDuplicated()
}
}
})
Expand Down
3 changes: 2 additions & 1 deletion src/components/MdChips/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
}
}

&.md-accent {
&.md-accent,
&.md-duplicated {
@include md-theme-property(background-color, accent);
@include md-theme-property(color, text-primary, accent);

Expand Down