Problem/Motivation
We are planning to rewrite UI Patterns upon SDC. To achieve this, we are proposing a few changes and additions:
- #3390980: Make SDC extensible
- #3352063: Allow schema references in Single Directory Component prop schemas
- Introduce component variants to SDC. The current issue.
- #3390717: Allow declaration of template path in SDC
- #3391702: SDC ComponentElement: Transform slots scalar values to #plain_text instead of throwing an exception
- #3391978: SDC: Add a method to retrieve only components not replaced by others
Variants is a common feature in UI Components:
- Bootstrap cards have vertical and horizontal variants
- Material Design buttons have text, outilned, raised and unelevated variants
- ...
Declaring variants as a prop is not enough for many reasons.
1. Using a string
type with enum
doesn't allow proper documentation (label, description):
props:
type: object
properties:
variant:
type: string
enum:
- primary
- secondary
- inverted
2. Using a anyOf
with constant
is verbose and complicated:
props:
type: object
properties:
variant:
anyOf:
- { "const": "primary", "title": "Primary", "description": "..." }
- { "const": "secondary", "title": "Secondary", "description": "..." }
- { "const": "inverted", "title": "Inverted", "description": "..." }
3. The prop ID is free and it will not always be "variant", but sometimes "variants", "variations", "versions", "scheme"... SDC ecosystem may suffer of this lack of consistency. A module which want to leverage components variants will have no way of guessing which prop is a variant.
Proposed resolution
Add a new "variant" property at the root of component declaration with the same structure as the slot
property :
name: Card
variants:
primary:
title: Primary
description: ...
secondary:
title: Secondary
description: ...
inverted:
title: Inverted
description: ...
primary:
title: Primary
description: ...
props: {}
slots: {}
Proposal 1: declare as variant, use as prop
Once declared, the variant is loaded a prop and used as a prop:
[
'#type' => 'component',
'#component' => 'card',
'#props' => [
'variant' => 'primary',
]
]
This is what we plan to do in UI Patterns 2.x if it is not done at the SDC level, not because it is our preference, but because we don't want to "hack" SDC too deeply.
Proposal 2: declare as variant, use as variant
With the introduction of a new property in the render element:
[
'#type' => 'component',
'#component' => 'card',
'#variant' => 'primary',
'#props' => [ ]
]
We have a preference for this solution.
Remaining tasks
If there is a chance for this feature to be accepted, we (UI Patterns team) can propose a merge request soon.
We have one month before the release of Drupal 10.2.0-alpha1.
If this is accepted, update the FAQ documentation.
API changes
Yes, but not breaking.