Невозможно заменить модальное окно TailwindCSS по умолчанию в Jetstream на модальное окно Bootstrap и по-прежнему достичь ожидаемого или такого же результата, как и при использовании TailwindCSS

Я работаю над пакетом Laravel 8, который меняет стек #TALL на то, что я называю стеком #BALL, и это в основном стек Bootstrap, AlpineJs Laravel, Livewire. Bootstrap 5 склоняется к служебным классам и больше не использует JQuery, который дает место для AlpineJ, поэтому я действительно не вижу много плюсов с Tailwind, не говоря уже о том, что я действительно освоился с Bootstrap, который должен быть всем, что имеет значение в конце правильно?

Теперь проблема в том, что я смог внести изменения во многие файлы блейдов ettream, и если вы установили Jetstream, то вы знакомы с этим изображением:

введите описание изображения здесь

(Да !!!! Это то же самое, но с Bootstrap!)

но один конкретный компонент не давал мне покоя в течение нескольких дней, и это Bootstrap Modal.

  1. Всякий раз, когда я вызываю модальные запросы Livewire Bootstrap, кажется, что сам модальный файл исчезает, оставляя только фон, заставляя запрос страницы до того, как можно будет щелкнуть что-либо еще.

  2. Последний запрос никогда не выполняется

  3. У меня нет возможности удерживать модальное окно до тех пор, пока не будет загружен запрос подтверждения, а затем программно отключить модальное окно по завершении.

Точное место, где у меня есть эта проблема, - это views/api/api-token-manager.blade, который добавляется Jetstream при установке стека livewire. Мои файлы выглядят так:

Мои представления / api / api-token-manager.blade

<!-- API Token List -->
// Inside a x-jet-action-section component
<x-slot name="content">
    <div class="space-y-6">
    @foreach ($this->user->tokens->sortBy('name') as $token)
        <div class="d-flex justify-content-between">
            <div>
                {{ $token->name }}
            </div>

            <div class="d-flex">
            @if ($token->last_used_at)
                <div class="text-sm text-muted">
                    Last used {{ $token->last_used_at->diffForHumans() }}
                </div>
            @endif

            @if (Laravel\Jetstream\Jetstream::hasPermissions())
                <button class="btn btn-link text-secondary" data-toggle="modal"
                                                wire:click="manageApiTokenPermissions({{ $token->id }})"
                                                data-target="#managingApiTokenPermissions-{{ $token->id }}">
                   Permissions
               </button>
            @endif

            <button class="btn btn-link text-danger text-decoration-none"
                                            data-toggle="modal"
                                            data-target="#confirmApiTokenDeletion-{{ $token->id }}">
                Delete
            </button>
            </div>
        </div>

                            <!-- API Token Permissions Modal -->
                            <x-jet-dialog-modal id="managingApiTokenPermissions-{{ $token->id }}">
                                <x-slot name="title">
                                    API Token Permissions
                                </x-slot>

                                <x-slot name="content">
                                    <div class="mt-2 row">
                                        @foreach (Laravel\Jetstream\Jetstream::$permissions as $permission)
                                            <div class="col-6">
                                                <div class="form-check">
                                                    <input class="form-check-input" type="checkbox" value="{{ $permission }}" wire:model.defer="updateApiTokenForm.permissions">
                                                    <label class="form-check-label">
                                                        {{ $permission }}
                                                    </label>
                                                </div>
                                            </div>
                                        @endforeach
                                    </div>
                                </x-slot>

                                <x-slot name="footer">
                                    <x-jet-secondary-button data-dismiss="modal">
                                        {{ __('Nevermind') }}
                                    </x-jet-secondary-button>

                                    <x-jet-button class="ml-2" wire:click="updateApiToken"
                                                  wire:click="$emit('updateApiToken', {{ $token->id }})"
                                                  data-dismiss="modal">
                                        {{ __('Save') }}
                                    </x-jet-button>
                                </x-slot>
                            </x-jet-dialog-modal>
                            @push('scripts')
                                <script>
                                    Livewire.on('updateApiToken', id => {
                                        @this.manageApiTokenPermissions(id)
                                        @this.updateApiToken()
                                    })
                                </script>
                            @endpush

                            <!-- Delete Token Confirmation Modal -->
                            <x-jet-confirmation-modal id="confirmApiTokenDeletion-{{ $token->id }}">
                                <x-slot name="title">
                                    Delete API Token
                                </x-slot>

                                <x-slot name="content">
                                    Are you sure you would like to delete this API token?
                                </x-slot>

                                <x-slot name="footer">
                                    <x-jet-secondary-button data-dismiss="modal">
                                        Nevermind
                                    </x-jet-secondary-button>

                                    <x-jet-danger-button class="ml-2"
                                                         wire:click="$emit('deleteApiToken', {{ $token->id }})"
                                                         data-dismiss="modal">
                                        Delete
                                    </x-jet-danger-button>
                                </x-slot>
                            </x-jet-confirmation-modal>
                            @push('scripts')
                                <script>
                                    Livewire.on('deleteApiToken', id => {
                                        @this.confirmApiTokenDeletion(id)
                                        @this.deleteApiToken()
                                    })
                                </script>
                            @endpush
                        @endforeach
                    </div>
                </x-slot>

Мой x-jet-dialog-modal компонент

@props(['id' => null, 'maxWidth' => null])

<x-jet-modal :id="$id" :maxWidth="$maxWidth" {{ $attributes }}>
    <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title">{{ $title }}</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
            {{ $content }}
        </div>
        <div class="modal-footer">
            {{ $footer }}
        </div>
    </div>
</x-jet-modal>

Мой x-jet-modal компонент

@props(['id', 'maxWidth', 'modal' => false])

@php
$id = $id ?? md5($attributes->wire('model'));

switch ($maxWidth ?? '') {
    case 'sm':
        $maxWidth = ' modal-sm';
        break;
    case 'md':
        $maxWidth = '';
        break;
    case 'lg':
        $maxWidth = ' modal-lg';
        break;
    case 'xl':
        $maxWidth = ' modal-xl';
        break;
    case '2xl':
    default:
        $maxWidth = '';
        break;
}
@endphp

<!-- Modal -->
<div class="modal fade" tabindex="-1" id="{{ $id }}" aria-labelledby="{{ $id }}" aria-hidden="true">
    <div class="modal-dialog{{ $maxWidth }}">
        {{ $slot }}
    </div>
</div>

Я действительно не хочу вносить изменения в Tailwind, несмотря на шумиху, поэтому я хотел бы получить любую помощь от сообщества.

Чтобы внести прямой вклад в проект, нажмите здесь.

Спасибо!!!


person tsommie    schedule 17.09.2020    source источник
comment
Потрясающий проект ... Думаю, вы тоже можете разместить свой вопрос на форуме laracasts: laracasts.com/discuss   -  person Tiago Silva Pereira    schedule 18.09.2020
comment
Хорошо спасибо ... сразу же   -  person tsommie    schedule 18.09.2020
comment
@TiagoSilvaPereira Прошло 7 часов, ответа нет laracasts.com/discuss/channels/general-discussion/   -  person tsommie    schedule 18.09.2020
comment
Привет, @tsommie, проблема уже решена? Я постараюсь помочь тебе присмотреть за этим сегодня   -  person Tiago Silva Pereira    schedule 22.09.2020
comment
Мне удалось взломать его, используя Livewire $ emit на модальной кнопке, поэтому, когда кнопка нажата, я мог прослушивать ее с помощью livewire, а затем вызывать модальное окно следующим образом: new Bootstrap.Modal(document.getElementById('confirmingUserDeletionModal')).toggle(). Он работает хорошо, но я надеюсь на лучшую альтернативу. Я прошел долгий путь с тех пор, как опубликовал этот вопрос, и теперь пытаюсь добавить поддержку как для B4, так и для B5. Думаю, на этой неделе будет готова альфа-версия. Большое спасибо за проявленный интерес, любой вклад приветствуется.   -  person tsommie    schedule 22.09.2020
comment
Круто, есть ли какая-то функция, которой я могу помочь?   -  person Tiago Silva Pereira    schedule 22.09.2020
comment
После следующего коммита я дам знать. Может быть, после RC, включая сообщество React, действительно будет отличная идея, но я мало что знаю о React. @TiagoSilvaPereira. Вы есть в Твиттере?   -  person tsommie    schedule 23.09.2020
comment
Привет @TiagoSilvaPereira, я думаю, что Jetstrap готов к версии, я бы не возражал против второго мнения, прежде чем я создам тег.   -  person tsommie    schedule 24.09.2020


Ответы (1)


Я смог решить указанную выше проблему с помощью Livewire Event. Важно отметить, что причиной всех этих хлопот было создание ресурсов для замены ресурсов Jetstream без влияния на бизнес-логику, то есть МОДЕЛЬ и КОНТРОЛЛЕР.

Вот как выглядит мое решение:

        <div class="mt-3">
            <x-jet-danger-button wire:click="$emit('confirmingUserDeletion')"
                                 wire:loading.attr="disabled">
                Delete Account
            </x-jet-danger-button>
        </div>

        <!-- Delete User Confirmation Modal -->
        <x-jet-dialog-modal id="confirmingUserDeletionModal">
            <x-slot name="title">
                Delete Account
            </x-slot>

            <x-slot name="content">
                Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.

                <div class="mt-4 w-75" x-data="{}" x-on:confirming-delete-user.window="setTimeout(() => $refs.password.focus(), 250)">
                    <x-jet-input type="password" class="{{ $errors->has('password') ? 'is-invalid' : '' }}" placeholder="Password"
                                 x-ref="password"
                                 wire:model.defer="password"
                                 wire:keydown.enter="deleteUser" />

                    <x-jet-input-error for="password" />
                </div>
            </x-slot>

            <x-slot name="footer">
                <x-jet-secondary-button wire:click="$toggle('confirmingUserDeletion')"
                                        wire:loading.attr="disabled"
                                        data-dismiss="modal">
                    Nevermind
                </x-jet-secondary-button>

                <x-jet-danger-button wire:click="deleteUser" wire:loading.attr="disabled">
                    Delete Account
                </x-jet-danger-button>
            </x-slot>
        </x-jet-dialog-modal>

    @push('scripts')
        <script>
            Livewire.on('confirmingUserDeletion', () => {
                @this.confirmUserDeletion()
                new Bootstrap.Modal(document.getElementById('confirmingUserDeletionModal')).toggle()
            })
        </script>
    @endpush
person tsommie    schedule 22.09.2020