diff --git a/src/Plugin/UiPatterns/Source/ClassAttributeWidget.php b/src/Plugin/UiPatterns/Source/ClassAttributeWidget.php
index 1285a0c9092de2968245e7320fcc634e9c5d01de..a6c3594047343d3d906e851f8f1b3edf5fe1ac75 100644
--- a/src/Plugin/UiPatterns/Source/ClassAttributeWidget.php
+++ b/src/Plugin/UiPatterns/Source/ClassAttributeWidget.php
@@ -5,9 +5,11 @@ declare(strict_types=1);
 namespace Drupal\ui_patterns\Plugin\UiPatterns\Source;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Security\TrustedCallbackInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\ui_patterns\Attribute\Source;
 use Drupal\ui_patterns\SourcePluginPropValue;
+use Drupal\ui_patterns\UnicodePatternValidatorTrait;
 
 /**
  * Plugin implementation of the source.
@@ -18,7 +20,16 @@ use Drupal\ui_patterns\SourcePluginPropValue;
   description: new TranslatableMarkup('A space-separated list of HTML classes.'),
   prop_types: ['attributes']
 )]
-class ClassAttributeWidget extends SourcePluginPropValue {
+class ClassAttributeWidget extends SourcePluginPropValue implements TrustedCallbackInterface {
+
+  use UnicodePatternValidatorTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function trustedCallbacks() {
+    return ['validateUnicodePattern'];
+  }
 
   /**
    * {@inheritdoc}
@@ -43,12 +54,13 @@ class ClassAttributeWidget extends SourcePluginPropValue {
       '#type' => 'textfield',
       '#default_value' => $this->getSetting('value'),
     ];
-    $form['value']['#pattern'] = $this->buildRegexPattern();
+    $form['value']['#pattern_unicode'] = $this->buildRegexPattern();
     // To allow form errors to be displayed correctly.
     $form['value']['#title'] = '';
     $form['value']['#placeholder'] = 'foo bar baz';
     $form['value']['#description'] = $this->t("A space-separated list of HTML classes");
     $this->addRequired($form['value']);
+    $form['value']['#element_validate'][] = [static::class, 'validateUnicodePattern'];
     return $form;
   }
 
diff --git a/src/Plugin/UiPatterns/Source/TextfieldWidget.php b/src/Plugin/UiPatterns/Source/TextfieldWidget.php
index d3d8833b4d4536f982baaa4a6f2429d56a3a5c17..b744d3179d70dcd513411727a77cd93e1721669c 100644
--- a/src/Plugin/UiPatterns/Source/TextfieldWidget.php
+++ b/src/Plugin/UiPatterns/Source/TextfieldWidget.php
@@ -9,6 +9,7 @@ use Drupal\Core\Security\TrustedCallbackInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\ui_patterns\Attribute\Source;
 use Drupal\ui_patterns\SourcePluginPropValue;
+use Drupal\ui_patterns\UnicodePatternValidatorTrait;
 
 /**
  * Plugin implementation of the source.
@@ -22,6 +23,8 @@ use Drupal\ui_patterns\SourcePluginPropValue;
 )]
 class TextfieldWidget extends SourcePluginPropValue implements TrustedCallbackInterface {
 
+  use UnicodePatternValidatorTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -29,37 +32,6 @@ class TextfieldWidget extends SourcePluginPropValue implements TrustedCallbackIn
     return ['validateUnicodePattern'];
   }
 
-  /**
-   * Validate pattern.
-   *
-   * #element_validate callback for #pattern form element property.
-   *
-   * @param array $element
-   *   An associative array containing the properties and children of the
-   *    generic form element.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @see https://www.drupal.org/project/drupal/issues/2633550
-   * @see https://www.drupal.org/project/webform/issues/3002374
-   */
-  public static function validateUnicodePattern(array &$element, FormStateInterface $form_state) : void {
-    if ($element['#value'] !== '') {
-      $pattern = $element['#pattern_unicode'] ?? $element['#pattern'];
-      // JavaScript-escaped Unicode characters to PCRE escape sequence format.
-      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $pattern);
-      $pattern = '{^(?:' . $pcre_pattern . ')$}u';
-      if (!preg_match($pattern, $element['#value'])) {
-        if (!empty($element['#pattern_error'])) {
-          $form_state->setError($element, $element['#pattern_error']);
-        }
-        else {
-          $form_state->setError($element, t('%name field is not in the right format.', ['%name' => $element['#title']]));
-        }
-      }
-    }
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/src/UnicodePatternValidatorTrait.php b/src/UnicodePatternValidatorTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a2e0f0732289c17df2aa2473371b8722039b9e6
--- /dev/null
+++ b/src/UnicodePatternValidatorTrait.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\ui_patterns;
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Trait for validating Unicode patterns.
+ */
+trait UnicodePatternValidatorTrait {
+
+  /**
+   * Validate pattern.
+   *
+   * #element_validate callback for #pattern_unicode form element property.
+   *
+   * @param array $element
+   *   An associative array containing the properties and children of the
+   *    generic form element.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @see https://www.drupal.org/project/drupal/issues/2633550
+   * @see https://www.drupal.org/project/webform/issues/3002374
+   */
+  public static function validateUnicodePattern(array &$element, FormStateInterface $form_state) : void {
+    if ($element['#value'] !== '') {
+      $pattern = $element['#pattern_unicode'];
+      // JavaScript-escaped Unicode characters to PCRE escape sequence format.
+      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $pattern);
+      $pattern = '{^(?:' . $pcre_pattern . ')$}u';
+      if (!preg_match($pattern, $element['#value'])) {
+        if (!empty($element['#pattern_error'])) {
+          $form_state->setError($element, $element['#pattern_error']);
+        }
+        else {
+          $form_state->setError($element, t('%name field is not in the right format.', ['%name' => $element['#title']]));
+        }
+      }
+    }
+  }
+
+}