feat(form): 统一表单组件样式并新增配置项
1. 新增标签字重、自动宽度上限、输入框边框/背景色等配置项 2. 统一ns-form、ns-newform和diy-form的输入框样式与默认值 3. 优化标签宽度计算逻辑,添加自动宽度上限防止布局溢出 4. 适配多端输入框样式,添加聚焦态交互效果
This commit is contained in:
@@ -187,11 +187,18 @@ export default {
|
||||
labelFixedWidth: pick('labelFixedWidth', 'label_fixed_width'),
|
||||
labelFontSize: pick('labelFontSize', 'label_font_size'),
|
||||
labelColor: pick('labelColor', 'label_color'),
|
||||
labelFontWeight: pick('labelFontWeight', 'label_font_weight'),
|
||||
labelAutoMaxWidth: pick('labelAutoMaxWidth', 'label_auto_max_width'),
|
||||
requiredColor: pick('requiredColor', 'required_color'),
|
||||
checkedColor: pick('checkedColor', 'checked_color'),
|
||||
// 占位符:遗漏会被 ns-newform SCSS 默认值回退覆盖
|
||||
placeholderColor: pick('placeholderColor', 'placeholder_color'),
|
||||
placeholderFontSize: pick('placeholderFontSize', 'placeholder_font_size'),
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
inputBorderColor: pick('inputBorderColor', 'input_border_color'),
|
||||
inputBgColor: pick('inputBgColor', 'input_bg_color'),
|
||||
inputFocusBorderColor: pick('inputFocusBorderColor', 'input_focus_border_color'),
|
||||
inputFocusBgColor: pick('inputFocusBgColor', 'input_focus_bg_color'),
|
||||
submitText: pick('submitText', 'submit_text'),
|
||||
submitColor: pick('submitColor', 'submit_color'),
|
||||
submitBgColor: pick('submitBgColor', 'submit_bg_color'),
|
||||
|
||||
@@ -281,10 +281,17 @@
|
||||
labelFixedWidth: 180,
|
||||
labelFontSize: 28,
|
||||
labelColor: '#1f2937',
|
||||
labelFontWeight: 600,
|
||||
labelAutoMaxWidth: 200,
|
||||
requiredColor: '#ef4444',
|
||||
checkedColor: '#ff4544',
|
||||
placeholderColor: '#909399',
|
||||
placeholderFontSize: 28,
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
inputBorderColor: '#e5e7eb',
|
||||
inputBgColor: '#f9fafb',
|
||||
inputFocusBorderColor: '#ff4544',
|
||||
inputFocusBgColor: '#ffffff',
|
||||
showRowDivider: true,
|
||||
rowDividerColor: '#f0f0f0'
|
||||
};
|
||||
@@ -308,10 +315,15 @@
|
||||
labelFixedWidth: pick('labelFixedWidth', 'label_fixed_width'),
|
||||
labelFontSize: pick('labelFontSize', 'label_font_size'),
|
||||
labelColor: pick('labelColor', 'label_color'),
|
||||
labelFontWeight: pick('labelFontWeight', 'label_font_weight'),
|
||||
requiredColor: pick('requiredColor', 'required_color'),
|
||||
checkedColor: pick('checkedColor', 'checked_color'),
|
||||
placeholderColor: pick('placeholderColor', 'placeholder_color'),
|
||||
placeholderFontSize: pick('placeholderFontSize', 'placeholder_font_size'),
|
||||
inputBorderColor: pick('inputBorderColor', 'input_border_color'),
|
||||
inputBgColor: pick('inputBgColor', 'input_bg_color'),
|
||||
inputFocusBorderColor: pick('inputFocusBorderColor', 'input_focus_border_color'),
|
||||
inputFocusBgColor: pick('inputFocusBgColor', 'input_focus_bg_color'),
|
||||
showRowDivider: pick('showRowDivider', 'show_row_divider'),
|
||||
rowDividerColor: pick('rowDividerColor', 'row_divider_color')
|
||||
};
|
||||
@@ -363,10 +375,16 @@
|
||||
'--label-fixed-width': this.$util.rpx(cfg.labelFixedWidth),
|
||||
'--label-font-size': this.$util.rpx(num(cfg.labelFontSize, 28)),
|
||||
'--label-color': cfg.labelColor,
|
||||
'--label-font-weight': cfg.labelFontWeight,
|
||||
'--required-color': cfg.requiredColor,
|
||||
'--checked-color': cfg.checkedColor,
|
||||
'--placeholder-color': cfg.placeholderColor,
|
||||
'--placeholder-font-size': this.$util.rpx(num(cfg.placeholderFontSize, 28)),
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
'--input-border-color': cfg.inputBorderColor,
|
||||
'--input-bg-color': cfg.inputBgColor,
|
||||
'--input-focus-border-color': cfg.inputFocusBorderColor,
|
||||
'--input-focus-bg-color': cfg.inputFocusBgColor,
|
||||
'--row-divider-color': cfg.rowDividerColor,
|
||||
'--show-row-divider': cfg.showRowDivider === false ? '0' : '1'
|
||||
});
|
||||
@@ -879,10 +897,16 @@
|
||||
--label-fixed-width: 180rpx;
|
||||
--label-font-size: 28rpx;
|
||||
--label-color: #1f2937;
|
||||
--label-font-weight: 600;
|
||||
--required-color: #ef4444;
|
||||
--placeholder-font-size: 28rpx;
|
||||
--checked-color: #ff4544;
|
||||
--placeholder-color: #909399;
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
--input-border-color: #e5e7eb;
|
||||
--input-bg-color: #f9fafb;
|
||||
--input-focus-border-color: #ff4544;
|
||||
--input-focus-bg-color: #ffffff;
|
||||
--row-divider-color: #f0f0f0;
|
||||
--show-row-divider: 1;
|
||||
}
|
||||
@@ -946,6 +970,7 @@
|
||||
text-align: left;
|
||||
font-size: var(--label-font-size, $font-size-base);
|
||||
color: var(--label-color, #1f2937);
|
||||
font-weight: var(--label-font-weight, 600);
|
||||
|
||||
text {
|
||||
font-size: var(--label-font-size, $font-size-base);
|
||||
@@ -967,6 +992,8 @@
|
||||
line-height: inherit;
|
||||
text-align: left;
|
||||
|
||||
// H5 端 <input> 可能被 uni-app 编译为 <uni-input> 包装组件,::v-deep 穿透 scoped 命中真实原生 input
|
||||
::v-deep input,
|
||||
input {
|
||||
font-size: var(--label-font-size, $font-size-base);
|
||||
text-align: left;
|
||||
@@ -978,8 +1005,16 @@
|
||||
min-height: var(--input-height, 60rpx);
|
||||
border-radius: var(--input-radius, 0rpx);
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
padding: 0 12rpx;
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:focus {
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
|
||||
// 原生 placeholder 样式(WebView / H5 生效;小程序/鸿蒙的 placeholder
|
||||
// 通过 placeholder-class="placeholder" 钩子走 .placeholder 规则)
|
||||
@@ -997,6 +1032,7 @@
|
||||
line-height: var(--input-height, 60rpx);
|
||||
}
|
||||
|
||||
::v-deep textarea,
|
||||
textarea {
|
||||
font-size: var(--label-font-size, $font-size-base);
|
||||
width: 100%;
|
||||
@@ -1009,8 +1045,16 @@
|
||||
text-align: left;
|
||||
border-radius: var(--input-radius, 0rpx);
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
padding: 12rpx;
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:focus {
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
}
|
||||
|
||||
.uni-input {
|
||||
@@ -1018,6 +1062,11 @@
|
||||
color: var(--label-color, #1f2937);
|
||||
line-height: var(--input-height, 60rpx);
|
||||
min-height: var(--input-height, 60rpx);
|
||||
// 输入框视觉增强(与 ns-newform 对齐)
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
border-radius: var(--input-radius, 0rpx);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.select-address {
|
||||
|
||||
@@ -371,10 +371,18 @@ export default {
|
||||
labelFixedWidth: 180,
|
||||
labelFontSize: 28,
|
||||
labelColor: '#1f2937',
|
||||
labelFontWeight: 600,
|
||||
labelAutoMaxWidth: 200, // auto 模式下 label 宽度上限(rpx),超过后 ellipsis 截断
|
||||
requiredColor: '#ef4444',
|
||||
checkedColor: '#ff4544',
|
||||
placeholderColor: '#ddd',
|
||||
placeholderFontSize: 28,
|
||||
// 输入框视觉增强(可由后端 form_config 覆盖)
|
||||
inputBorderColor: '#e5e7eb',
|
||||
inputBgColor: '#f9fafb',
|
||||
inputFocusBorderColor: '#ff4544',
|
||||
inputFocusBgColor: '#ffffff',
|
||||
labelFontWeight: 600,
|
||||
// 提交按钮
|
||||
submitColor: '#ffffff',
|
||||
submitBgColor: '#ff4544',
|
||||
@@ -444,6 +452,12 @@ export default {
|
||||
'--checked-color': cfg.checkedColor,
|
||||
'--placeholder-color': cfg.placeholderColor,
|
||||
'--placeholder-font-size': this.$util.rpx(num(cfg.placeholderFontSize, 28)),
|
||||
// 输入框视觉增强(边框 / 背景 / 聚焦 / label 字重)
|
||||
'--input-border-color': cfg.inputBorderColor,
|
||||
'--input-bg-color': cfg.inputBgColor,
|
||||
'--input-focus-border-color': cfg.inputFocusBorderColor,
|
||||
'--input-focus-bg-color': cfg.inputFocusBgColor,
|
||||
'--label-font-weight': cfg.labelFontWeight,
|
||||
'--submit-color': cfg.submitColor,
|
||||
'--submit-bg-color': cfg.submitBgColor,
|
||||
'--submit-margin-top': this.$util.rpx(cfg.submitMarginTop || 0),
|
||||
@@ -559,8 +573,13 @@ export default {
|
||||
if (len > maxChars) maxChars = len;
|
||||
});
|
||||
// 与后端公式一致:chars * (fontSize/2) * 1.1 + 12,单位 px → 转 rpx(×2)
|
||||
const widthPx = Math.max(40, maxChars * (fontSize / 2) * 1.1 + 12);
|
||||
this.maxLabelWidth = Math.round(widthPx * 2);
|
||||
let widthPx = Math.max(40, maxChars * (fontSize / 2) * 1.1 + 12);
|
||||
let widthRpx = Math.round(widthPx * 2);
|
||||
// auto 模式下加宽度上限:超长 title 撑爆布局时,按 labelAutoMaxWidth 截断(rpx)
|
||||
// 上限内 ellipsis 截断,保证控件区有足够空间;上限外也不会让 label 占满整行
|
||||
const maxWidthRpx = parseInt(this.config.labelAutoMaxWidth) || 200;
|
||||
if (widthRpx > maxWidthRpx) widthRpx = maxWidthRpx;
|
||||
this.maxLabelWidth = widthRpx;
|
||||
// 宽度变了,需要把全局 nameWidthStyle 重新合到每项 _labelStyle 里
|
||||
this.recomputeItemStyles();
|
||||
},
|
||||
@@ -961,6 +980,12 @@ export default {
|
||||
--submit-bg-color: #ff4544;
|
||||
--placeholder-color: #ddd;
|
||||
--placeholder-font-size: 28rpx;
|
||||
// 输入框视觉增强(边框 / 背景 / 聚焦 / label 字重)
|
||||
--input-border-color: #e5e7eb;
|
||||
--input-bg-color: #f9fafb;
|
||||
--input-focus-border-color: #ff4544;
|
||||
--input-focus-bg-color: #ffffff;
|
||||
--label-font-weight: 600;
|
||||
--show-row-divider: 1;
|
||||
|
||||
// 与后端 form-preview-wrap.no-divider-all 对齐:整组隐藏所有行分割线
|
||||
@@ -1012,13 +1037,13 @@ export default {
|
||||
&.vertical-layout {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
|
||||
.name {
|
||||
width: 100%;
|
||||
margin-bottom: 8rpx;
|
||||
margin-bottom: var(--label-gap, 16rpx);
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1068,7 +1093,7 @@ export default {
|
||||
text-align: left;
|
||||
font-size: var(--item-label-font-size, var(--label-font-size, 28rpx));
|
||||
color: var(--item-label-color, var(--label-color, #1f2937));
|
||||
font-weight: 500;
|
||||
font-weight: var(--item-label-font-weight, var(--label-font-weight, 600));
|
||||
letter-spacing: 0.2rpx;
|
||||
|
||||
text {
|
||||
@@ -1136,49 +1161,105 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
// H5 端 <input> 被 uni-app 编译为 <uni-input> 自定义组件,
|
||||
// 真实 <input> 是其子节点,需要 ::v-deep 穿透 scoped 才能命中
|
||||
::v-deep input {
|
||||
font-size: var(--label-font-size, 28rpx);
|
||||
text-align: left;
|
||||
height: var(--input-height, 60rpx);
|
||||
border: none;
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
border-radius: var(--input-radius, 10rpx);
|
||||
line-height: var(--input-height, 60rpx);
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
padding: 0 12rpx;
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
color: var(--label-color, #1f2937);
|
||||
transition: all 0.3s ease;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
&:focus {
|
||||
background: transparent;
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
|
||||
|
||||
&::placeholder {
|
||||
color: var(--placeholder-color, #ddd);
|
||||
font-size: var(--placeholder-font-size, 28rpx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 非 H5 端(小程序 / 鸿蒙 / App)<input> 是直接原生元素,普通选择器即可
|
||||
input {
|
||||
font-size: var(--label-font-size, 28rpx);
|
||||
text-align: left;
|
||||
height: var(--input-height, 60rpx);
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
border-radius: var(--input-radius, 10rpx);
|
||||
line-height: var(--input-height, 60rpx);
|
||||
padding: 0 12rpx;
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
color: var(--label-color, #1f2937);
|
||||
transition: all 0.3s ease;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: var(--placeholder-color, #ddd);
|
||||
font-size: var(--placeholder-font-size, 28rpx);
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep textarea {
|
||||
font-size: var(--label-font-size, 28rpx);
|
||||
width: 100%;
|
||||
min-height: 120rpx;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
border-radius: var(--input-radius, 10rpx);
|
||||
padding: 12rpx;
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
color: var(--label-color, #1f2937);
|
||||
transition: all 0.3s ease;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
|
||||
&:focus {
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: var(--placeholder-color, #ddd);
|
||||
font-size: var(--placeholder-font-size, 28rpx);
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: var(--label-font-size, 28rpx);
|
||||
width: 100%;
|
||||
min-height: 120rpx;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
border: none;
|
||||
border: 1rpx solid var(--input-border-color, #e5e7eb);
|
||||
border-radius: var(--input-radius, 10rpx);
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
padding: 12rpx;
|
||||
background: var(--input-bg-color, #f9fafb);
|
||||
color: var(--label-color, #1f2937);
|
||||
transition: all 0.3s ease;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
|
||||
|
||||
&:focus {
|
||||
background: transparent;
|
||||
background: var(--input-focus-bg-color, #ffffff);
|
||||
border-color: var(--input-focus-border-color, #ff4544);
|
||||
}
|
||||
|
||||
|
||||
&::placeholder {
|
||||
color: var(--placeholder-color, #ddd);
|
||||
font-size: var(--placeholder-font-size, 28rpx);
|
||||
|
||||
Reference in New Issue
Block a user