Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
23.67% |
40 / 169 |
|
24.53% |
13 / 53 |
|
3.95% |
3 / 76 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
| RenderableBuilderTrait | |
23.67% |
40 / 169 |
|
24.53% |
13 / 53 |
|
3.95% |
3 / 76 |
|
0.00% |
0 / 13 |
998.06 | |
0.00% |
0 / 1 |
| buildError | |
95.83% |
23 / 24 |
|
85.71% |
6 / 7 |
|
12.50% |
1 / 8 |
|
0.00% |
0 / 1 |
14.72 | |||
| buildPlaceholder | |
75.00% |
12 / 16 |
|
55.56% |
5 / 9 |
|
6.25% |
1 / 16 |
|
0.00% |
0 / 1 |
25.60 | |||
| buildPlaceholderButton | |
83.33% |
5 / 6 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| buildPlaceholderButtonWithPreview | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildPlaceholderCardWithPreview | |
0.00% |
0 / 13 |
|
0.00% |
0 / 5 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| buildButton | |
0.00% |
0 / 15 |
|
0.00% |
0 / 5 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| buildIconButton | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildMenuItem | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildMenuDivider | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildDraggables | |
0.00% |
0 / 13 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| buildTabs | |
0.00% |
0 / 11 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| buildInput | |
0.00% |
0 / 20 |
|
0.00% |
0 / 11 |
|
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
42 | |||
| wrapContent | |
0.00% |
0 / 8 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder; |
| 6 | |
| 7 | use Drupal\Core\StringTranslation\TranslatableMarkup; |
| 8 | use Drupal\Core\Url; |
| 9 | |
| 10 | /** |
| 11 | * Trait with helpers to build renderables. |
| 12 | */ |
| 13 | trait RenderableBuilderTrait { |
| 14 | |
| 15 | /** |
| 16 | * Build error message. |
| 17 | * |
| 18 | * @param string $builder_id |
| 19 | * The builder id. |
| 20 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $message |
| 21 | * The message to display. |
| 22 | * @param string|null $debug |
| 23 | * (Optional) Debug information to print. |
| 24 | * @param int|null $duration |
| 25 | * (Optional) Alert duration before closing. |
| 26 | * @param bool $global |
| 27 | * (Optional) Try to use the default builder message placeholder. |
| 28 | * |
| 29 | * @return array |
| 30 | * The input render array. |
| 31 | */ |
| 32 | public function buildError(string $builder_id, string|TranslatableMarkup $message, ?string $debug = NULL, ?int $duration = NULL, bool $global = FALSE): array { |
| 33 | $build = [ |
| 34 | '#type' => 'component', |
| 35 | '#component' => 'display_builder:alert', |
| 36 | '#slots' => [ |
| 37 | 'content' => $message, |
| 38 | ], |
| 39 | '#props' => [ |
| 40 | 'variant' => 'danger', |
| 41 | 'icon' => 'exclamation-octagon', |
| 42 | 'open' => TRUE, |
| 43 | 'closable' => TRUE, |
| 44 | ], |
| 45 | '#attributes' => [ |
| 46 | 'class' => 'db-message', |
| 47 | ], |
| 48 | ]; |
| 49 | |
| 50 | if ($debug) { |
| 51 | $build['#slots']['debug'] = $debug; |
| 52 | } |
| 53 | |
| 54 | if ($duration) { |
| 55 | $build['#props']['duration'] = $duration; |
| 56 | } |
| 57 | |
| 58 | if ($global) { |
| 59 | $build['#props']['id'] = \sprintf('message-%s', $builder_id); |
| 60 | $build['#attributes']['hx-swap-oob'] = 'true'; |
| 61 | } |
| 62 | |
| 63 | return $build; |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * Build placeholder. |
| 68 | * |
| 69 | * @param string $label |
| 70 | * The placeholder label. |
| 71 | * @param string $title |
| 72 | * (Optional) Title attribute value. |
| 73 | * @param array $vals |
| 74 | * (Optional) HTMX vals data when placeholder trigger something when moving. |
| 75 | * @param string|null $keywords |
| 76 | * (Optional) Data attributes keywords for search. |
| 77 | * |
| 78 | * @return array |
| 79 | * A renderable array. |
| 80 | */ |
| 81 | protected function buildPlaceholder(string|TranslatableMarkup $label, string $title = '', array $vals = [], ?string $keywords = NULL): array { |
| 82 | $build = [ |
| 83 | '#type' => 'component', |
| 84 | '#component' => 'display_builder:placeholder', |
| 85 | '#slots' => [ |
| 86 | 'content' => $label, |
| 87 | ], |
| 88 | ]; |
| 89 | |
| 90 | if (isset($vals['source_id'])) { |
| 91 | $build['#attributes']['class'][] = \sprintf('db-placeholder-%s', $vals['source_id']); |
| 92 | } |
| 93 | |
| 94 | if ($keywords) { |
| 95 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 96 | } |
| 97 | |
| 98 | if (!empty($title)) { |
| 99 | $build['#attributes']['title'] = $title; |
| 100 | } |
| 101 | |
| 102 | if (!empty($vals)) { |
| 103 | $build['#attributes']['hx-vals'] = \json_encode($vals); |
| 104 | } |
| 105 | |
| 106 | return $build; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Build placeholder. |
| 111 | * |
| 112 | * @param string $label |
| 113 | * The placeholder label. |
| 114 | * @param array $vals |
| 115 | * (Optional) HTMX vals data when placeholder trigger something when moving. |
| 116 | * @param string|null $keywords |
| 117 | * (Optional) Keywords attributes to add used by search. |
| 118 | * |
| 119 | * @return array |
| 120 | * A renderable array. |
| 121 | */ |
| 122 | protected function buildPlaceholderButton(string|TranslatableMarkup $label, array $vals = [], ?string $keywords = NULL): array { |
| 123 | $build = $this->buildPlaceholder($label, '', $vals); |
| 124 | $build['#props']['variant'] = 'button'; |
| 125 | // To be able to identify the node when dragging and set the drawer title. |
| 126 | $build['#attributes']['data-node-title'] = (string) $label; |
| 127 | |
| 128 | if ($keywords) { |
| 129 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 130 | } |
| 131 | |
| 132 | return $build; |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Build placeholder. |
| 137 | * |
| 138 | * @param string $builder_id |
| 139 | * The builder id. |
| 140 | * @param string $label |
| 141 | * The placeholder label. |
| 142 | * @param array $vals |
| 143 | * HTMX vals data if the placeholder is triggering something when moving. |
| 144 | * @param \Drupal\Core\Url $preview_url |
| 145 | * The preview_url prop value. |
| 146 | * @param string|null $keywords |
| 147 | * (Optional) Keywords attributes to add used by search. |
| 148 | * |
| 149 | * @return array |
| 150 | * A renderable array. |
| 151 | */ |
| 152 | protected function buildPlaceholderButtonWithPreview(string $builder_id, string|TranslatableMarkup $label, array $vals, Url $preview_url, ?string $keywords = NULL): array { |
| 153 | $build = $this->buildPlaceholderButton($label, $vals, $keywords); |
| 154 | |
| 155 | $hide_script = \sprintf('Drupal.displayBuilder.hidePreview(%s)', $builder_id); |
| 156 | $attributes = [ |
| 157 | 'hx-get' => $preview_url->toString(), |
| 158 | 'hx-target' => \sprintf('#preview-%s', $builder_id), |
| 159 | 'hx-trigger' => 'mouseenter delay:250ms', |
| 160 | 'hx-on:mouseenter' => \sprintf('Drupal.displayBuilder.showPreview(%s, this)', $builder_id), |
| 161 | 'hx-on:focus' => \sprintf('Drupal.displayBuilder.showPreview(%s, this)', $builder_id), |
| 162 | 'hx-on:mouseleave' => $hide_script, |
| 163 | 'hx-on:blur' => $hide_script, |
| 164 | // Disable the preview on click for a dragging operation. |
| 165 | 'hx-on:mousedown' => $hide_script, |
| 166 | ]; |
| 167 | |
| 168 | $build['#attributes'] = \array_merge($build['#attributes'], $attributes); |
| 169 | |
| 170 | return $build; |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * Build placeholder. |
| 175 | * |
| 176 | * @param string $label |
| 177 | * The placeholder label. |
| 178 | * @param array $vals |
| 179 | * HTMX vals data if the placeholder is triggering something when moving. |
| 180 | * @param \Drupal\Core\Url $preview_url |
| 181 | * The preview_url prop value. |
| 182 | * @param string|null $keywords |
| 183 | * (Optional) Keywords attributes to add used by search. |
| 184 | * @param string|null $thumbnail |
| 185 | * (Optional) The thumbnail URL. |
| 186 | * |
| 187 | * @return array |
| 188 | * A renderable array. |
| 189 | */ |
| 190 | protected function buildPlaceholderCardWithPreview(string|TranslatableMarkup $label, array $vals, Url $preview_url, ?string $keywords = NULL, ?string $thumbnail = NULL): array { |
| 191 | $build = $this->buildPlaceholder($label, '', $vals); |
| 192 | $build['#props']['preview_url'] = $preview_url; |
| 193 | |
| 194 | if ($thumbnail) { |
| 195 | $build['#slots']['image'] = [ |
| 196 | '#type' => 'html_tag', |
| 197 | '#tag' => 'img', |
| 198 | '#attributes' => [ |
| 199 | // @todo generate proper relative url. |
| 200 | 'src' => '/' . $thumbnail, |
| 201 | ], |
| 202 | ]; |
| 203 | } |
| 204 | |
| 205 | if ($keywords) { |
| 206 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 207 | } |
| 208 | |
| 209 | return $build; |
| 210 | } |
| 211 | |
| 212 | /** |
| 213 | * Build a button. |
| 214 | * |
| 215 | * Uniq id is required for keyboard mapping with ajax requests. |
| 216 | * |
| 217 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $label |
| 218 | * The button label. |
| 219 | * @param string $action |
| 220 | * (Optional) The action value attribute. Used mainly for e2e tests. |
| 221 | * @param string|null $icon |
| 222 | * (Optional) The icon name. Default none. |
| 223 | * @param string|TranslatableMarkup|null $tooltip |
| 224 | * (Optional) Enable the tooltip feature. Default no tooltip. |
| 225 | * @param array|null $keyboard |
| 226 | * (Optional) Keyboard shortcut as associative array key => description. |
| 227 | * |
| 228 | * @return array |
| 229 | * The button render array. |
| 230 | */ |
| 231 | protected function buildButton( |
| 232 | string|TranslatableMarkup $label, |
| 233 | ?string $action, |
| 234 | ?string $icon = NULL, |
| 235 | string|TranslatableMarkup|null $tooltip = NULL, |
| 236 | ?array $keyboard = NULL, |
| 237 | ): array { |
| 238 | $button = [ |
| 239 | '#type' => 'component', |
| 240 | '#component' => 'display_builder:button', |
| 241 | '#props' => [ |
| 242 | 'label' => $label, |
| 243 | 'icon' => $icon, |
| 244 | 'tooltip' => $tooltip, |
| 245 | ], |
| 246 | ]; |
| 247 | |
| 248 | if ($keyboard) { |
| 249 | $button['#attributes']['data-keyboard-key'] = \key($keyboard); |
| 250 | $button['#attributes']['data-keyboard-help'] = \reset($keyboard) ?? ''; |
| 251 | } |
| 252 | |
| 253 | // Used to ease e2e tests. |
| 254 | if ($action) { |
| 255 | $button['#attributes']['data-island-action'] = $action; |
| 256 | } |
| 257 | |
| 258 | return $button; |
| 259 | } |
| 260 | |
| 261 | /** |
| 262 | * Build an icon button. |
| 263 | * |
| 264 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $label |
| 265 | * The button label. |
| 266 | * @param string|null $icon |
| 267 | * (Optional) The icon name. Default none. |
| 268 | * |
| 269 | * @return array |
| 270 | * The icon button render array. |
| 271 | * |
| 272 | * @todo never used, replace existing buildButton() where relevant |
| 273 | */ |
| 274 | protected function buildIconButton(string|TranslatableMarkup $label, ?string $icon = NULL): array { |
| 275 | return [ |
| 276 | '#type' => 'component', |
| 277 | '#component' => 'display_builder:icon_button', |
| 278 | '#props' => [ |
| 279 | 'icon' => $icon ?? '', |
| 280 | 'label' => $label, |
| 281 | ], |
| 282 | ]; |
| 283 | } |
| 284 | |
| 285 | /** |
| 286 | * Build a menu item. |
| 287 | * |
| 288 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $title |
| 289 | * The menu title. |
| 290 | * @param string $value |
| 291 | * The menu value. |
| 292 | * @param string|null $icon |
| 293 | * (Optional) The icon name. Default none. |
| 294 | * @param string $icon_position |
| 295 | * (Optional) The icon position. Default 'prefix'. |
| 296 | * @param bool $disabled |
| 297 | * (Optional) Is the menu disabled? Default no. |
| 298 | * |
| 299 | * @return array |
| 300 | * The menu item render array. |
| 301 | */ |
| 302 | protected function buildMenuItem( |
| 303 | string|TranslatableMarkup $title, |
| 304 | string $value, |
| 305 | ?string $icon = NULL, |
| 306 | string $icon_position = 'prefix', |
| 307 | bool $disabled = FALSE, |
| 308 | ): array { |
| 309 | return [ |
| 310 | '#type' => 'component', |
| 311 | '#component' => 'display_builder:menu_item', |
| 312 | '#props' => [ |
| 313 | 'title' => $title, |
| 314 | 'value' => $value, |
| 315 | 'icon' => $icon, |
| 316 | 'icon_position' => $icon_position, |
| 317 | 'disabled' => $disabled, |
| 318 | ], |
| 319 | '#attributes' => [ |
| 320 | 'data-contextual-menu' => TRUE, |
| 321 | ], |
| 322 | ]; |
| 323 | } |
| 324 | |
| 325 | /** |
| 326 | * Build a menu item divider. |
| 327 | * |
| 328 | * @return array |
| 329 | * The menu item render array. |
| 330 | */ |
| 331 | protected function buildMenuDivider(): array { |
| 332 | return [ |
| 333 | '#type' => 'component', |
| 334 | '#component' => 'display_builder:menu_item', |
| 335 | '#props' => [ |
| 336 | 'variant' => 'divider', |
| 337 | ], |
| 338 | ]; |
| 339 | } |
| 340 | |
| 341 | /** |
| 342 | * Build draggables placeholders. |
| 343 | * |
| 344 | * Used in library islands. |
| 345 | * |
| 346 | * @param string $builder_id |
| 347 | * Builder ID. |
| 348 | * @param array $draggables |
| 349 | * Draggable placeholders. |
| 350 | * @param string $variant |
| 351 | * (Optional) The variant. |
| 352 | * |
| 353 | * @return array |
| 354 | * The draggables render array. |
| 355 | */ |
| 356 | protected function buildDraggables(string $builder_id, array $draggables, string $variant = ''): array { |
| 357 | $build = [ |
| 358 | '#type' => 'component', |
| 359 | '#component' => 'display_builder:draggables', |
| 360 | '#slots' => [ |
| 361 | 'content' => $draggables, |
| 362 | ], |
| 363 | '#attributes' => [ |
| 364 | // Required for JavaScript @see components/draggables/draggables.js. |
| 365 | 'data-db-id' => $builder_id, |
| 366 | ], |
| 367 | ]; |
| 368 | |
| 369 | if ($variant) { |
| 370 | $build['#props']['variant'] = $variant; |
| 371 | } |
| 372 | |
| 373 | return $build; |
| 374 | } |
| 375 | |
| 376 | /** |
| 377 | * Build tabs. |
| 378 | * |
| 379 | * @param string $id |
| 380 | * The ID. Used for saving active tab in local storage. |
| 381 | * @param array $tabs |
| 382 | * Tabs as links. |
| 383 | * @param bool $contextual |
| 384 | * (Optional) Is the tabs contextual? Default no. |
| 385 | * |
| 386 | * @return array |
| 387 | * The tabs render array. |
| 388 | */ |
| 389 | protected function buildTabs(string $id, array $tabs, bool $contextual = FALSE): array { |
| 390 | $build = [ |
| 391 | '#type' => 'component', |
| 392 | '#component' => 'display_builder:tabs', |
| 393 | '#props' => [ |
| 394 | 'tabs' => $tabs, |
| 395 | 'contextual' => $contextual, |
| 396 | ], |
| 397 | ]; |
| 398 | |
| 399 | if ($id) { |
| 400 | $build['#props']['id'] = $id; |
| 401 | } |
| 402 | |
| 403 | return $build; |
| 404 | } |
| 405 | |
| 406 | /** |
| 407 | * Build input. |
| 408 | * |
| 409 | * @param string $id |
| 410 | * The ID. Used for saving active tab in local storage. |
| 411 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $label |
| 412 | * The label. |
| 413 | * @param string $type |
| 414 | * The input type. |
| 415 | * @param string $size |
| 416 | * (Optional) The input size. Default medium. |
| 417 | * @param string|null $autocomplete |
| 418 | * (Optional) The input autocomplete. |
| 419 | * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $placeholder |
| 420 | * (Optional) The input placeholder. |
| 421 | * @param bool|null $clearable |
| 422 | * (Optional) The input clearable. |
| 423 | * @param string|null $icon |
| 424 | * (Optional) The input icon. |
| 425 | * |
| 426 | * @return array |
| 427 | * The input render array. |
| 428 | */ |
| 429 | protected function buildInput(string $id, string|TranslatableMarkup $label, string $type, string $size = 'medium', ?string $autocomplete = NULL, string|TranslatableMarkup $placeholder = '', ?bool $clearable = NULL, ?string $icon = NULL): array { |
| 430 | $build = [ |
| 431 | '#type' => 'component', |
| 432 | '#component' => 'display_builder:input', |
| 433 | '#props' => [ |
| 434 | 'label' => $label, |
| 435 | 'variant' => $type, |
| 436 | 'size' => $size, |
| 437 | ], |
| 438 | ]; |
| 439 | |
| 440 | if ($id) { |
| 441 | $build['#props']['id'] = $id; |
| 442 | } |
| 443 | |
| 444 | if ($autocomplete) { |
| 445 | $build['#props']['autocomplete'] = $autocomplete; |
| 446 | } |
| 447 | |
| 448 | if ($placeholder) { |
| 449 | $build['#props']['placeholder'] = $placeholder; |
| 450 | } |
| 451 | |
| 452 | if ($clearable) { |
| 453 | $build['#props']['clearable'] = TRUE; |
| 454 | } |
| 455 | |
| 456 | if ($icon) { |
| 457 | $build['#props']['icon'] = $icon; |
| 458 | } |
| 459 | |
| 460 | return $build; |
| 461 | } |
| 462 | |
| 463 | /** |
| 464 | * Wraps a renderable in a div. |
| 465 | * |
| 466 | * Commonly used with tabs. |
| 467 | * |
| 468 | * @param array $content |
| 469 | * The renderable content. |
| 470 | * @param string $id |
| 471 | * (Optional) The div id. |
| 472 | * |
| 473 | * @return array |
| 474 | * The wrapped render array. |
| 475 | */ |
| 476 | protected function wrapContent(array $content, string $id = ''): array { |
| 477 | $build = [ |
| 478 | '#type' => 'html_tag', |
| 479 | '#tag' => 'div', |
| 480 | 'content' => $content, |
| 481 | ]; |
| 482 | |
| 483 | if (!empty($id)) { |
| 484 | $build['#attributes']['id'] = $id; |
| 485 | } |
| 486 | |
| 487 | return $build; |
| 488 | } |
| 489 | |
| 490 | } |
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 231 | protected function buildButton( |
| 232 | string|TranslatableMarkup $label, |
| 233 | ?string $action, |
| 234 | ?string $icon = NULL, |
| 235 | string|TranslatableMarkup|null $tooltip = NULL, |
| 236 | ?array $keyboard = NULL, |
| 237 | ): array { |
| 238 | $button = [ |
| 239 | '#type' => 'component', |
| 240 | '#component' => 'display_builder:button', |
| 241 | '#props' => [ |
| 242 | 'label' => $label, |
| 243 | 'icon' => $icon, |
| 244 | 'tooltip' => $tooltip, |
| 245 | ], |
| 246 | ]; |
| 247 | |
| 248 | if ($keyboard) { |
| 249 | $button['#attributes']['data-keyboard-key'] = \key($keyboard); |
| 250 | $button['#attributes']['data-keyboard-help'] = \reset($keyboard) ?? ''; |
| 251 | } |
| 252 | |
| 253 | // Used to ease e2e tests. |
| 254 | if ($action) { |
| 254 | if ($action) { |
| 255 | $button['#attributes']['data-island-action'] = $action; |
| 256 | } |
| 257 | |
| 258 | return $button; |
| 258 | return $button; |
| 356 | protected function buildDraggables(string $builder_id, array $draggables, string $variant = ''): array { |
| 357 | $build = [ |
| 358 | '#type' => 'component', |
| 359 | '#component' => 'display_builder:draggables', |
| 360 | '#slots' => [ |
| 361 | 'content' => $draggables, |
| 362 | ], |
| 363 | '#attributes' => [ |
| 364 | // Required for JavaScript @see components/draggables/draggables.js. |
| 365 | 'data-db-id' => $builder_id, |
| 366 | ], |
| 367 | ]; |
| 368 | |
| 369 | if ($variant) { |
| 370 | $build['#props']['variant'] = $variant; |
| 371 | } |
| 372 | |
| 373 | return $build; |
| 373 | return $build; |
| 32 | public function buildError(string $builder_id, string|TranslatableMarkup $message, ?string $debug = NULL, ?int $duration = NULL, bool $global = FALSE): array { |
| 33 | $build = [ |
| 34 | '#type' => 'component', |
| 35 | '#component' => 'display_builder:alert', |
| 36 | '#slots' => [ |
| 37 | 'content' => $message, |
| 38 | ], |
| 39 | '#props' => [ |
| 40 | 'variant' => 'danger', |
| 41 | 'icon' => 'exclamation-octagon', |
| 42 | 'open' => TRUE, |
| 43 | 'closable' => TRUE, |
| 44 | ], |
| 45 | '#attributes' => [ |
| 46 | 'class' => 'db-message', |
| 47 | ], |
| 48 | ]; |
| 49 | |
| 50 | if ($debug) { |
| 51 | $build['#slots']['debug'] = $debug; |
| 52 | } |
| 53 | |
| 54 | if ($duration) { |
| 54 | if ($duration) { |
| 55 | $build['#props']['duration'] = $duration; |
| 56 | } |
| 57 | |
| 58 | if ($global) { |
| 58 | if ($global) { |
| 59 | $build['#props']['id'] = \sprintf('message-%s', $builder_id); |
| 60 | $build['#attributes']['hx-swap-oob'] = 'true'; |
| 61 | } |
| 62 | |
| 63 | return $build; |
| 63 | return $build; |
| 274 | protected function buildIconButton(string|TranslatableMarkup $label, ?string $icon = NULL): array { |
| 275 | return [ |
| 276 | '#type' => 'component', |
| 277 | '#component' => 'display_builder:icon_button', |
| 278 | '#props' => [ |
| 279 | 'icon' => $icon ?? '', |
| 280 | 'label' => $label, |
| 429 | protected function buildInput(string $id, string|TranslatableMarkup $label, string $type, string $size = 'medium', ?string $autocomplete = NULL, string|TranslatableMarkup $placeholder = '', ?bool $clearable = NULL, ?string $icon = NULL): array { |
| 430 | $build = [ |
| 431 | '#type' => 'component', |
| 432 | '#component' => 'display_builder:input', |
| 433 | '#props' => [ |
| 434 | 'label' => $label, |
| 435 | 'variant' => $type, |
| 436 | 'size' => $size, |
| 437 | ], |
| 438 | ]; |
| 439 | |
| 440 | if ($id) { |
| 441 | $build['#props']['id'] = $id; |
| 442 | } |
| 443 | |
| 444 | if ($autocomplete) { |
| 444 | if ($autocomplete) { |
| 445 | $build['#props']['autocomplete'] = $autocomplete; |
| 446 | } |
| 447 | |
| 448 | if ($placeholder) { |
| 448 | if ($placeholder) { |
| 449 | $build['#props']['placeholder'] = $placeholder; |
| 450 | } |
| 451 | |
| 452 | if ($clearable) { |
| 452 | if ($clearable) { |
| 453 | $build['#props']['clearable'] = TRUE; |
| 454 | } |
| 455 | |
| 456 | if ($icon) { |
| 456 | if ($icon) { |
| 457 | $build['#props']['icon'] = $icon; |
| 458 | } |
| 459 | |
| 460 | return $build; |
| 460 | return $build; |
| 333 | '#type' => 'component', |
| 302 | protected function buildMenuItem( |
| 303 | string|TranslatableMarkup $title, |
| 304 | string $value, |
| 305 | ?string $icon = NULL, |
| 306 | string $icon_position = 'prefix', |
| 307 | bool $disabled = FALSE, |
| 308 | ): array { |
| 309 | return [ |
| 310 | '#type' => 'component', |
| 81 | protected function buildPlaceholder(string|TranslatableMarkup $label, string $title = '', array $vals = [], ?string $keywords = NULL): array { |
| 82 | $build = [ |
| 83 | '#type' => 'component', |
| 84 | '#component' => 'display_builder:placeholder', |
| 85 | '#slots' => [ |
| 86 | 'content' => $label, |
| 87 | ], |
| 88 | ]; |
| 89 | |
| 90 | if (isset($vals['source_id'])) { |
| 91 | $build['#attributes']['class'][] = \sprintf('db-placeholder-%s', $vals['source_id']); |
| 92 | } |
| 93 | |
| 94 | if ($keywords) { |
| 94 | if ($keywords) { |
| 95 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 96 | } |
| 97 | |
| 98 | if (!empty($title)) { |
| 98 | if (!empty($title)) { |
| 99 | $build['#attributes']['title'] = $title; |
| 100 | } |
| 101 | |
| 102 | if (!empty($vals)) { |
| 102 | if (!empty($vals)) { |
| 103 | $build['#attributes']['hx-vals'] = \json_encode($vals); |
| 104 | } |
| 105 | |
| 106 | return $build; |
| 106 | return $build; |
| 122 | protected function buildPlaceholderButton(string|TranslatableMarkup $label, array $vals = [], ?string $keywords = NULL): array { |
| 123 | $build = $this->buildPlaceholder($label, '', $vals); |
| 124 | $build['#props']['variant'] = 'button'; |
| 125 | // To be able to identify the node when dragging and set the drawer title. |
| 126 | $build['#attributes']['data-node-title'] = (string) $label; |
| 127 | |
| 128 | if ($keywords) { |
| 129 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 130 | } |
| 131 | |
| 132 | return $build; |
| 132 | return $build; |
| 152 | protected function buildPlaceholderButtonWithPreview(string $builder_id, string|TranslatableMarkup $label, array $vals, Url $preview_url, ?string $keywords = NULL): array { |
| 153 | $build = $this->buildPlaceholderButton($label, $vals, $keywords); |
| 154 | |
| 155 | $hide_script = \sprintf('Drupal.displayBuilder.hidePreview(%s)', $builder_id); |
| 156 | $attributes = [ |
| 157 | 'hx-get' => $preview_url->toString(), |
| 158 | 'hx-target' => \sprintf('#preview-%s', $builder_id), |
| 159 | 'hx-trigger' => 'mouseenter delay:250ms', |
| 160 | 'hx-on:mouseenter' => \sprintf('Drupal.displayBuilder.showPreview(%s, this)', $builder_id), |
| 161 | 'hx-on:focus' => \sprintf('Drupal.displayBuilder.showPreview(%s, this)', $builder_id), |
| 162 | 'hx-on:mouseleave' => $hide_script, |
| 163 | 'hx-on:blur' => $hide_script, |
| 164 | // Disable the preview on click for a dragging operation. |
| 165 | 'hx-on:mousedown' => $hide_script, |
| 166 | ]; |
| 167 | |
| 168 | $build['#attributes'] = \array_merge($build['#attributes'], $attributes); |
| 169 | |
| 170 | return $build; |
| 190 | protected function buildPlaceholderCardWithPreview(string|TranslatableMarkup $label, array $vals, Url $preview_url, ?string $keywords = NULL, ?string $thumbnail = NULL): array { |
| 191 | $build = $this->buildPlaceholder($label, '', $vals); |
| 192 | $build['#props']['preview_url'] = $preview_url; |
| 193 | |
| 194 | if ($thumbnail) { |
| 196 | '#type' => 'html_tag', |
| 197 | '#tag' => 'img', |
| 198 | '#attributes' => [ |
| 199 | // @todo generate proper relative url. |
| 200 | 'src' => '/' . $thumbnail, |
| 201 | ], |
| 202 | ]; |
| 203 | } |
| 204 | |
| 205 | if ($keywords) { |
| 205 | if ($keywords) { |
| 206 | $build['#attributes']['data-keywords'] = \trim(\strtolower($keywords)); |
| 207 | } |
| 208 | |
| 209 | return $build; |
| 209 | return $build; |
| 389 | protected function buildTabs(string $id, array $tabs, bool $contextual = FALSE): array { |
| 390 | $build = [ |
| 391 | '#type' => 'component', |
| 392 | '#component' => 'display_builder:tabs', |
| 393 | '#props' => [ |
| 394 | 'tabs' => $tabs, |
| 395 | 'contextual' => $contextual, |
| 396 | ], |
| 397 | ]; |
| 398 | |
| 399 | if ($id) { |
| 400 | $build['#props']['id'] = $id; |
| 401 | } |
| 402 | |
| 403 | return $build; |
| 403 | return $build; |
| 476 | protected function wrapContent(array $content, string $id = ''): array { |
| 477 | $build = [ |
| 478 | '#type' => 'html_tag', |
| 479 | '#tag' => 'div', |
| 480 | 'content' => $content, |
| 481 | ]; |
| 482 | |
| 483 | if (!empty($id)) { |
| 484 | $build['#attributes']['id'] = $id; |
| 485 | } |
| 486 | |
| 487 | return $build; |
| 487 | return $build; |