Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions resources/js/components/ui/Dropdown/Dropdown.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { useAttrs } from 'vue';
import { inject, useAttrs } from 'vue';
import { cva } from 'cva';
import { DropdownMenuContent, DropdownMenuPortal, DropdownMenuRoot, DropdownMenuTrigger } from 'reka-ui';
import Button from '../Button/Button.vue';
Expand All @@ -10,6 +10,10 @@ defineOptions({

const attrs = useAttrs();

// Modal menus mark everything else aria-hidden, including the editor's other nodes, which makes
// ProseMirror re-parse them and recreate the set the dropdown lives in.
const modal = !inject('isInBardField', false);

const emit = defineEmits(['closed']);

const props = defineProps({
Expand Down Expand Up @@ -37,7 +41,7 @@ const dropdownContentClasses = cva({
</script>

<template>
<DropdownMenuRoot @update:open="onOpenChange">
<DropdownMenuRoot :modal @update:open="onOpenChange">
<DropdownMenuTrigger as-child data-ui-dropdown-trigger>
<slot name="trigger">
<Button icon="dots" variant="ghost" size="sm" v-bind="attrs" :aria-label="__('Open dropdown menu')" />
Expand Down
28 changes: 28 additions & 0 deletions resources/js/tests/components/ui/Dropdown.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { mount } from '@vue/test-utils';
import { expect, test } from 'vitest';
import Dropdown from '@/components/ui/Dropdown/Dropdown.vue';

window.__ = (key) => key;

function mountDropdown(provide = {}) {
return mount(Dropdown, {
global: {
provide,
stubs: {
DropdownMenuRoot: { props: ['modal'], template: '<div :data-modal="String(modal ?? \'default\')"><slot /></div>' },
DropdownMenuTrigger: true,
DropdownMenuPortal: true,
},
},
});
}

test('dropdowns are modal', () => {
expect(mountDropdown().find('[data-modal]').attributes('data-modal')).toBe('true');
});

// Modal menus mark everything else aria-hidden, including the editor's other nodes, which makes
// ProseMirror re-parse them and recreate the set the dropdown lives in.
test('dropdowns inside a bard field are not modal', () => {
expect(mountDropdown({ isInBardField: true }).find('[data-modal]').attributes('data-modal')).toBe('false');
});
Loading