Skip to content

Commit a623274

Browse files
authored
[6.x] Add branch-options-dropdown slot and modal prop to support confirmable actions in collection tree view
1 parent 7be9048 commit a623274

4 files changed

Lines changed: 105 additions & 54 deletions

File tree

resources/js/components/structures/Branch.vue

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,26 @@
5555

5656
<slot name="branch-icon" :branch="page" />
5757

58-
<template v-if="editable">
59-
<Dropdown placement="left-start" :class="{ invisible: isRoot }">
60-
<DropdownMenu>
61-
<slot
62-
name="branch-options"
63-
:branch="page"
64-
:depth="depth"
65-
:remove-branch="remove"
66-
/>
67-
</DropdownMenu>
68-
</Dropdown>
69-
</template>
58+
<template v-if="editable">
59+
<slot
60+
name="branch-options-dropdown"
61+
:branch="page"
62+
:depth="depth"
63+
:remove-branch="remove"
64+
:is-root="isRoot"
65+
>
66+
<Dropdown placement="left-start" :class="{ invisible: isRoot }">
67+
<DropdownMenu>
68+
<slot
69+
name="branch-options"
70+
:branch="page"
71+
:depth="depth"
72+
:remove-branch="remove"
73+
/>
74+
</DropdownMenu>
75+
</Dropdown>
76+
</slot>
77+
</template>
7078
</div>
7179
</div>
7280
</div>

resources/js/components/structures/PageTree.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
<template #branch-options="props">
7171
<slot name="branch-options" v-bind="{ ...props, stat }" />
7272
</template>
73+
74+
<template #branch-options-dropdown="props">
75+
<slot name="branch-options-dropdown" v-bind="{ ...props, stat }" />
76+
</template>
7377
</tree-branch>
7478
</template>
7579
</Draggable>

resources/js/components/ui/Dropdown/Dropdown.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ defineOptions({
1111
const attrs = useAttrs();
1212
1313
const props = defineProps({
14+
/** Whether the dropdown should behave as a modal and hide outside content from assistive tech. */
15+
modal: { type: Boolean, default: true },
1416
/** The preferred alignment against the trigger. May change when collisions occur. <br><br> Options: `start`, `center`, `end` */
1517
align: { type: String, default: 'start' },
1618
/** The distance in pixels from the trigger */
@@ -29,7 +31,7 @@ const dropdownContentClasses = cva({
2931
</script>
3032

3133
<template>
32-
<DropdownMenuRoot>
34+
<DropdownMenuRoot :modal="modal">
3335
<DropdownMenuTrigger as-child data-ui-dropdown-trigger>
3436
<slot name="trigger">
3537
<Button icon="dots" variant="ghost" size="sm" v-bind="attrs" :aria-label="__('Open dropdown menu')" />

resources/js/pages/collections/Show.vue

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -134,56 +134,93 @@
134134
/>
135135
</template>
136136

137-
<template #branch-options="{ branch, removeBranch, depth }">
138-
<template v-if="depth < structureMaxDepth">
139-
<DropdownLabel :text="__('Create Child Entry')" v-if="blueprints.length > 1" />
140-
<DropdownItem
141-
v-for="blueprint in blueprints"
142-
@click="createEntry(blueprint.handle, branch.id)"
143-
:icon="blueprint.icon || 'add-entry'"
144-
:key="blueprint.handle"
145-
:text="blueprints.length > 1 ? __(blueprint.title) : __('Create Child Entry')"
146-
/>
147-
</template>
148-
<DropdownSeparator v-if="depth < structureMaxDepth && branch.can_delete" />
149-
<DropdownItem
150-
v-if="branch.can_delete"
151-
:text="__('Delete')"
152-
icon="trash"
153-
variant="destructive"
154-
@click="deleteTreeBranch(branch, removeBranch)"
155-
/>
137+
<template #branch-options-dropdown="{ branch, removeBranch, depth, isRoot }">
156138
<ItemActions
157139
v-if="branch.entry"
158140
:url="entriesActionUrl"
159141
:context="{ view: 'tree' }"
160142
:item="branch.entry"
161-
auto-load
162-
v-slot="{ actions, shouldShowSkeleton }"
143+
v-slot="{ actions, loadActions, shouldShowSkeleton }"
163144
>
164-
<template v-if="shouldShowSkeleton">
165-
<DropdownSeparator />
166-
<div v-for="index in 3" :key="index" class="contents">
167-
<Skeleton class="m-1 size-5" />
168-
<Skeleton
169-
class="mx-2 my-1.5 h-5"
170-
:class="index === 1 ? 'w-28' : index === 2 ? 'w-36' : 'w-24'"
145+
<Dropdown
146+
@mouseover="loadActions"
147+
@focus="loadActions"
148+
@click="loadActions"
149+
placement="left-start"
150+
:modal="false"
151+
:class="{ invisible: isRoot }"
152+
>
153+
<DropdownMenu>
154+
<template v-if="depth < structureMaxDepth">
155+
<DropdownLabel :text="__('Create Child Entry')" v-if="blueprints.length > 1" />
156+
<DropdownItem
157+
v-for="blueprint in blueprints"
158+
@click="createEntry(blueprint.handle, branch.id)"
159+
:icon="blueprint.icon || 'add-entry'"
160+
:key="blueprint.handle"
161+
:text="blueprints.length > 1 ? __(blueprint.title) : __('Create Child Entry')"
162+
/>
163+
</template>
164+
165+
<DropdownSeparator v-if="depth < structureMaxDepth && branch.can_delete" />
166+
167+
<DropdownItem
168+
v-if="branch.can_delete"
169+
:text="__('Delete')"
170+
icon="trash"
171+
variant="destructive"
172+
@click="deleteTreeBranch(branch, removeBranch)"
173+
/>
174+
175+
<DropdownSeparator v-if="shouldShowSkeleton || branchTreeActions(actions).length" />
176+
177+
<template v-if="shouldShowSkeleton">
178+
<div v-for="index in 3" :key="index" class="contents">
179+
<Skeleton class="m-1 size-5" />
180+
<Skeleton
181+
class="mx-2 my-1.5 h-5"
182+
:class="index === 1 ? 'w-28' : index === 2 ? 'w-36' : 'w-24'"
183+
/>
184+
</div>
185+
</template>
186+
<template v-else>
187+
<DropdownItem
188+
v-for="action in branchTreeActions(actions)"
189+
:key="action.handle"
190+
:text="__(action.title)"
191+
:icon="action.icon"
192+
:variant="action.dangerous ? 'destructive' : 'default'"
193+
@click="action.run"
194+
/>
195+
</template>
196+
</DropdownMenu>
197+
</Dropdown>
198+
</ItemActions>
199+
200+
<Dropdown v-else placement="left-start" :modal="false" :class="{ invisible: isRoot }">
201+
<DropdownMenu>
202+
<template v-if="depth < structureMaxDepth">
203+
<DropdownLabel :text="__('Create Child Entry')" v-if="blueprints.length > 1" />
204+
<DropdownItem
205+
v-for="blueprint in blueprints"
206+
@click="createEntry(blueprint.handle, branch.id)"
207+
:icon="blueprint.icon || 'add-entry'"
208+
:key="blueprint.handle"
209+
:text="blueprints.length > 1 ? __(blueprint.title) : __('Create Child Entry')"
171210
/>
172-
</div>
173-
</template>
174-
<template v-else-if="branchTreeActions(actions).length">
175-
<DropdownSeparator />
211+
</template>
212+
213+
<DropdownSeparator v-if="depth < structureMaxDepth && branch.can_delete" />
214+
176215
<DropdownItem
177-
v-for="action in branchTreeActions(actions)"
178-
:key="action.handle"
179-
:text="__(action.title)"
180-
:icon="action.icon"
181-
:variant="action.dangerous ? 'destructive' : 'default'"
182-
@select.prevent
183-
@click="action.run()"
216+
v-if="branch.can_delete"
217+
:text="__('Delete')"
218+
icon="trash"
219+
variant="destructive"
220+
@click="deleteTreeBranch(branch, removeBranch)"
184221
/>
185-
</template>
186-
</ItemActions>
222+
</DropdownMenu>
223+
</Dropdown>
187224
</template>
188225
</page-tree>
189226

0 commit comments

Comments
 (0)