class DesignToken

Same name in this branch
  1. 11.x core/lib/Drupal/Core/Theme/DesignToken/DesignToken.php \Drupal\Core\Theme\DesignToken\DesignToken

Configuration entity.

Allow to override and scope design tokens.

@internal This API is experimental.

Attributes

#[ConfigEntityType(id: 'design_token', label: new TranslatableMarkup('Design token'), entity_keys: [ 'id' => 'id', 'label' => 'id', ], admin_permission: 'administer design tokens', constraints: [ 'ImmutableProperties' => [ 'properties' => [ 'id', 'path', 'type', ], ], ], config_export: [ 'id', 'path', 'type', 'scopes', ])]

Hierarchy

Expanded class hierarchy of DesignToken

6 files declare their use of DesignToken
DesignTokenConfigEntityKernelTest.php in core/tests/Drupal/KernelTests/Core/Theme/DesignToken/DesignTokenConfigEntityKernelTest.php
DesignTokenEntityTest.php in core/tests/Drupal/Tests/Core/Theme/DesignToken/DesignTokenEntityTest.php
DesignTokenResourceTestBase.php in core/tests/Drupal/FunctionalTests/Rest/DesignTokenResourceTestBase.php
DesignTokenTest.php in core/modules/jsonapi/tests/src/Functional/DesignTokenTest.php
DesignTokenValidationTest.php in core/tests/Drupal/KernelTests/Core/Theme/DesignToken/DesignTokenValidationTest.php

... See full list

File

core/lib/Drupal/Core/Theme/Entity/DesignToken.php, line 23

Namespace

Drupal\Core\Theme\Entity
View source
class DesignToken extends ConfigEntityBase implements DesignTokenInterface, EntityWithPluginCollectionInterface {
  
  /**
   * The design token ID.
   */
  protected ?string $id;
  
  /**
   * The design token path.
   */
  protected string $path;
  
  /**
   * The design token type.
   */
  protected string $type;
  
  /**
   * The design token scopes.
   */
  protected array $scopes;
  
  /**
   * Holds the collection of scopes.
   */
  private DesignTokenValuePluginCollection $scopesCollection;
  
  /**
   * {@inheritdoc}
   */
  public function getCssVariableName() : string {
    $name = $this->path;
    $name = \strtr($name, [
      '_' => '-',
      ' ' => '-',
      '.' => '-',
    ]);
    return "--{$name}";
  }
  
  /**
   * {@inheritdoc}
   */
  public function getScopes() : DesignTokenValuePluginCollection {
    if (!isset($this->scopesCollection)) {
      /** @var \Drupal\Core\Theme\DesignToken\DesignTokenValuePluginManagerInterface $manager */
      $manager = \Drupal::service(DesignTokenValuePluginManagerInterface::class);
      $this->scopesCollection = new DesignTokenValuePluginCollection($manager, $this->type, $this->scopes);
    }
    return $this->scopesCollection;
  }
  
  /**
   * {@inheritdoc}
   */
  public function getPluginCollections() {
    return [
      'scopes' => $this->getScopes(),
    ];
  }
  
  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) : void {
    parent::preSave($storage);
    // Ensure scope does not contain a dot.
    foreach ($this->scopes as $scope => $value) {
      if (\strpos($scope, '.') !== FALSE) {
        $this->scopes[static::getConfigScopeName($scope)] = $value;
        unset($this->scopes[$scope]);
      }
    }
  }
  
  /**
   * {@inheritdoc}
   */
  public static function toCss(array $tokens) : string {
    // Regroup values by scope.
    $scopes = [];
    foreach ($tokens as $token) {
      foreach ($token->getScopes() as $scope => $value) {
        $scope = static::getCssScopeName($scope);
        if (!isset($scopes[$scope])) {
          $scopes[$scope] = [];
        }
        $scopes[$scope][$token->getCssVariableName()] = $value;
      }
    }
    return static::getCssVariablesInlineCss($scopes);
  }
  
  /**
   * Prepares a scope for CSS usage.
   *
   * Transform DOT_CONVERSION_CHARACTER into dot.
   *
   * @param string $scope
   *   The scope to convert.
   *
   * @return string
   *   The converted scope.
   */
  public static function getCssScopeName(string $scope) : string {
    return \str_replace(self::DOT_CONVERSION_CHARACTER, '.', $scope);
  }
  
  /**
   * Prepares a scope for config storage.
   *
   * Transform dot into DOT_CONVERSION_CHARACTER.
   *
   * @param string $scope
   *   The scope to convert.
   *
   * @return string
   *   The converted scope.
   */
  public static function getConfigScopeName(string $scope) : string {
    return \str_replace('.', self::DOT_CONVERSION_CHARACTER, $scope);
  }
  
  /**
   * Prepares inline CSS from scope grouped CSS variables.
   *
   * @param array $scopes
   *   The prepared scopes.
   *
   * @return string
   *   The inline CSS.
   */
  protected static function getCssVariablesInlineCss(array $scopes) : string {
    $css = '';
    foreach ($scopes as $scope => $variables) {
      if (!\is_array($variables) || empty($variables)) {
        continue;
      }
      $scope_variables = [];
      foreach ($variables as $variableName => $variableValue) {
        $scope_variables[] = "{$variableName}:{$variableValue->toCss()};";
      }
      $css .= "{$scope}{" . \implode('', $scope_variables) . '}';
    }
    return $css;
  }

}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.