You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整自定义Lookup组件的输入宽度与标签间距匹配Lightning Input?

问题

我开发了一个LWC(Lightning Web Component),其中包含筛选区域,大部分筛选项为标准lightning-input组件,但有两个是自定义Lookup组件。尽管已部分应用SLDS CSS类,仍无法让自定义组件与标准组件对齐:标准lightning-input对齐正常,但自定义Lookup组件的输入框更宽,且标签与输入框间距过小。

Lookup组件的HTML代码如下:

<template>
<label if:true={label} class={getLabelClass} for="combobox">
    <abbr if:true={required} title="required" class="slds-required">*</abbr>
    {label}
</label>
<div class={getContainerClass}>
    <div class={getDropdownClass} aria-expanded={hasResults} aria-haspopup="listbox" role="combobox">
        <!-- Search input start -->
        <div class={getComboboxClass} role="none">
            <!-- Text input -->


            <template if:false={useInput}>

                <slot 
                aria-autocomplete="list"
                aria-controls="listbox"
                role="textbox"
                id="combobox"
                onchange={handleInput}
                oninput={handleInput}
                onkeydown={handleKeyDown}
                onslotchange={handleSlotChange}
                ></slot>
            </template>
            <template if:true={useInput}>
                <input onfocus={handleFocus}
                       onblur={handleBlur} 
                       oninput={handleInput} 
                       class="slds-input" 
                       style="color: black;"/>
            </template>    
              
            
                <template if:true={isLookup}>
                    <!-- Search icon -->
                      
                    <lightning-icon
                    icon-name="utility:search"
                    size="x-small"
                    alternative-text="Search icon"
                    class={getSearchIconClass}
                    ></lightning-icon>
                    
                    <button
                    title="Remove selected option"
                    type="button"
                    onclick={handleClearSelection}
                    class={getClearSelectionButtonClass}
                    disabled={disabled}
                    >
                    <lightning-icon
                    icon-name="utility:close"
                    size="x-small"
                    alternative-text="Remove selected option"
                    class="slds-button__icon"
                    ></lightning-icon>
                    </button>
                </template>
            </div>
       
        <!-- Search input end -->
        
        <!-- Result list box start -->
        <div
        id="listbox"
        role="listbox"
        >
        <ul class={getListboxClass} role="presentation">
                <!-- Spinner to display when waiting for results of search -->
                <div if:true={loading}>
                    <lightning-spinner variant="brand" alternative-text="Loading" size="small"></lightning-spinner>
                </div>

                <template for:each={_searchResults} for:item="result">
                    <li data-id={result.id} onmousedown={handleResultClick} class="slds-listbox__item" key={result.id} role="presentation">
                        <div class="slds-media slds-listbox__option slds-listbox__option_plain slds-media_small" role="option">
                            <c-lookup-result template={_template} result={result}></c-lookup-result>
                        </div>
                    </li>
                </template>
                <!-- Result list end -->

                <!-- No results start -->
                <template if:false={hasResults}>
                    <li role="presentation">
                        <span class="slds-media slds-listbox__option_entity" role="option">
                            <span if:false={loading} class="slds-media__body">No results.</span>
                            <span if:true={loading} class="slds-media__body">Loading...</span>
                        </span>
                    </li>
                </template>
                <!-- No results end -->

            </ul>
        </div>
        <!-- Result list box end -->
    </div>
</div>

</template>

当前场景下useInput为true。

相关getter方法代码如下:

get getContainerClass() {
    let css = 'slds-combobox_container'; // slds-has-inline-listbox  // sacado porque moleasta
    if (this._hasFocus && this.hasResults) {
        css += 'slds-has-input-focus ';
    }
    if (this.errors.length > 0) {
        css += 'has-custom-error';
    }
    return css;
}

get getDropdownClass() {
    let css = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click ';
    if (this._hasFocus && (this._currentConfig || this.loading)) {
        css += 'slds-is-open';
    }
    return css;
}

get getComboboxClass() {
    let css = 'slds-combobox__form-element slds-input-has-icon ';
    return css += this.hasSelection() ? 'slds-input-has-icon_left-right' : 'slds-input-has-icon_right';
}

get getListboxClass() {
    return (
        'slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid ' +
        (this.scrollAfterNItems ? 'slds-dropdown_length-with-icon-' + this.scrollAfterNItems : '')
    );
}

get getClearSelectionButtonClass() {
    return (
        'slds-button slds-button_icon slds-input__icon slds-input__icon_left ' +
        (this.hasSelection() ? '' : 'slds-hide')
    );
}

get getSearchIconClass() {
    let css = 'slds-input__icon slds-input__icon_right ';
    if (!this.isMultiEntry) {
        css += this.hasSelection() ? 'slds-hide' : '';
    }
    return css;
}

get getLabelClass() {
    return this.variant === VARIANT_LABEL_HIDDEN
        ? 'slds-form-element__label slds-assistive-text'
        : 'slds-form-element__label';
}

get input() {
    return this._input;
}

页面中使用组件的代码如下:

<template if:true={filters}>
    <div class="slds-grid slds-gutters">
        <div class="slds-col slds-size_1-of-2">
            <c-lwc-filter filter={filters.Nombre} input-variant="label-inline"></c-lwc-filter>
            <c-lwc-filter filter={filters.Codigo} input-variant="label-inline"></c-lwc-filter>
            <c-lwc-filter filter={filters.CodigoFabricante} input-variant="label-inline"></c-lwc-filter>
        </div>
        <div class="slds-col slds-size_1-of-2">
            <c-lwc-filter filter={filters.CodigoBarra} input-variant="label-inline"></c-lwc-filter>
            <div class="slds-form-element slds-form-element_horizontal">
                <c-lookup label="Familia" is-lookup=true use-input=true configs={configsFamilia} onremoveselection={removeSelection} data-name="_familiaId"></c-lookup>
            </div>
            <div class="slds-form-element slds-form-element_horizontal">
                <c-lookup label="Marca" is-lookup=true use-input=true configs={configsMarca} onremoveselection={removeSelection} data-name="_marcaId"></c-lookup>
            </div>
            <c-lwc-filter filter={filters.Modelo} input-variant="label-inline"></c-lwc-filter>
        </div>
    </div>
</template>

(其中c-lwc-filter组件内部使用lightning-input)

我已通过将自定义Lookup组件包裹在带有slds-form-element_horizontal类的div中实现标签横向排列,但输入框宽度和标签间距仍不符合要求。尝试过margin或padding调整,但无法适配所有屏幕尺寸。

请问如何让自定义Lookup组件与标准lightning-input样式完全一致,且适配所有屏幕尺寸?

解决方案

要让自定义Lookup和标准lightning-input完全对齐,需严格遵循SLDS的表单元素结构,调整以下几个关键点:

1. 完善表单元素层级结构

标准lightning-input在横向布局下会自动使用SLDS的表单嵌套结构,自定义Lookup需要匹配这个层级:

  • 将Lookup的标签和输入容器包裹在slds-form-element__control内
  • 外层保留slds-form-element,和父容器的slds-form-element_horizontal配合生效

修改Lookup的HTML结构:

<template>
  <div class="slds-form-element">
    <label if:true={label} class={getLabelClass} for="combobox">
        <abbr if:true={required} title="required" class="slds-required">*</abbr>
        {label}
    </label>
    <!-- 新增slds-form-element__control容器,匹配标准组件结构 -->
    <div class="slds-form-element__control">
      <div class={getContainerClass}>
          <div class={getDropdownClass} aria-expanded={hasResults} aria-haspopup="listbox" role="combobox">
              <!-- 原输入框代码保持不变 -->
              <div class={getComboboxClass} role="none">
                  <template if:true={useInput}>
                      <input onfocus={handleFocus}
                             onblur={handleBlur} 
                             oninput={handleInput} 
                             class="slds-input"/>
                  </template>
                  <!-- 原图标、按钮代码保持不变 -->
              </div>
              <!-- 原下拉列表代码保持不变 -->
          </div>
      </div>
    </div>
  </div>
</template>

2. 修正容器类,统一输入框宽度

当前getContainerClass存在类名拼接空格缺失的问题,且缺少控制宽度的类:

  • 添加slds-grow类,确保输入框和标准组件宽度一致
  • 补全类名拼接的空格,避免无效类名

修改getContainerClass:

get getContainerClass() {
    let css = 'slds-combobox_container slds-grow'; // 添加slds-grow控制宽度自适应
    if (this._hasFocus && this.hasResults) {
        css += ' slds-has-input-focus'; // 补全空格,避免类名拼接错误
    }
    if (this.errors.length > 0) {
        css += ' has-custom-error'; // 补全空格
    }
    return css;
}

3. 匹配横向布局的标签样式

标准横向表单的标签有固定宽度和间距,需给Lookup标签添加对应网格类:

  • 在Lookup组件中新增@api inputVariant属性,接收外部传入的布局类型
  • 修改getLabelClass逻辑,自动添加横向布局的标签类

修改getLabelClass:

// 先在组件中添加@api inputVariant;
get getLabelClass() {
    let baseClass = this.variant === VARIANT_LABEL_HIDDEN
        ? 'slds-form-element__label slds-assistive-text'
        : 'slds-form-element__label';
    // 匹配标准横向布局的标签宽度类
    if (this.inputVariant === 'label-inline' || this.inputVariant === 'horizontal') {
        baseClass += ' slds-col slds-size_1-of-4';
    }
    return baseClass;
}

使用Lookup时传入布局参数:

<div class="slds-form-element slds-form-element_horizontal">
    <c-lookup label="Familia" is-lookup=true use-input=true configs={configsFamilia} 
              onremoveselection={removeSelection} data-name="_familiaId"
              input-variant="label-inline"></c-lookup>
</div>

4. 移除内联样式,改用组件CSS

原输入框的style="color: black;"改用组件CSS文件设置,避免内联样式影响布局:

/* lookup.css */
.slds-input {
    color: black;
}

5. 保留下拉列表的自适应宽度

确保getListboxClass中的slds-dropdown_fluid类保留,让下拉列表宽度和输入框一致,适配所有屏幕尺寸。

完成以上修改后,自定义Lookup组件会完全遵循SLDS表单规范,和标准lightning-input在各种屏幕尺寸下保持对齐和样式一致。

内容的提问来源于stack exchange,提问作者joacoiudica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:45:36