fluent UI 中的Combobox如何在option的上面加一个input

fluent UI 9 中的Combobox如何在它自带的input框下面,option的上面,再加一个用于search的input框

会出现一个问题,点击search input框,可以触发input的onClick事件,但是无法获取焦点,焦点还在select的下拉框中

这种情况是由于 Combobox 的默认行为或者事件冒泡导致的。

解决方法:

bash 复制代码
const inputRef = React.useRef<any>(null);
 <Combobox
        aria-labelledby={comboId}
        placeholder="Select an animal"
        open={isOpen}
        onOpenChange={(event, data) => {
          setIsOpen(data.open);
          console.log(data.open, isOpen, 'setIsOpen');
        }}
        {...props}
        onClick={() => setIsOpen(true)} // 点击 Combobox 保持下拉框打开
      >
        <Input
          contentBefore={<SearchRegular />}
          ref={inputRef}
          onClick={(ev) => {
            ev.stopPropagation();
            inputRef.current?.focus();
            setIsOpen(true); // 点击 Input 保持下拉框打开
            console.log(ev, 'Input clicked');
          }}
        />
        {options.map((option) => (
          <Option key={option} disabled={option === 'Ferret'}>
            {option}
          </Option>
        ))}
      </Combobox>

首先在input的唯一可以触发的onClick方法中取消默认冒泡行为,(此时onFocus,onChange事件都不会触发)

然后强制设置焦点,在 onClick 事件中,手动将焦点设置到 Input 元素上,通过ref,走到这一步会发现点击input之后,下拉框消失了,这时候就要用到Combobox的open属性,点击input后,设置open的值一直是打开状态。使用onOpenChange,监听当点击其他地方时的监听事件。

这样就可以输入了,其他操作也会很流畅。

可以在官网链接测试
https://stackblitz.com/edit/9jdz2a-yxlsnb?file=src%2Fexample.tsx

完整代码

bash 复制代码
import * as React from 'react';
import {
  Combobox,
  makeStyles,
  Option,
  useId,
  Input,
} from '@fluentui/react-components';
import { SearchRegular } from '@fluentui/react-icons';
import type { ComboboxProps } from '@fluentui/react-components';

const useStyles = makeStyles({
  root: {
    // Stack the label above the field with a gap
    display: 'grid',
    gridTemplateRows: 'repeat(1fr)',
    justifyItems: 'start',
    gap: '2px',
    maxWidth: '400px',
  },
});

export const Default = (props: Partial<ComboboxProps>) => {
  const comboId = useId('combo-default');
  const [isOpen, setIsOpen] = React.useState(false);
  const options = ['Cat', 'Dog', 'Ferret', 'Fish', 'Hamster', 'Snake'];
  const styles = useStyles();
  const inputRef = React.useRef<any>(null);

  return (
    <div className={styles.root}>
      <label id={comboId}>Best pet</label>
      <Combobox
        aria-labelledby={comboId}
        placeholder="Select an animal"
        open={isOpen}
        onOpenChange={(event, data) => {
          setIsOpen(data.open);
          console.log(data.open, isOpen, 'setIsOpen');
        }}
        {...props}
        onClick={() => setIsOpen(true)} // 点击 Combobox 保持下拉框打开
      >
        <Input
          contentBefore={<SearchRegular />}
          ref={inputRef}
          onClick={(ev) => {
            ev.stopPropagation();
            inputRef.current?.focus();
            setIsOpen(true); // 点击 Input 保持下拉框打开
            console.log(ev, 'Input clicked');
          }}
        />
        {options.map((option) => (
          <Option key={option} disabled={option === 'Ferret'}>
            {option}
          </Option>
        ))}
      </Combobox>
    </div>
  );
};
相关推荐
朝朝辞暮i9 小时前
C++ 第 25 课:getter / setter + this
java·javascript·c++
蜗牛互联网9 小时前
Python接入Gemini 3.8 Flash实现票据视觉抽取与规则校验
java·javascript·网络·人工智能·python
xieter10 小时前
【技术精选】深入浅出现代前端渲染与性能优化实践指南 (2026-10-04)
前端·javascript
xieter10 小时前
【硬核实战】TypeScript Compiler API: Preserving Child Node Narrowing in Reusable Type Guards 🔧 (2026-10-03)
前端·javascript
xieter10 小时前
【硬核实战】React 19 useFormStatus Returning False? I Built a SubmitButton That Fixes It (2026-10-03)
前端·javascript
paopaokaka_luck12 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
Highcharts.js12 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
Helix25012 小时前
Electron、WebView 框架与 HTA 对比:桌面应用选型、安全性与现代替代方案
前端·javascript·electron·webview·vbscript·hta·本地html应用
Ikalus198813 小时前
三套 API 都告诉我成功了,浏览器一个字都没收到
javascript
Ikalus198813 小时前
计数器停在 0,我差点把一篇空摘要发出去
javascript