From 64579dc7fecd155ac7681348df0db1d5614360a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Thu, 29 Jan 2026 12:50:30 +0100 Subject: [PATCH 1/2] Add Nord, OpenColor, Dracula, and Material colors --- src/OpenColor/README.md | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/OpenColor/README.md diff --git a/src/OpenColor/README.md b/src/OpenColor/README.md new file mode 100644 index 0000000..869b2be --- /dev/null +++ b/src/OpenColor/README.md @@ -0,0 +1,72 @@ +# Open Color + +This package provides access to the Open Color palette, an open-source color scheme optimized for UI design. + +## Installation + +```bash +composer require phpcolor/open-color +``` + +## Usage + +### Create Colors Instance + +```php +use PhpColor\Colors\OpenColor\OpenColorColors as OpenColor; + +$colors = OpenColor::colors(); +``` + +### Color Names + +```php +use PhpColor\Colors\OpenColor\OpenColorColors as OpenColor; + +$colors = OpenColor::colors(); + +$names = $colors->getNames(); +// 'white', 'black', 'gray', 'red', 'pink', 'grape', +// 'violet', 'indigo', 'blue', 'cyan', 'teal', 'green', +// 'lime', 'yellow', 'orange' +``` + +### Color Shades + +```php +use PhpColor\Colors\OpenColor\OpenColorColors as OpenColor; + +$colors = OpenColor::colors(); + +// Get shades for a color (0-9) +$shades = $colors->getShades('gray'); +// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +``` + +### Color Values + +```php +use PhpColor\Colors\OpenColor\OpenColorColors as OpenColor; + +$colors = OpenColor::colors(); + +// Default shade is 5 +echo $colors->blue; // #339AF0 +echo $colors->blue(); // #339AF0 + +// Specify shade (0-9) +echo $colors->blue(7); // #1C7ED6 +echo $colors->get('red', 9); // #C92A2A + +// White and black have no shades +echo $colors->white; // #FFFFFF +echo $colors->black; // #000000 +``` + +## Credits + +The colors listed in this project are based on [Open Color](https://yeun.github.io/open-color/). + +## License + +This [PHPColor](https://phpcolor.dev) package is released under the [MIT license](LICENSE). From f5640388ca8c7a9dc127ea1256dc2bdcf81222ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Thu, 29 Jan 2026 12:51:01 +0100 Subject: [PATCH 2/2] Add Nord, OpenColor, Dracula, and Material colors --- .github/workflows/split.yml | 4 + README.md | 18 +- composer.json | 4 + src/Dracula/DraculaColors.php | 77 ++++++ src/Dracula/LICENSE | 21 ++ src/Dracula/README.md | 50 ++++ src/Dracula/Resources/colors.php | 26 ++ src/Dracula/composer.json | 36 +++ src/Material/LICENSE | 21 ++ src/Material/MaterialColors.php | 126 ++++++++++ src/Material/README.md | 72 ++++++ src/Material/Resources/colors.php | 307 ++++++++++++++++++++++++ src/Material/composer.json | 37 +++ src/Nord/LICENSE | 21 ++ src/Nord/NordColors.php | 85 +++++++ src/Nord/README.md | 54 +++++ src/Nord/Resources/colors.php | 31 +++ src/Nord/composer.json | 36 +++ src/OpenColor/LICENSE | 21 ++ src/OpenColor/OpenColorColors.php | 129 ++++++++++ src/OpenColor/Resources/colors.php | 173 +++++++++++++ src/OpenColor/composer.json | 36 +++ tests/Dracula/DraculaColorsTest.php | 80 ++++++ tests/Material/MaterialColorsTest.php | 143 +++++++++++ tests/Nord/NordColorsTest.php | 93 +++++++ tests/OpenColor/OpenColorColorsTest.php | 139 +++++++++++ 26 files changed, 1833 insertions(+), 7 deletions(-) create mode 100644 src/Dracula/DraculaColors.php create mode 100644 src/Dracula/LICENSE create mode 100644 src/Dracula/README.md create mode 100644 src/Dracula/Resources/colors.php create mode 100644 src/Dracula/composer.json create mode 100644 src/Material/LICENSE create mode 100644 src/Material/MaterialColors.php create mode 100644 src/Material/README.md create mode 100644 src/Material/Resources/colors.php create mode 100644 src/Material/composer.json create mode 100644 src/Nord/LICENSE create mode 100644 src/Nord/NordColors.php create mode 100644 src/Nord/README.md create mode 100644 src/Nord/Resources/colors.php create mode 100644 src/Nord/composer.json create mode 100644 src/OpenColor/LICENSE create mode 100644 src/OpenColor/OpenColorColors.php create mode 100644 src/OpenColor/Resources/colors.php create mode 100644 src/OpenColor/composer.json create mode 100644 tests/Dracula/DraculaColorsTest.php create mode 100644 tests/Material/MaterialColorsTest.php create mode 100644 tests/Nord/NordColorsTest.php create mode 100644 tests/OpenColor/OpenColorColorsTest.php diff --git a/.github/workflows/split.yml b/.github/workflows/split.yml index a0ad5d5..e03cf32 100644 --- a/.github/workflows/split.yml +++ b/.github/workflows/split.yml @@ -18,6 +18,10 @@ jobs: package: - { src: 'Apple', repo: 'apple-colors' } - { src: 'Bootstrap', repo: 'bootstrap-colors' } + - { src: 'Dracula', repo: 'dracula-colors' } + - { src: 'Material', repo: 'material-colors' } + - { src: 'Nord', repo: 'nord-colors' } + - { src: 'OpenColor', repo: 'open-color' } - { src: 'Pico', repo: 'pico-colors' } - { src: 'Primer', repo: 'primer-colors' } - { src: 'Tailwind', repo: 'tailwind-colors' } diff --git a/README.md b/README.md index 997fd8c..e5fae45 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,17 @@ ## Packages -| Name | Composer install | Description | -|--------------------------------------|-----------------------------|--------------------------------------| -| [Apple](src/Apple/README.md) | `phpcolor/apple-colors` | Apple color palettes & scales | -| [Bootstrap](src/Bootstrap/README.md) | `phpcolor/bootstrap-colors` | Bootstrap 5 color palettes & scales | -| [Pico](src/Pico/README.md) | `phpcolor/pico-colors` | Pico CSS color palettes & scales | -| [Primer](src/Primer/README.md) | `phpcolor/primer-colors` | Primer color palettes & scales | -| [Tailwind](src/Tailwind/README.md) | `phpcolor/tailwind-colors` | Tailwind CSS color palettes & scales | +| Name | Composer install | Description | +|--------------------------------------|-----------------------------|--------------------------------------------------| +| [Apple](src/Apple/README.md) | `phpcolor/apple-colors` | Apple color palettes & scales | +| [Bootstrap](src/Bootstrap/README.md) | `phpcolor/bootstrap-colors` | Bootstrap 5 color palettes & scales | +| [Dracula](src/Dracula/README.md) | `phpcolor/dracula-colors` | Dracula dark theme color palette | +| [Material](src/Material/README.md) | `phpcolor/material-colors` | Material Design color palette | +| [Nord](src/Nord/README.md) | `phpcolor/nord-colors` | Nord arctic, north-bluish color scheme | +| [Open Color](src/OpenColor/README.md)| `phpcolor/open-color` | Open Color palette optimized for UI design | +| [Pico](src/Pico/README.md) | `phpcolor/pico-colors` | Pico CSS color palettes & scales | +| [Primer](src/Primer/README.md) | `phpcolor/primer-colors` | Primer color palettes & scales | +| [Tailwind](src/Tailwind/README.md) | `phpcolor/tailwind-colors` | Tailwind CSS color palettes & scales | ## License diff --git a/composer.json b/composer.json index 3f2abc9..1bf5685 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,10 @@ "replace": { "phpcolor/apple-colors": "self.version", "phpcolor/bootstrap-colors": "self.version", + "phpcolor/dracula-colors": "self.version", + "phpcolor/material-colors": "self.version", + "phpcolor/nord-colors": "self.version", + "phpcolor/open-color": "self.version", "phpcolor/pico-colors": "self.version", "phpcolor/primer-colors": "self.version", "phpcolor/tailwind-colors": "self.version" diff --git a/src/Dracula/DraculaColors.php b/src/Dracula/DraculaColors.php new file mode 100644 index 0000000..ceb1889 --- /dev/null +++ b/src/Dracula/DraculaColors.php @@ -0,0 +1,77 @@ + + */ +final class DraculaColors extends \stdClass implements \IteratorAggregate, \Countable +{ + public static function colors(): self + { + return new self(require __DIR__.'/Resources/colors.php'); + } + + /** + * @param array $colors + */ + private function __construct(private readonly array $colors) + { + } + + public function has(string $name): bool + { + return array_key_exists($name, $this->colors); + } + + public function get(string $name): string + { + if (!$this->has($name)) { + throw new \InvalidArgumentException(sprintf('The color "%s" does not exist.', $name)); + } + + return $this->colors[$name][0]; + } + + /** + * @return list + */ + public function getNames(): array + { + return array_keys($this->colors); + } + + /** + * @return \ArrayIterator + */ + public function getIterator(): \Iterator + { + return new \ArrayIterator(array_map(fn ($a) => $a[0], $this->colors)); + } + + public function count(): int + { + return count($this->colors); + } + + public function __get(string $name): string + { + return $this->get($name); + } + + public function __set(string $name, mixed $value): void + { + throw new \BadMethodCallException('DraculaColors are read-only.'); + } +} diff --git a/src/Dracula/LICENSE b/src/Dracula/LICENSE new file mode 100644 index 0000000..418d53d --- /dev/null +++ b/src/Dracula/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-present Simon André & Raphaël Geffroy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/Dracula/README.md b/src/Dracula/README.md new file mode 100644 index 0000000..3d50007 --- /dev/null +++ b/src/Dracula/README.md @@ -0,0 +1,50 @@ +# Dracula Colors + +This package provides access to the Dracula color palette, a dark theme for code editors and terminal applications. + +## Installation + +```bash +composer require phpcolor/dracula-colors +``` + +## Usage + +### Create Colors Instance + +```php +use PhpColor\Colors\Dracula\DraculaColors as Dracula; + +$colors = Dracula::colors(); +``` + +### Color Names + +```php +use PhpColor\Colors\Dracula\DraculaColors as Dracula; + +$colors = Dracula::colors(); + +$names = $colors->getNames(); +// 'background', 'currentLine', 'foreground', 'comment', +// 'cyan', 'green', 'orange', 'pink', 'purple', 'red', 'yellow' +``` + +### Color Values + +```php +use PhpColor\Colors\Dracula\DraculaColors as Dracula; + +$colors = Dracula::colors(); + +echo $colors->purple; // #BD93F9 +echo $colors->get('cyan'); // #8BE9FD +``` + +## Credits + +The colors listed in this project are based on the [Dracula Theme](https://draculatheme.com/). + +## License + +This [PHPColor](https://phpcolor.dev) package is released under the [MIT license](LICENSE). diff --git a/src/Dracula/Resources/colors.php b/src/Dracula/Resources/colors.php new file mode 100644 index 0000000..edb871c --- /dev/null +++ b/src/Dracula/Resources/colors.php @@ -0,0 +1,26 @@ + ['#282A36', [40, 42, 54]], + 'currentLine' => ['#44475A', [68, 71, 90]], + 'foreground' => ['#F8F8F2', [248, 248, 242]], + 'comment' => ['#6272A4', [98, 114, 164]], + 'cyan' => ['#8BE9FD', [139, 233, 253]], + 'green' => ['#50FA7B', [80, 250, 123]], + 'orange' => ['#FFB86C', [255, 184, 108]], + 'pink' => ['#FF79C6', [255, 121, 198]], + 'purple' => ['#BD93F9', [189, 147, 249]], + 'red' => ['#FF5555', [255, 85, 85]], + 'yellow' => ['#F1FA8C', [241, 250, 140]], +]; diff --git a/src/Dracula/composer.json b/src/Dracula/composer.json new file mode 100644 index 0000000..ed2e04c --- /dev/null +++ b/src/Dracula/composer.json @@ -0,0 +1,36 @@ +{ + "name": "phpcolor/dracula-colors", + "description": "Dracula Colors - PHP Color Palette", + "license": "MIT", + "type": "library", + "keywords": [ + "dracula", + "color", + "palette", + "theme", + "dark" + ], + "authors": [ + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Raphaël Geffroy", + "email": "raphael@geffroy.dev" + } + ], + "homepage": "https://phpcolor.dev/", + "require": { + "php": ">=8.3" + }, + "autoload": { + "psr-4": { "PhpColor\\Colors\\Dracula\\": "" } + }, + "extra": { + "thanks": { + "name": "phpcolor/colors", + "url": "https://github.com/phpcolor/colors" + } + } +} diff --git a/src/Material/LICENSE b/src/Material/LICENSE new file mode 100644 index 0000000..418d53d --- /dev/null +++ b/src/Material/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-present Simon André & Raphaël Geffroy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/Material/MaterialColors.php b/src/Material/MaterialColors.php new file mode 100644 index 0000000..3bcb91b --- /dev/null +++ b/src/Material/MaterialColors.php @@ -0,0 +1,126 @@ +> + */ +final class MaterialColors extends \stdClass implements \IteratorAggregate, \Countable +{ + public static function colors(): self + { + return new self(require __DIR__.'/Resources/colors.php'); + } + + /** + * @param array> $colors + */ + private function __construct(private readonly array $colors) + { + } + + /** + * @return list + */ + public function getNames(): array + { + return array_keys($this->colors); + } + + /** + * @return list + */ + public function getShades(?string $color = null): array + { + $color ??= $this->getNames()[0]; + + return array_keys($this->colors[$color]); + } + + public function get(string $color, int|string $shade = 500): string + { + if (!isset($this->colors[$color])) { + throw new \InvalidArgumentException(sprintf('The color "%s" does not exist.', $color)); + } + if (!isset($this->colors[$color][$shade])) { + throw new \InvalidArgumentException(sprintf('The shade "%s" does not exist for the color "%s".', $shade, $color)); + } + + return $this->colors[$color][$shade]; + } + + public function has(string $name): bool + { + return \in_array($name, $this->getNames(), true); + } + + public function count(): int + { + return count($this->colors, COUNT_RECURSIVE); + } + + /** + * @return \ArrayIterator> + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->colors); + } + + /** + * @param array $arguments + */ + public function __call(string $name, array $arguments): mixed + { + if (!$this->has($name)) { + throw new \BadMethodCallException(sprintf('The method "%s" does not exist.', $name)); + } + + if (isset($arguments[0]) && !\is_int($arguments[0]) && !\is_string($arguments[0])) { + 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); + } + + public function __get(string $name): string + { + return $this->get($name); + } + + public function __set(string $name, mixed $value): void + { + throw new \BadMethodCallException('MaterialColors are read-only.'); + } +} diff --git a/src/Material/README.md b/src/Material/README.md new file mode 100644 index 0000000..16ac8d1 --- /dev/null +++ b/src/Material/README.md @@ -0,0 +1,72 @@ +# Material Design Colors + +This package provides access to the Material Design color palette, Google's design system colors. + +## Installation + +```bash +composer require phpcolor/material-colors +``` + +## Usage + +### Create Colors Instance + +```php +use PhpColor\Colors\Material\MaterialColors as Material; + +$colors = Material::colors(); +``` + +### Color Names + +```php +use PhpColor\Colors\Material\MaterialColors as Material; + +$colors = Material::colors(); + +$names = $colors->getNames(); +// 'red', 'pink', 'purple', 'deepPurple', 'indigo', 'blue', +// 'lightBlue', 'cyan', 'teal', 'green', 'lightGreen', 'lime', +// 'yellow', 'amber', 'orange', 'deepOrange', 'brown', 'gray', 'blueGray' +``` + +### Color Shades + +```php +use PhpColor\Colors\Material\MaterialColors as Material; + +$colors = Material::colors(); + +// Get shades for a color (50, 100-900, A100, A200, A400, A700) +$shades = $colors->getShades('red'); +// [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 'A100', 'A200', 'A400', 'A700'] +``` + +### Color Values + +```php +use PhpColor\Colors\Material\MaterialColors as Material; + +$colors = Material::colors(); + +// Default shade is 500 +echo $colors->blue; // #2196F3 +echo $colors->blue(); // #2196F3 + +// Specify numeric shade (50, 100-900) +echo $colors->blue(700); // #1976D2 +echo $colors->get('red', 900); // #B71C1C + +// Specify accent shade (A100, A200, A400, A700) +echo $colors->red('A700'); // #D50000 +echo $colors->get('blue', 'A200'); // #448AFF +``` + +## Credits + +The colors listed in this project are based on [Material Design](https://material.io/design/color/). + +## License + +This [PHPColor](https://phpcolor.dev) package is released under the [MIT license](LICENSE). diff --git a/src/Material/Resources/colors.php b/src/Material/Resources/colors.php new file mode 100644 index 0000000..ce00333 --- /dev/null +++ b/src/Material/Resources/colors.php @@ -0,0 +1,307 @@ + [ + 50 => '#FFEBEE', + 100 => '#FFCDD2', + 200 => '#EF9A9A', + 300 => '#E57373', + 400 => '#EF5350', + 500 => '#F44336', + 600 => '#E53935', + 700 => '#D32F2F', + 800 => '#C62828', + 900 => '#B71C1C', + 'A100' => '#FF8A80', + 'A200' => '#FF5252', + 'A400' => '#FF1744', + 'A700' => '#D50000', + ], + 'pink' => [ + 50 => '#FCE4EC', + 100 => '#F8BBD0', + 200 => '#F48FB1', + 300 => '#F06292', + 400 => '#EC407A', + 500 => '#E91E63', + 600 => '#D81B60', + 700 => '#C2185B', + 800 => '#AD1457', + 900 => '#880E4F', + 'A100' => '#FF80AB', + 'A200' => '#FF4081', + 'A400' => '#F50057', + 'A700' => '#C51162', + ], + 'purple' => [ + 50 => '#F3E5F5', + 100 => '#E1BEE7', + 200 => '#CE93D8', + 300 => '#BA68C8', + 400 => '#AB47BC', + 500 => '#9C27B0', + 600 => '#8E24AA', + 700 => '#7B1FA2', + 800 => '#6A1B9A', + 900 => '#4A148C', + 'A100' => '#EA80FC', + 'A200' => '#E040FB', + 'A400' => '#D500F9', + 'A700' => '#AA00FF', + ], + 'deepPurple' => [ + 50 => '#EDE7F6', + 100 => '#D1C4E9', + 200 => '#B39DDB', + 300 => '#9575CD', + 400 => '#7E57C2', + 500 => '#673AB7', + 600 => '#5E35B1', + 700 => '#512DA8', + 800 => '#4527A0', + 900 => '#311B92', + 'A100' => '#B388FF', + 'A200' => '#7C4DFF', + 'A400' => '#651FFF', + 'A700' => '#6200EA', + ], + 'indigo' => [ + 50 => '#E8EAF6', + 100 => '#C5CAE9', + 200 => '#9FA8DA', + 300 => '#7986CB', + 400 => '#5C6BC0', + 500 => '#3F51B5', + 600 => '#3949AB', + 700 => '#303F9F', + 800 => '#283593', + 900 => '#1A237E', + 'A100' => '#8C9EFF', + 'A200' => '#536DFE', + 'A400' => '#3D5AFE', + 'A700' => '#304FFE', + ], + 'blue' => [ + 50 => '#E3F2FD', + 100 => '#BBDEFB', + 200 => '#90CAF9', + 300 => '#64B5F6', + 400 => '#42A5F5', + 500 => '#2196F3', + 600 => '#1E88E5', + 700 => '#1976D2', + 800 => '#1565C0', + 900 => '#0D47A1', + 'A100' => '#82B1FF', + 'A200' => '#448AFF', + 'A400' => '#2979FF', + 'A700' => '#2962FF', + ], + 'lightBlue' => [ + 50 => '#E1F5FE', + 100 => '#B3E5FC', + 200 => '#81D4FA', + 300 => '#4FC3F7', + 400 => '#29B6F6', + 500 => '#03A9F4', + 600 => '#039BE5', + 700 => '#0288D1', + 800 => '#0277BD', + 900 => '#01579B', + 'A100' => '#80D8FF', + 'A200' => '#40C4FF', + 'A400' => '#00B0FF', + 'A700' => '#0091EA', + ], + 'cyan' => [ + 50 => '#E0F7FA', + 100 => '#B2EBF2', + 200 => '#80DEEA', + 300 => '#4DD0E1', + 400 => '#26C6DA', + 500 => '#00BCD4', + 600 => '#00ACC1', + 700 => '#0097A7', + 800 => '#00838F', + 900 => '#006064', + 'A100' => '#84FFFF', + 'A200' => '#18FFFF', + 'A400' => '#00E5FF', + 'A700' => '#00B8D4', + ], + 'teal' => [ + 50 => '#E0F2F1', + 100 => '#B2DFDB', + 200 => '#80CBC4', + 300 => '#4DB6AC', + 400 => '#26A69A', + 500 => '#009688', + 600 => '#00897B', + 700 => '#00796B', + 800 => '#00695C', + 900 => '#004D40', + 'A100' => '#A7FFEB', + 'A200' => '#64FFDA', + 'A400' => '#1DE9B6', + 'A700' => '#00BFA5', + ], + 'green' => [ + 50 => '#E8F5E9', + 100 => '#C8E6C9', + 200 => '#A5D6A7', + 300 => '#81C784', + 400 => '#66BB6A', + 500 => '#4CAF50', + 600 => '#43A047', + 700 => '#388E3C', + 800 => '#2E7D32', + 900 => '#1B5E20', + 'A100' => '#B9F6CA', + 'A200' => '#69F0AE', + 'A400' => '#00E676', + 'A700' => '#00C853', + ], + 'lightGreen' => [ + 50 => '#F1F8E9', + 100 => '#DCEDC8', + 200 => '#C5E1A5', + 300 => '#AED581', + 400 => '#9CCC65', + 500 => '#8BC34A', + 600 => '#7CB342', + 700 => '#689F38', + 800 => '#558B2F', + 900 => '#33691E', + 'A100' => '#CCFF90', + 'A200' => '#B2FF59', + 'A400' => '#76FF03', + 'A700' => '#64DD17', + ], + 'lime' => [ + 50 => '#F9FBE7', + 100 => '#F0F4C3', + 200 => '#E6EE9C', + 300 => '#DCE775', + 400 => '#D4E157', + 500 => '#CDDC39', + 600 => '#C0CA33', + 700 => '#AFB42B', + 800 => '#9E9D24', + 900 => '#827717', + 'A100' => '#F4FF81', + 'A200' => '#EEFF41', + 'A400' => '#C6FF00', + 'A700' => '#AEEA00', + ], + 'yellow' => [ + 50 => '#FFFDE7', + 100 => '#FFF9C4', + 200 => '#FFF59D', + 300 => '#FFF176', + 400 => '#FFEE58', + 500 => '#FFEB3B', + 600 => '#FDD835', + 700 => '#FBC02D', + 800 => '#F9A825', + 900 => '#F57F17', + 'A100' => '#FFFF8D', + 'A200' => '#FFFF00', + 'A400' => '#FFEA00', + 'A700' => '#FFD600', + ], + 'amber' => [ + 50 => '#FFF8E1', + 100 => '#FFECB3', + 200 => '#FFE082', + 300 => '#FFD54F', + 400 => '#FFCA28', + 500 => '#FFC107', + 600 => '#FFB300', + 700 => '#FFA000', + 800 => '#FF8F00', + 900 => '#FF6F00', + 'A100' => '#FFE57F', + 'A200' => '#FFD740', + 'A400' => '#FFC400', + 'A700' => '#FFAB00', + ], + 'orange' => [ + 50 => '#FFF3E0', + 100 => '#FFE0B2', + 200 => '#FFCC80', + 300 => '#FFB74D', + 400 => '#FFA726', + 500 => '#FF9800', + 600 => '#FB8C00', + 700 => '#F57C00', + 800 => '#EF6C00', + 900 => '#E65100', + 'A100' => '#FFD180', + 'A200' => '#FFAB40', + 'A400' => '#FF9100', + 'A700' => '#FF6D00', + ], + 'deepOrange' => [ + 50 => '#FBE9E7', + 100 => '#FFCCBC', + 200 => '#FFAB91', + 300 => '#FF8A65', + 400 => '#FF7043', + 500 => '#FF5722', + 600 => '#F4511E', + 700 => '#E64A19', + 800 => '#D84315', + 900 => '#BF360C', + 'A100' => '#FF9E80', + 'A200' => '#FF6E40', + 'A400' => '#FF3D00', + 'A700' => '#DD2C00', + ], + 'brown' => [ + 50 => '#EFEBE9', + 100 => '#D7CCC8', + 200 => '#BCAAA4', + 300 => '#A1887F', + 400 => '#8D6E63', + 500 => '#795548', + 600 => '#6D4C41', + 700 => '#5D4037', + 800 => '#4E342E', + 900 => '#3E2723', + ], + 'gray' => [ + 50 => '#FAFAFA', + 100 => '#F5F5F5', + 200 => '#EEEEEE', + 300 => '#E0E0E0', + 400 => '#BDBDBD', + 500 => '#9E9E9E', + 600 => '#757575', + 700 => '#616161', + 800 => '#424242', + 900 => '#212121', + ], + 'blueGray' => [ + 50 => '#ECEFF1', + 100 => '#CFD8DC', + 200 => '#B0BEC5', + 300 => '#90A4AE', + 400 => '#78909C', + 500 => '#607D8B', + 600 => '#546E7A', + 700 => '#455A64', + 800 => '#37474F', + 900 => '#263238', + ], +]; diff --git a/src/Material/composer.json b/src/Material/composer.json new file mode 100644 index 0000000..120c13b --- /dev/null +++ b/src/Material/composer.json @@ -0,0 +1,37 @@ +{ + "name": "phpcolor/material-colors", + "description": "Material Design Colors - PHP Color Palette", + "license": "MIT", + "type": "library", + "keywords": [ + "material", + "material-design", + "color", + "palette", + "scale", + "google" + ], + "authors": [ + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Raphaël Geffroy", + "email": "raphael@geffroy.dev" + } + ], + "homepage": "https://phpcolor.dev/", + "require": { + "php": ">=8.3" + }, + "autoload": { + "psr-4": { "PhpColor\\Colors\\Material\\": "" } + }, + "extra": { + "thanks": { + "name": "phpcolor/colors", + "url": "https://github.com/phpcolor/colors" + } + } +} diff --git a/src/Nord/LICENSE b/src/Nord/LICENSE new file mode 100644 index 0000000..418d53d --- /dev/null +++ b/src/Nord/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-present Simon André & Raphaël Geffroy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/Nord/NordColors.php b/src/Nord/NordColors.php new file mode 100644 index 0000000..0532f6c --- /dev/null +++ b/src/Nord/NordColors.php @@ -0,0 +1,85 @@ + + */ +final class NordColors extends \stdClass implements \IteratorAggregate, \Countable +{ + public static function colors(): self + { + return new self(require __DIR__.'/Resources/colors.php'); + } + + /** + * @param array $colors + */ + private function __construct(private readonly array $colors) + { + } + + public function has(string $name): bool + { + return array_key_exists($name, $this->colors); + } + + public function get(string $name): string + { + if (!$this->has($name)) { + throw new \InvalidArgumentException(sprintf('The color "%s" does not exist.', $name)); + } + + return $this->colors[$name][0]; + } + + /** + * Get color by ID (e.g., 0 for nord0). + */ + public function id(int $id): string + { + return $this->get('nord'.$id); + } + + /** + * @return list + */ + public function getNames(): array + { + return array_keys($this->colors); + } + + /** + * @return \ArrayIterator + */ + public function getIterator(): \Iterator + { + return new \ArrayIterator(array_map(fn ($a) => $a[0], $this->colors)); + } + + public function count(): int + { + return count($this->colors); + } + + public function __get(string $name): string + { + return $this->get($name); + } + + public function __set(string $name, mixed $value): void + { + throw new \BadMethodCallException('NordColors are read-only.'); + } +} diff --git a/src/Nord/README.md b/src/Nord/README.md new file mode 100644 index 0000000..ae1d6a5 --- /dev/null +++ b/src/Nord/README.md @@ -0,0 +1,54 @@ +# Nord Colors + +This package provides access to the Nord color palette, an arctic, north-bluish color scheme. + +## Installation + +```bash +composer require phpcolor/nord-colors +``` + +## Usage + +### Create Colors Instance + +```php +use PhpColor\Colors\Nord\NordColors as Nord; + +$colors = Nord::colors(); +``` + +### Color Names + +```php +use PhpColor\Colors\Nord\NordColors as Nord; + +$colors = Nord::colors(); + +$names = $colors->getNames(); +// 'nord0', 'nord1', 'nord2', 'nord3', 'nord4', 'nord5', +// 'nord6', 'nord7', 'nord8', 'nord9', 'nord10', 'nord11', +// 'nord12', 'nord13', 'nord14', 'nord15' +``` + +### Color Values + +```php +use PhpColor\Colors\Nord\NordColors as Nord; + +$colors = Nord::colors(); + +echo $colors->nord10; // #5E81AC +echo $colors->get('nord8'); // #88C0D0 + +// Or use the id() method +echo $colors->id(10); // #5E81AC +``` + +## Credits + +The colors listed in this project are based on the [Nord Theme](https://www.nordtheme.com/). + +## License + +This [PHPColor](https://phpcolor.dev) package is released under the [MIT license](LICENSE). diff --git a/src/Nord/Resources/colors.php b/src/Nord/Resources/colors.php new file mode 100644 index 0000000..7944a33 --- /dev/null +++ b/src/Nord/Resources/colors.php @@ -0,0 +1,31 @@ + ['#2E3440', [46, 52, 64]], + 'nord1' => ['#3B4252', [59, 66, 82]], + 'nord2' => ['#434C5E', [67, 76, 94]], + 'nord3' => ['#4C566A', [76, 86, 106]], + 'nord4' => ['#D8DEE9', [216, 222, 233]], + 'nord5' => ['#E5E9F0', [229, 233, 240]], + 'nord6' => ['#ECEFF4', [236, 239, 244]], + 'nord7' => ['#8FBCBB', [143, 188, 187]], + 'nord8' => ['#88C0D0', [136, 192, 208]], + 'nord9' => ['#81A1C1', [129, 161, 193]], + 'nord10' => ['#5E81AC', [94, 129, 172]], + 'nord11' => ['#BF616A', [191, 97, 106]], + 'nord12' => ['#D08770', [208, 135, 112]], + 'nord13' => ['#EBCB8B', [235, 203, 139]], + 'nord14' => ['#A3BE8C', [163, 190, 140]], + 'nord15' => ['#B48EAD', [180, 142, 173]], +]; diff --git a/src/Nord/composer.json b/src/Nord/composer.json new file mode 100644 index 0000000..7ed6fcf --- /dev/null +++ b/src/Nord/composer.json @@ -0,0 +1,36 @@ +{ + "name": "phpcolor/nord-colors", + "description": "Nord Colors - PHP Color Palette", + "license": "MIT", + "type": "library", + "keywords": [ + "nord", + "color", + "palette", + "arctic", + "theme" + ], + "authors": [ + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Raphaël Geffroy", + "email": "raphael@geffroy.dev" + } + ], + "homepage": "https://phpcolor.dev/", + "require": { + "php": ">=8.3" + }, + "autoload": { + "psr-4": { "PhpColor\\Colors\\Nord\\": "" } + }, + "extra": { + "thanks": { + "name": "phpcolor/colors", + "url": "https://github.com/phpcolor/colors" + } + } +} diff --git a/src/OpenColor/LICENSE b/src/OpenColor/LICENSE new file mode 100644 index 0000000..418d53d --- /dev/null +++ b/src/OpenColor/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-present Simon André & Raphaël Geffroy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/OpenColor/OpenColorColors.php b/src/OpenColor/OpenColorColors.php new file mode 100644 index 0000000..5b43a55 --- /dev/null +++ b/src/OpenColor/OpenColorColors.php @@ -0,0 +1,129 @@ +> + */ +final class OpenColorColors extends \stdClass implements \IteratorAggregate, \Countable +{ + public static function colors(): self + { + return new self(require __DIR__.'/Resources/colors.php'); + } + + /** + * @param array|string> $colors + */ + private function __construct(private readonly array $colors) + { + } + + /** + * @return list + */ + public function getNames(): array + { + return array_keys($this->colors); + } + + /** + * @return list + */ + public function getShades(?string $color = null): array + { + $color ??= 'gray'; + + if (!isset($this->colors[$color]) || !is_array($this->colors[$color])) { + return []; + } + + return array_keys($this->colors[$color]); + } + + public function get(string $color, int $shade = 5): string + { + if (!isset($this->colors[$color])) { + throw new \InvalidArgumentException(sprintf('The color "%s" does not exist.', $color)); + } + + if (is_string($this->colors[$color])) { + return $this->colors[$color]; + } + + if (!isset($this->colors[$color][$shade])) { + throw new \InvalidArgumentException(sprintf('The shade "%d" does not exist for the color "%s".', $shade, $color)); + } + + return $this->colors[$color][$shade]; + } + + public function has(string $name): bool + { + return array_key_exists($name, $this->colors); + } + + public function count(): int + { + return count($this->colors, COUNT_RECURSIVE); + } + + /** + * @return \ArrayIterator|string> + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->colors); + } + + /** + * @param array $arguments + */ + public function __call(string $name, array $arguments): mixed + { + if (!$this->has($name)) { + throw new \BadMethodCallException(sprintf('The method "%s" does not exist.', $name)); + } + + if (isset($arguments[0]) && !\is_int($arguments[0])) { + 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); + } + + public function __get(string $name): string + { + return $this->get($name); + } + + public function __set(string $name, mixed $value): void + { + throw new \BadMethodCallException('OpenColorColors are read-only.'); + } +} diff --git a/src/OpenColor/Resources/colors.php b/src/OpenColor/Resources/colors.php new file mode 100644 index 0000000..b4bdb04 --- /dev/null +++ b/src/OpenColor/Resources/colors.php @@ -0,0 +1,173 @@ + '#FFFFFF', + 'black' => '#000000', + 'gray' => [ + 0 => '#F8F9FA', + 1 => '#F1F3F5', + 2 => '#E9ECEF', + 3 => '#DEE2E6', + 4 => '#CED4DA', + 5 => '#ADB5BD', + 6 => '#868E96', + 7 => '#495057', + 8 => '#343A40', + 9 => '#212529', + ], + 'red' => [ + 0 => '#FFF5F5', + 1 => '#FFE3E3', + 2 => '#FFC9C9', + 3 => '#FFA8A8', + 4 => '#FF8787', + 5 => '#FF6B6B', + 6 => '#FA5252', + 7 => '#F03E3E', + 8 => '#E03131', + 9 => '#C92A2A', + ], + 'pink' => [ + 0 => '#FFF0F6', + 1 => '#FFDEEB', + 2 => '#FCC2D7', + 3 => '#FAA2C1', + 4 => '#F783AC', + 5 => '#F06595', + 6 => '#E64980', + 7 => '#D6336C', + 8 => '#C2255C', + 9 => '#A61E4D', + ], + 'grape' => [ + 0 => '#F8F0FC', + 1 => '#F3D9FA', + 2 => '#EEBEFA', + 3 => '#E599F7', + 4 => '#DA77F2', + 5 => '#CC5DE8', + 6 => '#BE4BDB', + 7 => '#AE3EC9', + 8 => '#9C36B5', + 9 => '#862E9C', + ], + 'violet' => [ + 0 => '#F3F0FF', + 1 => '#E5DBFF', + 2 => '#D0BFFF', + 3 => '#B197FC', + 4 => '#9775FA', + 5 => '#845EF7', + 6 => '#7950F2', + 7 => '#7048E8', + 8 => '#6741D9', + 9 => '#5F3DC4', + ], + 'indigo' => [ + 0 => '#EDF2FF', + 1 => '#DBE4FF', + 2 => '#BAC8FF', + 3 => '#91A7FF', + 4 => '#748FFC', + 5 => '#5C7CFA', + 6 => '#4C6EF5', + 7 => '#4263EB', + 8 => '#3B5BDB', + 9 => '#364FC7', + ], + 'blue' => [ + 0 => '#E7F5FF', + 1 => '#D0EBFF', + 2 => '#A5D8FF', + 3 => '#74C0FC', + 4 => '#4DABF7', + 5 => '#339AF0', + 6 => '#228BE6', + 7 => '#1C7ED6', + 8 => '#1971C2', + 9 => '#1864AB', + ], + 'cyan' => [ + 0 => '#E3FAFC', + 1 => '#C5F6FA', + 2 => '#99E9F2', + 3 => '#66D9E8', + 4 => '#3BC9DB', + 5 => '#22B8CF', + 6 => '#15AABF', + 7 => '#1098AD', + 8 => '#0C8599', + 9 => '#0B7285', + ], + 'teal' => [ + 0 => '#E6FCF5', + 1 => '#C3FAE8', + 2 => '#96F2D7', + 3 => '#63E6BE', + 4 => '#38D9A9', + 5 => '#20C997', + 6 => '#12B886', + 7 => '#0CA678', + 8 => '#099268', + 9 => '#087F5B', + ], + 'green' => [ + 0 => '#EBFBEE', + 1 => '#D3F9D8', + 2 => '#B2F2BB', + 3 => '#8CE99A', + 4 => '#69DB7C', + 5 => '#51CF66', + 6 => '#40C057', + 7 => '#37B24D', + 8 => '#2F9E44', + 9 => '#2B8A3E', + ], + 'lime' => [ + 0 => '#F4FCE3', + 1 => '#E9FAC8', + 2 => '#D8F5A2', + 3 => '#C0EB75', + 4 => '#A9E34B', + 5 => '#94D82D', + 6 => '#82C91E', + 7 => '#74B816', + 8 => '#66A80F', + 9 => '#5C940D', + ], + 'yellow' => [ + 0 => '#FFF9DB', + 1 => '#FFF3BF', + 2 => '#FFEC99', + 3 => '#FFE066', + 4 => '#FFD43B', + 5 => '#FCC419', + 6 => '#FAB005', + 7 => '#F59F00', + 8 => '#F08C00', + 9 => '#E67700', + ], + 'orange' => [ + 0 => '#FFF4E6', + 1 => '#FFE8CC', + 2 => '#FFD8A8', + 3 => '#FFC078', + 4 => '#FFA94D', + 5 => '#FF922B', + 6 => '#FD7E14', + 7 => '#F76707', + 8 => '#E8590C', + 9 => '#D9480F', + ], +]; diff --git a/src/OpenColor/composer.json b/src/OpenColor/composer.json new file mode 100644 index 0000000..e4ea38e --- /dev/null +++ b/src/OpenColor/composer.json @@ -0,0 +1,36 @@ +{ + "name": "phpcolor/open-color", + "description": "Open Color - PHP Color Palette", + "license": "MIT", + "type": "library", + "keywords": [ + "open-color", + "color", + "palette", + "scale", + "ui" + ], + "authors": [ + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Raphaël Geffroy", + "email": "raphael@geffroy.dev" + } + ], + "homepage": "https://phpcolor.dev/", + "require": { + "php": ">=8.3" + }, + "autoload": { + "psr-4": { "PhpColor\\Colors\\OpenColor\\": "" } + }, + "extra": { + "thanks": { + "name": "phpcolor/colors", + "url": "https://github.com/phpcolor/colors" + } + } +} diff --git a/tests/Dracula/DraculaColorsTest.php b/tests/Dracula/DraculaColorsTest.php new file mode 100644 index 0000000..a335d05 --- /dev/null +++ b/tests/Dracula/DraculaColorsTest.php @@ -0,0 +1,80 @@ +getNames()); + } + + public function testIterator(): void + { + foreach (DraculaColors::colors() as $name => $color) { + $this->assertEquals('background', $name); + $this->assertEquals('#282A36', $color); + break; + } + } + + public function testGetter(): void + { + $colors = DraculaColors::colors(); + + self::assertTrue($colors->has('purple')); + self::assertStringStartsWith('#', $colors->get('purple')); + self::assertIsString($colors->purple); + self::assertStringStartsWith('#', $colors->purple); + } + + public function testGetUnknownColor(): void + { + $colors = DraculaColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('unknown'); + } + + public function testSetter(): void + { + $colors = DraculaColors::colors(); + self::expectException(\BadMethodCallException::class); + $colors->red = '#FF0000'; + } +} diff --git a/tests/Material/MaterialColorsTest.php b/tests/Material/MaterialColorsTest.php new file mode 100644 index 0000000..6a597bf --- /dev/null +++ b/tests/Material/MaterialColorsTest.php @@ -0,0 +1,143 @@ +getNames(); + + self::assertIsArray($colorNames); + self::assertCount(19, $colorNames); + self::assertContains('red', $colorNames); + self::assertContains('blue', $colorNames); + self::assertContains('deepPurple', $colorNames); + } + + public function testGetShades(): void + { + $colors = MaterialColors::colors(); + $shades = $colors->getShades('red'); + + self::assertIsArray($shades); + self::assertCount(14, $shades); + self::assertContains(50, $shades); + self::assertContains(500, $shades); + self::assertContains(900, $shades); + self::assertContains('A100', $shades); + self::assertContains('A700', $shades); + } + + public function testCountColors(): void + { + $colors = MaterialColors::colors(); + + self::assertCount(273, $colors); + } + + public function testHasColor(): void + { + $colors = MaterialColors::colors(); + + self::assertTrue($colors->has('red')); + self::assertTrue($colors->has('deepOrange')); + self::assertFalse($colors->has('unknown')); + } + + public function testGetColor(): void + { + $colors = MaterialColors::colors(); + + self::assertTrue($colors->has('red')); + self::assertStringStartsWith('#', $colors->get('red')); + + self::assertIsString($colors->red); + self::assertStringStartsWith('#', $colors->red); + } + + public function testGetColorWithNumericShade(): void + { + $colors = MaterialColors::colors(); + + self::assertEquals('#F44336', $colors->get('red', 500)); + self::assertEquals('#B71C1C', $colors->get('red', 900)); + self::assertEquals('#FFEBEE', $colors->get('red', 50)); + } + + public function testGetColorWithAccentShade(): void + { + $colors = MaterialColors::colors(); + + self::assertEquals('#FF8A80', $colors->get('red', 'A100')); + self::assertEquals('#D50000', $colors->get('red', 'A700')); + } + + public function testGetUnknownColor(): void + { + $colors = MaterialColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('unknown'); + } + + public function testGetUnknownShade(): void + { + $colors = MaterialColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('red', 1000); + } + + public function testIterator(): void + { + $colors = MaterialColors::colors(); + foreach ($colors as $name => $color) { + self::assertIsString($name); + self::assertIsArray($color); + break; + } + } + + public function testCallColor(): void + { + $colors = MaterialColors::colors(); + + self::assertSame($colors->get('red'), $colors->red); + self::assertSame($colors->get('red'), $colors->red()); + self::assertSame($colors->get('red', 300), $colors->red(300)); + self::assertSame($colors->get('red', 'A200'), $colors->red('A200')); + } + + public function testCallUnknownColor(): void + { + $colors = MaterialColors::colors(); + self::expectException(\BadMethodCallException::class); + /* + * @phpstan-ignore-next-line + */ + $colors->unknown(); + } + + public function testSetColor(): void + { + $colors = MaterialColors::colors(); + self::expectException(\BadMethodCallException::class); + $colors->red = '#FF0000'; + } +} diff --git a/tests/Nord/NordColorsTest.php b/tests/Nord/NordColorsTest.php new file mode 100644 index 0000000..0b10554 --- /dev/null +++ b/tests/Nord/NordColorsTest.php @@ -0,0 +1,93 @@ +getNames()); + } + + public function testIterator(): void + { + foreach (NordColors::colors() as $name => $color) { + $this->assertEquals('nord0', $name); + $this->assertEquals('#2E3440', $color); + break; + } + } + + public function testGetter(): void + { + $colors = NordColors::colors(); + + self::assertTrue($colors->has('nord10')); + self::assertStringStartsWith('#', $colors->get('nord10')); + self::assertIsString($colors->nord10); + self::assertStringStartsWith('#', $colors->nord10); + } + + public function testGetById(): void + { + $colors = NordColors::colors(); + + self::assertEquals('#2E3440', $colors->id(0)); + self::assertEquals('#B48EAD', $colors->id(15)); + } + + public function testGetUnknownColor(): void + { + $colors = NordColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('unknown'); + } + + public function testSetter(): void + { + $colors = NordColors::colors(); + self::expectException(\BadMethodCallException::class); + $colors->nord0 = '#FF0000'; + } +} diff --git a/tests/OpenColor/OpenColorColorsTest.php b/tests/OpenColor/OpenColorColorsTest.php new file mode 100644 index 0000000..97a9265 --- /dev/null +++ b/tests/OpenColor/OpenColorColorsTest.php @@ -0,0 +1,139 @@ +getNames(); + + self::assertIsArray($colorNames); + self::assertCount(15, $colorNames); + self::assertContains('white', $colorNames); + self::assertContains('black', $colorNames); + self::assertContains('gray', $colorNames); + self::assertContains('red', $colorNames); + } + + public function testGetShades(): void + { + $colors = OpenColorColors::colors(); + $shades = $colors->getShades('gray'); + + self::assertIsArray($shades); + self::assertCount(10, $shades); + self::assertContains(0, $shades); + self::assertContains(9, $shades); + } + + public function testCountColors(): void + { + $colors = OpenColorColors::colors(); + + self::assertCount(145, $colors); + } + + public function testHasColor(): void + { + $colors = OpenColorColors::colors(); + + self::assertTrue($colors->has('red')); + self::assertTrue($colors->has('white')); + self::assertFalse($colors->has('unknown')); + } + + public function testGetColor(): void + { + $colors = OpenColorColors::colors(); + + self::assertTrue($colors->has('red')); + self::assertStringStartsWith('#', $colors->get('red')); + + self::assertIsString($colors->red); + self::assertStringStartsWith('#', $colors->red); + } + + public function testGetColorWithShade(): void + { + $colors = OpenColorColors::colors(); + + self::assertEquals('#FF6B6B', $colors->get('red', 5)); + self::assertEquals('#C92A2A', $colors->get('red', 9)); + } + + public function testGetWhiteBlack(): void + { + $colors = OpenColorColors::colors(); + + self::assertEquals('#FFFFFF', $colors->get('white')); + self::assertEquals('#000000', $colors->get('black')); + } + + public function testGetUnknownColor(): void + { + $colors = OpenColorColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('unknown'); + } + + public function testGetUnknownShade(): void + { + $colors = OpenColorColors::colors(); + self::expectException(\InvalidArgumentException::class); + $colors->get('gray', 100); + } + + public function testIterator(): void + { + $colors = OpenColorColors::colors(); + foreach ($colors as $name => $color) { + self::assertIsString($name); + self::assertTrue(is_array($color) || is_string($color)); + break; + } + } + + public function testCallColor(): void + { + $colors = OpenColorColors::colors(); + + self::assertSame($colors->get('red'), $colors->red); + self::assertSame($colors->get('red'), $colors->red()); + self::assertSame($colors->get('red', 3), $colors->red(3)); + } + + public function testCallUnknownColor(): void + { + $colors = OpenColorColors::colors(); + self::expectException(\BadMethodCallException::class); + /* + * @phpstan-ignore-next-line + */ + $colors->unknown(); + } + + public function testSetColor(): void + { + $colors = OpenColorColors::colors(); + self::expectException(\BadMethodCallException::class); + $colors->red = '#FF0000'; + } +}