邹景立 875c3a16d7 feat(form): 增加表单栅格布局模块
新增 FormModules::grid 与 gridColumn,用统一方法生成 1 到 4 列的标准表单栅格,避免各业务表单重复拼接 layui 栅格类名。

在表单渲染壳层中注入标准样式,统一栅格列宽、字段间距、单行说明省略和自动补全下拉层样式,保证弹窗与页面模式展示一致。

补充 FormBuilderTest 覆盖可复用栅格布局、nowrap 说明文案和标准样式输出,防止后续表单布局能力回退。
2026-05-21 00:15:34 +08:00

135 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
namespace think\admin\builder\form\module;
use think\admin\builder\form\FormComponents;
use think\admin\builder\form\FormNode;
/**
* 表单通用模块。
* @class FormModules
*/
class FormModules
{
/**
* 标准表单栅格容器.
*/
public static function grid(FormNode $parent, int $columns = 2, string|array $class = '', int $space = 15): FormNode
{
$columns = self::normalizeGridColumns($columns);
$space = max(0, min(30, $space));
$node = $parent->div()->class([
'layui-row',
"layui-col-space{$space}",
'ta-form-grid',
"ta-form-grid-{$columns}",
]);
if ($class !== '' && $class !== []) {
$node->class($class);
}
return $node;
}
/**
* 标准表单栅格列.
*/
public static function gridColumn(FormNode $parent, int $columns = 2, string|array $class = ''): FormNode
{
$columns = self::normalizeGridColumns($columns);
$span = match ($columns) {
1 => 12,
2 => 6,
3 => 4,
default => 3,
};
$node = $parent->div()->class([
"layui-col-xs{$span}",
'ta-form-grid-col',
]);
if ($class !== '' && $class !== []) {
$node->class($class);
}
return $node;
}
/**
* @param array<string, mixed> $config
*/
public static function intro(FormNode $parent, array $config = []): FormNode
{
return FormComponents::intro()->config($config)->mount($parent);
}
/**
* @param array<string, mixed> $config
* @param callable(FormNode): void $callback
*/
public static function section(FormNode $parent, array $config, callable $callback): FormNode
{
return FormComponents::section()->config($config)->body($callback)->mount($parent);
}
public static function note(FormNode $parent, string $text, string $class = 'help-block color-desc'): FormNode
{
return FormComponents::note($text)->class($class)->mount($parent);
}
/**
* @param array<string, mixed> $config
*/
public static function readonlyField(FormNode $parent, array $config = []): FormNode
{
return FormComponents::readonlyField()->config($config)->mount($parent);
}
/**
* @param array<string, mixed> $config
*/
public static function pickerField(FormNode $parent, array $config = []): FormNode
{
return FormComponents::pickerField()->config($config)->mount($parent);
}
/**
* @param array<string, array<string, mixed>> $themes
* @param array<string, mixed> $config
*/
public static function themePalette(FormNode $parent, array $themes, string $current = '', array $config = []): FormNode
{
return FormComponents::themePalette($themes, $current)->config($config)->mount($parent);
}
/**
* @param array<string, mixed> $theme
*/
private static function themePreviewStyle(array $theme): string
{
$styles = [];
foreach ([
'theme-accent' => strval($theme['primary'] ?? ''),
'theme-header' => strval($theme['header'] ?? ''),
'theme-side' => strval($theme['side'] ?? ''),
'theme-surface' => strval($theme['surface'] ?? ''),
'theme-body' => strval($theme['body'] ?? ''),
] as $name => $value) {
if ($value !== '') {
$styles[] = '--' . $name . ':' . $value;
}
}
return join(';', $styles);
}
private static function escape(string $content): string
{
return htmlentities($content, ENT_QUOTES, 'UTF-8');
}
private static function normalizeGridColumns(int $columns): int
{
return max(1, min(4, $columns));
}
}