# ComboBox · HeroUI

> A combo box combines a text input with a listbox, allowing users to filter a list of options to items matching a query

- Page: https://jiguang132.com/systems/heroui/docs/components/combo-box
- Based on: HeroUI documentation (Apache-2.0) @ 60edd8ed751b1d2a270623fbb182bbcfa8baa9af

## Import

```tsx
import { ComboBox } from '@heroui/react';
```

### Usage


> Example `combo-box-default`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Anatomy

Import the ComboBox component and access all parts using dot notation.

```tsx
import { ComboBox, Input, Label, Description, Header, ListBox, Separator } from '@heroui/react';

export default () => (
  <ComboBox>
    <Label />
    <ComboBox.InputGroup>
      <Input />
      <ComboBox.Trigger />
    </ComboBox.InputGroup>
    <Description />
    <ComboBox.Popover>
      <ListBox>
        <ListBox.Item>
          <Label />
          <Description />
          <ListBox.ItemIndicator />
        </ListBox.Item>
        <ListBox.Section>
          <Header />
          <ListBox.Item>
            <Label />
          </ListBox.Item>
        </ListBox.Section>
      </ListBox>
    </ComboBox.Popover>
  </ComboBox>
)
```

### With Description


> Example `combo-box-with-description`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### With Sections


> Example `combo-box-with-sections`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### With Disabled Options


> Example `combo-box-with-disabled-options`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Custom Indicator


> Example `combo-box-custom-indicator`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Required


> Example `combo-box-required`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Custom Value


> Example `combo-box-custom-value`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Controlled


> Example `combo-box-controlled`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Controlled Input Value


> Example `combo-box-controlled-input-value`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Asynchronous Loading


> Example `combo-box-asynchronous-loading`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Custom Filtering


> Example `combo-box-custom-filtering`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Allows Custom Value


> Example `combo-box-allows-custom-value`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Disabled


> Example `combo-box-disabled`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Default Selected Key


> Example `combo-box-default-selected-key`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Full Width


> Example `combo-box-full-width`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### In Surface

When used inside a [Surface](/systems/heroui/docs/components/surface) component, use `variant="secondary"` to apply the lower emphasis variant suitable for surface backgrounds.


> Example `combo-box-on-surface`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Menu Trigger

Use the `menuTrigger` prop to control when the popover opens:

- `focus` (default): popover opens when the user focuses the input
- `input`: popover opens when the user edits the input text
- `manual`: popover only opens when the user presses the trigger button or uses the arrow keys


> Example `combo-box-menu-trigger`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


### Custom Render Function


> Example `combo-box-custom-render-function`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/combo-box


## Styling

### Passing Tailwind CSS classes

```tsx
import { ComboBox, Input } from '@heroui/react';

function CustomComboBox() {
  return (
    <ComboBox className="w-full">
      <Label>Favorite Animal</Label>
      <ComboBox.InputGroup className="border rounded-lg p-2 bg-surface">
        <Input placeholder="Search animals..." />
        <ComboBox.Trigger className="text-muted" />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox>
          <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
            Item 1
          </ListBox.Item>
        </ListBox>
      </ComboBox.Popover>
    </ComboBox>
  );
}
```

### Customizing the component classes

To customize the ComboBox component classes, you can use the `@layer components` directive.
  
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).

```css
@layer components {
  .combo-box {
    @apply flex flex-col gap-1;
  }

  .combo-box__input-group {
    @apply relative inline-flex items-center;
  }

  .combo-box__trigger {
    @apply absolute right-0 text-muted;
  }

  .combo-box__popover {
    @apply rounded-lg border border-border bg-surface p-2;
  }
}
```

HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.

### CSS Classes

The ComboBox component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/combo-box.css)):

#### Base Classes
- `.combo-box` - Base ComboBox container
- `.combo-box__input-group` - Container for the input and trigger button
- `.combo-box__trigger` - The button that triggers the popover
- `.combo-box__popover` - The popover container

#### State Classes
- `.combo-box[data-invalid="true"]` - Invalid state
- `.combo-box[data-disabled="true"]` - Disabled ComboBox state
- `.combo-box__trigger[data-focus-visible="true"]` - Focused trigger state
- `.combo-box__trigger[data-disabled="true"]` - Disabled trigger state
- `.combo-box__trigger[data-open="true"]` - Open trigger state

### Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

- **Hover**: `:hover` or `[data-hovered="true"]` on trigger
- **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on trigger
- **Disabled**: `:disabled` or `[data-disabled="true"]` on ComboBox
- **Open**: `[data-open="true"]` on trigger

## API Reference

### ComboBox Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `inputValue` | `string` | - | Current input value (controlled) |
| `defaultInputValue` | `string` | - | Default input value (uncontrolled) |
| `onInputChange` | `(value: string) => void` | - | Handler called when the input value changes |
| `selectedKey` | `Key \| null` | - | Current selected key (controlled) |
| `defaultSelectedKey` | `Key \| null` | - | Default selected key (uncontrolled) |
| `onSelectionChange` | `(key: Key \| null) => void` | - | Handler called when the selection changes |
| `items` | `Iterable` | - | The items to display in the listbox |
| `disabledKeys` | `Iterable` | - | Keys of disabled items |
| `defaultFilter` | `(text: string, inputValue: string) => boolean` | - | Custom filter function for filtering items |
| `isDisabled` | `boolean` | - | Whether the ComboBox is disabled |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed by the user |
| `isRequired` | `boolean` | - | Whether user input is required |
| `isInvalid` | `boolean` | - | Whether the ComboBox value is invalid |
| `validate` | `(value: ComboBoxValidationValue) => ValidationError \| true \| null \| undefined` | - | A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if `validationBehavior="native"`. For realtime validation, use the `isInvalid` prop instead |
| `validationBehavior` | `"native" \| "aria"` | `"native"` | Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA |
| `name` | `string` | - | The name of the input, used when submitting an HTML form |
| `form` | `string` | - | The id of a `<form>` element to associate the input with |
| `formValue` | `"text" \| "key"` | `"key"` | Whether the text or key of the selected item is submitted as part of an HTML form. When `allowsCustomValue` is `true`, this option does not apply and the text is always submitted |
| `autoComplete` | `string` | - | Describes the type of autocomplete functionality |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render |
| `allowsCustomValue` | `boolean` | - | Whether the ComboBox allows custom values not in the list |
| `allowsEmptyCollection` | `boolean` | - | Whether the ComboBox allows an empty collection |
| `menuTrigger` | `"focus" \| "input" \| "manual"` | `"focus"` | The interaction required to display the ComboBox menu |
| `shouldFocusWrap` | `boolean` | - | Whether keyboard navigation is circular |
| `fullWidth` | `boolean` | `false` | Whether the ComboBox should take full width of its container |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | ComboBox content or render function |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, ComboBoxRenderProps>` | - | Overrides the default DOM element with a custom render function.|

### ComboBox.InputGroup Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode` | - | InputGroup content |

### ComboBox.Trigger Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode` | - | Custom trigger content |

### ComboBox.Popover Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placement` | `"bottom" \| "bottom left" \| "bottom right" \| "bottom start" \| "bottom end" \| "top" \| "top left" \| "top right" \| "top start" \| "top end" \| "left" \| "left top" \| "left bottom" \| "start" \| "start top" \| "start bottom" \| "right" \| "right top" \| "right bottom" \| "end" \| "end top" \| "end bottom"` | `"bottom"` | Placement of the popover relative to the trigger |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode` | - | Content children |

### RenderProps

When using render functions with ComboBox, these values are provided:

| Prop | Type | Description |
|------|------|-------------|
| `state` | `ComboBoxState` | The state of the ComboBox |
| `inputValue` | `string` | The current input value |
| `selectedKey` | `Key \| null` | The currently selected key |
| `selectedItem` | `Node \| null` | The currently selected item |

## Examples

### Basic Usage

```tsx
import { ComboBox, Input, Label, ListBox } from '@heroui/react';

<ComboBox className="w-[256px]">
  <Label>Favorite Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
      <ListBox.Item id="dog" textValue="Dog">
        Dog
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
</ComboBox>
```

### With Sections

```tsx
import { ComboBox, Input, Label, ListBox, Header, Separator } from '@heroui/react';

<ComboBox className="w-[256px]">
  <Label>Country</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search countries..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Section>
        <Header>North America</Header>
        <ListBox.Item id="usa" textValue="United States">
          United States
          <ListBox.ItemIndicator />
        </ListBox.Item>
      </ListBox.Section>
      <Separator />
      <ListBox.Section>
        <Header>Europe</Header>
        <ListBox.Item id="uk" textValue="United Kingdom">
          United Kingdom
          <ListBox.ItemIndicator />
        </ListBox.Item>
      </ListBox.Section>
    </ListBox>
  </ComboBox.Popover>
</ComboBox>
```

### Controlled Selection

```tsx
import type { Key } from '@heroui/react';

import { ComboBox, Input, Label, ListBox } from '@heroui/react';
import { useState } from 'react';

function ControlledComboBox() {
  const [selectedKey, setSelectedKey] = useState<Key | null>('cat');

  return (
    <ComboBox
      className="w-[256px]"
      selectedKey={selectedKey}
      onSelectionChange={setSelectedKey}
    >
      <Label>Animal</Label>
      <ComboBox.InputGroup>
        <Input placeholder="Search animals..." />
        <ComboBox.Trigger />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox>
          <ListBox.Item id="cat" textValue="Cat">
            Cat
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="dog" textValue="Dog">
            Dog
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </ComboBox.Popover>
    </ComboBox>
  );
}
```

### Controlled Input Value

```tsx
import { ComboBox, Input, Label, ListBox } from '@heroui/react';
import { useState } from 'react';

function ControlledInputComboBox() {
  const [inputValue, setInputValue] = useState('');

  return (
    <ComboBox
      className="w-[256px]"
      inputValue={inputValue}
      onInputChange={setInputValue}
    >
      <Label>Search</Label>
      <ComboBox.InputGroup>
        <Input placeholder="Type to search..." />
        <ComboBox.Trigger />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox>
          <ListBox.Item id="cat" textValue="Cat">
            Cat
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="dog" textValue="Dog">
            Dog
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </ComboBox.Popover>
    </ComboBox>
  );
}
```

### Asynchronous Loading

```tsx
import { Collection, ComboBox, EmptyState, Input, Label, ListBox, ListBoxLoadMoreItem, Spinner } from '@heroui/react';
import { useAsyncList } from '@react-stately/data';

interface Character {
  name: string;
}

function AsyncComboBox() {
  const list = useAsyncList<Character>({
    async load({cursor, filterText, signal}) {
      const res = await fetch(
        cursor || `https://swapi.py4e.com/api/people/?search=${filterText}`,
        { signal }
      );
      const json = await res.json();

      return {
        items: json.results,
        cursor: json.next,
      };
    },
  });

  return (
    <ComboBox
      allowsEmptyCollection
      className="w-[256px]"
      inputValue={list.filterText}
      onInputChange={list.setFilterText}
    >
      <Label>Pick a Character</Label>
      <ComboBox.InputGroup>
        <Input placeholder="Star Wars characters..." />
        <ComboBox.Trigger />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox renderEmptyState={() => <EmptyState />}>
          <Collection items={list.items}>
            {(item) => (
              <ListBox.Item id={item.name} textValue={item.name}>
                {item.name}
                <ListBox.ItemIndicator />
              </ListBox.Item>
            )}
          </Collection>
          <ListBoxLoadMoreItem
            isLoading={list.loadingState === "loadingMore"}
            onLoadMore={list.loadMore}
          >
            <div className="flex items-center justify-center gap-2 py-2">
              <Spinner size="sm" />
              <span className="text-sm text-muted">Loading more...</span>
            </div>
          </ListBoxLoadMoreItem>
        </ListBox>
      </ComboBox.Popover>
    </ComboBox>
  );
}
```

### Custom Filtering

```tsx
import { ComboBox, Input, Label, ListBox } from '@heroui/react';

<ComboBox
  className="w-[256px]"
  defaultFilter={(text, inputValue) => {
    if (!inputValue) return true;
    return text.toLowerCase().includes(inputValue.toLowerCase());
  }}
>
  <Label>Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
      <ListBox.Item id="dog" textValue="Dog">
        Dog
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
</ComboBox>
```

### Menu Trigger

Control when the popover opens using the `menuTrigger` prop:

```tsx
import { ComboBox, Description, Input, Label, ListBox } from '@heroui/react';

// Opens on focus (default)
<ComboBox className="w-[256px]" menuTrigger="focus">
  <Label>Favorite Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
  <Description>Popover opens when the input is focused</Description>
</ComboBox>

// Opens when typing
<ComboBox className="w-[256px]" menuTrigger="input">
  <Label>Favorite Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
  <Description>Popover opens when the user edits the input text</Description>
</ComboBox>

// Opens only manually
<ComboBox className="w-[256px]" menuTrigger="manual">
  <Label>Favorite Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
  <Description>Popover only opens when the trigger button is pressed or arrow keys are used</Description>
</ComboBox>
```

### Form Value

Use the `formValue` prop to control whether the selected item's key or text is submitted in forms:

```tsx
import { Button, ComboBox, FieldError, Form, Input, Label, ListBox } from '@heroui/react';

function FormValueExample() {
  const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    console.log('Submitted value:', formData.get('animal')); // Will be "cat" (the key)
  };

  return (
    <Form onSubmit={onSubmit}>
      {/* Submits the key (default) */}
      <ComboBox name="animal" formValue="key" isRequired>
        <Label>Animal</Label>
        <ComboBox.InputGroup>
          <Input placeholder="Select an animal..." />
          <ComboBox.Trigger />
        </ComboBox.InputGroup>
        <ComboBox.Popover>
          <ListBox>
            <ListBox.Item id="cat" textValue="Cat">
              Cat
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="dog" textValue="Dog">
              Dog
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </ComboBox.Popover>
        <FieldError />
      </ComboBox>

      {/* Submits the text */}
      <ComboBox name="animal-text" formValue="text" isRequired>
        <Label>Animal (text)</Label>
        <ComboBox.InputGroup>
          <Input placeholder="Select an animal..." />
          <ComboBox.Trigger />
        </ComboBox.InputGroup>
        <ComboBox.Popover>
          <ListBox>
            <ListBox.Item id="cat" textValue="Cat">
              Cat
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="dog" textValue="Dog">
              Dog
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </ComboBox.Popover>
        <FieldError />
      </ComboBox>

      <Button type="submit">Submit</Button>
    </Form>
  );
}
```

### Validation Behavior

Control how validation is displayed using the `validationBehavior` prop:

```tsx
import { Button, ComboBox, FieldError, Form, Input, Label, ListBox } from '@heroui/react';

function ValidationExample() {
  return (
    <div className="space-y-8">
      {/* Native validation (default) - blocks form submission */}
      <Form>
        <ComboBox name="animal" isRequired validationBehavior="native">
          <Label>Animal (native validation)</Label>
          <ComboBox.InputGroup>
            <Input placeholder="Select an animal..." />
            <ComboBox.Trigger />
          </ComboBox.InputGroup>
          <ComboBox.Popover>
            <ListBox>
              <ListBox.Item id="cat" textValue="Cat">
                Cat
                <ListBox.ItemIndicator />
              </ListBox.Item>
            </ListBox>
          </ComboBox.Popover>
          <FieldError />
        </ComboBox>
        <Button type="submit">Submit</Button>
      </Form>

      {/* ARIA validation - shows errors in realtime, doesn't block submission */}
      <Form>
        <ComboBox name="animal-aria" isRequired validationBehavior="aria">
          <Label>Animal (ARIA validation)</Label>
          <ComboBox.InputGroup>
            <Input placeholder="Select an animal..." />
            <ComboBox.Trigger />
          </ComboBox.InputGroup>
          <ComboBox.Popover>
            <ListBox>
              <ListBox.Item id="cat" textValue="Cat">
                Cat
                <ListBox.ItemIndicator />
              </ListBox.Item>
            </ListBox>
          </ComboBox.Popover>
          <FieldError />
        </ComboBox>
        <Button type="submit">Submit</Button>
      </Form>
    </div>
  );
}
```

### Custom Validation

Use the `validate` prop to add custom validation logic:

```tsx
import { ComboBox, FieldError, Input, Label, ListBox } from '@heroui/react';

function CustomValidationExample() {
  return (
    <ComboBox
      className="w-[256px]"
      isRequired
      validate={(value) => {
        if (!value || value.selectedKey === null) {
          return 'Please select an animal';
        }
        if (value.selectedKey === 'snake') {
          return 'Snakes are not allowed';
        }
        return true;
      }}
    >
      <Label>Favorite Animal</Label>
      <ComboBox.InputGroup>
        <Input placeholder="Search animals..." />
        <ComboBox.Trigger />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox>
          <ListBox.Item id="cat" textValue="Cat">
            Cat
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="dog" textValue="Dog">
            Dog
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="snake" textValue="Snake">
            Snake
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </ComboBox.Popover>
      <FieldError />
    </ComboBox>
  );
}
```

### Read Only

Use the `isReadOnly` prop to make the comboBox read-only:

```tsx
import { ComboBox, Input, Label, ListBox } from '@heroui/react';

<ComboBox className="w-[256px]" isReadOnly defaultSelectedKey="cat">
  <Label>Favorite Animal</Label>
  <ComboBox.InputGroup>
    <Input placeholder="Search animals..." />
    <ComboBox.Trigger />
  </ComboBox.InputGroup>
  <ComboBox.Popover>
    <ListBox>
      <ListBox.Item id="cat" textValue="Cat">
        Cat
        <ListBox.ItemIndicator />
      </ListBox.Item>
      <ListBox.Item id="dog" textValue="Dog">
        Dog
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </ComboBox.Popover>
</ComboBox>
```

## Accessibility

The ComboBox component implements the ARIA comboBox pattern and provides:

- Full keyboard navigation support
- Screen reader announcements for selection changes and input changes
- Proper focus management
- Support for disabled states
- Typeahead search functionality
- HTML form integration
- Support for custom values

For more information, see the [React Aria ComboBox documentation](https://react-spectrum.adobe.com/react-aria/ComboBox.html).

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
