diff --git a/.cspell-project-words.txt b/.cspell-project-words.txt
index a3a6be5a032a505498aefc21bc13468bffbd203e..1c342aba563869aadf3c9d37a7d037ee542b47a7 100644
--- a/.cspell-project-words.txt
+++ b/.cspell-project-words.txt
@@ -15,3 +15,4 @@ sdc's
 subcomponent
 toolset
 daisyui
+uips
\ No newline at end of file
diff --git a/css/color.css b/css/color.css
new file mode 100644
index 0000000000000000000000000000000000000000..aa559542155c8c7e97dd48b61484aa08889efd69
--- /dev/null
+++ b/css/color.css
@@ -0,0 +1,23 @@
+.uips-layout-color {
+  display: grid !important;
+  grid-template-columns: repeat(auto-fill, 32px) !important;
+  gap: 10px !important;
+}
+
+.uips-layout-color .uips-radio-item {
+  width: 100%;
+  aspect-ratio: 1 / 1;
+  cursor: pointer;
+  border-radius: 50%;
+}
+
+.uips-layout-color .form-radio {
+  display: none;
+}
+
+.uips-layout-color .form-radio:checked + .uips-radio-item {
+  border: 2px solid black;
+  box-shadow:
+    0 0 2px #fff,
+    0 0 0 4px #222330;
+}
diff --git a/css/grid.css b/css/grid.css
new file mode 100644
index 0000000000000000000000000000000000000000..c26565202aa2ea09a6b9b516145ab2502fe250d7
--- /dev/null
+++ b/css/grid.css
@@ -0,0 +1,22 @@
+.uips-layout-grid {
+  display: grid !important;
+  grid-template-columns: repeat(auto-fill, 64px) !important;
+  gap: 10px !important;
+}
+
+.uips-layout-grid .uips-radio-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  aspect-ratio: 1 / 1;
+  width: 100%;
+  cursor: pointer;
+}
+
+.uips-layout-grid .form-radio {
+  display: none;
+}
+
+.uips-layout-grid .form-radio:checked + .uips-radio-item {
+  border: 2px solid black;
+}
diff --git a/src/Plugin/UiPatterns/Source/EnumWidget.php b/src/Plugin/UiPatterns/Source/EnumWidget.php
new file mode 100644
index 0000000000000000000000000000000000000000..c78d3d7219421588948efb518e11e6fa35d78eae
--- /dev/null
+++ b/src/Plugin/UiPatterns/Source/EnumWidget.php
@@ -0,0 +1,159 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\ui_patterns_settings\Plugin\UiPatterns\Source;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\ui_patterns\Attribute\Source;
+use Drupal\ui_patterns\EnumTrait;
+use Drupal\ui_patterns\Plugin\UiPatterns\Source\SelectWidget;
+
+/**
+ * Enum widget source.
+ */
+#[Source(
+  id: 'enum_widget',
+  label: new TranslatableMarkup('Enum CSS widget'),
+  description: new TranslatableMarkup('A drop-down menu or scrolling selection box.'),
+  prop_types: ['enum', 'variant'],
+  tags: ['widget']
+)]
+class EnumWidget extends SelectWidget {
+
+  use EnumTrait;
+
+  /**
+   * Alter enum options.
+   */
+  protected function enumAlterOptions(array $options, array $configure): array {
+    $overwrite_options = $configure['overwrite'] ?? [];
+    foreach ($overwrite_options as $overwrite_option_id => $overwrite_option) {
+      if ($overwrite_option['enable'] == '0') {
+        unset($options[$overwrite_option_id]);
+        continue;
+      }
+      if (!empty($overwrite_option['title'])) {
+        $options[$overwrite_option_id] = $overwrite_option['title'];
+      }
+    }
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state): array {
+    $form = parent::settingsForm($form, $form_state);
+    $form['value']['#options'] = $this->enumAlterOptions($form['value']['#options'], $this->getConfiguration()['configure'] ?? []);
+    $form['#attached']['library'][] = 'ui_patterns_settings/layout';
+    $form['#attached']['library'][] = 'ui_patterns_settings/color';
+    $widget = $this->getWidgetSetting('widget');
+    $widget_configs = [
+      'select' => ['type' => 'select'],
+      'colors' => [
+        'type' => 'radios',
+        'wrapper_classes' => 'uips-layout-color',
+        'library' => ['ui_patterns_settings/color'],
+      ],
+      '4_grid' => [
+        'type' => 'radios',
+        'wrapper_classes' => 'uips-layout-grid',
+        'library' => ['ui_patterns_settings/grid'],
+      ],
+    ];
+    $widget_config = $widget_configs[$widget];
+    $form['value']['#type'] = $widget_config['type'];
+    $configure = $this->getEnumConfiguration();
+    $configure['css']['wrapper_classes'] .= $widget_config['wrapper_classes'] ?? '';
+    $form['value']['#enum_widget'] = $configure;
+    if ($form['value']['#type'] === 'select') {
+      $form['value']['#theme'] = 'ui_patterns_settings_select_widget';
+    }
+    elseif ($form['value']['#type'] === 'radios') {
+      $form['value']['#pre_render'][] = function ($element) use ($configure) {
+        foreach (Element::children($element) as $key) {
+          $element[$key]['#theme_wrappers'][0] = ['ui_patterns_settings_radio_wrapper_widget'];
+          $element[$key]['#theme'] = ['ui_patterns_settings_radio_widget'];
+          $element[$key]['#enum_widget'] = $configure;
+        }
+        return $element;
+      };
+    }
+    $form['value']['#attached']['library'] = $widget_config['library'] ?? [];
+    return $form;
+  }
+
+  /**
+   * Returns base enum configuration.
+   */
+  private function getEnumConfiguration(): array {
+    return [
+      'widget' => $this->getWidgetSetting('widget'),
+      'overwrite' => $this->getWidgetSetting('overwrite'),
+      'css' => $this->getWidgetSetting('css'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function widgetSettingsForm(array $form, FormStateInterface $form_state): array {
+    $form = parent::widgetSettingsForm($form, $form_state);
+    $configure = $this->getEnumConfiguration();
+    $options = self::getEnumOptions($this->getPropDefinition());
+
+    $form['widget'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Widget'),
+      '#description' => $this->t('Enum widget type.'),
+      '#options' => [
+        'select' => $this->t('Select'),
+        'colors' => $this->t('Colors'),
+        '4_grid' => $this->t('4 Grid / Eg. Icons'),
+      ],
+      '#default_value' => $configure['widget'] ?? 'select',
+    ];
+
+    $form['css']['wrapper_classes'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Wrapper CSS classes'),
+      '#default_value' => $configure['css']['wrapper_classes'] ?? '',
+      '#description' => $this->t('Classes assigned to wrapping select element'),
+    ];
+
+    foreach ($options as $option_id => $label) {
+      $form['overwrite'][$option_id] = [
+        '#type' => 'details',
+        '#title' => $this->t('Option: %label', ['%label' => $label]),
+      ];
+      $form['overwrite'][$option_id]['enable'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Enable'),
+        '#default_value' => $configure['overwrite'][$option_id]['enable'] ?? TRUE,
+      ];
+      $form['overwrite'][$option_id]['title'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('Title'),
+        '#default_value' => $configure['overwrite'][$option_id]['title'] ?? '',
+      ];
+      $form['overwrite'][$option_id]['icon'] = [
+        '#type' => 'icon_autocomplete',
+        '#title' => $this->t('Icon'),
+        '#return_id' => TRUE,
+        '#description' => $this->t('May not work with your widget.'),
+        '#default_value' => $configure['overwrite'][$option_id]['icon']['target_id'] ?? '',
+      ];
+      $form['overwrite'][$option_id]['css'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('CSS'),
+        '#default_value' => $configure['overwrite'][$option_id]['css'] ?? '',
+      ];
+    }
+    return $form;
+
+  }
+
+}
diff --git a/templates/ui-patterns-settings-radio-widget.html.twig b/templates/ui-patterns-settings-radio-widget.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..627ae719964df85cc98a5ecfc655c26fae764a26
--- /dev/null
+++ b/templates/ui-patterns-settings-radio-widget.html.twig
@@ -0,0 +1,7 @@
+<input{{ attributes }} />{{ children }}
+<div{{ layout_attributes.addClass('uips-radio-item') }}>
+    {% if icon_id is not empty %}
+        {{ icon_preview(pack_id, icon_id) }}
+    {% endif %}
+</div>
+
diff --git a/templates/ui-patterns-settings-radio-wrapper-widget.html.twig b/templates/ui-patterns-settings-radio-wrapper-widget.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..e7ba34d72fdabb93daef84e2a70e56d854a13af4
--- /dev/null
+++ b/templates/ui-patterns-settings-radio-wrapper-widget.html.twig
@@ -0,0 +1,76 @@
+
+{#
+/**
+ * @file
+ * Default theme implementation for a form element.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the containing element.
+ * - errors: (optional) Any errors for this form element, may not be set.
+ * - prefix: (optional) The form element prefix, may not be set.
+ * - suffix: (optional) The form element suffix, may not be set.
+ * - required: The required marker, or empty if the associated form element is
+ *   not required.
+ * - type: The type of the element.
+ * - name: The name of the element.
+ * - label: A rendered label element.
+ * - label_display: Label display setting. It can have these values:
+ *   - before: The label is output before the element. This is the default.
+ *     The label includes the #title and the required marker, if #required.
+ *   - after: The label is output after the element. For example, this is used
+ *     for radio and checkbox #type elements. If the #title is empty but the
+ *     field is #required, the label will contain only the required marker.
+ *   - invisible: Labels are critical for screen readers to enable them to
+ *     properly navigate through forms but can be visually distracting. This
+ *     property hides the label for everyone except screen readers.
+ *   - attribute: Set the title attribute on the element to create a tooltip but
+ *     output no label element. This is supported only for checkboxes and radios
+ *     in \Drupal\Core\Render\Element\CompositeFormElementTrait::preRenderCompositeFormElement().
+ *     It is used where a visual label is not needed, such as a table of
+ *     checkboxes where the row and column provide the context. The tooltip will
+ *     include the title and required marker.
+ * - description: (optional) A list of description properties containing:
+ *    - content: A description of the form element, may not be set.
+ *    - attributes: (optional) A list of HTML attributes to apply to the
+ *      description content wrapper. Will only be set when description is set.
+ * - description_display: Description display setting. It can have these values:
+ *   - before: The description is output before the element.
+ *   - after: The description is output after the element. This is the default
+ *     value.
+ *   - invisible: The description is output after the element, hidden visually
+ *     but available to screen readers.
+ * - disabled: True if the element is disabled.
+ * - title_display: Title display setting.
+ *
+ * @see template_preprocess_form_element()
+ *
+ * @ingroup themeable
+ */
+#}
+{%
+    set classes = [
+    'js-form-item',
+    'form-item',
+    'js-form-type-' ~ type|clean_class,
+    'form-item-' ~ name|clean_class,
+    'js-form-item-' ~ name|clean_class,
+    title_display not in ['after', 'before'] ? 'form-no-label',
+    disabled == 'disabled' ? 'form-disabled',
+    errors ? 'form-item--error',
+]
+%}
+{%
+    set description_classes = [
+    'description',
+    description_display == 'invisible' ? 'visually-hidden',
+]
+%}
+<label{{ attributes.addClass(classes) }}>
+
+    {{ children }}
+    {% if errors %}
+        <div class="form-item--error-message">
+            {{ errors }}
+        </div>
+    {% endif %}
+</label>
diff --git a/templates/ui-patterns-settings-select-widget.html.twig b/templates/ui-patterns-settings-select-widget.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..ba8834450730c668edcbd6ee759a0ded2e01d06e
--- /dev/null
+++ b/templates/ui-patterns-settings-select-widget.html.twig
@@ -0,0 +1,27 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a select element.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the <select> tag.
+ * - options: The <option> element children.
+ *
+ * @see template_preprocess_select()
+ *
+ * @ingroup themeable
+ */
+#}
+<select{{ attributes }}>
+  {% for option in options %}
+    {% if option.type == 'optgroup' %}
+      <optgroup label="{{ option.label }}">
+        {% for sub_option in option.options %}
+          <option{{ option.attributes }} value="{{ sub_option.value }}"{{ sub_option.selected ? ' selected="selected"' }}>{{ sub_option.label }}</option>
+        {% endfor %}
+      </optgroup>
+    {% elseif option.type == 'option' %}
+      <option{{ option.attributes }} value="{{ option.value }}"{{ option.selected ? ' selected="selected"' }}>{{ option.label }}</option>
+    {% endif %}
+  {% endfor %}
+</select>
diff --git a/ui_patterns_settings.libraries.yml b/ui_patterns_settings.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..37e7cada3080064fc641fe0da888f3448071a1b1
--- /dev/null
+++ b/ui_patterns_settings.libraries.yml
@@ -0,0 +1,8 @@
+color:
+  css:
+    theme:
+      css/color.css: {}
+grid:
+  css:
+    theme:
+      css/grid.css: {}
diff --git a/ui_patterns_settings.module b/ui_patterns_settings.module
index 68201a60a12604fe6c06a558e462fdbc5a78fbf2..e55ca90a8b9c395eb1a7aa80271c294ddab9801d 100644
--- a/ui_patterns_settings.module
+++ b/ui_patterns_settings.module
@@ -4,3 +4,77 @@
  * @file
  * Contains ui_patterns_settings.module.
  */
+
+use Drupal\Core\Render\Element;
+use Drupal\Core\Render\Element\RenderElementBase;
+use Drupal\Core\Template\Attribute;
+
+/**
+ * Implements hook_theme().
+ */
+function ui_patterns_settings_theme(): array {
+  return [
+    'ui_patterns_settings_select_widget' => [
+      'render element' => 'element',
+    ],
+    'ui_patterns_settings_radio_wrapper_widget' => [
+      'render element' => 'element',
+    ],
+    'ui_patterns_settings_radio_widget' => [
+      'render element' => 'element',
+    ],
+  ];
+}
+
+/**
+ * Implements hook_preprocess_ui_patterns_settings_select_widget().
+ */
+function template_preprocess_ui_patterns_settings_select_widget(array &$variables): void {
+  $element = $variables['element'];
+  Element::setAttributes($element, ['id', 'name', 'size']);
+  RenderElementBase::setAttributes($element, ['form-select']);
+  $variables['attributes'] = $element['#attributes'];
+  $options = form_select_options($element);
+  foreach ($options as $delta => $option) {
+    if (isset($element['#enum_widget']['overwrite'][$option['value']]['css'])) {
+      $options[$delta]['attributes'] = new Attribute(
+        ['class' => $element['#enum_widget']['overwrite'][$option['value']]['css']]
+      );
+
+    }
+    if (isset($element['#enum_widget']['overwrite'][$option['value']]['icon']['target_id'])) {
+      [$options[$delta]['pack_id'], $options[$delta]['icon_id']] = explode(':', $element['#enum_widget']['overwrite'][$option['value']]['icon']['target_id'] ?? '');
+    }
+  }
+  $variables['options'] = $options;
+}
+
+/**
+ * Implements hook_radios().
+ */
+function ui_patterns_settings_preprocess_radios(array &$variables): void {
+  if (isset($variables['element']['#enum_widget'])) {
+    $variables['attributes']['class'][] = $variables['element']['#enum_widget']['css']['wrapper_classes'];
+    $variables['attributes']['class'][] = 'ck-reset';
+
+  }
+}
+
+/**
+ * Implements hook_preprocess_ui_patterns_settings_radio_wrapper_widget().
+ */
+function template_preprocess_ui_patterns_settings_radio_wrapper_widget(array &$variables): void {
+  template_preprocess_form_element($variables);
+}
+
+/**
+ * Implements hook_preprocess_ui_patterns_settings_radio_widget().
+ */
+function template_preprocess_ui_patterns_settings_radio_widget(array &$variables): void {
+  template_preprocess_input($variables);
+  $element = &$variables['element'];
+  $variables['layout_attributes'] = new Attribute();
+  $css_config = $element['#enum_widget']['overwrite'][$element['#return_value']]['css'] ?? NULL;
+  $variables['layout_attributes']->addClass($css_config);
+  [$variables['pack_id'], $variables['icon_id']] = explode(':', $element['#enum_widget']['overwrite'][$element['#return_value']]['icon']['target_id'] ?? '');
+}