From 217b1c9ea985e49690ef290f80e2755f24c8890e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=AF=E7=AB=8B?= Date: Wed, 20 May 2026 23:20:09 +0800 Subject: [PATCH] =?UTF-8?q?style(menu):=20=E4=BC=98=E5=8C=96=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E8=A1=A8=E5=8D=95=E5=9B=BE=E6=A0=87=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 PickerFieldComponent 增加 control_class 和 control_attrs 包裹层配置,让输入框与右侧图标能够在相对定位容器内稳定对齐,同时保留外层 label 的自定义能力。 菜单编辑表单引入专用内联样式,调整图标选择器输入框、右侧图标按钮和图标预览区域的间距与边框,提升图标选择交互的视觉一致性。 为菜单状态单选区域增加专用 class 和样式,统一选项高度、背景和单选图标尺寸,避免表单网格中状态项显示拥挤。 --- .../form/component/PickerFieldComponent.php | 13 ++-- .../src/builder/MenuBuilder.php | 60 ++++++++++++++++++- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/plugin/think-library/src/builder/form/component/PickerFieldComponent.php b/plugin/think-library/src/builder/form/component/PickerFieldComponent.php index 41d1881b7..e221ad3bf 100644 --- a/plugin/think-library/src/builder/form/component/PickerFieldComponent.php +++ b/plugin/think-library/src/builder/form/component/PickerFieldComponent.php @@ -28,7 +28,7 @@ class PickerFieldComponent extends AbstractFormComponent public function mount(FormNode $parent): FormNode { - $node = $parent->node('label')->class(trim(strval($this->config['class'] ?? 'relative block'))); + $node = $parent->node('label')->class(trim(strval($this->config['class'] ?? 'block'))); foreach ((array)($this->config['attrs'] ?? []) as $name => $value) { $node->attr(strval($name), $value); } @@ -51,9 +51,14 @@ class PickerFieldComponent extends AbstractFormComponent ]); } - $input = $node->node('input')->attrs([ + $control = $node->div()->class(trim(strval($this->config['control_class'] ?? 'relative'))); + foreach ((array)($this->config['control_attrs'] ?? []) as $name => $value) { + $control->attr(strval($name), $value); + } + + $input = $control->node('input')->attrs([ 'readonly' => null, - 'class' => trim(strval($this->config['input_class'] ?? 'layui-input')), + 'class' => trim(strval($this->config['input_class'] ?? 'layui-input pr40')), 'value' => strval($this->config['value'] ?? ''), 'title' => strval($this->config['value'] ?? ''), ]); @@ -64,7 +69,7 @@ class PickerFieldComponent extends AbstractFormComponent foreach ((array)($this->config['input_attrs'] ?? []) as $name => $value) { $input->attr(strval($name), $value); } - $icon = $node->node('span')->class(trim(strval($this->config['icon_class'] ?? 'input-right-icon layui-icon layui-icon-theme'))); + $icon = $control->node('span')->class(trim(strval($this->config['icon_class'] ?? 'input-right-icon layui-icon layui-icon-theme'))); foreach ((array)($this->config['icon_attrs'] ?? []) as $name => $value) { $icon->attr(strval($name), $value); } diff --git a/plugin/think-plugs-system/src/builder/MenuBuilder.php b/plugin/think-plugs-system/src/builder/MenuBuilder.php index b1f45dd11..d1e258ab3 100644 --- a/plugin/think-plugs-system/src/builder/MenuBuilder.php +++ b/plugin/think-plugs-system/src/builder/MenuBuilder.php @@ -153,6 +153,7 @@ SCRIPT); $form->action(strval($context['actionUrl'] ?? '')) ->attrs(['id' => 'MenuForm', 'data-table-id' => 'MenuTable']) ->class('system-menu-form'); + $form->html(''); FormModules::section($form, [ 'title' => '层级归属', @@ -236,7 +237,7 @@ SCRIPT); $fields = $grid->div()->class('layui-col-xs12 layui-col-md6'); $fields->fields(function ($fields) { - $fields->text('icon', '菜单图标', 'Menu Icon', false, '可手动输入图标类名,或通过右侧图标选择器回填。', null, [ + $status = $fields->text('icon', '菜单图标', 'Menu Icon', false, '可手动输入图标类名,或通过右侧图标选择器回填。', null, [ 'placeholder' => '例如:layui-icon layui-icon-set-fill', ])->text('sort', '排序权重', 'Sort Order', false, '数值越大越靠前。', null, [ 'type' => 'number', @@ -244,7 +245,8 @@ SCRIPT); 'placeholder' => '请输入排序权重', ])->defaultValue(0)->radio('status', '使用状态', 'Status', '', true, [ 'required-error' => '请选择当前菜单的启用状态。', - ])->options([ + ]); + $status->body()->class('system-menu-status-options')->end()->options([ 1 => '已启用', 0 => '已禁用', ])->defaultValue('1'); @@ -255,6 +257,9 @@ SCRIPT); 'title' => '图标选择器', 'subtitle' => 'Icon Picker', 'value' => '点击打开图标选择器', + 'class' => 'block system-menu-icon-picker', + 'control_class' => 'relative', + 'input_class' => 'layui-input pr40', 'attrs' => ['data-open-menu-icon' => null], 'input_attrs' => [ 'data-open-menu-icon' => null, @@ -264,7 +269,7 @@ SCRIPT); 'icon_attrs' => ['data-open-menu-icon' => null], 'help' => '选择后会自动同步到“菜单图标”字段,并实时预览当前图标样式。', ]); - $picker->div()->class('layui-form-mid color-desc')->html(sprintf( + $picker->div()->class('layui-form-mid color-desc system-menu-icon-preview')->html(sprintf( '%s', self::escape(BuilderLang::text('未设置图标')) )); @@ -345,6 +350,55 @@ SCRIPT; return strval(json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT)); } + private static function renderFormStyle(): string + { + return <<<'STYLE' +#MenuForm .system-menu-icon-picker .layui-input { + cursor: pointer; + padding-right: 44px !important; +} +#MenuForm .system-menu-icon-picker .input-right-icon { + top: 1px; + right: 1px; + width: 34px; + height: 32px; + line-height: 32px; + box-sizing: border-box; + border-left: 1px solid var(--ta-border-color, #dce8e5); + border-radius: 0 3px 3px 0; +} +#MenuForm .system-menu-icon-preview { + min-height: 20px; + margin-top: 8px; + padding: 0 2px; + line-height: 20px; +} +#MenuForm .system-menu-icon-preview .layui-icon { + width: 18px; + text-align: center; +} +#MenuForm [data-field-name="status"] .system-menu-status-options { + height: auto !important; + min-height: 34px !important; + padding: 1px 0 1px 8px !important; + line-height: 32px !important; + align-items: center; + box-sizing: border-box; + border-color: var(--ta-border-color, #dce8e5); + background: var(--ta-surface-soft, #f7fbfb) !important; +} +#MenuForm [data-field-name="status"] .system-menu-status-options .layui-form-radio { + margin: 0 18px 0 0; + padding-right: 0; + line-height: 32px; +} +#MenuForm [data-field-name="status"] .system-menu-status-options .layui-form-radio > i { + margin-right: 5px; + font-size: 18px; +} +STYLE; + } + private static function renderFormScript(): string { return sprintf(<<<'SCRIPT'