ospnko/hush

PHP 构建仪表板组件

dev-master 2024-07-27 05:56 UTC

This package is auto-updated.

Last update: 2024-09-27 06:17:26 UTC


README

一个无依赖关系的包,用于构建 PHP 网络应用的仪表板。

入门

安装

  1. composer require ospnko/hush
  2. 创建一个指向 asset 目录的符号链接,使其可用于浏览器

创建页面

所有功能的入口点是 HushBuilder 类。它提供了使用几乎每个组件的方法。

每个页面都以布局开始。要配置布局,您需要调用 ->layout() 方法

<?php

use Ospnko\Hush\HushBuilder;

$hush = new HushBuilder();

$hush->layout(
    csrfToken: '<app csrf token if exists, otherwise provide an empty string>',
    cssPath: '<http path to the app.css from the package\'s asset/css directory>',
    cssColorsPath: '<http path to the dashboard theme from the package\'s asset/css directory>',
    faviconPath: '<path to desired favicon>',
    faviconType: '<favicon type>',
    fontsPath: '<http path to the asset/fonts directory>',
    jsPath: '<http path to the asset/js directory>',
    locale: '<app\'s locale for the HTML lang tag>',
    title: '<current page title>',
);

要渲染页面,您需要调用 ->render() 方法,它将生成 HTML,您需要将其发送给用户。

此示例目前生成一个空页面。

作为构建单元,Hush 使用 。块将组件组合成有意义的单元,其标题描述了这些单元。让我们添加一个

// ...layout definition here

$hush->block(
    headline: 'Greeting',
    content: fn (HushBuilder $hush) => $hush->text('Greeting text'),
);

$hush->render();

现在页面上有了一段问候文本。如您所见,块的 内容也使用了 HushBuilder 类,这样就可以继续将其添加到其中。

目前没有太多限制,但从 ->block() 中调用 ->layout()->block() 方法绝对是个坏主意。

文档

属性

许多组件支持 $attributes 参数,它允许您以关联数组的形式指定自定义 HTML 属性。

示例

attributes: ['class' => 'my-class', 'id' => 'my-id']

块是 Hush 接口的构建单元。

示例

// this one produces block without the headline
$hush->block(
    content: fn (HushBuilder $hush) => $hush->text('Hello there'),
);

// you can add heading inside the content (useful when it gets more functionality then just displaying text)
$hush->block(
    content: fn (HushBuilder $hush) => $hush
        ->heading('Greeting')
        ->text('Hello there'),
);

$hush->block(
    headline: 'Greeting',
    content: fn (HushBuilder $hush) => $hush->text('Hello there'),
    attributes: ['style' => 'padding: 200px;'],
);

面包屑

面包屑组件为用户提供有用的链接树。

示例

use Ospnko\Hush\Component\Breadcrumb\Breadcrumb;

$hush->block(
    content: fn (HushBuilder $hush) => $hush->breadcrumbs(
        fn (Breadcrumb $breadcrumb) => $breadcrumb
            ->addItem('Home', '/dashboard')
            ->addItem('Products', '/dashboard/products'))
            ->addItem('Edit product'),
    ),
);

按钮

它看起来像一个按钮,行为也像一个按钮,但请注意,它并不总是由 <button> HTML 属性表示,有时它是由 <a> 表示(通常当提供 $link 参数时)。

示例

$hush->button(
    content: 'Submit',
);

$hush->button(
    link: '/dashboard',
    content: 'Home',
);

$hush->button(
    link: '/dashboard',
    content: fn (HushBuilder $hush) => $hush->text('Home'),
    attributes: ['class' => 'my-button'],
);

控制结构

if

仅为 if 语句提供构建方法。

示例

// instead of this
$hush->text('Something');

if ($isTrue) {
    $hush->text('Something additional');
}

// you can do this
$hush
    ->text('Something')
    ->if($isTrue, fn (HushBuilder $hush) => $hush->text('Something additional'));

循环

仅为 foreach 语句提供构建方法。

示例

// instead of this
$hush->text('Row #1');

foreach ([1, 2, 3] as $rowNumber) {
    $hush->text('Row #' . $rowNumber);
}

// you can do this
$hush
    ->text('Row #1')
    ->loop(
        row: [1, 2, 3],
        content: fn (HushBuilder $hush, int $rowNumber) => $hush
            ->text('Row #' . $row),
        attributes: [ // loop wraps its content into <div> which may have attributes
            'class' => 'my-looped-content'
        ],
    );

Flex

它是 <div style="display: flex"> 的包装器,它允许您使用 PHP 仅通过列分割内容。

示例

$hush->flex(
    // applied to the parent <div>
    attributes: ['style' => 'gap: 16px;'],
    // applied to the flex item
    childAttributes: [
        'leftBlock' => ['style' => 'color: #000'],
        'rightBlock' => ['style' => 'color: #fff'],
    ],
    // all below param names are at your discretion
    leftBlock: fn (HushBuilder $hush) => $hush->block(),
    rightBlock: fn (HushBuilder $hush) => $hush->block(),
);

表单

一个简单的 <form>

示例

$hush->form(
    method: 'POST',
    action: '/dashboard/products',
    content: fn (HushBuilder $hush) => $hush->block(),
    csrfField: '<your csrf field if exists>',
    attributes: ['class' => 'my-form'],
);

标题

一个简单的 <h1>

示例

$hush->heading(
    text: 'Heading',
    attributes: ['class' => 'my-heading'],
);

HTML

允许您粘贴原始 HTML。

示例

$hush->html(<<<HTML
    <div class="my-div">Text</div>
HTML);

图片

一个简单的 <img>

示例

$hush->image(
    link: '...',
    alt: '...',
    attributes: ['class' => 'my-image'],
);

输入

复选框

<input type="checkbox"> 的一种稍微修改过的版本。

示例

$hush->checkbox(
    label: 'My checkbox',
    name: 'my_checkbox',
    isChecked: true,
    value: 'my_value',
    attributes: ['class' => 'my-class'],
);

文件

<input type="file"> 的一种稍微修改过的版本。

支持 multiple,通过传递 isMultiple: true 实现。

支持异步加载 - 这是指文件在选中后立即加载到服务器,在表单提交时后端仅接收它的路径。如果提供 asyncUrl,输入变为异步。

它向 asyncUrl 中的 URL 发送 POST 请求,在请求正文中包含文件的二进制表示形式,并在 body 中以 file 字段的形式发送。它期望接收带有 mimepath 字段的 JSON。

您还可以提供一些额外的 HTML 来显示在输入本身之前的内容,这可能会对处理特定类型文件的输入很有用。请注意,对于异步字段,您可能需要自己编写前端逻辑。

同步单个文件输入的示例

$hush->inputFile(
    name: 'my_file',
    value: '/my-image.jpg',
    placeholder: 'My placeholder',
    isMultiple: false,
    errors: ['Error #1'],
    attributes: ['class' => 'my-class'],
    mainInputAttributes: [],
);

同步多个文件输入的示例

$hush->inputFile(
    name: 'my_file',
    value: ['/my-image.jpg'],
    placeholder: 'My placeholder',
    isMultiple: true,
    errors: ['Error #1'],
    attributes: ['class' => 'my-class'],
    mainInputAttributes: [],
);

异步多个文件输入的示例

$hush->inputFile(
    name: 'my_file',
    value: ['/my-image.jpg'],
    placeholder: 'My placeholder',
    isMultiple: true,
    asyncUrl: '/api/v1/image',
    upperContent: <<<HTML
        <img src="/my-image.jpg" alt="">
    HTML,
    errors: ['Error #1'],
    attributes: ['class' => 'my-class'],
    mainInputAttributes: [],
);

文件(图片)

仅支持图片的文件输入的特殊输入。

示例

$hush->inputImage(
    name: 'my_image',
    image: '/my-image.jpg',
    placeholder: 'My placeholder',
    asyncUrl: '',
    errors: ['Error #1'],
);

文件(图片多选)

与上一个示例相同,但支持多张图片。

参数 deleted 用于提供需要标记为删除的图片路径(当需要在处理前要求用户修复验证错误时变得有用)。

支持重新排序功能。当启用时,提供控件来管理上传图片的位置。仅与异步上传一起工作。

示例

$hush->inputImageMultiple(
    name: 'my_images',
    images: ['/my-image.jpg'],
    deleted: ['/my-image.jpg'],
    placeholder: 'My placeholder',
    asyncUrl: '',
    isReorderingEnabled: true,
    errors: ['Error #1'],
);

文件(媒体)

几乎与 文件(图片) 相同,但允许上传视频。

示例

$hush->inputMedia(
    name: 'my_media',
    media: '/my-video.mp4',
    isVideo: false, // yeah, you should check this manually
    placeholder: 'My placeholder',
    asyncUrl: '',
    errors: [],
);

输入

只是一个简单的 <input>

示例

$hush->input(
    type: 'text',
    name: 'my_input',
    placeholder: 'My placeholder',
    value: 'My value',
    isRequired: true,
    attributes: ['class' => 'my-class'],
    errors: ['Error #1', 'Error #2'],
);

输入(搜索)

具有一些自定义功能(如提交表单的按钮和清除按钮)的一种输入类型。

示例

$hush->inputSearch(
    name: 'my_search',
    placeholder: 'My search',
    value: '',
    attributes: ['class' => 'my-search'],
);

选择

经典 <select> 的略微修改版本。

它支持搜索,要启用它,您只需传递 isSearchable: true + searchPlaceholder(如果需要)。

它还支持异步搜索 - 当根据搜索值从后端动态上传行时。它向提供的 URL 发送 GET 请求,带有包含搜索字段值的 query 参数和 selected,它支持当前选中元素的值。它期望接收包含字段 textvalue 的对象的数组 JSON 响应。

示例

$hush->select(
    name: 'my_select',
    options: ['red' => 'Red', 'green' => 'Green', 'blue' => 'Blue'],
    value: 'green',
    errors: [],
    placeholder: 'My placeholder',
    searchPlaceholder: 'Search',
    isRequired: true,
    isSearchable: true,
    asyncSearchUrl: '',
);

选择(多选)

允许选择多个值的类型。

示例

$hush->selectMultiple(
    name: 'my_select',
    options: ['red' => 'Red', 'green' => 'Green', 'blue' => 'Blue'],
    values: ['red', 'green'],
    errors: [],
    placeholder: 'My select',
    searchPlaceholder: 'Search',
    isRequired: true,
    isSearchable: true,
);

文本区域

只是一个简单的 <textarea>

示例

$hush->textarea(
    name: 'my_textarea',
    value: '',
    placeholder: 'My textarea',
    errors: [],
    attributes: [],
);

错误

显示小红色文本。主要用于指示验证错误。

示例

$hush->errors(['Error #1', 'Error #2']);

标签

只是一个简单的 <label>

示例

$hush->label(
    content: 'Label #1',
    attributes: ['class' => 'my-label'],
);

$hush->label(
    content: fn (HushBuilder $hush) => $hush->text('Label #2'),
);

布局

设置应用程序布局。

示例

$hush->layout(
    csrfToken: '',
    cssPath: '/asset/css/app.css',
    cssColorsPath: '/asset/css/light.css',
    faviconPath: '/favicon.png',
    faviconType: 'image/png',
    fontsPath: '/asset/fonts',
    jsPath: '/asset/js',
    locale: 'en',
    title: 'My awesome dashboard',
    customEndHeadHtml: '<script src="/my.js"></script>',
    customEndBodyHtml: '<script src="/my-another.js"></script>',
);

链接

只是一个简单的 <a>

示例

$hush->link(
    link: '/dashboard/products',
    content: 'Products',
    attributes: ['class' => 'my-link'],
);

$hush->link(
    link: '/dashboard/products',
    content: fn (HushBuilder $hush) => $hush->heading('Products'),
);

菜单

创建水平菜单。有两个样式选项

  • 岛屿 - 当按钮存在时,如独立的岛屿
  • 粘性 - 当按钮粘附在菜单下方的块上时

示例

use Ospnko\Hush\Component\Menu\Menu;

$hush->menu(
    attributes: ['class' => 'sticky'], // makes it sticky, remove to use islands
    content: fn (Menu $menu) => $menu
        ->addItem(
            link: '/dashboard/orders',
            text: 'Orders',
            isActive: false, // marks element as active if true
        )
        ->addItem(
            text: 'Stock',
            isActive: true,
            submenu: fn (Menu $menu) => $menu // it can have only 1 level of submenu for now
                ->addItem(
                    link: '/dashboard/products',
                    text: 'Products',
                    isActive: true,
                )
        )
);

模态框

在页面上插入模态框,默认打开。

示例

$hush->modal(
    title: 'My modal',
    content: fn (HushBuilder $hush) => $hush
        ->text('My modal text'),
    footer: fn (HushBuilder $hush) => $hush
        ->button('Cancel')
        ->button('Submit'),
);

分页

只是一个简单的分页元素。

示例

$hush->pagination(
    currentPage: 1,
    pages: 10, // total amount of pages
    baseLink: '/dashboard/products', // link to the current page without GET params
    paramName: 'page', // GET param name to send clicked page number
    params: ['search' => 'phone'], // custom GET params which should be sent on backend too
);

样式

只是一个简单的 style

示例

$hush->style(<<<CSS
    .element {
        color: #000;
    }
CSS);

SVG

有一个 SVG 枚举 Ospnko\Hush\Enum\Svg,它提供了默认 SVG 的列表。

示例

$hush->html( // you can insert them using ->html
    Svg::Warning->render(),
);

表格

用于构建表格。

您应指定列和操作(如果指定,操作是 1 个额外表格列中的小按钮)。

有一些隐藏的 JS 片段用于处理表格。

  • href = #hush-table-row-add 将从它的 data-target=<selector> 添加一个新行到表格中,内容从 data-template=<html>
  • href = #hush-table-row-drop 将从表格中删除行。

示例

use Ospnko\Hush\Component\Table\Table;

$hush->table(
    attributes: [ // table uses CSS grid, so you need to manually adjust column sizes
        'style' => 'grid-template-columns: auto auto max-content',
    ],
    rows: [ // data that we need to display
        ['id' => 1, 'name' => 'Item #1'],
        ['id' => 2, 'name' => 'Item #2'],
    ],
    table: fn (Table $table) => $table
        ->addColumn(
            header: '#',
            content: fn (array $row) => $row['id'],
        )
        ->addColumn(
            header: 'Name',
            content: fn (array $row, HushBuilder $hush) => $hush
                ->link(
                    content: $row['name'],
                    link: '/dashboard/products/' . $row['id']
                )
        )
        ->addAction(
            icon: Svg::Edit->render(), // icon expects HTML
            note: 'Edit',
            link: fn (array $row) => '/dashboard/products/' . $row['id'] . '/edit',
        )
        ->addAction(
            icon: Svg::Delete->render(),
            note: 'Delete',
            link: fn (array $row) => '/dashboard/products/' . $row['id'] . '/delete',
            isAsyncModal: true, // means that action expects modal HTML from backend
        )
);

文本

只是一个简单的 <p>

示例

$hush->text(
    text: 'My text',
    attributes: ['class' => 'my-class'],
);

视频

只是一个简单的 <video>

示例

$hush->video(
    source: '/my-video.mp4',
    attributes: ['controls' => ''],
);