Skip to content

v9 regression: selecting an NcSelect option inside NcModal resets focused element #7946

@Sector6759

Description

@Sector6759

Hey, in v9, if you include an NcSelect inside an NcModal/NcDialog, there is a weird focus behavior when selecting an option of the NcSelect, resulting in no element being focused afterwards.

Steps to reproduce the faulty behavior in v9

  1. Go to https://nextcloud-vue-components.netlify.app/#/Components/NcDialog
  2. Under the first "Basic example", click "VIEW CODE" and paste the code below into the editor
  3. Click "Show dialog"
  4. Observe the NcTextField being selected
  5. Press tab once to move the focus to the NcSelect
  6. Using the arrow keys, select an option in the list, then press Enter
  7. Observe how there is no focus on any element
  8. Press tab again and observe the focus is back on the first focusable element, which is the NcTextField

Observed behavior

After pressing Enter in step 6, any element focus is lost

Expected behavior

After pressing Enter in step 6, the focus should still be on the NcSelect , like it is in v8

Reproduction code for faulty behavior in v9

<template>
  <div>
    <NcButton @click="showDialog = true">Show dialog</NcButton>
    <NcDialog v-model:open="showDialog" name="Confirmation" :buttons="buttons">
      <NcTextField
        v-model="text1"
        label="Leading icon and clear trailing button"
        trailing-button-icon="close"
        :show-trailing-button="text1 !== ''"
      >
        <template #icon>
          <Magnify :size="20" />
        </template>
      </NcTextField>
      <NcSelect
        input-label="Require a selection"
        :options="options"
        v-model="singleValue"
        required
      />
    </NcDialog>
    <p>Last response: {{ lastResponse }}</p>
  </div>
</template>
<script>
import IconCancel from "@mdi/svg/svg/cancel.svg?raw";
import IconCheck from "@mdi/svg/svg/check.svg?raw";

export default {
  data() {
    return {
      text1: "",
      options: ["foo", "bar", "baz", "qux", "quux"],
      singleValue: null,
      showDialog: false,
      lastResponse: "None",
      buttons: [
        {
          label: "Cancel",
          icon: IconCancel,
          callback: () => {
            this.lastResponse = 'Pressed "Cancel"';
          },
        },
        {
          label: "Ok",
          type: "primary",
          icon: IconCheck,
          callback: () => {
            this.lastResponse = 'Pressed "Ok"';
          },
        },
      ],
    };
  },
};
</script>

Steps to reproduce the desired behavior in v8

  1. Go to https://stable8--nextcloud-vue-components.netlify.app/#/Components/NcDialog
  2. Under the first "Basic example", click "VIEW CODE" and paste the code below into the editor
  3. Click "Show dialog"
  4. Observe the NcTextField being selected
  5. Press tab once to move the focus to the NcSelect
  6. Using the arrow keys, select an option in the list, then press Enter
  7. Observe the focus is still on the NcSelect
  8. Press tab again and observe the focus moving to the "Clear selected" button

Reproduction code for desired behavior in v8

<template>
  <div>
    <NcButton @click="showDialog = true">Show dialog</NcButton>
    <NcDialog :open.sync="showDialog" name="Confirmation" :buttons="buttons">
      <NcTextField
        v-model="text1"
        label="Leading icon and clear trailing button"
        trailing-button-icon="close"
        :show-trailing-button="text1 !== ''"
      >
        <template #icon>
          <Magnify :size="20" />
        </template>
      </NcTextField>
      <NcSelect
        input-label="Require a selection"
        :options="options"
        v-model="singleValue"
        required
      />
    </NcDialog>
    <p>Last response: {{ lastResponse }}</p>
  </div>
</template>
<script>
import IconCancel from "@mdi/svg/svg/cancel.svg?raw";
import IconCheck from "@mdi/svg/svg/check.svg?raw";

export default {
  data() {
    return {
      text1: "",
      options: ["foo", "bar", "baz", "qux", "quux"],
      singleValue: null,
      showDialog: false,
      lastResponse: "None",
      buttons: [
        {
          label: "Cancel",
          icon: IconCancel,
          callback: () => {
            this.lastResponse = 'Pressed "Cancel"';
          },
        },
        {
          label: "Ok",
          type: "primary",
          icon: IconCheck,
          callback: () => {
            this.lastResponse = 'Pressed "Ok"';
          },
        },
      ],
    };
  },
};
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions