robsontenorio / mary

Laravel Blade UI Components for Livewire 3
https://mary-ui.com
Other
943 stars 112 forks source link

The Tabs goes duplicated when runs /update from livewire #565

Closed cooffeeRequired closed 3 weeks ago

cooffeeRequired commented 1 month ago

maryUI version

1.34.2

daisyUI version

4.12.10

Livewire version

3.5.4

What browsers are affected?

Firefox, Chrome, Safari, Microsoft Edge

What happened?

image

<x-tabs wire:model="selectedTab" selected="_waiting">
   <x-tab name="_waiting">
     some table with actions
   </x-tab>
   <x-tab name="_success">
     some table with actions
   </x-tab>
</x-tabs>

for e.g. delete button

    #[FnController] public function delete(?int $id, bool $modalen = false): void
    {
        if ($modalen) {
            $this->clearFields();
            $this->modal["#deletion"] = true;
            $this->inUse = self::$model::find($id)->first()->toArray();
            return;
        }

        $service = app(OrdersService::class);
        $response = $service->delete($this->inUse);
        if ($response->isSuccess()) {
            $this->success("Objednávka s id {$this->inUse['id']} byla úspěšně smazána!");
        } else {
            $this->error('Opps', "Nastala chyba při mazaní objednávky s id {$this->inUse['id']}, $response->message");
        }
        $this->handleClose('#deletion');
    }
cooffeeRequired commented 1 month ago

The problem are when use wanna use x-badge for that

for e.g.

@slot('label')
   Dokončeno
   <x-badge :value="$this->countOfItems($query_finished)" class="badge-success badge-sm" />
@endslot

so when the value goes updated, the tabs goes duplicate

cooffeeRequired commented 1 month ago

image

        return <<<'HTML'
                    <a
                        class="hidden"
                        :class="{ 'tab-active': selected === '{{ $name }}' }"
                        data-name="{{ $name }}"
                        x-init="
                                tabs.push({ name: '{{ $name }}', label: {{ json_encode($tabLabel($label)) }} });
                                Livewire.hook('morph.removed', ({el}) => {
                                    console.log(el, el.getAttribute('data-name'), '{{ $name }}')
                                    if (el.getAttribute('data-name') == '{{ $name }}'){
                                        tabs = tabs.filter(i => i.name !== '{{ $name }}')
                                    }
                                })
                            "
                    ></a>

                    <div x-show="selected === '{{ $name }}'" role="tabpanel" {{ $attributes->class("tab-content py-5 px-1") }}>
                        {{ $slot }}
                    </div>
ANJANS commented 1 month ago

I'm having the exact same problem. This happens as x-dab changes label.

cooffeeRequired commented 1 month ago

i did my own "component" for temp resolve

<?php

namespace App\View\Components;

use Blade;
use Exception;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class TabsCompute extends Component
{
    /**
     * @throws Exception
     */
    public function __construct(
        public ?string $selectedTab = null
    ) {
        if (is_null($this->selectedTab)) {
            throw new Exception('The key $selectedTab is null, need to be define!');
        }
    }

    public function render(): View|Htmlable|\Closure|string
    {
        return <<<'blade'
            @php
                $sections = preg_split('/(<div\s+name="[^"]*">.*?<\/div>)/s', $slot, -1, PREG_SPLIT_DELIM_CAPTURE);
            @endphp
            <div class="flex flex-row gap-6 items-center px-4 font-semibold">
                @foreach ($sections as $section)
                    @if (preg_match('/<div\s+name="([^"]*)">.*<\/div>/s', $section, $matches))
                        @php
                            $name = $matches[1];
                            $content = trim($section);
                        @endphp
                        <div
                            tab-computed
                            class="flex flex-row gap-2 items-center hover:cursor-pointer focus:cursor-pointer p-2 border-b-2 dark:border-b-gray-200/50 border-b-gray-600/50"
                            name="{{ $name }}"
                            x-data="{
                                select(name) {
                                    const elements = document.querySelectorAll('div[tab-computed]');
                                    elements.forEach(el => {
                                        if (el.getAttribute('name') === name) {
                                            el.classList.add('border-b-primary', 'dark:border-b-primary');
                                            el.classList.remove('border-b-gray-600/50', 'dark:border-b-gray-200/50');
                                        } else {
                                            el.classList.add('border-b-gray-600/50', 'dark:border-b-gray-200/50');
                                            el.classList.remove('border-b-primary', 'dark:border-b-primary');
                                        }
                                    });
                                    $wire.selectedTab = name;
                                }
                            }"
                            x-init="select('{{ $selectedTab }}');"
                            @click="select('{{ $name }}')"
                        >
                            {!! $content . '</div>' !!}
                        </div>
                    @endif
                @endforeach
            </div>
        blade;

    }
}
      <x-tabs-compute :selected-tab="$selectedTab">
          <div name="_waiting">
              Čekající
              <x-badge :value="$query->count('id')" class="badge-warning badge-sm" />
          </div>
          <div name="_finished">
              Dokončeno
              <x-badge :value="$query_finished->count('id')" class="badge-success badge-sm" />
          </div>
          <div name="_canceled">
              Zrušeno
              <x-badge :value="$query_canceled->count('id')" class="badge-error badge-sm" />
          </div>
      </x-tabs-compute>
robsontenorio commented 3 weeks ago

Could you try the main branch? There is a fix merged.

composer require robsontenorio/mary:dev-main
php artisan view:clear
cooffeeRequired commented 1 week ago

Okey ill try