I wanted to make a custom button that basically when clicked on would make a v-data-table pop out below it. I am basically making a data table show up when a button is clicked and using this transition
https://vuetifyjs.com/en/styles/transitions/#scale
But the transition sort of makes the table go to the right more and also has an active state with a background with opacity, basically there is a lot of built in styles that are making it hard to make a table drop down below the button as the default behavior is when you click on the transition, the item that pops up covers the button.
Below is the code that causes this
<v-menu transition="scroll-y-transition" class="scroll-button">
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on">
Scrolling Y Transition
</v-btn>
</template>
<v-data-table> </v-data-table>
</v-menu>
Is there a better way to implement this?
I don't recommend using menu. Maybe you are looking for this kind of animation.
<v-btn #click="show = !show">
{{ show ? 'Hide' ? 'Show' }}
</v-btn>
<v-expand-transition>
<div v-show="show">
<v-table></v-table>
</div>
</v-expand-transition>
And in the script
data() {
return {
show: false
}
}
You should use the native props for v-menu to reposition the menu how you like. See this snippet: https://codepen.io/bgtor/pen/BaWdBMO .
Note the use of offset-y which allow you to offset the menu on the Y axis, and bottom which tell it to offset to the bottom. Also, nudge-left="200px" is translating the menu to the left by "200px". You can find more props for customisation on the vuetify site: https://vuetifyjs.com/en/api/v-menu/.
Other than that, I agree with #scar-2018, it seems odd to display a table in a menu.
Related
I have a text that displays when I hover a button.
What I'd like is to set the tooltip a bit away from the button (without changing the button's size) because at the moment, it's appearing a bit on the button, they are way too close together.
<v-btn
v-if="
crosshairToggle &&
(tn.length > 10 || tn.length == 0)"
elevation="0"
id="zoom_out"
ref="zoomout"
class="zmbtn minus"
dark
width="45px"
>
<v-tooltip
right
open-delay="500"
>
<template v-slot:activator="{ on }">
<v-icon v-on="on" class="zoom-icon" :color="textLightGrey">
mdi-image-filter-center-focus
</v-icon>
</template>
<span>Focus Mode - Enables when 10 or less actors are mapped</span>
</v-tooltip>
And since the tooltip is only appearing when I'm hovering the button, I can't inspect it. Does anyone know how to set margins on tooltips ?
I believe the prop you are looking for is nudge-top (or nudge-bottom). Take a look at the v-tooltip API page.
Example:
<v-tooltip
right
open-delay="500"
:nudge-top="-50"
>
I'm trying to write test for my component and in this component i have a <V-MENU> and when it's activated, I'll get a form inside that component and in this form there's a <V-BTN>. so i managed to reach to buttons or items outside this menu but when i try to find my button inside menu, test will fail.
Basic Vue Component :
<v-btn
data-testid="working-button"
#click="workingbutton()"
>
Working Button
</v-btn>
<v-menu
v-model="menu"
data-testid="isMenu"
:close-on-content-click="false"
:nudge-width="200"
offset-x
>
<v-btn
data-testid="btn-one"
#click="doSomething"
>
BTN 1
</v-btn>
<v-card data-testid="card-test">
<v-text-field
v-model="country"
outlined
label="Email"/>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
data-testid="btn-two"
#click="doSomething"
>
{{ login ? 'Login' : 'Register' }}
</v-btn>
</v-card-actions>
</v-card>
</v-menu>
Test Unit :
const wrapper = mount(TestComponent, {
store,
localVue,
vuetify
})
// Passed
expect(wrapper.vm.menu).toBe(false);
expect(wrapper.find('[data-testid="working-button"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="isMenu"]').exists()).toBe(true);
const menuButton = wrapper.find('[data-testid="working-button"]')
menuButton.vm.$emit('click')
expect(wrapper.vm.menu).toBe(true);
// Will Fail
expect(wrapper.find('[data-testid="btn-one"]').exists()).toBe(true);
// Will Fail
expect(wrapper.find('[data-testid="card-test"]').exists()).toBe(true);
// Will Fail
expect(wrapper.find('[data-testid="btn-two"]').exists()).toBe(true);
Above codes are a basic example which I've tried to make it short in order to don't waste your time in reading it.
So as you can see in top I've triggered Working button to set menu to true, then tried to find the button, and the reason that I've did this was that, i thought maybe menu should be true, but it wasn't and it's still fail.
Like most components that create popups or overlays, the content of Vuetify's v-menu isn't rendered within the component itself, but at the point specified in its attach property, by default the root of your Vue app.
You will have to look outside your wrapper for the rendered menu. This should do it, assuming you have createWrapper imported from vue-test-utils:
const menu = createWrapper(document.body).find('.v-menu__content');
(You could also pass the specific element that is your app root instead of document.body to be more precise.) Then you would look for everything within the menu on the menu wrapper instead of the wrapper wrapper.
How can I check and handle the click event of a v-menu in Vuetify?
The best way is to use v-model on v-menu & watch to variable change.
HTML
<v-menu
v-model="isOpened">
</v-menu>
SCRIPT
export default({
watch:{
isOpened: function(){
// do whatever you want
}
}
})
Here is an example:
<template v-slot:activator="{ on: { click } }">
<v-btn #click="(click) (exit=!exit)" icon>
<v-icon v-if="!exit">mdi-dots-vertical</v-icon>
<v-icon v-else>mdi-close</v-icon>
</v-btn>
</template>
As you can see, if the menu is clicked the exit var is set to its opposite value and therefore the mdi-close icon is shown on the button. If the menu is clicked again, the event changing the exit variable will trigger again and the vertical dots will be shown.
I only posted this question to save the exact syntax for myself for later because I have been digging Vuetify docs for hours and finally figured out how to do it.
I am trying to put a tooltip on a v-icon who randomly gets assigned a color. Every time I mouse over the v-icon, the color changes. I only want the color to be set one time. I do not want the color to change every time the mouse is hovered over the v-icon. Any suggestions?
<v-tooltip bottom>
<template #activator="{on}">
<v-icon v-on="on" :color="getRandomColor()">mdi-close</v-icon>
</template>
<span>Some Tooltip text</span>
</v-tooltip>
I got around this by making a color array in the data: section of Vue and generating the random colors there. Then, I just call that specific array index in color. Something like this:
data() {
return {
rColors: [getRandomColor(), getRandomColor()],
}
}
<v-icon v-on="on" :color="rColors[0]">mdi-close</v-icon>
Is there a way to avoid doing this by putting a keyword in the previous code?
Something like
v-on:once="on" ?
How do I make this expansion-panel open content only on clicking icon?
Tried using readonly but it didn't help.
Thanks in advance!
https://vuetifyjs.com/en/components/expansion-panels#expansion-panel
You can put online the argument in all collapse like: expanded={!expanded}
and in the icon you put the onClick={toggle}
I was having the same problem and just found a solution for that.
You need to implement a custom button on the expansion panel, so it will accept custom events. You can achieve that using template and v-slot:
<v-expansion-panel #click.prevent="onClick()">
<v-expansion-panel-header>
...your expansion panel code here
<template v-slot:actions>
<v-btn icon #click.stop="onClick()">
<v-icon>mdi-filter-variant</v-icon>
</v-btn>
</template>
</v-expansion-panel-header>
</v-expansion-panel>
...and your onClick method would be like this:
onClick() {
/*this will toggle only by icon click. at the same time, will prevent toggle
by clicking on header. */
const curr = this.panel
this.panel = curr === undefined ? 0 : undefined
}
It may seem a little magical that the same function is toggling on icon click and preventing toggle on header click, but this happens because the custom icon button does not toggle itself, so we force that using the onClick method. On the other hand, the expansion panel header has its native property of toggling the panel. So when we click it, its value will automatically change and we need to change it back to what it was before the click.
To make the expansion-panel open only on clicking icon you can use css that disables all clicks on the header and only allows clicks on the icon:
<style>
.v-expansion-panel-header{
pointer-events: none;
}
.v-expansion-panel-header__icon{
pointer-events: All;
}
</style>
Keep in mind if you are using scoped style you have use >>>:
https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors
Here is the template example, I added #click to provide btn like experience when user clicks on an icon, it's not necessary:
<template>
<v-expansion-panel>
<v-expansion-panel-header>
<template #actions>
<v-icon class="icon Icon Icon--32 icon-utility-arrows-carrot_down-32"
#click/>
</template>
</v-expansion-panel-header>
<v-expansion-panels >
<v-expansion-panel-content >
<!--content here-->
</v-expansion-panel-content>
</v-expansion-panels>
</v-expansion-panel>
</template>