I am building a component which has two icons: like and dislike. When any of the icon is clicked, the icon should get bigger, show color and the upper heading should disappear.
I'm able to implement the functionality of hiding the heading when icon is clicked. The icon is coming from a shared Button component. I'm not able to comprehend how to give value to the bgColor based on condition that the icon is clicked on not.
For clarity:
- This is initial screen where icons aren't clicked yet: [![enter image description here][1]][1]
2.1. This is the screen which is appearing now when icon is clicked [Problem State] [![enter image description here][2]][2]
2.2: This is how the screen should appear when any icon is clicked [ Desired State]. [![enter image description here][3]][3]
My code for the component is:
<template v-slot:main>
<div class="feedbackComponent">
<div class="feedback-content">
<label v-if="!hideText" class="title">Appointment Confirmed!</label>
<label class="subtitle">How would you rate your experience?</label>
<div>
<ButtonIcon
symbol="thumbs-up"
@click="handleFeedback('up')"
bgColor= "transparent; width: 70px; height: 70px; stroke-width: 1px"
/>
<ButtonIcon
symbol="thumbs-down"
bgColor="transparent; width: 70px; height: 70px; stroke-width: 1px"
@click="handleFeedback('down')"
/>
</div>
</div>
</div>
</template>
This is script functions:
<script>
import ModalLayout from "@/components/Shared/ModalLayout.vue";
import ButtonIcon from '../Shared/ButtonIcon.vue';
export default {
name: 'ScheduleTourFeedback',
components: {
ModalLayout,
ButtonIcon,
},
data() {
return {
selected: null,
hideText: false,
}
},
methods: {
handleFeedback(feedback) {
this.selected = feedback
this.$emit('feedback-clicked', true);
this.handleClick();
},
handleClick() {
this.hideText = true;
},
},
}
</script>
I want to implement conditional rendering on bgColor such that based on the icon click it changes to the value to
bgColor="transparent; width: 90px; height: 90px; stroke-width: 1px; fill: #d64ba1"
Sorry about the long post. I just wanted to make the use-case clear. Any help would be appreciated as I'm stuck on this for a while.
UPDATED: My ButtonIcon.vue component looks like this:
<template>
<!---<button :disabled="disabled">{{ text }}</button>-->
<a @click="onClick" :style="backgroundColor" :class="text ? 'TextIcon' : ''">
{{ text }}
<i
:data-feather="symbol"
:class="type ? 'btn-white' : 'btn-continue'"
:style="backgroundColor"
/>
</a>
</template>
<script>
import feather from 'feather-icons'
export default {
name: 'ButtonIcon',
props: {
// iconCode: String,
// iconColor: String,
bgColor: String,
symbol: String,
disabled: Boolean,
type: String,
text: String,
},
computed: {
backgroundColor() {
let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
return 'background: ' + bgColor + ';' + 'border-radius: 24px;'
}
},
mounted() {
feather.replace()
},
data() {
return {}
},
methods: {
onClick() {
this.$emit('onClick')
},
},
}
</script>
<style scoped>
.btn-continue {
padding: 8px 10px;
gap: 10px;
width: 37px;
height: 37px;
position: relative;
/* Quext/Pink */
background: #d64ba1;
border-radius: 24px;
color: white;
flex: none;
order: 0;
flex-grow: 0;
}
.btn-white {
padding: 8px 10px;
gap: 10px;
width: 45px;
height: 45px;
position: relative;
/* Quext/Transparent */
background: white;
border-radius: 24px;
color: black;
border: 2px solid #000;
/* Inside auto layout */
flex: none;
order: 0;
flex-grow: 0;
}
.TextIcon {
display: flex;
align-items: center;
justify-content: center;
width: 95px;
}
a {
color: #fff;
}
</style>
You can change the
bgColor
in response to the value ofselected
For the thumbs-up icon, change
to
And for the thumbs-down icon, do similarly but obviously make it test for
selected==='down'
.Note that we need to put the
:
character beforebgColor
so that what is between the""
is no longer passed directly toButtonIcon
as a parameter, but rather it becomes interpreted as a Javascript expression, and the result is sent toButtonIcon
as a parameter.How to debug
You comment that when you click on the icon it shows the problem state instead of the desired state.
There are three possible explanations.
The
this.selected
is not being updatedThe
bgColor
is not being updatedThe
bgColor
is being updated, but theButtonIcon
component is not changing in appearance.To separate these possibilities, between
<div>
and<ButtonIcon...
add two pieces of information to assist you:Please report back what those messages say, before and after you click an icon.
Outcome was:
Next step of debugging
There must be something wrong with the
ButtonIcon
component. Can you show that component please?I am particularly interested in why a prop called
bgColor
should be doing so much more than setting the background colour.Is it from a publically available library? If so please provide a link to the manual.
Is it constructed privately by you? If so, please provide a minimal version of the code.
OK the problem is the poorly named variables!
Change the name of the property to something like
iconStyle
because that is what it represents.bgColor
was just one of the features it could transmit.Then, in the
ButtonIcon
component:Change
to
And in the JS, change
to
What was going wrong
The ButtonIcon component seems to be expecting
bgColor
to contain either a colour string or nothing (in which case a default colour was applied).In practice you were stuffing multiple things into the
bgColor
prop, and prepending it with abackground:
string. This probably caused the CSS strings to become erroneous and therefore the change you caused was not creating the effect expected.In the revised code, we are still stuffing multiple things into the prop, but now when we are in the child component it is obvious to us that the prop is not just a colour string. This helps us remember to treat it more carefully.