bombenprodukt/livewire-calendar

使用 Laravel Livewire 构建日历的包。


README

本项目由 Brian Faust 创建并维护,是一个用于使用 Laravel Livewire 构建日历的包。请务必浏览变更日志行为准则贡献指南许可协议安全策略

安装

注意 此包需要 PHP 8.2 或更高版本,并支持 Laravel 10 或更高版本。

要获取最新版本,请使用 Composer 引入项目。

$ composer require bombenprodukt/livewire-calendar

使用方法

注意 请查阅 我们的测试套件 获取详细的用法示例。

为了使用此组件,您必须创建一个新的 Livewire 组件,该组件扩展了 AbstractCalendar 类。此类提供了日历的基本功能,您可以重写方法以根据需要自定义日历。events() 函数是唯一必需的方法,它必须返回一个 Event 对象的 Collection

<?php

declare(strict_types=1);

namespace App\Http\Livewire;

use Illuminate\Support\Collection;
use BombenProdukt\LivewireCalendar\Calendar;
use BombenProdukt\LivewireCalendar\Http\Livewire\AbstractCalendar;

final class Calendar extends AbstractCalendar
{
    public function events(): Collection
    {
        return new Collection([
            Calendar::createEvent(
                id: 'unique-id',
                name: 'Sales Meeting',
                description: 'Review the sales for the month',
                href: 'https://openai.com/',
                startTime: Carbon::today()->addHours(8),
                endTime: Carbon::today()->addHours(16),
            ),
            Calendar::createEvent(
                id: 'another-unique-id',
                name: 'Marketing Meeting',
                description: 'Review the marketing for the month',
                href: 'https://openai.com/',
                startTime: Carbon::tomorrow()->addHours(8),
                endTime: Carbon::tomorrow()->addHours(16),
            ),
        ]);
    }
}

如果您想使用 Eloquent 从数据库中加载事件,您需要为每条记录创建一个新的 Event 对象。您可以使用 map() 方法创建一个新的 Event 对象的 Collection

<?php

declare(strict_types=1);

namespace App\Http\Livewire;

use Illuminate\Support\Collection;
use BombenProdukt\LivewireCalendar\Data\Event;
use BombenProdukt\LivewireCalendar\Http\Livewire\AbstractCalendar;

final class Calendar extends AbstractCalendar
{
    public function events(): Collection
    {
        return Model::get()->map(
            fn (Model $model): Event => new Event(
                id: $model->id,
                name: $model->name,
                description: $model->description,
                href: route('event', $model->id),
                startTime: $model->starts_at,
                endTime: $model->ends_at,
            )
        );
    }
}

在页面上渲染此 Livewire 组件的最基本方法是使用 <livewire: 标签语法。

<livewire:calendar />

或者,您可以使用 @livewire blade 指令。

@livewire('calendar')

拖放

如果您想启用拖放功能,您需要在您的应用程序中包含以下 JavaScript。这将允许您将事件拖放到不同的天。

注意 我们建议将其放入您的 resources/js/app.js 文件中。

window.onLivewireCalendarEventDragStart = function(event, eventId) {
	event.dataTransfer.setData('id', eventId);
};

window.onLivewireCalendarEventDragEnter = function(event, componentId, dateString, dragAndDropClasses) {
	event.stopPropagation();
	event.preventDefault();

	const element = document.getElementById(`${componentId}-${dateString}`);
	element.className = `${element.className} ${dragAndDropClasses}`;
};

window.onLivewireCalendarEventDragLeave = function(event, componentId, dateString, dragAndDropClasses) {
	event.stopPropagation();
	event.preventDefault();

	const element = document.getElementById(`${componentId}-${dateString}`);
	element.className = element.className.replace(dragAndDropClasses, '');
};

window.onLivewireCalendarEventDragOver = function(event) {
	event.stopPropagation();
	event.preventDefault();
};

window.onLivewireCalendarEventDrop = function(event, componentId, dateString, dragAndDropClasses) {
	event.stopPropagation();
	event.preventDefault();

	const element = document.getElementById(`${componentId}-${dateString}`);
	element.className = element.className.replace(dragAndDropClasses, '');

	window.Livewire
		.find(componentId)
		.call('onEventDropped', event.dataTransfer.getData('id'), dateString);
};

故障排除

如果您遇到日历无法渲染的问题,请确保您的 tailwind.config.js 文件配置正确。您可以使用以下示例作为起点:

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/bombenprodukt/livewire-calendar/**/*.blade.php',
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './vendor/laravel/jetstream/**/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Inter', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'), require('@tailwindcss/typography')],
};