From 1296e40f78e0edbe9fd1996e1c4887405e674bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Thu, 29 Jan 2026 13:36:52 +0100 Subject: [PATCH 1/2] Refactor color loading and type annotations in color classes --- composer.json | 4 ++-- src/Apple/AppleColors.php | 26 ++++++++++++++++++++++---- src/Bootstrap/BootstrapColors.php | 21 ++++++++++++++++++--- src/Dracula/DraculaColors.php | 5 ++++- src/Material/MaterialColors.php | 9 +++++++-- src/Nord/NordColors.php | 5 ++++- src/OpenColor/OpenColorColors.php | 13 +++++++++++-- src/Pico/PicoColors.php | 21 ++++++++++++++++++--- src/Primer/PrimerColors.php | 13 +++++++++++-- src/Tailwind/TailwindColors.php | 13 +++++++++++-- 10 files changed, 108 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index 1bf5685..8dbb58f 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/var-dumper": "^7.0" + "phpunit/phpunit": "^12.5", + "symfony/var-dumper": "^8.0" }, "replace": { "phpcolor/apple-colors": "self.version", diff --git a/src/Apple/AppleColors.php b/src/Apple/AppleColors.php index a3758a1..99a369a 100644 --- a/src/Apple/AppleColors.php +++ b/src/Apple/AppleColors.php @@ -19,7 +19,7 @@ final class AppleColors extends \stdClass implements \IteratorAggregate, \Countable { /** - * @var array> + * @var array */ private static array $files = []; @@ -63,13 +63,31 @@ private static function create(string $file, ?string $theme = null): self throw new \InvalidArgumentException(sprintf('The theme "%s" does not exist.', $theme)); } - $file = self::$files[$file] ??= require __DIR__.'/Resources/colors/'.$file.'.php'; + if (!isset(self::$files[$file])) { + self::$files[$file] = require __DIR__.'/Resources/colors/'.$file.'.php'; + } + + $fileData = self::$files[$file]; + + if ($theme) { + if (!is_array($fileData) || !isset($fileData[$theme])) { + throw new \RuntimeException(sprintf('Theme "%s" not found in file "%s".', $theme, $file)); + } + /** @var array */ + $colors = $fileData[$theme]; + } else { + if (!is_array($fileData)) { + throw new \RuntimeException(sprintf('Invalid data structure in file "%s".', $file)); + } + /** @var array */ + $colors = $fileData; + } - return new self($theme ? $file[$theme] : $file); + return new self($colors); } /** - * @param array $colors + * @param array $colors */ private function __construct(private readonly array $colors) { diff --git a/src/Bootstrap/BootstrapColors.php b/src/Bootstrap/BootstrapColors.php index 48b0a05..4ea61b2 100644 --- a/src/Bootstrap/BootstrapColors.php +++ b/src/Bootstrap/BootstrapColors.php @@ -32,7 +32,10 @@ final class BootstrapColors extends \stdClass implements \IteratorAggregate, \Co { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array> $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** @@ -77,9 +80,15 @@ public function has(string $name): bool return \in_array($name, $this->getNames(), true); } + /** + * @return int<0, max> + */ public function count(): int { - return count($this->colors, COUNT_RECURSIVE) - count($this->colors); + $total = count($this->colors, COUNT_RECURSIVE) - count($this->colors); + assert($total >= 0); + + return $total; } /** @@ -103,7 +112,13 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = 500; + if (isset($arguments[0])) { + assert(\is_int($arguments[0])); + $shade = $arguments[0]; + } + + return $this->get($name, $shade); } public function __get(string $name): string diff --git a/src/Dracula/DraculaColors.php b/src/Dracula/DraculaColors.php index ceb1889..a0380ae 100644 --- a/src/Dracula/DraculaColors.php +++ b/src/Dracula/DraculaColors.php @@ -20,7 +20,10 @@ final class DraculaColors extends \stdClass implements \IteratorAggregate, \Coun { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** diff --git a/src/Material/MaterialColors.php b/src/Material/MaterialColors.php index 3bcb91b..343b71a 100644 --- a/src/Material/MaterialColors.php +++ b/src/Material/MaterialColors.php @@ -40,7 +40,10 @@ final class MaterialColors extends \stdClass implements \IteratorAggregate, \Cou { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array> $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** @@ -111,7 +114,9 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer or string, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = isset($arguments[0]) ? (\is_int($arguments[0]) || \is_string($arguments[0]) ? $arguments[0] : 500) : 500; + + return $this->get($name, $shade); } public function __get(string $name): string diff --git a/src/Nord/NordColors.php b/src/Nord/NordColors.php index 0532f6c..a002625 100644 --- a/src/Nord/NordColors.php +++ b/src/Nord/NordColors.php @@ -20,7 +20,10 @@ final class NordColors extends \stdClass implements \IteratorAggregate, \Countab { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** diff --git a/src/OpenColor/OpenColorColors.php b/src/OpenColor/OpenColorColors.php index 5b43a55..f2cf809 100644 --- a/src/OpenColor/OpenColorColors.php +++ b/src/OpenColor/OpenColorColors.php @@ -34,7 +34,10 @@ final class OpenColorColors extends \stdClass implements \IteratorAggregate, \Co { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array|string> $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** @@ -114,7 +117,13 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = 5; + if (isset($arguments[0])) { + assert(\is_int($arguments[0])); + $shade = $arguments[0]; + } + + return $this->get($name, $shade); } public function __get(string $name): string diff --git a/src/Pico/PicoColors.php b/src/Pico/PicoColors.php index ec8ee2b..55bbeb8 100644 --- a/src/Pico/PicoColors.php +++ b/src/Pico/PicoColors.php @@ -41,7 +41,10 @@ final class PicoColors extends \stdClass implements \IteratorAggregate, \Countab { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array> $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** @@ -86,9 +89,15 @@ public function has(string $name): bool return \in_array($name, $this->getNames(), true); } + /** + * @return int<0, max> + */ public function count(): int { - return count($this->colors, COUNT_RECURSIVE) - count($this->colors); + $total = count($this->colors, COUNT_RECURSIVE) - count($this->colors); + assert($total >= 0); + + return $total; } /** @@ -112,7 +121,13 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = 500; + if (isset($arguments[0])) { + assert(\is_int($arguments[0])); + $shade = $arguments[0]; + } + + return $this->get($name, $shade); } public function __get(string $name): string diff --git a/src/Primer/PrimerColors.php b/src/Primer/PrimerColors.php index 41e24ee..a1b6da0 100644 --- a/src/Primer/PrimerColors.php +++ b/src/Primer/PrimerColors.php @@ -41,7 +41,10 @@ public static function colors(string $theme = 'light'): self throw new \InvalidArgumentException(sprintf('The theme "%s" does not exist.', $theme)); } - return new self(require __DIR__.'/Resources/'.$theme.'.php'); + /** @var array> $colors */ + $colors = require __DIR__.'/Resources/'.$theme.'.php'; + + return new self($colors); } /** @@ -112,7 +115,13 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = 5; + if (isset($arguments[0])) { + assert(\is_int($arguments[0])); + $shade = $arguments[0]; + } + + return $this->get($name, $shade); } public function __get(string $name): string diff --git a/src/Tailwind/TailwindColors.php b/src/Tailwind/TailwindColors.php index c933b79..0f2fe2c 100644 --- a/src/Tailwind/TailwindColors.php +++ b/src/Tailwind/TailwindColors.php @@ -32,7 +32,10 @@ final class TailwindColors extends \stdClass implements \IteratorAggregate, \Cou { public static function colors(): self { - return new self(require __DIR__.'/Resources/colors.php'); + /** @var array> $colors */ + $colors = require __DIR__.'/Resources/colors.php'; + + return new self($colors); } /** @@ -103,7 +106,13 @@ public function __call(string $name, array $arguments): mixed throw new \InvalidArgumentException(sprintf('The first argument of "%s" must be an integer, "%s" given.', $name, get_debug_type($arguments[0]))); } - return $this->get($name, ...$arguments); + $shade = 500; + if (isset($arguments[0])) { + assert(\is_int($arguments[0])); + $shade = $arguments[0]; + } + + return $this->get($name, $shade); } public function __get(string $name): string From 9015da5951848d6986107bb2f545c8b41c311bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Thu, 29 Jan 2026 13:40:19 +0100 Subject: [PATCH 2/2] Fix composer requirement --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8dbb58f..aab8ec6 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "phpunit/phpunit": "^12.5", - "symfony/var-dumper": "^8.0" + "symfony/var-dumper": "^7.0 || ^8.0" }, "replace": { "phpcolor/apple-colors": "self.version",