Skip to content
Snippets Groups Projects
Commit 175f51c6 authored by David Galeano's avatar David Galeano
Browse files

Issue #3470251 by gxleano: Add Iconify Icons Link field widget and remove Url...

parent 5d5aee37
No related branches found
Tags 8.x-1.0
1 merge request!17Issue #3470251 by gxleano: Add Iconify Icons Link field widget and remove Url...
Pipeline #265248 passed with warnings
......@@ -6,3 +6,13 @@
.iconify-icons-preview svg {
height: 30px;
}
/* Dark mode */
.gin--dark-mode .iconify-icons-preview {
background-color: var(--gin-bg-input);
}
.gin--dark-mode .iconify-result-collection,
.gin--edit-form .iconify-result-collection {
color: var(--gin-color-primary);
}
......@@ -22,6 +22,7 @@
.iconify-icons-wrapper {
display: flex;
align-items: center;
flex-wrap: nowrap;
}
......@@ -48,24 +49,14 @@
display: flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
width: 2.9rem;
height: 2.9rem;
margin-right: 0.5rem;
border: 1px solid #d3d4d987;
border-radius: 10px;
border-radius: .3rem;
background-color: var(--color-gray-050);
}
/* Gin Theme */
.gin--dark-mode .iconify-icons-preview {
background-color: var(--gin-bg-input);
}
.gin--dark-mode .iconify-result-collection,
.gin--edit-form .iconify-result-collection {
color: var(--gin-color-primary);
}
.iconify-icons-preview svg {
width: auto;
height: 35px;
......
......@@ -6,6 +6,7 @@ use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\iconify_icons\IconifyServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -64,6 +65,110 @@ class IconifyIconFormatter extends FormatterBase implements ContainerFactoryPlug
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'advanced_settings' => [],
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$advanced_settings = $this->getSetting('advanced_settings');
$elements['advanced_settings'] = [
'#type' => 'container',
];
$elements['advanced_settings']['width'] = [
'#type' => 'number',
'#title' => $this->t('Width'),
'#description' => $this->t('Icon dimensions in pixels. If only one dimension is specified, such as height, other dimension will be automatically set to match it.'),
'#size' => 8,
'#maxlength' => 8,
'#min' => 1,
'#max' => 99999,
'#field_suffix' => $this->t('pixels'),
'#default_value' => $advanced_settings['width'] ?? 50,
];
$elements['advanced_settings']['height'] = [
'#type' => 'number',
'#title' => $this->t('Height'),
'#description' => $this->t('Icon dimensions in pixels. If only one dimension is specified, such as height, other dimension will be automatically set to match it.'),
'#size' => 8,
'#maxlength' => 8,
'#min' => 1,
'#max' => 99999,
'#field_suffix' => $this->t('pixels'),
'#default_value' => $advanced_settings['height'] ?? 50,
];
$elements['advanced_settings']['color'] = [
'#type' => 'color',
'#title' => $this->t('Color'),
'#description' => $this->t('Icon color. Sets color for monotone icons.'),
'#default_value' => $advanced_settings['color'] ?? '',
];
$elements['advanced_settings']['flip'] = [
'#type' => 'select',
'#title' => $this->t('Flip'),
'#empty_option' => $this->t('None'),
'#options' => [
'vertical' => $this->t('Vertical'),
'horizontal' => $this->t('Horizontal'),
],
'#description' => $this->t('Flip icon.'),
'#default_value' => $advanced_settings['flip'] ?? '',
];
$elements['advanced_settings']['rotate'] = [
'#type' => 'select',
'#title' => $this->t('Rotate'),
'#empty_option' => $this->t('None'),
'#options' => [
'90' => $this->t('90°'),
'180' => $this->t('180°'),
'270' => $this->t('270°'),
],
'#description' => $this->t('Rotate icon by 90, 180 or 270 degrees.'),
'#default_value' => $advanced_settings['rotate'] ?? '',
];
return $elements;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$advanced_settings = $this->getSetting('advanced_settings');
// Define the settings with their default values.
$settings = [
'width' => 25,
'height' => 25,
'color' => '#000',
'flip' => '',
'rotate' => '',
];
// Create the summary output.
$output = [];
foreach ($settings as $key => $default) {
if (isset($advanced_settings[$key]) && $default) {
$output[] = ucfirst($key) . ': ' . $advanced_settings[$key];
}
}
return $output;
}
/**
* {@inheritdoc}
*/
......@@ -78,11 +183,16 @@ class IconifyIconFormatter extends FormatterBase implements ContainerFactoryPlug
// Loop over each icon and build data.
$icons = [];
foreach ($iconify_icons as $icon) {
$settings = unserialize($icon['settings'] ?? '', ['allowed_classes']);
// Link settings coming from the Iconify icons link widget (URL and Link
// text).
$link_settings = unserialize($icon['settings'] ?? '', ['allowed_classes']) ?: [];
// Advanced settings coming from field formatter settings.
$advanced_settings = $this->getSetting('advanced_settings') ?? [];
$icons[] = [
'#type' => 'iconify_icon',
'#icon' => $icon['icon'],
'#settings' => $settings,
'#settings' => array_merge($link_settings, $advanced_settings),
];
}
......
<?php
namespace Drupal\iconify_icons\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'iconify_icon' widget.
*
* @FieldWidget(
* id = "iconify_icon_link_widget",
* module = "iconify_icons",
* label = @Translation("Iconify Icon Link"),
* field_types = {
* "iconify_icon"
* }
* )
*/
class IconifyIconLinkWidget extends IconifyIconWidget {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
/** @var \Drupal\iconify_icons\Plugin\Field\FieldType\IconifyIcon $iconify_icon */
$iconify_icon = $items[$delta];
$settings = unserialize($iconify_icon->get('settings')->getValue() ?? '', ['allowed_classes']);
$element['link_url'] = [
'#type' => 'textfield',
'#title' => $this->t('URL'),
'#description' => $this->t('The URL to which the user should be redirected. This can be an internal URL like /node/1234, an external URL like @url, or an anchor like #main-content.', ['@url' => 'http://example.com']),
'#size' => 100,
'#default_value' => $settings['link_url'] ?? '',
'#pattern' => '^(https?:\/\/[^\s]+|www\.[^\s]+|\/[^\s]+|#[a-zA-Z0-9_-]+)$',
];
$element['link_text'] = [
'#type' => 'textfield',
'#title' => $this->t('Link Text'),
'#description' => $this->t('It will show a text close to the icon.'),
'#size' => 100,
'#default_value' => $settings['link_text'] ?? '',
];
return $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
$collection = $this->getSetting('collections');
foreach ($values as $delta => &$item) {
$item['delta'] = $delta;
$item['selected_collection'] = $collection;
$settings['link_url'] = $item['link_url'] ?? '';
$settings['link_text'] = $item['link_text'] ?? '';
$item['settings'] = serialize(array_filter($settings));
}
return $values;
}
}
......@@ -79,8 +79,8 @@ class IconifyIconWidget extends WidgetBase {
*/
public static function defaultSettings() {
return [
'collections' => [],
] + parent::defaultSettings();
'collections' => [],
] + parent::defaultSettings();
}
/**
......@@ -151,22 +151,17 @@ class IconifyIconWidget extends WidgetBase {
// Get selected collections from widget settings.
$selected_collections = $this->getSetting('collections');
$collection = implode(',', array_filter($selected_collections, static fn($value) => $value !== 0));
$settings = unserialize($iconify_icon->get('settings')->getValue() ?? '', ['allowed_classes']);
$icon = $iconify_icon->get('icon')->getValue() ?? '';
// Extract the icon name and collection name using a regular expression.
if ($iconDetails = $this->extractIconDetails($icon)) {
[$icon_name, $icon_collection] = $iconDetails;
$icon_svg = $this->iconify->generateSvgIcon($icon_collection, $icon_name, $settings);
$icon_svg = $this->iconify->generateSvgIcon($icon_collection, $icon_name);
}
$element['iconify_icons'] = [
'#type' => 'details',
'#title' => $cardinality === 1 ? $this->fieldDefinition->getLabel() : $this->t('Icon Name'),
'#open' => TRUE,
];
$element['iconify_icons']['icon'] = [
$element['icon'] = [
'#type' => 'iconify_icons',
'#title' => $cardinality === 1 ? $this->fieldDefinition->getLabel() : $this->t('Icon'),
'#default_value' => $iconify_icon->get('icon')->getValue(),
'#required' => $element['#required'],
'#size' => 50,
......@@ -186,82 +181,6 @@ class IconifyIconWidget extends WidgetBase {
],
];
$element['iconify_icons']['settings'] = [
'#type' => 'details',
'#title' => $this->t('Advanced settings'),
];
$element['iconify_icons']['settings']['width'] = [
'#type' => 'number',
'#title' => $this->t('Width'),
'#description' => $this->t('Icon dimensions in pixels. If only one dimension is specified, such as height, other dimension will be automatically set to match it.'),
'#size' => 8,
'#maxlength' => 8,
'#min' => 1,
'#max' => 99999,
'#field_suffix' => $this->t('pixels'),
'#default_value' => $settings['width'] ?? 50,
];
$element['iconify_icons']['settings']['height'] = [
'#type' => 'number',
'#title' => $this->t('Height'),
'#description' => $this->t('Icon dimensions in pixels. If only one dimension is specified, such as height, other dimension will be automatically set to match it.'),
'#size' => 8,
'#maxlength' => 8,
'#min' => 1,
'#max' => 99999,
'#field_suffix' => $this->t('pixels'),
'#default_value' => $settings['height'] ?? 50,
];
$element['iconify_icons']['settings']['color'] = [
'#type' => 'color',
'#title' => $this->t('Color'),
'#description' => $this->t('Icon color. Sets color for monotone icons.'),
'#default_value' => $settings['color'] ?? '',
];
$element['iconify_icons']['settings']['flip'] = [
'#type' => 'select',
'#title' => $this->t('Flip'),
'#empty_option' => $this->t('- None -'),
'#options' => [
'vertical' => $this->t('Vertical'),
'horizontal' => $this->t('Horizontal'),
],
'#description' => $this->t('Flip icon.'),
'#default_value' => $settings['flip'] ?? '',
];
$element['iconify_icons']['settings']['rotate'] = [
'#type' => 'select',
'#title' => $this->t('Rotate'),
'#empty_option' => $this->t('- None -'),
'#options' => [
'90' => $this->t('90°'),
'180' => $this->t('180°'),
'270' => $this->t('270°'),
],
'#description' => $this->t('Rotate icon by 90, 180 or 270 degrees.'),
'#default_value' => $settings['rotate'] ?? '',
];
$element['iconify_icons']['settings']['link_url'] = [
'#type' => 'textfield',
'#title' => $this->t('URL'),
'#description' => $this->t('The URL to which the user should be redirected. This can be an internal URL like /node/1234, an external URL like @url, or an anchor like #main-content.', ['@url' => 'http://example.com']),
'#default_value' => $settings['link_url'] ?? '',
'#pattern' => '^(https?:\/\/[^\s]+|www\.[^\s]+|\/[^\s]+|#[a-zA-Z0-9_-]+)$',
];
$element['iconify_icons']['settings']['link_text'] = [
'#type' => 'textfield',
'#title' => $this->t('Link Text'),
'#description' => $this->t('It will show a text close to the icon.'),
'#default_value' => $settings['link_text'] ?? '',
];
return $element;
}
......@@ -271,10 +190,8 @@ class IconifyIconWidget extends WidgetBase {
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
$collection = $this->getSetting('collections');
foreach ($values as $delta => &$item) {
$item = $item['iconify_icons'];
$item['delta'] = $delta;
$item['selected_collection'] = $collection;
$item['settings'] = serialize(array_filter($item['settings']));
}
return $values;
......
......@@ -4,7 +4,7 @@
* Default implementation for Iconify icons.
*
* Available variables:
* - icons: a list of Font Awesome icons to be rendered.
* - icons: a list of Iconify icons to be rendered.
*
* @ingroup themeable
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment