From 0777205a254892e591990ec9a7df8768220c4fb0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Frank=20Na=CC=88gler?= <frank.naegler@typo3.org>
Date: Mon, 10 Aug 2015 15:52:44 +0200
Subject: [PATCH] [TASK] Introduce icon state for IconFactory

Resolves: #69095
Releases: master
Change-Id: I4a1077a9267ed293f049f6457aef5d8012aa28d4
Reviewed-on: http://review.typo3.org/42482
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Tested-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
---
 .../Resources/Public/Less/Component/icon.less | 10 +++++
 typo3/sysext/core/Classes/Imaging/Icon.php    | 35 ++++++++++++++++-
 .../core/Classes/Imaging/IconFactory.php      | 10 +++--
 .../core/Classes/Type/Icon/IconState.php      | 33 ++++++++++++++++
 .../Classes/ViewHelpers/IconViewHelper.php    | 10 +++--
 ...69095-IntroduceIconStateForIconFactory.rst | 39 +++++++++++++++++++
 .../core/Tests/Unit/Imaging/DimensionTest.php |  2 -
 .../Tests/Unit/Imaging/IconFactoryTest.php    | 11 +++---
 .../FontawesomeIconProviderTest.php           |  8 ----
 .../core/Tests/Unit/Imaging/IconTest.php      | 11 +++++-
 .../Unit/ViewHelpers/IconViewHelperTest.php   | 25 +++++++++---
 .../t3skin/Resources/Public/Css/backend.css   | 25 ++++++------
 12 files changed, 178 insertions(+), 41 deletions(-)
 create mode 100644 typo3/sysext/core/Classes/Type/Icon/IconState.php
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst

diff --git a/Build/Resources/Public/Less/Component/icon.less b/Build/Resources/Public/Less/Component/icon.less
index cd24960a910d..9b023e441108 100644
--- a/Build/Resources/Public/Less/Component/icon.less
+++ b/Build/Resources/Public/Less/Component/icon.less
@@ -25,6 +25,7 @@
 @icon-size-default:      32px;
 @icon-size-large:        48px;
 @icon-unify-modifier:    0.86;
+@icon-opacity-disabled:  0.5;
 
 //
 // Component
@@ -93,6 +94,15 @@
 	}
 }
 
+//
+// States
+//
+.icon-state-disabled {
+	.icon-markup {
+		opacity: @icon-opacity-disabled;
+	}
+}
+
 //
 // Variants
 //
diff --git a/typo3/sysext/core/Classes/Imaging/Icon.php b/typo3/sysext/core/Classes/Imaging/Icon.php
index 18464e2c573b..550791d48869 100644
--- a/typo3/sysext/core/Classes/Imaging/Icon.php
+++ b/typo3/sysext/core/Classes/Imaging/Icon.php
@@ -13,6 +13,8 @@ namespace TYPO3\CMS\Core\Imaging;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -44,28 +46,39 @@ class Icon {
 
 	/**
 	 * The identifier which the PHP code that calls the IconFactory hands over
+	 *
 	 * @var string
 	 */
 	protected $identifier;
 
 	/**
 	 * The identifier for a possible overlay icon
+	 *
 	 * @var Icon
 	 */
 	protected $overlayIcon = NULL;
 
 	/**
 	 * Contains the size string ("large", "small" or "default")
+	 *
 	 * @var string
 	 */
 	protected $size = '';
 
 	/**
 	 * Flag to indicate if the icon has a spinning animation
+	 *
 	 * @var bool
 	 */
 	protected $spinning = FALSE;
 
+	/**
+	 * Contains the state information
+	 *
+	 * @var IconState
+	 */
+	protected $state;
+
 	/**
 	 * @var Dimension
 	 */
@@ -128,6 +141,7 @@ class Icon {
 
 	/**
 	 * Sets the size and creates the new dimension
+	 *
 	 * @param string $size
 	 */
 	public function setSize($size) {
@@ -136,19 +150,35 @@ class Icon {
 	}
 
 	/**
-	 * @return boolean
+	 * @return bool
 	 */
 	public function isSpinning() {
 		return $this->spinning;
 	}
 
 	/**
-	 * @param boolean $spinning
+	 * @param bool $spinning
 	 */
 	public function setSpinning($spinning) {
 		$this->spinning = $spinning;
 	}
 
+	/**
+	 * @return IconState
+	 */
+	public function getState() {
+		return $this->state;
+	}
+
+	/**
+	 * Sets the state of the icon
+	 *
+	 * @param IconState $state
+	 */
+	public function setState(IconState $state) {
+		$this->state = $state;
+	}
+
 	/**
 	 * @return Dimension
 	 */
@@ -187,6 +217,7 @@ class Icon {
 		$classes = array();
 		$classes[] = 'icon';
 		$classes[] = 'icon-size-' . $this->size;
+		$classes[] = 'icon-state-' . htmlspecialchars((string)$this->state);
 		$classes[] = 'icon-' . $this->getIdentifier();
 		if ($this->isSpinning()) {
 			$classes[] = 'icon-spin';
diff --git a/typo3/sysext/core/Classes/Imaging/IconFactory.php b/typo3/sysext/core/Classes/Imaging/IconFactory.php
index 5407183cd6dd..74533358cd93 100644
--- a/typo3/sysext/core/Classes/Imaging/IconFactory.php
+++ b/typo3/sysext/core/Classes/Imaging/IconFactory.php
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Imaging;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -36,17 +37,19 @@ class IconFactory {
 
 	/**
 	 * @param string $identifier
-	 * @param string $size
+	 * @param string $size "large", "small" or "default", see the constants of the Icon class
 	 * @param string $overlayIdentifier
+	 * @param IconState $state
 	 *
 	 * @return Icon
 	 */
-	public function getIcon($identifier, $size = Icon::SIZE_DEFAULT, $overlayIdentifier = NULL) {
+	public function getIcon($identifier, $size = Icon::SIZE_DEFAULT, $overlayIdentifier = NULL, IconState $state = NULL) {
 		if (!$this->iconRegistry->isRegistered($identifier)) {
 			$identifier = $this->iconRegistry->getDefaultIconIdentifier();
 		}
 
 		$iconConfiguration = $this->iconRegistry->getIconConfigurationByIdentifier($identifier);
+		$iconConfiguration['state'] = $state;
 		$icon = $this->createIcon($identifier, $size, $overlayIdentifier, $iconConfiguration);
 		/** @var IconProviderInterface $iconProvider */
 		$iconProvider = GeneralUtility::makeInstance($iconConfiguration['provider']);
@@ -58,7 +61,7 @@ class IconFactory {
 	 * Creates an icon object
 	 *
 	 * @param string $identifier
-	 * @param string $size "large" "small" or "default", see the constants of the Icon class
+	 * @param string $size "large", "small" or "default", see the constants of the Icon class
 	 * @param string $overlayIdentifier
 	 * @param array $iconConfiguration the icon configuration array
 	 * @return Icon
@@ -67,6 +70,7 @@ class IconFactory {
 		$icon = GeneralUtility::makeInstance(Icon::class);
 		$icon->setIdentifier($identifier);
 		$icon->setSize($size);
+		$icon->setState($iconConfiguration['state'] ?: new IconState());
 		if ($overlayIdentifier !== NULL) {
 			$icon->setOverlayIcon($this->getIcon($overlayIdentifier, Icon::SIZE_OVERLAY));
 		}
diff --git a/typo3/sysext/core/Classes/Type/Icon/IconState.php b/typo3/sysext/core/Classes/Type/Icon/IconState.php
new file mode 100644
index 000000000000..a87519337000
--- /dev/null
+++ b/typo3/sysext/core/Classes/Type/Icon/IconState.php
@@ -0,0 +1,33 @@
+<?php
+namespace TYPO3\CMS\Core\Type\Icon;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * A class providing constants for icon states
+ */
+class IconState extends \TYPO3\CMS\Core\Type\Enumeration {
+
+	const __default = self::STATE_DEFAULT;
+
+	/**
+	 * @var string the default state identifier
+	 */
+	const STATE_DEFAULT = 'default';
+
+	/**
+	 * @var string the disabled state identifier
+	 */
+	const STATE_DISABLED = 'disabled';
+}
diff --git a/typo3/sysext/core/Classes/ViewHelpers/IconViewHelper.php b/typo3/sysext/core/Classes/ViewHelpers/IconViewHelper.php
index 7032c067492b..be40d53e2ad7 100644
--- a/typo3/sysext/core/Classes/ViewHelpers/IconViewHelper.php
+++ b/typo3/sysext/core/Classes/ViewHelpers/IconViewHelper.php
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\ViewHelpers;
 
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
 use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
@@ -32,14 +33,16 @@ class IconViewHelper extends AbstractViewHelper implements CompilableInterface {
 	 * @param string $identifier
 	 * @param string $size
 	 * @param string $overlay
+	 * @param string $state
 	 * @return string
 	 */
-	public function render($identifier, $size = Icon::SIZE_SMALL, $overlay = NULL) {
+	public function render($identifier, $size = Icon::SIZE_SMALL, $overlay = NULL, $state = IconState::STATE_DEFAULT) {
 		return static::renderStatic(
 			array(
 				'identifier' => $identifier,
 				'size' => $size,
-				'overlay' => $overlay
+				'overlay' => $overlay,
+				'state' => $state
 			),
 			$this->buildRenderChildrenClosure(),
 			$this->renderingContext
@@ -58,9 +61,10 @@ class IconViewHelper extends AbstractViewHelper implements CompilableInterface {
 		$identifier = $arguments['identifier'];
 		$size = $arguments['size'];
 		$overlay = $arguments['overlay'];
+		$state = IconState::cast($arguments['state']);
 		/** @var IconFactory $iconFactory */
 		$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
-		return $iconFactory->getIcon($identifier, $size, $overlay)->render();
+		return $iconFactory->getIcon($identifier, $size, $overlay, $state)->render();
 	}
 
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst
new file mode 100644
index 000000000000..30835b98e5b3
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst
@@ -0,0 +1,39 @@
+======================================================
+Feature: #69095 - Introduce icon state for IconFactory
+======================================================
+
+Description
+===========
+
+A state (default or disabled) for icons has been added. The state "disabled" marks an icon as disabled and shows the icon with 50% opacity.
+
+
+Use an icon
+-----------
+
+The method ``IconFactory::getIcon()`` has now a fourth parameter for the state.
+
+The ``\TYPO3\CMS\Core\Type\Icon\IconState`` class provides only the following constants for icon states:
+
+* ``State::STATE_DEFAULT`` which currently means 100% opacity
+* ``State::STATE_DISABLED`` which currently means 50% opacity
+
+The states may change in future, so please make use of the constants for an unified layout.
+
+.. code-block:: php
+
+	$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+	$iconFactory->getIcon($identifier, Icon::SIZE_SMALL, $overlay, IconState::cast(IconState::STATE_DEFAULT))->render();
+
+
+ViewHelper
+----------
+
+The core provides a Fluid ViewHelper which makes it really easy to use icons within a Fluid view.
+This ViewHelper has an argument for the new state parameter.
+
+.. code-block:: html
+
+	{namespace core = TYPO3\CMS\Core\ViewHelpers}
+	<core:icon identifier="my-icon-identifier" size="small" state="disabled" />
+
diff --git a/typo3/sysext/core/Tests/Unit/Imaging/DimensionTest.php b/typo3/sysext/core/Tests/Unit/Imaging/DimensionTest.php
index 6931be1b846f..8e0eb4526f6f 100644
--- a/typo3/sysext/core/Tests/Unit/Imaging/DimensionTest.php
+++ b/typo3/sysext/core/Tests/Unit/Imaging/DimensionTest.php
@@ -15,8 +15,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
  */
 
 use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Imaging\IconFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Testcase for \TYPO3\CMS\Core\Imaging\Dimension
diff --git a/typo3/sysext/core/Tests/Unit/Imaging/IconFactoryTest.php b/typo3/sysext/core/Tests/Unit/Imaging/IconFactoryTest.php
index f4da1fb28dc8..ada1dee6f553 100644
--- a/typo3/sysext/core/Tests/Unit/Imaging/IconFactoryTest.php
+++ b/typo3/sysext/core/Tests/Unit/Imaging/IconFactoryTest.php
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
  */
 
 use Prophecy\Argument;
-use Prophecy\Prophecy\ObjectProphecy;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Imaging\IconProvider\FontawesomeIconProvider;
@@ -94,7 +93,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 	 * @test
 	 */
 	public function getIconByIdentifierReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed() {
-		$this->assertContains('<span class="icon icon-size-default icon-actions-document-close">',
+		$this->assertContains('<span class="icon icon-size-default icon-state-default icon-actions-document-close">',
 			$this->subject->getIcon($this->registeredIconIdentifier)->render());
 	}
 
@@ -103,7 +102,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 	 * @dataProvider differentSizesDataProvider
 	 */
 	public function getIconByIdentifierAndSizeReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed($size) {
-		$this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-actions-document-close">',
+		$this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-state-default icon-actions-document-close">',
 			$this->subject->getIcon($this->registeredIconIdentifier, $size['input'])->render());
 	}
 
@@ -129,7 +128,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 				'additionalClasses' => 'fa-fw'
 			)
 		]);
-		$this->assertContains('<span class="icon icon-size-default icon-default-not-found">',
+		$this->assertContains('<span class="icon icon-size-default icon-state-default icon-default-not-found">',
 			$this->subject->getIcon($this->notRegisteredIconIdentifier)->render());
 	}
 
@@ -147,7 +146,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 				'additionalClasses' => 'fa-fw'
 			)
 		]);
-		$this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-default-not-found">',
+		$this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-state-default icon-default-not-found">',
 			$this->subject->getIcon($this->notRegisteredIconIdentifier, $size['input'])->render());
 	}
 
@@ -163,7 +162,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 				'spinning' => TRUE
 			)
 		]);
-		$this->assertContains('<span class="icon icon-size-default icon-' . $this->registeredSpinningIconIdentifier . ' icon-spin">',
+		$this->assertContains('<span class="icon icon-size-default icon-state-default icon-' . $this->registeredSpinningIconIdentifier . ' icon-spin">',
 			$this->subject->getIcon($this->registeredSpinningIconIdentifier)->render());
 	}
 
diff --git a/typo3/sysext/core/Tests/Unit/Imaging/IconProvider/FontawesomeIconProviderTest.php b/typo3/sysext/core/Tests/Unit/Imaging/IconProvider/FontawesomeIconProviderTest.php
index 0b0937abf3b4..cf90bf817ef7 100644
--- a/typo3/sysext/core/Tests/Unit/Imaging/IconProvider/FontawesomeIconProviderTest.php
+++ b/typo3/sysext/core/Tests/Unit/Imaging/IconProvider/FontawesomeIconProviderTest.php
@@ -52,14 +52,6 @@ class FontawesomeIconProviderTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 		$this->assertEquals('<span class="icon-unify"><i class="fa fa-times"></i></span>', $this->icon->getMarkup());
 	}
 
-	/**
-	 * @test
-	 */
-	public function prepareIconMarkupWithNameAndAdditionalClassesReturnsInstanceOfIconWithCorrectMarkup() {
-		$this->subject->prepareIconMarkup($this->icon, array('name' => 'times', 'additionalClasses' => 'foo'));
-		$this->assertEquals('<span class="icon-unify"><i class="fa fa-times foo"></i></span>', $this->icon->getMarkup());
-	}
-
 	/**
 	 * DataProvider for icon names
 	 *
diff --git a/typo3/sysext/core/Tests/Unit/Imaging/IconTest.php b/typo3/sysext/core/Tests/Unit/Imaging/IconTest.php
index 86354ba88994..a9159554aaf9 100644
--- a/typo3/sysext/core/Tests/Unit/Imaging/IconTest.php
+++ b/typo3/sysext/core/Tests/Unit/Imaging/IconTest.php
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
 
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 
 /**
  * Testcase for \TYPO3\CMS\Core\Imaging\Icon
@@ -44,7 +45,7 @@ class IconTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 	 */
 	protected function setUp() {
 		$iconFactory = new IconFactory();
-		$this->subject = $iconFactory->getIcon($this->iconIdentifier, Icon::SIZE_SMALL, $this->overlayIdentifier);
+		$this->subject = $iconFactory->getIcon($this->iconIdentifier, Icon::SIZE_SMALL, $this->overlayIdentifier, IconState::cast(IconState::STATE_DISABLED));
 	}
 
 	/**
@@ -74,4 +75,12 @@ class IconTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 	public function getSizedentifierReturnsCorrectIdentifier() {
 		$this->assertEquals(Icon::SIZE_SMALL, $this->subject->getSize());
 	}
+
+	/**
+	 * @test
+	 */
+	public function getStateReturnsCorrectIdentifier() {
+		$this->assertTrue($this->subject->getState()->equals(IconState::STATE_DISABLED));
+	}
+
 }
diff --git a/typo3/sysext/core/Tests/Unit/ViewHelpers/IconViewHelperTest.php b/typo3/sysext/core/Tests/Unit/ViewHelpers/IconViewHelperTest.php
index 5e131c0775cb..5c0c814ad66d 100644
--- a/typo3/sysext/core/Tests/Unit/ViewHelpers/IconViewHelperTest.php
+++ b/typo3/sysext/core/Tests/Unit/ViewHelpers/IconViewHelperTest.php
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\ViewHelpers;
 use Prophecy\Argument;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\ViewHelpers\IconViewHelper;
 use TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\ViewHelperBaseTestcase;
@@ -41,12 +42,12 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
 	/**
 	 * @test
 	 */
-	public function renderCallsIconFactoryWithDefaultSizeAndReturnsResult() {
+	public function renderCallsIconFactoryWithDefaultSizeAndDefaultStateAndReturnsResult() {
 		$iconFactoryProphecy = $this->prophesize(IconFactory::class);
 		GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
 		$iconProphecy = $this->prophesize(Icon::class);
 
-		$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL)->shouldBeCalled()->willReturn($iconProphecy->reveal());
+		$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
 		$iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
 		$this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier'));
@@ -60,12 +61,26 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
 		GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
 		$iconProphecy = $this->prophesize(Icon::class);
 
-		$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_LARGE, NULL)->shouldBeCalled()->willReturn($iconProphecy->reveal());
+		$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_LARGE, NULL, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
 		$iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
 		$this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_LARGE));
 	}
 
+	/**
+	 * @test
+	 */
+	public function renderCallsIconFactoryWithGivenStateAndReturnsResult() {
+		$iconFactoryProphecy = $this->prophesize(IconFactory::class);
+		GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
+		$iconProphecy = $this->prophesize(Icon::class);
+
+		$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DISABLED))->shouldBeCalled()->willReturn($iconProphecy->reveal());
+		$iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
+
+		$this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DISABLED)));
+	}
+
 	/**
 	 * @test
 	 */
@@ -74,10 +89,10 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
 		GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
 		$iconProphecy = $this->prophesize(Icon::class);
 
-		$iconFactoryProphecy->getIcon('myIdentifier', Argument::any(), 'overlayString')->shouldBeCalled()->willReturn($iconProphecy->reveal());
+		$iconFactoryProphecy->getIcon('myIdentifier', Argument::any(), 'overlayString', IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
 		$iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
 		$this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_LARGE, 'overlayString'));
 	}
 
-}
\ No newline at end of file
+}
diff --git a/typo3/sysext/t3skin/Resources/Public/Css/backend.css b/typo3/sysext/t3skin/Resources/Public/Css/backend.css
index b812a096094e..c2f602b793fe 100644
--- a/typo3/sysext/t3skin/Resources/Public/Css/backend.css
+++ b/typo3/sysext/t3skin/Resources/Public/Css/backend.css
@@ -1,14 +1,14 @@
-/*!
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
+/*!
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
  */
 /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
 html {
@@ -7810,6 +7810,9 @@ button.close {
     transform: rotate(359deg);
   }
 }
+.icon-state-disabled .icon-markup {
+  opacity: 0.5;
+}
 .icon-size-small {
   height: 16px;
   width: 16px;
-- 
GitLab