diff --git a/css/paragraphs.widget.css b/css/paragraphs.widget.css index 9994da3..27ebc83 100644 --- a/css/paragraphs.widget.css +++ b/css/paragraphs.widget.css @@ -69,6 +69,7 @@ } .js .paragraph-type-title { flex-basis: 25%; + flex-grow: 1; min-width: 80px; white-space: nowrap; text-overflow: ellipsis; @@ -103,3 +104,65 @@ .js .paragraph-type-top .paragraphs-dropbutton-wrapper { text-align: right; } + +.paragraph-collapse-button-container{ + float: right; +} + +.paragraphs-collapse-icon { + background: url('/core/misc/icons/000000/more-vertical.svg') no-repeat center; + width: 30px; + height: 25px; + transition: all 0.1s; + cursor: pointer; + -webkit-font-smoothing: antialiased; +} + +.paragraphs-dropbutton-wrapper { + position: absolute; + z-index: 1000; + float: left; + display: none; + padding: 4px 0; + margin: 0; + list-style: none; + background-color: #f2f1eb; + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.2); + border-style: solid; + border-width: 1px; +} + +.paragraphs-dropbutton-wrapper.open { + display: block; + margin-top: 15px; + position: absolute; + box-sizing: border-box; + z-index: 100; +} + +.js .paragraphs-collapsible-action-item { + display: block; + width: 100%; + padding: 3px 15px; + clear: both; + font-weight: 600; + line-height: 18px; + color: #555555; + white-space: nowrap; + border: 0; + border-radius: 0; + background-image: none; +} + +.remove { + list-style: none; +} + +.duplicate { + list-style: none; +} + +.collapse { + list-style: none; +} diff --git a/js/paragraphs_widget.js b/js/paragraphs_widget.js new file mode 100644 index 0000000..e57d97c --- /dev/null +++ b/js/paragraphs_widget.js @@ -0,0 +1,24 @@ +(function ($, Drupal) { + + 'use strict'; + + + /** + * Process elements with the .paragraphscollapse class on page load. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches dropButton behaviors. + */ + Drupal.behaviors.paragraphscollapse = { + attach: function (context, settings) { + var $dropbutton = $(context).find('.paragraphs-collapse-icon'); + // Adds the delegated handler that will toggle dropdowns on click. + $dropbutton.unbind('click').on('click', function () { + // Show action buttons. + $(this).parent().find('.paragraphs-dropbutton-wrapper').toggleClass('open'); + }); + } + }; +})(jQuery, Drupal); diff --git a/paragraphs.libraries.yml b/paragraphs.libraries.yml index bb2015d..ebfc9b3 100644 --- a/paragraphs.libraries.yml +++ b/paragraphs.libraries.yml @@ -16,3 +16,12 @@ drupal.paragraphs.widget: css: theme: css/paragraphs.widget.css: {} + js: + js/paragraphs_widget.js: {} + dependencies: + - core/drupalSettings + - core/jquery.once + - core/jquery + - core/jquery.form + - core/drupal.ajax + - core/drupal diff --git a/src/Element/ParagraphsCollapse.php b/src/Element/ParagraphsCollapse.php new file mode 100644 index 0000000..3804491 --- /dev/null +++ b/src/Element/ParagraphsCollapse.php @@ -0,0 +1,52 @@ + 'paragraphs_collapse', + * ); + * @endcode + * + * @FormElement("paragraphs_collapse") + */ +class ParagraphsCollapse extends RenderElement { + + /** + * {@inheritdoc} + */ + public function getInfo() { + $class = get_class($this); + + return [ + '#pre_render' => [ + [$class, 'preRenderParagraphsCollapse'], + ], + ]; + } + + /** + * #pre_render callback for #type 'paragraphs_collapse'. + * + * @param array $element + * An associative array containing the properties and children of the table + * element. + * + * @return array + * The processed element. + */ + public static function preRenderParagraphsCollapse($element) { + // @todo Make the $element a dropbutton with the actions. + $element['#attached']['library'][] = 'paragraphs/drupal.paragraphs.widget'; + $element['#attributes']['class'][] = 'paragraphscollapse'; + $element['#prefix'] = '
'; + $element['#suffix'] = '
'; + return $element; + } +} diff --git a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php index eda8415..eda1f74 100644 --- a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php @@ -386,6 +386,11 @@ class ParagraphsWidget extends WidgetBase { '#value' => $this->t('Duplicate'), '#name' => strtr($id_prefix, '-', '_') . '_duplicate', '#weight' => 502, + '#attributes' => [ + 'class' => [ + 'paragraphs-collapsible-action-item', + ], + ], '#submit' => [[get_class($this), 'duplicateSubmit']], '#limit_validation_errors' => [array_merge($parents, [$field_name, 'add_more'])], '#delta' => $delta, @@ -407,6 +412,11 @@ class ParagraphsWidget extends WidgetBase { '#value' => $this->t('Remove'), '#name' => strtr($id_prefix, '-', '_') . '_remove', '#weight' => 501 , + '#attributes' => [ + 'class' => [ + 'paragraphs-collapsible-action-item', + ], + ], '#submit' => [[get_class($this), 'paragraphsItemSubmit']], '#limit_validation_errors' => [array_merge($parents, [$field_name, 'add_more'])], '#delta' => $delta, @@ -430,6 +440,11 @@ class ParagraphsWidget extends WidgetBase { '#value' => $this->t('Collapse'), '#name' => strtr($id_prefix, '-', '_') . '_collapse', '#weight' => 499, + '#attributes' => [ + 'class' => [ + 'paragraphs-collapsible-action-item', + ], + ], '#submit' => array(array(get_class($this), 'paragraphsItemSubmit')), '#delta' => $delta, '#ajax' => array( @@ -545,26 +560,16 @@ class ParagraphsWidget extends WidgetBase { if ($show_links > 0) { + $element['top']['collapsible_button'] = [ + '#type' => 'paragraphs_collapse', + '#weight' => 1000, + ]; + $element['top']['links'] = $links; - if ($show_links > 1) { - $element['top']['links']['#theme_wrappers'] = array('dropbutton_wrapper', 'paragraphs_dropbutton_wrapper'); - $element['top']['links']['prefix'] = array( - '#markup' => '