From ffee4611be9846c83283fa60cc98996b1f0b4282 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Sun, 30 Mar 2025 23:01:34 +0000
Subject: [PATCH 01/10] Add possibility to add a legend + style the table from
 the formatter

---
 css/table-themes.css                          | 113 +++++++++++++++++
 src/Element/UltimateTable.php                 |  26 +++-
 .../UltimateTableFieldFormatter.php           | 117 +++++++++++++++++-
 .../FieldType/UltimateTableFieldType.php      |   9 ++
 .../FieldWidget/UltimateTableFieldWidget.php  |   2 +
 ultimate_table_field.libraries.yml            |   8 +-
 6 files changed, 269 insertions(+), 6 deletions(-)
 create mode 100644 css/table-themes.css

diff --git a/css/table-themes.css b/css/table-themes.css
new file mode 100644
index 0000000..aceef97
--- /dev/null
+++ b/css/table-themes.css
@@ -0,0 +1,113 @@
+:root {
+  --table-width: 100%;
+  --table-vertical-align: top;
+  --table-border-color: #dee2e6;
+  --table-caption-side: bottom;
+  --table-border-collapse: collapse;
+  --table-border-width: 1px;
+  --table-cell-padding: 0.5rem;
+  --table-striped-bg: rgba(0, 0, 0, 0.05);
+  --table-striped-color: #212529;
+  --table-hover-bg: rgba(0, 0, 0, 0.075);
+  --table-hover-color: #212529;
+  --table-head-bg: #212529;
+  --table-head-color: #FFF;
+}
+
+/* Material Design Blue Theme */
+.table-blue {
+  --table-border-color: #bbdefb;
+  --table-striped-bg: #e3f2fd;
+  --table-striped-color: #0a2248;
+  --table-hover-bg: #90caf9;
+  --table-hover-color: white;
+  --table-head-bg: #2196f3;
+}
+
+/* Material Design Green Theme */
+.table-green {
+  --table-border-color: #c8e6c9;
+  --table-striped-bg: #e8f5e9;
+  --table-striped-color: #073a0a;
+  --table-hover-bg: #a5d6a7;
+  --table-hover-color: white;
+  --table-head-bg: #4caf50;
+}
+
+/* Material Design Purple Theme */
+.table-purple {
+  --table-border-color: #e1bee7;
+  --table-striped-bg: #f3e5f5;
+  --table-striped-color: #230646;
+  --table-hover-bg: #ce93d8;
+  --table-hover-color: white;
+  --table-head-bg: #9c27b0;
+}
+
+/* Base styles */
+.table-ultimate {
+  overflow-x: auto;
+  width: 100%;
+  display: block;
+  -webkit-overflow-scrolling: touch;
+  -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+
+.table-ultimate table {
+  width: var(--table-width);
+  vertical-align: var(--table-vertical-align);
+  border-color: var(--table-border-color);
+  caption-side: var(--table-caption-side);
+  border-collapse: var(--table-border-collapse);
+}
+
+.table-ultimate thead {
+  vertical-align: bottom;
+}
+
+.table-ultimate tbody,
+.table-ultimate td,
+.table-ultimate tfoot,
+.table-ultimate th,
+.table-ultimate thead,
+.table-ultimate tr {
+  border-color: inherit;
+  border-style: solid;
+  border-width: 0;
+}
+
+.table-ultimate table>:not(caption)>*>* {
+  padding: var(--table-cell-padding);
+  border-bottom-width: var(--table-border-width);
+}
+
+.table-ultimate th {
+  text-align: inherit;
+  text-align: -webkit-match-parent;
+}
+
+/* Variants */
+.table-ultimate .striped-odd>tbody>tr:nth-of-type(odd) {
+  background-color: var(--table-striped-bg);
+  color: var(--table-striped-color);
+}
+
+.table-ultimate .striped-even>tbody>tr:nth-of-type(even) {
+  background-color: var(--table-striped-bg);
+  color: var(--table-striped-color);
+}
+
+.table-ultimate .filled-head>thead>* {
+  background-color: var(--table-head-bg);
+  color: var(--table-head-color);
+}
+
+.table-ultimate .hoverable>tbody>tr:hover {
+  background-color: var(--table-hover-bg);
+  color: var(--table-hover-color);
+}
+
+.table-ultimate .side-filled>tbody>tr>th {
+  background-color: var(--table-head-bg);
+  color: var(--table-head-color);
+}
diff --git a/src/Element/UltimateTable.php b/src/Element/UltimateTable.php
index f50a89a..68689ec 100644
--- a/src/Element/UltimateTable.php
+++ b/src/Element/UltimateTable.php
@@ -108,6 +108,18 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       '#type' => 'markup',
       '#markup' => !empty($label) ? '<strong class="form-item__label ' . ($required ? 'js-form-required form-required' : '') . '">' . $label . '</strong>' : '',
     ];
+
+    // Add legend field if enabled
+    if (!empty($element['#enable_legend'])) {
+      $element['legend'] = [
+        '#type' => 'text_format',
+        '#title' => t('Legend'),
+        '#format' => 'full_html',
+        '#default_value' => $values['legend'] ?? '',
+        '#rows' => 3,
+      ];
+    }
+
     $element['nb_unit'] = [
       '#type' => 'number',
       '#default_value' => 1,
@@ -197,7 +209,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     }
     $element['update'] = [
       '#type' => 'submit',
-      '#name' => 'update_table::' . str_replace('-', '_', $id),
+      '#name' => 'update_table__' . str_replace('-', '_', $id),
       '#value' => t('Update'),
       '#limit_validation_errors' => [[$first_parent]],
       '#attributes' => [
@@ -231,7 +243,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     $values = $form_state->getValues();
     $triggering_element = $form_state->getTriggeringElement();
     $name = $triggering_element['#name'] ?? '';
-    $name_pieces = explode('::', $name);
+    $name_pieces = explode('__', $name);
     $name_from_id = $name_pieces[0] ?? NULL;
     $id = $name_pieces[1] ?? NULL;
     $name = $name_from_id ?? $name;
@@ -340,7 +352,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     $user_input = $form_state->getUserInput();
     $triggering_element = $form_state->getTriggeringElement();
     $name = $triggering_element['#name'];
-    $name_pieces = explode('::', $name);
+    $name_pieces = explode('__', $name);
     $name_from_id = $name_pieces[0] ?? NULL;
     $id = $name_pieces[1] ?? NULL;
     $formatted_id = str_replace('_', '-', $id);
@@ -358,7 +370,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       $items_data = $data ? Json::decode($data) : [];
       unset($items_data[$k]);
       $response = new AjaxResponse();
-      $update_button_selector = 'input[name="update_table::' . $id . '"]';
+      $update_button_selector = 'input[name="update_table__' . $id . '"]';
       $data_input_selector = '#data-input-' . $i . '-' . $j . '--' . $formatted_id;
       $response->addCommand(new InvokeCommand($data_input_selector, 'val', [Json::encode($items_data)]))
         ->addCommand(new InvokeCommand($update_button_selector, 'trigger', ['mousedown']));
@@ -386,7 +398,12 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
     $columns_values = [];
     $rows_values = [];
+    $legend = '';
+
     if ($input) {
+      if (isset($input['legend'])) {
+        $legend = $input['legend']['value'];
+      }
       $input = $input['table'] ?? $input;
       $columns = $input[0];
       unset($input[0]);
@@ -430,6 +447,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       'values' => [
         'columns' => $columns_values,
         'rows' => $rows_values,
+        'legend' => $legend,
       ],
     ];
 
diff --git a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
index 0d6483c..9710e8d 100644
--- a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
@@ -5,6 +5,7 @@ namespace Drupal\ultimate_table_field\Plugin\Field\FieldFormatter;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FormatterBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Form\FormStateInterface;
 
 /**
  * Plugin implementation of the ultimate table field widget.
@@ -44,6 +45,74 @@ class UltimateTableFieldFormatter extends FormatterBase {
     return $instance;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'legend_position' => 'before',
+      'table_theme' => 'default',
+      'table_color' => '',
+      'table_style' => [],
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+    
+    $form['legend_position'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Legend position'),
+      '#options' => [
+        'before' => $this->t('Before table'),
+        'after' => $this->t('After table'),
+      ],
+      '#default_value' => $this->getSetting('legend_position'),
+    ];
+
+    $form['table_theme'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Table color theme'),
+      '#options' => [
+        '' => $this->t('Default'),
+        'blue' => $this->t('Blue'),
+        'green' => $this->t('Green'),
+        'purple' => $this->t('Purple'),
+      ],
+      '#default_value' => $this->getSetting('table_theme'),
+    ];
+
+    $form['table_style'] = [
+      '#type' => 'checkboxes',
+      '#title' => $this->t('Table styles'),
+      '#options' => [
+      'striped-odd' => $this->t('Striped rows (odd)'),
+      'striped-even' => $this->t('Striped rows (even)'),
+      'filled-head' => $this->t('Filled header'),
+      'hoverable' => $this->t('Hoverable rows'),
+      'side-filled' => $this->t('Side filled'),
+      ],
+      '#default_value' => $this->getSetting('table_style'),
+    ];
+
+    // Make striped-odd and striped-even mutually exclusive
+    $form['table_style']['striped-odd']['#states'] = [
+      'disabled' => [
+      ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-even]"]' => ['checked' => TRUE],
+      ],
+    ];
+    $form['table_style']['striped-even']['#states'] = [
+      'disabled' => [
+      ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-odd]"]' => ['checked' => TRUE],
+      ],
+    ];
+
+    return $form;
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -53,6 +122,19 @@ class UltimateTableFieldFormatter extends FormatterBase {
       $values = $item->value;
       $columns = $values['columns'] ?? [];
       $rows = $values['rows'] ?? [];
+      $legend = $values['legend'] ?? '';
+      
+      $element = [];
+      
+      // Add legend based on position setting
+      if ($legend && $this->getSetting('legend_position') === 'before') {
+        $element['legend'] = [
+          '#type' => 'markup',
+          '#markup' => $legend,
+        ];
+      }
+      
+      // Add table
       foreach ($rows as &$row) {
         foreach ($row as $j => $items) {
           if ($j === 0) {
@@ -66,14 +148,47 @@ class UltimateTableFieldFormatter extends FormatterBase {
           $row[$j] = $this->renderer->renderPlain($items);
         }
       }
-      $elements[] = [
+      $element['table'] = [
         '#type' => 'table',
         '#header' => $columns,
         '#rows' => $rows,
         '#empty' => t('No entries available'),
+        '#attributes' => [
+          'class' => $this->getTableClasses(),
+        ],
+        '#prefix' => '<div class="table-ultimate">',
+        '#suffix' => '</div>',
+        '#attached' => [
+          'library' => ['ultimate_table_field/table-themes'],
+        ],
       ];
+      
+      // Add legend after table if configured
+      if ($legend && $this->getSetting('legend_position') === 'after') {
+        $element['legend'] = [
+          '#type' => 'markup',
+          '#markup' => $legend,
+        ];
+      }
+      
+      $elements[] = $element;
     }
     return $elements;
   }
 
+  protected function getTableClasses() {
+    $classes = ['custom-bordered-table'];
+    
+    // Add color theme
+    if ($theme = $this->getSetting('table_theme')) {
+      $classes[] = 'table-' . $theme;
+    }
+    
+    // Add selected styles
+    $styles = array_filter($this->getSetting('table_style'));
+    $classes = array_merge($classes, array_keys($styles));
+    
+    return $classes;
+  }
+
 }
diff --git a/src/Plugin/Field/FieldType/UltimateTableFieldType.php b/src/Plugin/Field/FieldType/UltimateTableFieldType.php
index 8ba4f61..a2a1a85 100644
--- a/src/Plugin/Field/FieldType/UltimateTableFieldType.php
+++ b/src/Plugin/Field/FieldType/UltimateTableFieldType.php
@@ -95,6 +95,7 @@ class UltimateTableFieldType extends FieldItemBase {
   public static function defaultFieldSettings() {
     return [
       'allowed_types' => [],
+      'enable_legend' => FALSE,
     ] + parent::defaultFieldSettings();
   }
 
@@ -112,6 +113,14 @@ class UltimateTableFieldType extends FieldItemBase {
       '#default_value' => $this->getSetting('allowed_types') ?? [],
       '#description' => $this->t('Select table cell allowed field types plugins, leave empty to allow all types'),
     ];
+    
+    $form['enable_legend'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable legend field'),
+      '#default_value' => $this->getSetting('enable_legend'),
+      '#description' => $this->t('Add a legend field to the table.'),
+    ];
+    
     return $form;
   }
 
diff --git a/src/Plugin/Field/FieldWidget/UltimateTableFieldWidget.php b/src/Plugin/Field/FieldWidget/UltimateTableFieldWidget.php
index eecb6bb..60e4a1a 100644
--- a/src/Plugin/Field/FieldWidget/UltimateTableFieldWidget.php
+++ b/src/Plugin/Field/FieldWidget/UltimateTableFieldWidget.php
@@ -36,6 +36,8 @@ class UltimateTableFieldWidget extends WidgetBase {
       '#tree' => TRUE,
       '#allowed_types' => array_values($allowed_value),
       '#default_value' => $default_value,
+      '#enable_legend' => $this->getFieldSetting('enable_legend'),
+      '#enable_summary' => $this->getFieldSetting('enable_summary'),
     ];
 
     return $element;
diff --git a/ultimate_table_field.libraries.yml b/ultimate_table_field.libraries.yml
index 889d9b4..f79adf4 100644
--- a/ultimate_table_field.libraries.yml
+++ b/ultimate_table_field.libraries.yml
@@ -10,4 +10,10 @@ table-actions:
     'assets/js/ultimate-table.js': {}
   dependencies:
     - core/drupal
-    - core/jquery
\ No newline at end of file
+    - core/jquery
+
+table-themes:
+  version: 1.x
+  css:
+    theme:
+      css/table-themes.css: {}
\ No newline at end of file
-- 
GitLab


From 5f643ec2167c62d5afc62e8f43cb2ca83f416889 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Sun, 30 Mar 2025 23:23:05 +0000
Subject: [PATCH 02/10] Fix pipeline

---
 css/table-themes.css                          | 55 ++++++++++---------
 src/Element/UltimateTable.php                 |  2 +-
 .../UltimateTableFieldFormatter.php           | 35 +++++++-----
 .../FieldType/UltimateTableFieldType.php      |  4 +-
 4 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index aceef97..a0ec8d6 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -11,7 +11,7 @@
   --table-hover-bg: rgba(0, 0, 0, 0.075);
   --table-hover-color: #212529;
   --table-head-bg: #212529;
-  --table-head-color: #FFF;
+  --table-head-color: #fff;
 }
 
 /* Material Design Blue Theme */
@@ -46,18 +46,18 @@
 
 /* Base styles */
 .table-ultimate {
-  overflow-x: auto;
-  width: 100%;
-  display: block;
-  -webkit-overflow-scrolling: touch;
-  -ms-overflow-style: -ms-autohiding-scrollbar;
+    display: block;
+    width: 100%;
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
 }
 
 .table-ultimate table {
   width: var(--table-width);
   vertical-align: var(--table-vertical-align);
-  border-color: var(--table-border-color);
   caption-side: var(--table-caption-side);
+  border-color: var(--table-border-color);
   border-collapse: var(--table-border-collapse);
 }
 
@@ -71,14 +71,14 @@
 .table-ultimate th,
 .table-ultimate thead,
 .table-ultimate tr {
-  border-color: inherit;
-  border-style: solid;
   border-width: 0;
+  border-style: solid;
+  border-color: inherit;
 }
 
-.table-ultimate table>:not(caption)>*>* {
-  padding: var(--table-cell-padding);
-  border-bottom-width: var(--table-border-width);
+.table-ultimate table > :not(caption) > * > * {
+    padding: var(--table-cell-padding);
+    border-bottom-width: var(--table-border-width);
 }
 
 .table-ultimate th {
@@ -87,27 +87,28 @@
 }
 
 /* Variants */
-.table-ultimate .striped-odd>tbody>tr:nth-of-type(odd) {
-  background-color: var(--table-striped-bg);
-  color: var(--table-striped-color);
+.table-ultimate .striped-odd·>·tbody·>·tr:nth-of-type(odd) {
+    color: var(--table-striped-color);
+    background-color: var(--table-striped-bg);
 }
 
-.table-ultimate .striped-even>tbody>tr:nth-of-type(even) {
-  background-color: var(--table-striped-bg);
-  color: var(--table-striped-color);
+.table-ultimate .striped-even·>·tbody·>·tr:nth-of-type(even) {
+    background-color: var(--table-striped-bg);
+    color: var(--table-striped-color);
 }
 
-.table-ultimate .filled-head>thead>* {
-  background-color: var(--table-head-bg);
-  color: var(--table-head-color);
+.table-ultimate .filled-head·>·thead·>·* {
+    background-color: var(--table-head-bg);
+    color: var(--table-head-color);
+    background-color: var(--table-head-bg);
 }
 
-.table-ultimate .hoverable>tbody>tr:hover {
-  background-color: var(--table-hover-bg);
-  color: var(--table-hover-color);
+.table-ultimate .hoverable·>·tbody·>·tr:hover {
+    color: var(--table-hover-color);
+    background-color: var(--table-hover-bg);
 }
 
-.table-ultimate .side-filled>tbody>tr>th {
-  background-color: var(--table-head-bg);
-  color: var(--table-head-color);
+.table-ultimate .side-filled·>·tbody·>·tr·>·th {
+    color: var(--table-head-color);
+    background-color: var(--table-head-bg);
 }
diff --git a/src/Element/UltimateTable.php b/src/Element/UltimateTable.php
index 68689ec..4914f64 100644
--- a/src/Element/UltimateTable.php
+++ b/src/Element/UltimateTable.php
@@ -109,7 +109,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       '#markup' => !empty($label) ? '<strong class="form-item__label ' . ($required ? 'js-form-required form-required' : '') . '">' . $label . '</strong>' : '',
     ];
 
-    // Add legend field if enabled
+    // Add legend field if enabled.
     if (!empty($element['#enable_legend'])) {
       $element['legend'] = [
         '#type' => 'text_format',
diff --git a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
index 9710e8d..ef5d6a2 100644
--- a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
@@ -89,24 +89,24 @@ class UltimateTableFieldFormatter extends FormatterBase {
       '#type' => 'checkboxes',
       '#title' => $this->t('Table styles'),
       '#options' => [
-      'striped-odd' => $this->t('Striped rows (odd)'),
-      'striped-even' => $this->t('Striped rows (even)'),
-      'filled-head' => $this->t('Filled header'),
-      'hoverable' => $this->t('Hoverable rows'),
-      'side-filled' => $this->t('Side filled'),
+        'striped-odd' => $this->t('Striped rows (odd)'),
+        'striped-even' => $this->t('Striped rows (even)'),
+        'filled-head' => $this->t('Filled header'),
+        'hoverable' => $this->t('Hoverable rows'),
+        'side-filled' => $this->t('Side filled'),
       ],
       '#default_value' => $this->getSetting('table_style'),
     ];
 
-    // Make striped-odd and striped-even mutually exclusive
+    // Make striped-odd and striped-even mutually exclusive.
     $form['table_style']['striped-odd']['#states'] = [
       'disabled' => [
-      ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-even]"]' => ['checked' => TRUE],
+        ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-even]"]' => ['checked' => TRUE],
       ],
     ];
     $form['table_style']['striped-even']['#states'] = [
       'disabled' => [
-      ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-odd]"]' => ['checked' => TRUE],
+        ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][table_style][striped-odd]"]' => ['checked' => TRUE],
       ],
     ];
 
@@ -126,7 +126,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
       
       $element = [];
       
-      // Add legend based on position setting
+      // Add legend based on position setting.
       if ($legend && $this->getSetting('legend_position') === 'before') {
         $element['legend'] = [
           '#type' => 'markup',
@@ -134,7 +134,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
         ];
       }
       
-      // Add table
+      // Add table.
       foreach ($rows as &$row) {
         foreach ($row as $j => $items) {
           if ($j === 0) {
@@ -144,10 +144,11 @@ class UltimateTableFieldFormatter extends FormatterBase {
             $cell_field_instance = $this->ultimateTableCellFieldManager->createInstance($cell_item['type']);
             $cell_item = $cell_field_instance->cellFieldFormatter($cell_item);
           }
-          // @phpstan-ignore-next-line
           $row[$j] = $this->renderer->renderPlain($items);
         }
       }
+
+      // Add table element.
       $element['table'] = [
         '#type' => 'table',
         '#header' => $columns,
@@ -163,7 +164,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
         ],
       ];
       
-      // Add legend after table if configured
+      // Add legend after table if configured.
       if ($legend && $this->getSetting('legend_position') === 'after') {
         $element['legend'] = [
           '#type' => 'markup',
@@ -176,15 +177,21 @@ class UltimateTableFieldFormatter extends FormatterBase {
     return $elements;
   }
 
+  /**
+   * Gets the CSS classes for the table.
+   *
+   * @return array
+   *   An array of CSS classes.
+   */
   protected function getTableClasses() {
     $classes = ['custom-bordered-table'];
     
-    // Add color theme
+    // Add color theme.
     if ($theme = $this->getSetting('table_theme')) {
       $classes[] = 'table-' . $theme;
     }
     
-    // Add selected styles
+    // Add selected styles.
     $styles = array_filter($this->getSetting('table_style'));
     $classes = array_merge($classes, array_keys($styles));
     
diff --git a/src/Plugin/Field/FieldType/UltimateTableFieldType.php b/src/Plugin/Field/FieldType/UltimateTableFieldType.php
index a2a1a85..da3f917 100644
--- a/src/Plugin/Field/FieldType/UltimateTableFieldType.php
+++ b/src/Plugin/Field/FieldType/UltimateTableFieldType.php
@@ -113,14 +113,14 @@ class UltimateTableFieldType extends FieldItemBase {
       '#default_value' => $this->getSetting('allowed_types') ?? [],
       '#description' => $this->t('Select table cell allowed field types plugins, leave empty to allow all types'),
     ];
-    
+
     $form['enable_legend'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Enable legend field'),
       '#default_value' => $this->getSetting('enable_legend'),
       '#description' => $this->t('Add a legend field to the table.'),
     ];
-    
+
     return $form;
   }
 
-- 
GitLab


From 56d2b065884bf0c8ec2ef24aaa7b2183906569c0 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Sun, 30 Mar 2025 23:32:26 +0000
Subject: [PATCH 03/10] Fix pipeline

---
 css/table-themes.css                          | 45 +++++++++----------
 .../UltimateTableFieldFormatter.php           | 20 ++++-----
 2 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index a0ec8d6..65374e2 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -46,11 +46,11 @@
 
 /* Base styles */
 .table-ultimate {
-    display: block;
-    width: 100%;
-    overflow-x: auto;
-    -webkit-overflow-scrolling: touch;
-    -ms-overflow-style: -ms-autohiding-scrollbar;
+  display: block;
+  width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+  -ms-overflow-style: -ms-autohiding-scrollbar;
 }
 
 .table-ultimate table {
@@ -77,8 +77,8 @@
 }
 
 .table-ultimate table > :not(caption) > * > * {
-    padding: var(--table-cell-padding);
-    border-bottom-width: var(--table-border-width);
+  padding: var(--table-cell-padding);
+  border-bottom-width: var(--table-border-width);
 }
 
 .table-ultimate th {
@@ -87,28 +87,27 @@
 }
 
 /* Variants */
-.table-ultimate .striped-odd·>·tbody·>·tr:nth-of-type(odd) {
-    color: var(--table-striped-color);
-    background-color: var(--table-striped-bg);
+.table-ultimate .striped-odd > tbody > tr:nth-of-type(odd) {
+  color: var(--table-striped-color);
+  background-color: var(--table-striped-bg);
 }
 
-.table-ultimate .striped-even·>·tbody·>·tr:nth-of-type(even) {
-    background-color: var(--table-striped-bg);
-    color: var(--table-striped-color);
+.table-ultimate .striped-even > tbody > tr:nth-of-type(even) {
+  color: var(--table-striped-color);
+  background-color: var(--table-striped-bg);
 }
 
-.table-ultimate .filled-head·>·thead·>·* {
-    background-color: var(--table-head-bg);
-    color: var(--table-head-color);
-    background-color: var(--table-head-bg);
+.table-ultimate .filled-head > thead > * {
+  color: var(--table-head-color);
+  background-color: var(--table-head-bg);
 }
 
-.table-ultimate .hoverable·>·tbody·>·tr:hover {
-    color: var(--table-hover-color);
-    background-color: var(--table-hover-bg);
+.table-ultimate .hoverable > tbody > tr:hover {
+  color: var(--table-hover-color);
+  background-color: var(--table-hover-bg);
 }
 
-.table-ultimate .side-filled·>·tbody·>·tr·>·th {
-    color: var(--table-head-color);
-    background-color: var(--table-head-bg);
+.table-ultimate .side-filled > tbody > tr > th {
+  color: var(--table-head-color);
+  background-color: var(--table-head-bg);
 }
diff --git a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
index ef5d6a2..79dd1ca 100644
--- a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
@@ -62,7 +62,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
    */
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $form = parent::settingsForm($form, $form_state);
-    
+
     $form['legend_position'] = [
       '#type' => 'select',
       '#title' => $this->t('Legend position'),
@@ -123,9 +123,9 @@ class UltimateTableFieldFormatter extends FormatterBase {
       $columns = $values['columns'] ?? [];
       $rows = $values['rows'] ?? [];
       $legend = $values['legend'] ?? '';
-      
+
       $element = [];
-      
+
       // Add legend based on position setting.
       if ($legend && $this->getSetting('legend_position') === 'before') {
         $element['legend'] = [
@@ -133,7 +133,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
           '#markup' => $legend,
         ];
       }
-      
+
       // Add table.
       foreach ($rows as &$row) {
         foreach ($row as $j => $items) {
@@ -144,7 +144,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
             $cell_field_instance = $this->ultimateTableCellFieldManager->createInstance($cell_item['type']);
             $cell_item = $cell_field_instance->cellFieldFormatter($cell_item);
           }
-          $row[$j] = $this->renderer->renderPlain($items);
+          $row[$j] = $this->renderer->renderInIsolation($items);
         }
       }
 
@@ -163,7 +163,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
           'library' => ['ultimate_table_field/table-themes'],
         ],
       ];
-      
+
       // Add legend after table if configured.
       if ($legend && $this->getSetting('legend_position') === 'after') {
         $element['legend'] = [
@@ -171,7 +171,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
           '#markup' => $legend,
         ];
       }
-      
+
       $elements[] = $element;
     }
     return $elements;
@@ -185,16 +185,16 @@ class UltimateTableFieldFormatter extends FormatterBase {
    */
   protected function getTableClasses() {
     $classes = ['custom-bordered-table'];
-    
+
     // Add color theme.
     if ($theme = $this->getSetting('table_theme')) {
       $classes[] = 'table-' . $theme;
     }
-    
+
     // Add selected styles.
     $styles = array_filter($this->getSetting('table_style'));
     $classes = array_merge($classes, array_keys($styles));
-    
+
     return $classes;
   }
 
-- 
GitLab


From 31b1c2cc1197f514bb69a5951c157c1cbbed9927 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Sun, 30 Mar 2025 23:38:03 +0000
Subject: [PATCH 04/10] Fix pipeline

---
 css/table-themes.css | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index 65374e2..17f794e 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -47,18 +47,18 @@
 /* Base styles */
 .table-ultimate {
   display: block;
-  width: 100%;
   overflow-x: auto;
+  width: 100%;
   -webkit-overflow-scrolling: touch;
   -ms-overflow-style: -ms-autohiding-scrollbar;
 }
 
 .table-ultimate table {
-  width: var(--table-width);
-  vertical-align: var(--table-vertical-align);
   caption-side: var(--table-caption-side);
-  border-color: var(--table-border-color);
+  vertical-align: var(--table-vertical-align);
   border-collapse: var(--table-border-collapse);
+  border-color: var(--table-border-color);
+  width: var(--table-width);
 }
 
 .table-ultimate thead {
-- 
GitLab


From 34a6d49dfed4b60e18eb638016d9d1cebbe1d307 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Sun, 30 Mar 2025 23:41:42 +0000
Subject: [PATCH 05/10] Fix pipeline

---
 css/table-themes.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index 17f794e..85e4413 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -57,8 +57,8 @@
   caption-side: var(--table-caption-side);
   vertical-align: var(--table-vertical-align);
   border-collapse: var(--table-border-collapse);
-  border-color: var(--table-border-color);
   width: var(--table-width);
+  border-color: var(--table-border-color);
 }
 
 .table-ultimate thead {
-- 
GitLab


From 6d6946069cab2c7c6b0b59709d35f95425e2b076 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Mon, 31 Mar 2025 00:00:02 +0000
Subject: [PATCH 06/10] Fix pipeline

---
 css/table-themes.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index 85e4413..f7c627d 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -56,8 +56,8 @@
 .table-ultimate table {
   caption-side: var(--table-caption-side);
   vertical-align: var(--table-vertical-align);
-  border-collapse: var(--table-border-collapse);
   width: var(--table-width);
+  border-collapse: var(--table-border-collapse);
   border-color: var(--table-border-color);
 }
 
-- 
GitLab


From ee78ce1ee3fffafcb4c7f52041eab12ce56939b2 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Mon, 31 Mar 2025 00:03:38 +0000
Subject: [PATCH 07/10] Fix pipeline

---
 css/table-themes.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index f7c627d..9c038fa 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -55,8 +55,8 @@
 
 .table-ultimate table {
   caption-side: var(--table-caption-side);
-  vertical-align: var(--table-vertical-align);
   width: var(--table-width);
+  vertical-align: var(--table-vertical-align);
   border-collapse: var(--table-border-collapse);
   border-color: var(--table-border-color);
 }
-- 
GitLab


From ef14f4ffbb32e4fd999f685e76a23b7bcdf2fa36 Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Mon, 31 Mar 2025 00:14:59 +0000
Subject: [PATCH 08/10] Fix pipeline

---
 css/table-themes.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index 9c038fa..db4c184 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -54,8 +54,8 @@
 }
 
 .table-ultimate table {
-  caption-side: var(--table-caption-side);
   width: var(--table-width);
+  caption-side: var(--table-caption-side);
   vertical-align: var(--table-vertical-align);
   border-collapse: var(--table-border-collapse);
   border-color: var(--table-border-color);
-- 
GitLab


From ba2d0f02dceca5ae913da3e5ddfa6a7f2b6aa50b Mon Sep 17 00:00:00 2001
From: "akram.zairig" <akram.zairig@dropteam.fr>
Date: Mon, 31 Mar 2025 00:21:45 +0000
Subject: [PATCH 09/10] Fix pipeline

---
 css/table-themes.css                                          | 4 ++--
 .../Field/FieldFormatter/UltimateTableFieldFormatter.php      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index db4c184..05bce9f 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -50,7 +50,7 @@
   overflow-x: auto;
   width: 100%;
   -webkit-overflow-scrolling: touch;
-  -ms-overflow-style: -ms-autohiding-scrollbar;
+  -ms-overflow-style: -ms-auto-hiding-scrollbar;
 }
 
 .table-ultimate table {
@@ -102,7 +102,7 @@
   background-color: var(--table-head-bg);
 }
 
-.table-ultimate .hoverable > tbody > tr:hover {
+.table-ultimate .row-hover > tbody > tr:hover {
   color: var(--table-hover-color);
   background-color: var(--table-hover-bg);
 }
diff --git a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
index 79dd1ca..164fe41 100644
--- a/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/UltimateTableFieldFormatter.php
@@ -92,7 +92,7 @@ class UltimateTableFieldFormatter extends FormatterBase {
         'striped-odd' => $this->t('Striped rows (odd)'),
         'striped-even' => $this->t('Striped rows (even)'),
         'filled-head' => $this->t('Filled header'),
-        'hoverable' => $this->t('Hoverable rows'),
+        'row-hover' => $this->t('Row hover effect'),
         'side-filled' => $this->t('Side filled'),
       ],
       '#default_value' => $this->getSetting('table_style'),
-- 
GitLab


From abeea14c23e77573b1a15d7f01a2417b5f5ecdcc Mon Sep 17 00:00:00 2001
From: Brahim Khouy <brahim.khouy@gmail.com>
Date: Sat, 5 Apr 2025 19:24:29 +0000
Subject: [PATCH 10/10] Fix table formatter style issues

---
 css/table-themes.css          |  2 +-
 src/Element/UltimateTable.php | 28 ++++++++++++++--------------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/css/table-themes.css b/css/table-themes.css
index 05bce9f..aeff5c2 100644
--- a/css/table-themes.css
+++ b/css/table-themes.css
@@ -107,7 +107,7 @@
   background-color: var(--table-hover-bg);
 }
 
-.table-ultimate .side-filled > tbody > tr > th {
+.table-ultimate .side-filled > tbody > tr > td:first-child {
   color: var(--table-head-color);
   background-color: var(--table-head-bg);
 }
diff --git a/src/Element/UltimateTable.php b/src/Element/UltimateTable.php
index 4914f64..933ddb3 100644
--- a/src/Element/UltimateTable.php
+++ b/src/Element/UltimateTable.php
@@ -109,17 +109,6 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       '#markup' => !empty($label) ? '<strong class="form-item__label ' . ($required ? 'js-form-required form-required' : '') . '">' . $label . '</strong>' : '',
     ];
 
-    // Add legend field if enabled.
-    if (!empty($element['#enable_legend'])) {
-      $element['legend'] = [
-        '#type' => 'text_format',
-        '#title' => t('Legend'),
-        '#format' => 'full_html',
-        '#default_value' => $values['legend'] ?? '',
-        '#rows' => 3,
-      ];
-    }
-
     $element['nb_unit'] = [
       '#type' => 'number',
       '#default_value' => 1,
@@ -209,7 +198,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     }
     $element['update'] = [
       '#type' => 'submit',
-      '#name' => 'update_table__' . str_replace('-', '_', $id),
+      '#name' => 'update_table::' . str_replace('-', '_', $id),
       '#value' => t('Update'),
       '#limit_validation_errors' => [[$first_parent]],
       '#attributes' => [
@@ -222,6 +211,17 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
       ],
     ];
 
+    // Add legend field if enabled.
+    if (!empty($element['#enable_legend'])) {
+      $element['legend'] = [
+        '#type' => 'text_format',
+        '#title' => t('Legend'),
+        '#format' => 'full_html',
+        '#default_value' => $values['legend'] ?? '',
+        '#rows' => 3,
+      ];
+    }
+
     $element['#attached']['library'][] = 'ultimate_table_field/style';
     $element['#attached']['library'][] = 'ultimate_table_field/table-actions';
     $element['#attached']['library'][] = 'core/drupal.dialog.ajax';
@@ -243,7 +243,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     $values = $form_state->getValues();
     $triggering_element = $form_state->getTriggeringElement();
     $name = $triggering_element['#name'] ?? '';
-    $name_pieces = explode('__', $name);
+    $name_pieces = explode('::', $name);
     $name_from_id = $name_pieces[0] ?? NULL;
     $id = $name_pieces[1] ?? NULL;
     $name = $name_from_id ?? $name;
@@ -352,7 +352,7 @@ class UltimateTable extends FormElement implements ContainerFactoryPluginInterfa
     $user_input = $form_state->getUserInput();
     $triggering_element = $form_state->getTriggeringElement();
     $name = $triggering_element['#name'];
-    $name_pieces = explode('__', $name);
+    $name_pieces = explode('::', $name);
     $name_from_id = $name_pieces[0] ?? NULL;
     $id = $name_pieces[1] ?? NULL;
     $formatted_id = str_replace('_', '-', $id);
-- 
GitLab