Ryan Rapini
Ryan Rapini

Reputation: 385

Vuetify use v-dialog components inside v-card-actions without causing padding issues

You can see the issue I'm having here:

https://codepen.io/ryanrapini/pen/LYeWZKR?editors=1010

Essentially, I have several dialogs which I have contained into their own custom "vue components" i.e. order-dialog.vue. In an ideal world, I could simply include this <order-dialog> component wherever I need it, and it would render the activator button and then handle all of the dialog state inside the component, so the parent doesn't need to worry.

Unfortunately, if I do this in a v-card-actions section I get spacing issues. Is this a bug with Vuetify or am I doing something wrong?

I thought that by moving the activator out of the <v-dialog> tag it might fix the issue, but it still doesn't unless I break my component up into a v-dialog component and a separate activator, which means I now need to manage the state of the dialog in the parent.

Thanks for any help.

Upvotes: 0

Views: 985

Answers (2)

TeeJay
TeeJay

Reputation: 31

Sorry for raising this from the afterlife, but I ran into this same issue, and wanted to help anyone who didn't want to use the other mentioned method. This works on Vue3 as well.

After digging a bit into the docs, I realized that v-slot actions isn't actually necessary for the dialog to function. All it does is style the template with the slot "actions" to handle the button styling in v-card. What I did to style everything how I wanted without the awkward (in my own eyes, but not saying it's wrong) targeting, was remove the entire template and add a button at the bottom of the template wrapped by "default". I felt this was a little more friendly as this sort of change seems less drastic and more scalable to me.

Example before:

<v-dialog max-width="500">
  <template v-slot:activator="{ props: activatorProps }">
    <v-btn
      v-bind="activatorProps"
      color="surface-variant"
      text="Open Dialog"
      variant="flat"
    ></v-btn>
  </template>

  <template v-slot:default="{ isActive }">
    <v-card title="Dialog">
      <v-card-text>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      </v-card-text>

      <v-card-actions>
        <v-spacer></v-spacer>

        <v-btn
          text="Close Dialog"
          @click="isActive.value = false"
        ></v-btn>
      </v-card-actions>
    </v-card>
  </template>
</v-dialog>

Example after:

<v-dialog max-width="500">
  <template #activator="{ props: activatorProps }">
    <v-btn
    :="activatorProps"
    color="surface-variant" 
    text="Open Dialog" 
    variant="flat"></v-btn>
  </template>

    <template #default="{ isActive }">
    <v-card title="Dialog">
      <v-card-text>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
        eiusmod tempor incididunt ut labore et dolore magna aliqua.
      </v-card-text>

    <button @click="isActive.value = false">Close</button>
    </v-card>
  </template>
</v-dialog>
    
        

Upvotes: 0

Alexander Shkirkov
Alexander Shkirkov

Reputation: 3857

I don't think you are doing something wrong, and I'm not sure that it's a Vuetify bug.

This comes from CSS rule in Vuetify library:

.v-application--is-ltr .v-card__actions>.v-btn.v-btn+.v-btn {
    margin-left: 8px;
}

I think the authors assumed that this block should contain only buttons. But in your case (in 2nd and 3rd approach) an output HTML looks like this:

<div class="v-card__actions">
  <button class="v-btn ...">
    ...
  </button>
  <div class="v-dialog__container"><!----></div>
  <button type="button" class="v-btn ...">
    ...
  </button>
  <button type="button" class="v-btn ...">
    ...
  </button>
</div>

So v-dialog__container breaks this rule.

You can fix you issue, by example, with an additional rule:

.v-application--is-ltr .v-card__actions>.v-btn:not(:first-child) {
    margin-left: 8px !important;
}

Or you can also apply helper classes (ml-2) into specific buttons.

Upvotes: 3

Related Questions