diatechnis/vellum

一个基于原子设计原则构建的站点库。

v0.6.2 2019-03-23 14:43 UTC

This package is auto-updated.

Last update: 2024-09-24 05:20:58 UTC


README

Vellum 是一个基于 PHP 编写的模块化组件库,灵感来源于 原子设计原则

Vellum 示例项目 中查看一些 Vellum 组件的实际应用。

$renderer = new HtmlRenderer();
        
$arguments = [
    'button_text' => 'Submit',
    'classes' => 'btn btn-success',
];

$component = new \Example\Component\Button($arguments, $renderer);

echo $component->render(); // would display:
/*
<button type="submit" class="btn btn-success">
    Submit
</button>
*/

为什么选择 Vellum?

以下是采用 Vellum 的几个好处。

结构化

你有多少次忘记了一个视图文件需要哪些数据,不得不翻遍 HTML 来确定要传递给它什么?

Vellum 使用具有显示类型和输入的 PHP 类,这些类记录了一个 API,当使用组件时你可以参考。

不要重复自己

编写一次组件,反复使用。

如果你将组件放在一个独立的库中,那么你可以在每个项目中重用它们。

编写一次

一旦组件被编码,你就可以在任何地方使用它。不需要每次都编写 <a></a> 标签。

一致性和合规性

一旦你有了可访问的、符合品牌的组件,你的团队可以每次都使用相同的 HTML,而不必担心遗漏重要的属性或类。

概念

原子设计给设计师提供了构建协作工作的界面的工具,"以更谨慎和分层的方式创建界面设计系统。" - http://atomicdesign.bradfrost.com/chapter-2/

同样,Vellum 提供了 PHP 接口,允许设计师/团队创建他们自己的设计系统分层。Vellum 组件可以实例化和渲染来构建 UI。最后,Vellum 提供了一种显式声明参数的方法,每个组件都可以消耗和响应这些参数。

组件

Vellum 提供了 \Vellum\Contracts\AbstractComponent 以扩展。该 AbstractComponent 实现了以下所述的几个接口。

渲染器

组件的目标是被人使用,无论是人类还是其他。Vellum 提供了一种通过渲染器进行消费的手段。Vellum 假设组件将被渲染,但它对此发生的具体方式是无关紧要的。

每个组件都会注入一个设计师提供的渲染器(一个实现 \Vellum\Contracts\Renderers\RenderInterface 的 PHP 对象)。这允许团队选择他们喜欢的模板引擎(Twig、Plates 等...)。如果对 Twig 感兴趣,有一个 配套库

路径

Vellum 需要知道你的组件在哪里,以便实例化和渲染它们。但,又一次,Vellum 希望尽可能地保持无关紧要,关于如何以及在哪里找到它们。

Vellum 提供了 \Vellum\Path\ClassPathInterface\Vellum\Path\TemplatePathInterface,分别用于查找组件类和模板。基本实现位于 \Vellum\Path\SimpleClassPathResolverSimpleTemplatePathResolver

输入

向组件提供指令告诉它要渲染的内容,但你可以给它提供什么指令呢?输入提供了API,用于确定每个组件期望的指令、每个指令应提交的数据类型以及未提供指令时的默认值。

protected function createInputs(): InputsInterface
{
    return new Inputs(
        new TextInput(
            $name = 'button_text',
            $description = 'Button Text',
            $default_value = 'Submit'
        )
    );
}

选项

某些输入可能具有预期选择的离散数量(是/否或1-5)。选项表达了这些选择。

protected function createInputs(): InputsInterface
{
    return new Inputs(
        new SelectOneInput(
            $name = 'open_in_new_window',
            $description = 'Open the link in a new window?',
            $supply_value_as = Formats::NUMBER,
            $options = new Options(
                new Option('Same window', 0),
                new Option('New window', 1)
            ),
            $default_value = 0
        )
    );
}

显示类型

显示类型是一种特殊的输入类型。某些组件可能使用相同的数据,但可以以非常不同的方式显示。例如,博客文章的预览列表可以使用卡片界面、轮播图或简单的 <ul> 列表显示。这是相同的博客数据,但HTML却非常不同。让我们再说说,每种显示数据的方式都有仅适用于该特定视图类型的输入(例如轮播图的幻灯片过渡速度)。显示类型允许您定义查看组件的不同方式以及特定于每种显示的输入。

protected function createDisplayTypes(): DisplayTypesInterface
{
    return new DisplayTypes(
        new DisplayType(
            $name = 'submit',
            $inputs = new Inputs(
                new SelectOneInput(
                    'submit_via_ajax',
                    'Submit form via an ajax request?',
                    Formats::NUMBER,
                    new Options(
                        new Option('No', 0),
                        new Option('Yes', 1)
                    ),
                    0
                )
            ),
            $description = 'Submit Button',
            $default_display_type = true
        ),
        new DisplayType(
            $name = 'cancel',
            $inputs = new Inputs(
                new TextInput(
                    'confirm_message',
                    'Message to ask if user is sure',
                    'Are you sure you want to cancel this?'
                )
            ),
            $description = 'Cancel Button'
        )
    );
}

参数

输入、选项和显示类型提供了创建组件需要以正确渲染自己的指令的手段。提供的指令数据被实例化为一个Arguments对象,渲染器可以使用该对象在模板/视图中访问指令。

$arguments = new Arguments([
    'button_text' => 'Submit',
    'classes' => 'btn btn-success',
]);

$arguments->get('button_text'); // returns 'Submit'

$arguments->get('nonexistent_key'); // returns null

$arguments->get('nonexistent_key', 'default_value'); // returns 'default_value'