From 95cb563d471420fe7f0030c14f7d625e5accb6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9ia=20Bohner?= Date: Wed, 27 Mar 2024 15:27:35 -0300 Subject: [PATCH] Add options to list timezones by country or region --- README.md | 27 +++++++++++++- src/Concerns/HasTimezoneOptions.php | 57 ++++++++++++++++++++++++++++- src/Enums/Region.php | 25 +++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 src/Enums/Region.php diff --git a/README.md b/README.md index e7479b7..bca6a6f 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,32 @@ public static function form(Form $form): Form } ``` -All [Filament select field](https://filamentphp.com/docs/2.x/forms/fields#select) methods are available to use: +To list only the timezones for a country, you can pass the country code to `->byCountry()` method. For example, to list only United States timezones: + +```php +TimezoneSelect::make('timezone') + ->byCountry('US') +``` + +It's also possible to list the timezones for a region using `->byRegion()` method. You can specify a region with a [Region enum value](src/Enums/Region.php): + +```php +use Tapp\FilamentTimezoneField\Enums\Region; + +TimezoneSelect::make('timezone') + ->byRegion(Region::Australia) +``` + +or you can use one of the [PHP's DateTimeZone predifined constants](https://www.php.net/manual/en/class.datetimezone.php): + +```php +use DateTimeZone; + +TimezoneSelect::make('timezone') + ->byRegion(DateTimeZone::AUSTRALIA) +``` + +Also all [Filament select field](https://filamentphp.com/docs/2.x/forms/fields#select) methods are available to use: ```php use Tapp\FilamentTimezoneField\Forms\Components\TimezoneSelect; diff --git a/src/Concerns/HasTimezoneOptions.php b/src/Concerns/HasTimezoneOptions.php index c11bdc7..43707e6 100644 --- a/src/Concerns/HasTimezoneOptions.php +++ b/src/Concerns/HasTimezoneOptions.php @@ -4,9 +4,14 @@ use DateTime; use DateTimeZone; +use Tapp\FilamentTimezoneField\Enums\Region; trait HasTimezoneOptions -{ +{ + protected string | Closure | null $byCountry = null; + + protected Region | int | Closure | null $byRegion = null; + public function getOptions(): array { $options = $this->getTimezones(); @@ -18,7 +23,11 @@ public function getOptions(): array public function getTimezones(): array { - $timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL); + $timezones = match(true) { + !empty($this->byCountry) => $this->listTimezonesByCountry($this->byCountry), + !empty($this->byRegion) => $this->listTimezonesByRegion($this->byRegion), + default => $this->listAllTimezones(), + }; $data = []; @@ -40,4 +49,48 @@ public function getTimezones(): array return $data; } + + public function byCountry(string | Closure | null $countryCode): static + { + $this->byCountry = $countryCode; + + return $this; + } + + public function getByCountry(): string | null + { + return $this->evaluate($this->byCountry); + } + + public function byRegion(Region | int | Closure | null $region): static + { + $this->byRegion = $region; + + return $this; + } + + public function getByRegion(): Region | int | null + { + return $this->evaluate($this->byRegion); + } + + protected function listTimezonesByCountry($countryCode) + { + return DateTimeZone::listIdentifiers( + timezoneGroup: DateTimeZone::PER_COUNTRY, + countryCode: $countryCode, + ); + } + + protected function listTimezonesByRegion($region) + { + return DateTimeZone::listIdentifiers( + timezoneGroup: $region?->value ?? $region, + ); + } + + protected function listAllTimezones() + { + return DateTimeZone::listIdentifiers(DateTimeZone::ALL); + } } diff --git a/src/Enums/Region.php b/src/Enums/Region.php new file mode 100644 index 0000000..b30be3d --- /dev/null +++ b/src/Enums/Region.php @@ -0,0 +1,25 @@ +name; + } +}