diff --git a/src/ComponentPluginManager.php b/src/ComponentPluginManager.php index 627101e45e2719079a2123e97ccb6ddd2ed81b11..f9f5eb49e8da760d96cda3badb016bcacdadab1b 100644 --- a/src/ComponentPluginManager.php +++ b/src/ComponentPluginManager.php @@ -125,6 +125,9 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu if (!isset($definition['props']['properties'])) { return $definition; } + if (isset($definition["variants"])) { + $definition['props']['properties']['variant'] = $this->buildVariantProp($definition); + } foreach ($definition['props']['properties'] as $prop_id => $prop) { $definition["title"] = $definition["title"] ?? $prop_id; $prop_type = $this->propTypePluginManager->guessFromSchema($prop); @@ -163,10 +166,25 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu $definition['slots'][$slot_id] = $slot; } } - return $definition; } + private function buildVariantProp(array $definition): array { + $enums = []; + $meta_enums = []; + foreach ($definition["variants"] as $variant_id => $variant) { + $enums[] = $variant_id; + $meta_enums[$variant_id] = $variant['title'] ?? $variant_id; + } + return [ + 'title' => 'Variant', + 'type' => 'string', + '$ref' => "ui-patterns://variant", + 'enum' => $enums, + 'meta:enum' => $meta_enums + ]; + } + /** * Finds assets related to the provided metadata file. * diff --git a/src/Element/ComponentElementBuilder.php b/src/Element/ComponentElementBuilder.php index 13f8138f690dca98bd25f21c8e6cbcbb4530f060..470d167b2856f67604773d59a4b3f51508e7df53 100644 --- a/src/Element/ComponentElementBuilder.php +++ b/src/Element/ComponentElementBuilder.php @@ -57,12 +57,14 @@ class ComponentElementBuilder implements TrustedCallbackInterface { protected function buildProps(array $build, Component $component, array $configuration, array $contexts): array { $props = $component->metadata->schema['properties'] ?? []; foreach ($props as $prop_id => $prop_definition) { - $prop_configuration = $configuration['props'][$prop_id] ?? []; + if ($prop_id === 'variant') { + $prop_configuration = $configuration['variant_id'] ?? []; + } + else { + $prop_configuration = $configuration['props'][$prop_id] ?? []; + } $build = $this->buildProp($build, $prop_id, $prop_definition, $prop_configuration, $contexts); } - if (isset($configuration["variant_id"])) { - $build['#props']["variant"] = $configuration["variant_id"]; - } return $build; } diff --git a/src/Element/ComponentForm.php b/src/Element/ComponentForm.php index ec72a73215b12d0e0b3fdef23c08272c8b4150dc..ec72bdb562753a598630d47bce9f7285dda9a1f0 100644 --- a/src/Element/ComponentForm.php +++ b/src/Element/ComponentForm.php @@ -146,10 +146,13 @@ class ComponentForm extends ComponentFormBase { if (!$component_id) { return $element; } - $element['variant_id'] = self::buildComponentVariantSelectorForm( - $element, - $element['#default_value']['variant_id'] ?? NULL, - ); + $component = static::getComponent($element); + if (isset($component->metadata->schema['properties']['variant'])) { + $element['variant_id'] = self::buildComponentVariantSelectorForm( + $component_id, + $element['#default_value']['variant_id'] ?? NULL, + ); + } $element['slots'] = self::buildSlotsForm($element, $component_id); $element['props'] = self::buildPropsForm($element, $component_id); } @@ -195,22 +198,15 @@ class ComponentForm extends ComponentFormBase { * The variant select. */ private static function buildComponentVariantSelectorForm( - array $element, - string|NULL $default_variant_id, + string $component_id, + array|NULL $default_variant_id, ): array { - $component = static::getComponent($element); - $definition = $component->getPluginDefinition(); - if (!isset($definition["variants"])) { - return []; - } - $options = []; - foreach ($definition["variants"] as $variant_id => $variant) { - $options[$variant_id] = $variant["title"] ?? $variant_id; - } + return [ - "#type" => "select", + "#type" => "component_prop_form", "#title" => t("Variant"), - "#options" => $options, + "#component_id" => $component_id, + "#prop_id" => 'variant', '#default_value' => $default_variant_id, ]; } diff --git a/src/Element/ComponentPropsForm.php b/src/Element/ComponentPropsForm.php index 61851c7c19317e1c61cb7dd74b6f0065c956a5b3..c0a8668a8559d3ed9063f8b390f1b712cde00ca7 100644 --- a/src/Element/ComponentPropsForm.php +++ b/src/Element/ComponentPropsForm.php @@ -73,6 +73,9 @@ class ComponentPropsForm extends ComponentFormBase { } $configuration = $element['#default_value']['props'] ?? []; foreach ($props as $prop_id => $prop) { + if ($prop_id === 'variant') { + continue; + } $prop_type = $prop['ui_patterns']['type_definition']; $element[$prop_id] = [ '#type' => 'component_prop_form', diff --git a/src/Plugin/UiPatterns/PropType/VariantPropType.php b/src/Plugin/UiPatterns/PropType/VariantPropType.php new file mode 100644 index 0000000000000000000000000000000000000000..8de4a9a02c9d7ca3b383d5b6d83d83046a57a3fa --- /dev/null +++ b/src/Plugin/UiPatterns/PropType/VariantPropType.php @@ -0,0 +1,26 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\ui_patterns\Plugin\UiPatterns\PropType; + +use Drupal\Component\Render\MarkupInterface; +use Drupal\Core\Render\RenderableInterface; +use Drupal\ui_patterns\PropTypePluginBase; + +/** + * Provides a 'Variant' PropType. + * + * @PropType( + * id = "variant", + * label = @Translation("Variant"), + * description = @Translation("Prop Type for component variants."), + * priority = 10, + * default_source = "select", + * schema = { + * }, + * ) + */ +class VariantPropType extends PropTypePluginBase { + +} diff --git a/src/Plugin/UiPatterns/Source/SelectWidget.php b/src/Plugin/UiPatterns/Source/SelectWidget.php index 47b6158c5ea1229367b1a602f50e4a507f8486e3..2f4d07a1aa1ea61f086f1184d4b99eca427b54e1 100644 --- a/src/Plugin/UiPatterns/Source/SelectWidget.php +++ b/src/Plugin/UiPatterns/Source/SelectWidget.php @@ -15,7 +15,8 @@ use Drupal\ui_patterns\SourcePluginPropValue; * label = @Translation("Select"), * description = @Translation("A drop-down menu or scrolling selection box."), * prop_types = { - * "enum" + * "enum", + * "variant" * }, * tags = { "widget" } * ) diff --git a/tests/modules/ui_patterns_test/components/card/card.component.yml b/tests/modules/ui_patterns_test/components/card/card.component.yml index f47288a7205cb3229c11d0ac9a1adc9312c47356..cdbf92f97f56f61bc98f01097fe484e571160773 100644 --- a/tests/modules/ui_patterns_test/components/card/card.component.yml +++ b/tests/modules/ui_patterns_test/components/card/card.component.yml @@ -9,9 +9,9 @@ icon_map: - [rectangle_vertical, square_four, square_five] variants: default: - title: "Default" + title: "Default title" horizontal: - title: "Horizontal" + title: "Horizontal title" props: type: object properties: diff --git a/tests/modules/ui_patterns_test/components/card/card.twig b/tests/modules/ui_patterns_test/components/card/card.twig index 0f806b25a3d3295a4d1d1a10b83841fc48bc2e15..cea6299fdc2fcb90c8f7e3b7ff7ebb1c5fa61c6f 100644 --- a/tests/modules/ui_patterns_test/components/card/card.twig +++ b/tests/modules/ui_patterns_test/components/card/card.twig @@ -1,4 +1,5 @@ {% set attributes = (variant and variant|lower != 'default') ? attributes.addClass('card--' ~ variant) : attributes %} +Variant: {{ variant }} <div{{ attributes.addClass('card') }}> {% if image and image_position != 'bottom' %} {{ image|add_class('card-img-top') }}