Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Menu
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 2
6
0.00% covered (danger)
0.00%
0 / 1
 build
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addShortcut
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\StringTranslation\TranslatableMarkup;
8use Drupal\display_builder\Attribute\Island;
9use Drupal\display_builder\InstanceInterface;
10use Drupal\display_builder\Island\IslandPluginBase;
11use Drupal\display_builder\Island\IslandType;
12
13/**
14 * Menu island plugin implementation.
15 */
16#[Island(
17  id: 'menu',
18  label: new TranslatableMarkup('Main menu items'),
19  description: new TranslatableMarkup('Copy, paste and duplicate.'),
20  type: IslandType::Menu,
21)]
22class Menu extends IslandPluginBase {
23
24  /**
25   * {@inheritdoc}
26   */
27  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
28    $builder_id = (string) $builder->id();
29
30    // Copy, paste and duplicate are also reachable with Ctrl/Cmd+C / +V / +D,
31    // without opening the menu, acting on whichever node is currently selected.
32    // @see components/display_builder/js/keyboard.js
33    $copy = $this->buildMenuItem($this->t('Copy'), 'copy');
34    $this->addShortcut($copy, 'mod+c', (string) $this->t('Copy the selected element'));
35
36    $paste = $this->buildMenuItem($this->t('Paste'), 'paste');
37    $this->addShortcut($paste, 'mod+v', (string) $this->t('Paste next to the selected element'));
38    $paste = $this->htmxEvents->onClickPaste($paste, $builder_id);
39
40    $duplicate = $this->buildMenuItem($this->t('Duplicate'), 'duplicate');
41    $this->addShortcut($duplicate, 'mod+d', (string) $this->t('Duplicate the selected element'));
42    $duplicate = $this->htmxEvents->onClickDuplicate($duplicate, $builder_id);
43
44    return [
45      $copy,
46      $paste,
47      $duplicate,
48    ];
49  }
50
51  /**
52   * Adds a keyboard shortcut to a menu item render array.
53   *
54   * @param array $item
55   *   The menu item render array, modified by reference.
56   * @param string $key
57   *   The canonical combo string, e.g. "mod+c".
58   * @param string $help
59   *   The help text shown in the shortcuts dialog.
60   */
61  private function addShortcut(array &$item, string $key, string $help): void {
62    $item['#attributes']['data-keyboard-key'] = $key;
63    $item['#attributes']['data-keyboard-help'] = $help;
64    $item['#attributes']['aria-keyshortcuts'] = $key;
65  }
66
67}