ChillCMS Design System Component

Ark Combobox Popup Input

Thành phần chọn dạng nút bấm kích hoạt (Trigger Button) kết hợp @ark-ui/react/popover và ô tìm kiếm chuyên dụng bên trong popup. Hỗ trợ tìm kiếm tiếng Việt không dấu, tìm kiếm ngữ nghĩa theo mảng keywords, điều hướng phím tắt và tùy biến toàn diện cả nút bấm kích hoạt lẫn từng dòng gợi ý.

1. Ví dụ cơ bản (Basic Popup Input)Phổ biến nhất

Nút bấm gọn gàng hiển thị lựa chọn hiện tại, bấm mở popover tìm kiếm chuyên dụng

Bấm vào nút trigger để mở hộp tìm kiếm, nhập từ khóa lọc và nhấn Enter hoặc click để chọn.

Múi giờ đang chọn:Asia/Ho_Chi_Minh
Mô hình Trigger Button + Internal Search

Khác với Combobox truyền thống (người dùng gõ trực tiếp vào ô input), ArkComboboxPopupInput giữ giao diện gọn gàng như một nút bấm Select chuẩn. Khi mở ra, một ô tìm kiếm chuyên dụng tự động nhận tiêu điểm (focus), giúp giao diện thanh thoát và tiết kiệm không gian toolbar.

<ArkComboboxPopupInput
  options={timezones}
  value={timezone}
  onChange={(val) => setTimezone(val)}
  placeholder="Chọn múi giờ..."
  searchPlaceholder="Tìm kiếm..."
/>

2. Tìm kiếm tiếng Việt không dấu & Từ khóa mở rộngTiện lợi cao

Tìm kiếm chính xác với tiếng Việt không dấu và hỗ trợ từ khóa ngữ nghĩa keywords

Hỗ trợ tìm kiếm theo cả tiếng Việt có dấu, không dấu và các từ khóa phụ trong mảng keywords.

Tỉnh/thành đã chọn:TP. Hồ Chí Minh
Mã hành chính:79
Sức mạnh tìm kiếm ngữ nghĩa

Mỗi option có thể chứa mảng keywords. Hàm lọc nội bộ filterOption sẽ nối label, value và các từ khóa lại, chuẩn hóa bằng tiện ích removeAccents() giúp trải nghiệm gõ phím cực kỳ tự nhiên.

const options = [
  { 
    label: 'TP. Hồ Chí Minh', 
    value: '79', 
    keywords: ['SG', 'TPHCM', 'Sai Gon', 'Mien Nam', '028'] 
  },
  { 
    label: 'Hà Nội', 
    value: '01', 
    keywords: ['HN', 'Thu do', 'Mien Bac', '024'] 
  },
];

3. Tùy biến giao diện mục hiển thị (renderItemContent)

Hiển thị avatar, tên, email và badge phòng ban sinh động cho từng mục

Thành viên đang chọn:
Nguyễn Văn An(Lead Architect - Kỹ thuật)
Tùy biến với `renderItemContent`

Thuộc tính renderItemContent(option) cho phép bạn trả về bất kỳ cấu trúc JSX nào cho từng dòng mục gợi ý trong popup, bao gồm avatar, icon, badge hoặc thông tin phụ nhiều dòng.

<ArkComboboxPopupInput
  options={members}
  value={selectedId}
  renderItemContent={(opt) => (
    <div className="flex items-center gap-3">
      <Avatar initials={opt.initials} />
      <div>
        <p className="font-semibold">{opt.name}</p>
        <p className="text-2xs">{opt.role}</p>
      </div>
    </div>
  )}
/>

4. Tùy biến nút kích hoạt (renderTriggerLabel)Tùy biến cao

Biến nút trigger thành pill trạng thái màu sắc phong cách Notion / Linear

Mã trạng thái:in_progress
Biến hóa nút bấm với `renderTriggerLabel`

Nhờ renderTriggerLabel(selectedOption), bạn có thể biến nút kích hoạt thành thẻ pill màu sắc, biểu tượng trạng thái hoặc badge chuyên nghiệp phong cách Notion / Linear mà không làm thay đổi logic bên trong.

<ArkComboboxPopupInput
  options={taskStatuses}
  value={status}
  renderTriggerLabel={(selected) => (
    <span className={selected?.badgeClass}>
      <span className={selected?.dotClass} />
      {selected?.label}
    </span>
  )}
/>

5. Điều khiển bằng bàn phím (Keyboard Navigation)

Hỗ trợ phím mũi tên lên/xuống duyệt nhanh danh sách và phím Enter để chọn

Trợ năng & Phím tắt tương tác
ArrowDown (↓)

Di chuyển highlight xuống mục tiếp theo.

ArrowUp (↑)

Di chuyển highlight lên mục phía trên.

Enter (↵)

Chọn mục đang được highlight và đóng popover.

6. Phân loại lớp CSS tùy biến & Mục vô hiệu hóa

Gán class màu sắc riêng cho từng tùy chọn và vô hiệu hóa các mục không khả dụng

Mục Xuất bản Facebookdisabled: true và không thể click. Mục Xóa vĩnh viễn có class màu đỏ riêng biệt.

Thao tác đã chọn:null
Sử dụng `getItemClassName`

Hàm callback getItemClassName(option) cho phép gán class Tailwind tùy biến dựa trên thuộc tính của từng option, rất hữu ích cho các menu ngữ cảnh chứa hành động cảnh báo hoặc nguy hiểm.

<ArkComboboxPopupInput
  options={actions}
  getItemClassName={(opt) =>
    opt.value === 'delete_permanent'
      ? 'text-destructive hover:bg-destructive/10'
      : undefined
  }
/>

7. Trạng thái điều khiển (Controlled, Readonly, Disabled)

Đồng bộ hai chiều với React state và hỗ trợ các trạng thái chỉ đọc, vô hiệu hóa

State hiện thời:Asia/Tokyo
Đồng bộ 2 chiều (2-way Binding)

Khi truyền prop value, thành phần hoạt động ở chế độ Controlled hoàn toàn. Mọi thay đổi từ click, phím Enter đều kích hoạt onChange(nextValue, selectedOption) để cập nhật state đồng bộ.

8. Kích thước chuẩn ControlSize (Size Variants: xs, sm, md, lg)ControlSize Token

Hỗ trợ cả 4 kích thước chuẩn của ChillCMS, căn chỉnh thẳng hàng hoàn hảo với Input và Button

Chọn kích thước tương tác:
Chiều cao: 36pxCỡ chữ: 14px (text-sm)
Căn chỉnh thẳng hàng hoàn hảo (ControlSize: MD)
36px

Khi đặt cùng hàng với InputButton có cùng size="md", tất cả đều có chiều cao, khoảng đệm và bo góc đồng bộ 100%.

Size xs28px

Kích thước siêu gọn, thích hợp cho toolbar, ô lọc nhỏ gọn hoặc bảng dữ liệu dày đặc.

Size sm32px

Thích hợp cho khu vực bộ lọc (filter bar), thanh công cụ bảng hoặc form thu nhỏ.

Size mdDefault36px

Kích thước chuẩn cho phần lớn form nhập liệu, modal và giao diện quản trị.

Size lg44px

Kích thước lớn nổi bật, tối ưu cho hero section, form tìm kiếm chính hoặc màn hình cảm ứng.

9. Chọn nhiều phần tử (Multiple Selection)Nâng cao

Chọn nhiều mục với thẻ chip trực quan trên nút bấm, hỗ trợ xóa nhanh và giữ popup mở khi chọn

Số lượng đã chọn:3 / 12
ReactTypeScriptTailwind CSS

Dùng renderTriggerLabel để thay thế danh sách chip bằng badge số lượng gọn gàng nếu trigger cần kích thước cố định.

Cơ chế hoạt động khi chọn nhiều (Multiple = true)
  • Click vào mục chưa chọn sẽ thêm vào mảng; click vào mục đã chọn sẽ bỏ chọn (toggle).
  • Popup vẫn mở liên tục để bạn lọc từ khóa và chọn nhiều mục kế tiếp một cách nhanh chóng mà không bị gián đoạn.
  • Người dùng có thể xóa trực tiếp từng thẻ chip ngay trên trigger bằng icon × mà không cần mở popup.
<ArkComboboxPopupInput
  multiple
  options={skills}
  value={selectedSkills}
  onChange={(values, options) => setSelectedSkills(values)}
  placeholder="Chọn kỹ năng..."
/>

10. Bảng tra cứu thuộc tính (Props Reference)

Thuộc tínhKiểu dữ liệuMặc địnhMô tả
optionsArkComboboxPopupInputOption[]Bắt buộcDanh sách các tùy chọn gồm label, value, keywords, disabled.
valueOptionValue | OptionValue[] | nullundefinedGiá trị hiện tại ở chế độ Controlled (dạng đơn hoặc mảng khi multiple).
defaultValueOptionValue | OptionValue[] | nullnull / []Giá trị khởi tạo ban đầu ở chế độ Uncontrolled.
size'xs' | 'sm' | 'md' | 'lg''md'Kích thước chuẩn theo hệ thống token ControlSize (xs: 28px, sm: 32px, md: 36px, lg: 44px).
multiplebooleanfalseBật chế độ chọn nhiều phần tử. Giá trị nhận và trả về dạng mảng.
closeOnSelectboolean!multipleTự động đóng popup sau khi chọn một mục (mặc định true cho đơn chọn, false cho đa chọn).
chipClassNamestringundefinedClass CSS tùy biến cho thẻ chip/tag hiển thị trên nút trigger khi ở chế độ multiple.
placeholderstring'Chọn...'Văn bản gợi ý hiển thị trên nút trigger khi chưa chọn mục nào.
searchPlaceholderstring'Tìm kiếm...'Văn bản gợi ý hiển thị bên trong ô tìm kiếm của popover.
renderTriggerLabel(selectedOption) => ReactNodeundefinedHàm tùy biến nội dung JSX hiển thị trên nút trigger khi đã chọn (nhận mảng khi multiple).
renderItemContent(option) => ReactNodeundefinedHàm tùy biến nội dung JSX cho từng mục trong danh sách gợi ý.
getItemClassName(option) => string | undefinedundefinedHàm gán class CSS động cho từng dòng tùy chọn theo dữ liệu item.
autoHighlightbooleantrueTự động highlight mục đang chọn hoặc mục đầu tiên khi mở popover.
disabledbooleanfalseVô hiệu hóa toàn bộ tương tác mở popover của nút trigger.
readOnlybooleanfalseKhóa không cho phép chọn mục mới khi đang mở popup.
positioningPopoverRootProps['positioning']{ placement: 'bottom-start', sameWidth: true, gutter: 4 }Tùy biến cấu hình vị trí thả xuống (placement, offset, sameWidth, fitViewport).
onChangeArkComboboxPopupInputChangeHandlerundefinedCallback khi giá trị thay đổi, nhận (value, selectedOption, eventDetails).
© 2026. FlatVn All rights reserved. Version 4.3.40