diff --git a/README.md b/README.md
index 00c439c..5243f99 100644
--- a/README.md
+++ b/README.md
@@ -94,26 +94,6 @@ public function setUp(): void
> The `setUp` method is called on `mount` of the widget. See [livewire lifecycle hooks](https://laravel-livewire.com/docs/2.x/lifecycle-hooks) for more information.
-### Global Configuration
-
-If you want to set a default configuration for all instances of the map widget, you can use the `configureUsing` method in a service provider:
-
-```php
-MyMap::configureUsing(function (ResellerMap $widget) {
- $widget->mapMarkers([
- Marker::make('id')
- ->lat(51.505)
- ->lng(-0.09)
- ->popup('I am a popup')
- ->tooltip('I am a tooltip'),
- ])
- ->tileLayerUrl('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')
- ->tileLayerOptions([
- 'attribution' => 'Map data © OpenStreetMap contributors',
- ])
-});
-```
-
## Tile Layers
The map uses OpenStreetMap tiles by default, but you can change it to use any other provider using `$tileLayerUrl` property or `tileLayerUrl` method. It's recommended to also use the `tileLayerOptions` to set correct attributions.
@@ -566,24 +546,6 @@ $livewire->addCircle(Circle::make('circle-name')->lat(...)->lng(...)->options([.
$livewire->removeCircle('circle-name');
$livewire->updateCircle(Circle::make('circle-name')->lat(...)->lng(...)->options([...]));
```
-
-### Update Map / Polling
-
-set pollingInterval to anything you like inside your widget:
-```php
- protected static ?string $pollingInterval = '10s';
-```
-
-then inside your widget declare public function named updateMap, and add any logic you wish inside it
-
-```php
- public function updateMap(): void
- {
- // for example this clears markers, you can add markers, polygon ..etc
- $this->mapMarkers([]);
- }
-```
-
## Images

diff --git a/composer.json b/composer.json
index 534a45e..7455a38 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
],
"require": {
"php": "^8.0",
- "filament/filament": "^3.0.0",
+ "filament/filament": "^4.0 || ^5.0",
"spatie/laravel-package-tools": "^1.16"
},
"autoload": {
diff --git a/resources/views/button-action.blade.php b/resources/views/button-action.blade.php
index 65af881..d6a88d4 100644
--- a/resources/views/button-action.blade.php
+++ b/resources/views/button-action.blade.php
@@ -2,5 +2,4 @@
:action="$action"
:label="$getLabel()"
component="filament-maps::icon-button"
- class="filament-page-icon-button-action"
/>
diff --git a/resources/views/components/actions/action.blade.php b/resources/views/components/actions/action.blade.php
index 978eae1..c7f9dce 100644
--- a/resources/views/components/actions/action.blade.php
+++ b/resources/views/components/actions/action.blade.php
@@ -4,25 +4,34 @@
'icon' => null,
])
+@php
+ $isDisabled = $action->isDisabled();
+ $url = $action->getUrl();
+@endphp
+
{{ $slot }}
diff --git a/resources/views/components/actions/index.blade.php b/resources/views/components/actions/index.blade.php
index 5713eeb..f5a0ad7 100644
--- a/resources/views/components/actions/index.blade.php
+++ b/resources/views/components/actions/index.blade.php
@@ -1,35 +1,3 @@
-@props([
- 'actions',
- 'alignment' => 'left',
- 'fullWidth' => false,
-])
-
-@if ($actions instanceof \Illuminate\Contracts\View\View)
- {{ $actions }}
-@elseif (is_array($actions))
- @php
- $actions = array_filter(
- $actions,
- fn (\Filament\Pages\Actions\Action | \Filament\Pages\Actions\ActionGroup $action): bool => ! $action->isHidden(),
- );
- @endphp
-
- @if (count($actions))
-
class([
- 'filament-page-actions',
- 'flex flex-wrap items-center gap-4' => ! $fullWidth,
- match ($alignment) {
- 'center' => 'justify-center',
- 'right' => 'flex-row-reverse space-x-reverse',
- default => 'justify-start',
- } => ! $fullWidth,
- 'grid gap-2 grid-cols-[repeat(auto-fit,minmax(0,1fr))]' => $fullWidth,
- ]) }}
- >
- @foreach ($actions as $action)
- {{ $action }}
- @endforeach
-
- @endif
-@endif
+
diff --git a/resources/views/components/card/heading.blade.php b/resources/views/components/card/heading.blade.php
new file mode 100644
index 0000000..3f81bc8
--- /dev/null
+++ b/resources/views/components/card/heading.blade.php
@@ -0,0 +1,5 @@
+class(['fi-maps-card-header-heading text-base font-semibold leading-6 text-gray-950 dark:text-white']) }}
+>
+ {{ $slot }}
+
diff --git a/resources/views/components/card/index.blade.php b/resources/views/components/card/index.blade.php
new file mode 100644
index 0000000..aa796ca
--- /dev/null
+++ b/resources/views/components/card/index.blade.php
@@ -0,0 +1,60 @@
+@props([
+ 'hasBorder' => true,
+ 'heading' => null,
+ 'footer' => null,
+])
+
+@php
+ $hasHeading = filled($heading);
+ $hasHeader = $hasHeading;
+
+ $hasFooter = filled($footer);
+@endphp
+
+
+ @if ($hasHeader)
+
+ @endif
+
+ 'p-6',
+ false => '',
+ },
+ ])
+ >
+ {{ $slot }}
+
+
+ @if ($hasFooter)
+
+ @endif
+
diff --git a/resources/views/components/icon-button.blade.php b/resources/views/components/icon-button.blade.php
index aea0ee8..399caa6 100644
--- a/resources/views/components/icon-button.blade.php
+++ b/resources/views/components/icon-button.blade.php
@@ -1,79 +1,138 @@
+@php
+ use Filament\Support\Enums\ActionSize;
+ use Filament\Support\Enums\IconSize;
+@endphp
+
@props([
+ 'badge' => null,
+ 'badgeColor' => 'primary',
+ 'badgeSize' => 'xs',
'color' => 'primary',
- 'darkMode' => config('filament.dark_mode'),
'disabled' => false,
'form' => null,
- 'iconAlias' => null,
+ 'formId' => null,
+ 'href' => null,
'icon' => null,
+ 'iconAlias' => null,
+ 'iconSize' => null,
'keyBindings' => null,
- 'indicator' => null,
'label' => null,
- 'size' => 'md',
+ 'loadingIndicator' => true,
+ 'size' => ActionSize::Medium,
+ 'spaMode' => null,
'tag' => 'button',
+ 'target' => null,
'tooltip' => null,
'type' => 'button',
])
@php
- $buttonClasses = array_merge([
- "filament-button filament-button-size-{$size} inline-flex items-center justify-center py-1 gap-1 font-medium rounded-lg border transition-colors focus:outline-none focus:ring-offset-2 focus:ring-2 focus:ring-inset",
- 'dark:focus:ring-offset-0' => $darkMode,
- 'opacity-70 cursor-not-allowed pointer-events-none' => $disabled,
- 'min-h-[2.25rem] px-2 text-sm' => $size === 'md',
- 'min-h-[2rem] px-1 text-sm' => $size === 'sm',
- 'min-h-[2.75rem] px-4 text-lg' => $size === 'lg',
- ], [
- 'text-white shadow focus:ring-white border-transparent' => $color !== 'secondary',
- 'bg-primary-600 hover:bg-primary-500 focus:bg-primary-700 focus:ring-offset-primary-700' => $color === 'primary',
- 'bg-success-600 hover:bg-success-500 focus:bg-success-700 focus:ring-offset-success-700' => $color === 'success',
- 'bg-danger-600 hover:bg-danger-500 focus:bg-danger-700 focus:ring-offset-danger-700' => $color === 'danger',
- 'bg-warning-600 hover:bg-warning-500 focus:bg-warning-700 focus:ring-offset-warning-700' => $color === 'warning',
- 'bg-gray-600 hover:bg-gray-500 focus:bg-gray-700 focus:ring-offset-gray-700' => $color === 'gray',
- 'text-gray-800 bg-white border-gray-300 hover:bg-gray-50 focus:ring-primary-600 focus:text-primary-600 focus:bg-primary-50 focus:border-primary-600' => $color === 'secondary',
- 'dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-500 dark:text-gray-200 dark:focus:text-primary-400 dark:focus:border-primary-400 dark:focus:bg-gray-800' => $color === 'secondary' && $darkMode,
+ if (! $size instanceof ActionSize) {
+ $size = filled($size) ? (ActionSize::tryFrom($size) ?? $size) : null;
+ }
+
+ $iconSize ??= match ($size) {
+ ActionSize::ExtraSmall => IconSize::Small,
+ ActionSize::Small, ActionSize::Medium => IconSize::Medium,
+ ActionSize::Large, ActionSize::ExtraLarge => IconSize::Large,
+ default => IconSize::Medium,
+ };
+
+ if (! $iconSize instanceof IconSize) {
+ $iconSize = filled($iconSize) ? (IconSize::tryFrom($iconSize) ?? $iconSize) : null;
+ }
+
+ $buttonClasses = \Illuminate\Support\Arr::toCssClasses([
+ ...[
+ 'fi-icon-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2 shadow-sm rounded-lg',
+ 'pointer-events-none opacity-70' => $disabled,
+ 'cursor-pointer' => $tag === 'label',
+ match ($color) {
+ 'gray' => null,
+ default => 'fi-color-custom',
+ },
+ is_string($color) ? "fi-color-{$color}" : null,
+ ($size instanceof ActionSize) ? "fi-size-{$size->value}" : null,
+ match ($size) {
+ ActionSize::ExtraSmall => 'gap-1 px-2 py-1.5 text-xs',
+ ActionSize::Small => 'gap-1 px-2.5 py-1.5 text-sm',
+ ActionSize::Medium => 'gap-1.5 px-3 py-2 text-sm',
+ ActionSize::Large => 'gap-1.5 px-3.5 py-2.5 text-sm',
+ ActionSize::ExtraLarge => 'gap-1.5 px-4 py-3 text-sm',
+ default => $size,
+ },
+ 'bg-white text-gray-950 hover:bg-gray-50 dark:bg-white/5 dark:text-white dark:hover:bg-white/10' => ($color === 'gray') || ($tag === 'label'),
+ 'ring-1 ring-gray-950/10 dark:ring-white/20' => (($color === 'gray') || ($tag === 'label')),
+ 'bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50' => ($color !== 'gray') && ($tag !== 'label'),
+ '[input:checked+&]:bg-custom-600 [input:checked+&]:text-white [input:checked+&]:ring-0 [input:checked+&]:hover:bg-custom-500 dark:[input:checked+&]:bg-custom-500 dark:[input:checked+&]:hover:bg-custom-400 [input:checked:focus-visible+&]:ring-custom-500/50 dark:[input:checked:focus-visible+&]:ring-custom-400/50 [input:focus-visible+&]:z-10 [input:focus-visible+&]:ring-2 [input:focus-visible+&]:ring-gray-950/10 dark:[input:focus-visible+&]:ring-white/20' => ($color !== 'gray') && ($tag === 'label'),
+ '[input:checked+&]:bg-gray-400 [input:checked+&]:text-white [input:checked+&]:ring-0 [input:checked+&]:hover:bg-gray-300 dark:[input:checked+&]:bg-gray-600 dark:[input:checked+&]:hover:bg-gray-500' => ($color === 'gray'),
+ ],
]);
- $iconClasses = \Illuminate\Support\Arr::toCssClasses([
- 'filament-icon-button-icon',
- 'w-5 h-5' => $size === 'md',
- 'w-4 h-4' => $size === 'sm',
- 'w-4 h-4 md:w-5 md:h-5' => $size === 'sm md:md',
- 'w-6 h-6' => $size === 'lg',
+ $buttonStyles = \Illuminate\Support\Arr::toCssStyles([
+ \Filament\Support\get_color_css_variables(
+ $color,
+ shades: [400, 500, 600],
+ alias: 'button',
+ ) => $color !== 'gray',
]);
- $indicatorClasses = \Illuminate\Support\Arr::toCssClasses([
- 'filament-icon-button-indicator absolute rounded-full text-xs inline-block w-4 h-4 -top-0.5 -right-0.5',
- 'bg-primary-500/10' => $color === 'primary',
- 'bg-danger-500/10' => $color === 'danger',
- 'bg-gray-500/10' => $color === 'secondary',
- 'bg-success-500/10' => $color === 'success',
- 'bg-warning-500/10' => $color === 'warning',
+ $iconClasses = \Illuminate\Support\Arr::toCssClasses([
+ 'fi-icon-btn-icon transition duration-75',
+ match ($iconSize) {
+ IconSize::Small => 'h-4 w-4',
+ IconSize::Medium => 'h-5 w-5',
+ IconSize::Large => 'h-6 w-6',
+ default => $iconSize,
+ },
+ 'text-gray-400 dark:text-gray-500' => ($color === 'gray') || ($tag === 'label'),
+ 'text-white' => ($color !== 'gray') && ($tag !== 'label'),
+ '[:checked+*>&]:text-white' => $tag === 'label',
]);
- $hasLoadingIndicator = filled($attributes->get('wire:target')) || filled($attributes->get('wire:click')) || (($type === 'submit') && filled($form));
+ $badgeContainerClasses = 'fi-icon-btn-badge-ctn absolute start-full top-1 z-[1] w-max -translate-x-1/2 -translate-y-1/2 rounded-md bg-white dark:bg-gray-900 rtl:translate-x-1/2';
+
+ $wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
+
+ $hasLoadingIndicator = filled($wireTarget) || ($type === 'submit' && filled($form));
if ($hasLoadingIndicator) {
- $loadingIndicatorTarget = html_entity_decode($attributes->get('wire:target', $attributes->get('wire:click', $form)), ENT_QUOTES);
+ $loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
}
+
+ $hasTooltip = filled($tooltip);
@endphp
@if ($tag === 'button')
@elseif ($tag === 'a')
map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}
- @endif
- @if ($label)
- title="{{ $label }}"
+ {{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
+ @if ($keyBindings || $hasTooltip)
+ x-data="{}"
@endif
- @if ($tooltip)
- x-tooltip.raw="{{ $tooltip }}"
+ @if ($keyBindings)
+ x-bind:id="$id('key-bindings')"
+ x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
@endif
- @if ($keyBindings || $tooltip)
- x-data="{}"
+ @if ($hasTooltip)
+ x-tooltip="{
+ content: @js($tooltip),
+ theme: $store.theme,
+ }"
@endif
- {{ $attributes->class($buttonClasses) }}
+ {{
+ $attributes
+ ->merge([
+ 'title' => $hasTooltip ? null : $label,
+ ], escape: true)
+ ->class([$buttonClasses])
+ ->style([$buttonStyles])
+ }}
>
@if ($label)
@@ -137,10 +211,12 @@
:class="$iconClasses"
/>
- @if ($indicator)
-
- {{ $indicator }}
-
+ @if (filled($badge))
+
+
+ {{ $badge }}
+
+
@endif
@endif
diff --git a/resources/views/components/map.blade.php b/resources/views/components/map.blade.php
index 8542bcf..849eb55 100644
--- a/resources/views/components/map.blade.php
+++ b/resources/views/components/map.blade.php
@@ -12,6 +12,7 @@
'modals' => null,
'rounded' => true,
'fullpage' => false,
+ 'pollingInterval' => null,
])
@php
@@ -20,7 +21,15 @@
fn (\Webbingbrasil\FilamentMaps\Actions\Action $action ): bool => ! $action->isHidden(),
);
@endphp
-
+
class([
'h-full w-full overflow-hidden',
@@ -28,6 +37,7 @@
]) }}
{{ $extraAttributeBag }}>
-
+
+
-
+
diff --git a/resources/views/widgets/map.blade.php b/resources/views/widgets/map.blade.php
index e71d3ed..7cafa91 100644
--- a/resources/views/widgets/map.blade.php
+++ b/resources/views/widgets/map.blade.php
@@ -1,47 +1,20 @@
-@php
- $heading = $this->getHeading();
- $footer = $this->getFooter();
- $hasBorder = $this->getHasBorder();
- $rounded = $this->getRounded();
-@endphp
-
-
- @if ($heading)
- $hasBorder,
- 'px-6 py-4' => !$hasBorder,
- ])>
-
- {{ $heading }}
-
-
- @endif
-
- $hasBorder])
- @if ($pollingInterval = $this->getPollingInterval())
- wire:poll.{{ $pollingInterval }}.visible="updateMap"
- @endif
- >
-
-
-
- @if ($footer)
- $hasBorder,
- 'px-6 py-4' => !$hasBorder,
- ])>
- {{ $footer }}
-
- @endif
-
+
+
+
+
-
diff --git a/resources/views/zoom-action.blade.php b/resources/views/zoom-action.blade.php
index 250458c..4a2426e 100644
--- a/resources/views/zoom-action.blade.php
+++ b/resources/views/zoom-action.blade.php
@@ -1,19 +1,17 @@
@php
- $zoomIn = $action;
- $zoomOut = (clone $action)->icon('heroicon-o-minus');
+ $zoomIn = $action;
+ $zoomOut = (clone $action)->icon('heroicon-o-minus');
@endphp
diff --git a/src/Widgets/MapWidget.php b/src/Widgets/MapWidget.php
index 58b130a..ebcb806 100644
--- a/src/Widgets/MapWidget.php
+++ b/src/Widgets/MapWidget.php
@@ -30,14 +30,13 @@ abstract class MapWidget extends Widget implements HasForms, HasActions
use Concerns\HasPolygones;
use Concerns\HasRectangles;
use Concerns\HasCircles;
+ use CanPoll;
use Configurable {
configure as protected configureWidget;
}
- protected static string $view = 'filament-maps::widgets.map';
-
- protected static ?string $pollingInterval = null;
+ protected string $view = 'filament-maps::widgets.map';
protected string $height = '400px';
@@ -60,23 +59,16 @@ public function mount()
public function configure(): static
{
- return $this
+ $this
->configureMarkers()
->configurePolylines()
->configurePolygones()
->configureRectangles()
->configureCircles();
-// ->configureWidget();
- }
- protected function getPollingInterval(): ?string
- {
- return static::$pollingInterval;
- }
+ $this->setUp();
- public function updateMap(): void
- {
- // Add Code you want to update map with.
+ return $this;
}
public function height(string $height): self
@@ -136,7 +128,7 @@ public function rounded(bool $rounded = true): self
public function getRounded(): bool
{
- return $this->rounded;
+ return $this->rounded && $this->getHasBorder();
}
public function isFullPage(): bool