Skip to content

Commit

Permalink
Add a new Twig component to create Action Menus
Browse files Browse the repository at this point in the history
  • Loading branch information
javiereguiluz committed Jan 4, 2025
1 parent 996be4b commit da8ece2
Show file tree
Hide file tree
Showing 20 changed files with 216 additions and 112 deletions.
9 changes: 9 additions & 0 deletions assets/css/easyadmin-theme/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ body.ea-mobile-sidebar-visible .sidebar {
inset-inline-start: 0;
}

.dropdown-toggle.dropdown-toggle-hidden-marker:after { display: none; }
.dropdown-toggle.dropdown-toggle-hidden-marker:hover { cursor: pointer; }

.user-menu-wrapper a.user-details,
a.user-menu-wrapper .user-details:hover {
align-items: center;
Expand Down Expand Up @@ -232,6 +235,9 @@ a.user-menu-wrapper .user-details:hover {
inline-size: 2em;
text-align: center;
}
.user-menu-wrapper .dropdown-user-details .user-avatar .icon {
display: block;
}

.user-menu-wrapper .dropdown-menu {
min-inline-size: 200px;
Expand Down Expand Up @@ -718,6 +724,9 @@ a.user-menu-wrapper .user-details:hover {
margin: 0 10px 0 4px;
font-size: 15px;
}
.dropdown-menu .icon {
display: inline-flex;
}

.dropdown-menu .dropdown-item,
.dropdown-menu .dropdown-header {
Expand Down
19 changes: 14 additions & 5 deletions assets/css/easyadmin-theme/datagrids.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ table.datagrid {
margin-block-end: 0;
inline-size: 100%;
}
table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions,
table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dropdown {
min-width: 50px;
}
@media (max-width: 767px) {
table.datagrid:not(.datagrid-empty) tbody,
table.datagrid:not(.datagrid-empty) tr,
Expand Down Expand Up @@ -182,17 +186,22 @@ table.datagrid {
outline: none;
}

.datagrid .dropdown-actions {
display: inline-block;
}
.datagrid .dropdown-actions .dropdown-toggle {
border: 1px solid transparent;
border-radius: var(--border-radius);
color: var(--dropdown-toggle-color);
padding: 3px 5px;
display: block;
padding: 1px 5px;
}
/* hides the caret added automatically by Bootstrap */
.datagrid .dropdown-actions .dropdown-toggle:after { display: none; }
.datagrid .dropdown-actions .dropdown-toggle:hover { cursor: pointer; }

.datagrid .dropdown-actions .dropdown-toggle svg { vertical-align: top; }
.datagrid .dropdown-actions .dropdown-toggle .icon {
display: block;
font-size: 21px;
inline-size: unset;
}

.datagrid .dropdown-actions .dropdown-menu { z-index: var(--zindex-900); }

Expand Down
4 changes: 4 additions & 0 deletions assets/icons/internal/dots-horizontal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"symfony/uid": "^5.4|^6.0|^7.0",
"symfony/ux-twig-component": "^2.21",
"symfony/validator": "^5.4|^6.0|^7.0",
"twig/extra-bundle": "^3.17",
"twig/html-extra": "^3.17",
"twig/twig": "^3.15"
},
"require-dev": {
Expand Down
2 changes: 1 addition & 1 deletion public/app.25fa02d0.css → public/app.62f32d02.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/entrypoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"entrypoints": {
"app": {
"css": [
"/app.25fa02d0.css"
"/app.62f32d02.css"
],
"js": [
"/app.1ecd6d7a.js"
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"app.css": "app.25fa02d0.css",
"app.css": "app.62f32d02.css",
"app.js": "app.1ecd6d7a.js",
"form.js": "form.bcec6c2a.js",
"page-layout.js": "page-layout.3347892e.js",
Expand Down
12 changes: 12 additions & 0 deletions src/DependencyInjection/EasyAdminExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,17 @@ public function prepend(ContainerBuilder $builder): void
],
],
]);

$bundleTemplatesOverrideDir = $builder->getParameter('kernel.project_dir').'/templates/bundles/EasyAdminBundle/';
$builder->prependExtensionConfig('twig', [
'paths' => is_dir($bundleTemplatesOverrideDir)
? [
'templates/bundles/EasyAdminBundle/' => 'ea',
\dirname(__DIR__).'/../templates/' => 'ea',
]
: [
\dirname(__DIR__).'/../templates/' => 'ea',
],
]);
}
}
7 changes: 7 additions & 0 deletions templates/components/ActionMenu.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{# ActionMenu is a component to create dropdowns of related actions.
It defines several sub-components (Overlay, ActionList, etc.)
Inspired by https://primer.style/components/action-menu
#}
<div {{ attributes.defaults({class: 'dropdown'}) }}>
<twig:block name="content"></twig:block>
</div>
3 changes: 3 additions & 0 deletions templates/components/ActionMenu/ActionList.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ul {{ attributes.defaults({class: 'dropdown-menu dropdown-menu-end'}) }}>
<twig:block name="content"></twig:block>
</ul>
3 changes: 3 additions & 0 deletions templates/components/ActionMenu/ActionList/Content.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li {{ attributes }}>
<twig:block name="content"></twig:block>
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<li class="dropdown-divider"></li>
13 changes: 13 additions & 0 deletions templates/components/ActionMenu/ActionList/Header.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% props
label = null,
renderLabelRaw = false,
icon = null,
htmlAttributes = {},
%}

{% if label is not empty or icon is not empty %}
<li {{ attributes.defaults({class: 'dropdown-header'}|merge(htmlAttributes)) }}>
{%- if icon %}<twig:ea:Icon {{ ...attributes.nested('icon').defaults({name: icon}) }} /> {% endif -%}
{%- if label is not empty -%}<span {{ attributes.nested('label') }}>{{ renderLabelRaw ? label|raw : label }}</span>{%- endif -%}
</li>
{% endif %}
14 changes: 14 additions & 0 deletions templates/components/ActionMenu/ActionList/Item.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% props
label = null,
renderLabelRaw = false,
icon = null,
url = null,
htmlAttributes = {},
%}

<li>
<a {{ attributes.defaults({class: 'dropdown-item', href: url}|merge(htmlAttributes)) }}>
{%- if icon %}<twig:ea:Icon {{ ...attributes.nested('icon').defaults({name: icon}) }} /> {% endif -%}
{%- if label is not empty -%}<span {{ attributes.nested('label') }}>{{ renderLabelRaw ? label|raw : label }}</span>{%- endif -%}
</a>
</li>
12 changes: 12 additions & 0 deletions templates/components/ActionMenu/Button.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% props
withoutDropdownToggleMarker = false,
%}

{% set css_class = html_classes(
'dropdown-toggle',
{ 'dropdown-toggle-hidden-marker': withoutDropdownToggleMarker }
) %}

<a {{ attributes.defaults({class: css_class, href: '#', role: 'button', 'data-bs-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false'}) }}>
<twig:block name="content"></twig:block>
</a>
3 changes: 3 additions & 0 deletions templates/components/ActionMenu/Overlay.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div {{ attributes.defaults({class: 'dropdown-overlay'}) }}>
<twig:block name="content"></twig:block>
</div>
32 changes: 17 additions & 15 deletions templates/crud/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,23 @@
<td class="actions {{ ea.crud.showEntityActionsAsDropdown ? 'actions-as-dropdown' }}">
{% if entity.actions.count > 0 %}
{% if ea.crud.showEntityActionsAsDropdown %}
<div class="dropdown dropdown-actions">
<a class="dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{# don't use FontAwesome 'fa-ellipsis-h' icon here because it doesn't look good #}
{# this icon is 'dots-horizontal' icon from https://heroicons.com/ #}
<svg xmlns="http://www.w3.org/2000/svg" height="21" width="21" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" />
</svg>
</a>

<div class="dropdown-menu dropdown-menu-right">
{% for action in entity.actions %}
{{ include(action.templatePath, { action: action, entity: entity, isIncludedInDropdown: ea.crud.showEntityActionsAsDropdown }, with_context = false) }}
{% endfor %}
</div>
</div>
<twig:ea:ActionMenu class="dropdown-actions">
<twig:ea:ActionMenu:Button withoutDropdownToggleMarker>
<twig:ea:Icon name="internal:dots-horizontal" />
</twig:ea:ActionMenu:Button>

<twig:ea:ActionMenu:Overlay>
<twig:ea:ActionMenu:ActionList>
{% for action in entity.actions %}
<twig:ea:ActionMenu:ActionList:Item
class="{{ action.cssClass }}" url="{{ action.linkUrl }}"
icon="{{ action.icon }}" icon:class="action-icon"
htmlAttributes="{{ action.htmlAttributes }}"
label="{{ action.label|trans }}" label:class="action-label" renderLabelRaw />
{% endfor %}
</twig:ea:ActionMenu:ActionList>
</twig:ea:ActionMenu:Overlay>
</twig:ea:ActionMenu>
{% else %}
{% for action in entity.actions %}
{{ include(action.templatePath, { action: action, entity: entity, isIncludedInDropdown: ea.crud.showEntityActionsAsDropdown }, with_context = false) }}
Expand Down
Loading

0 comments on commit da8ece2

Please sign in to comment.