VVibeFlui

React Select

Generated UI previewADAPTERS

React Select field adapter

Select...
Select...

Role and Skills render through the @vibeflui/react-select adapter registered by createReactSelectPlugin().

Install:

BASH
npm install @vibeflui/react-select react-select

app/providers.tsx

TSX
import { FluiKitProvider } from "@vibeflui/core";
import { createReactSelectPlugin } from "@vibeflui/react-select";

const reactSelectPlugin = createReactSelectPlugin();

export function Providers({ children }: { children: React.ReactNode }) {
  return <FluiKitProvider plugins={[reactSelectPlugin]}>{children}</FluiKitProvider>;
}

schemas/users/select.schema.ts

TS
export const selectSchema = {
  resource: "users",
  form: {
    fields: [
      {
        name: "role",
        label: "Role",
        type: "select",
        adapter: "react-select",
        options: [
          { label: "Admin", value: "admin" },
          { label: "Editor", value: "editor" }
        ]
      }
    ]
  }
} as const;

The default plugin registers the react-select field adapter. The react-select-async and react-select-creatable keys are available for custom adapter maps passed to createReactSelectPlugin.

React Select table filter

Table filters do not use field.adapter. To render React Select in a table filter, use a custom filter component and reference it with filter.type: "custom" plus filter.component. This pattern imports react-select directly inside the filter component; the @vibeflui/react-select plugin is only needed for form field adapters.

components/vibeflui/filters/orders/OrderStatusReactSelectFilter.tsx

TSX
import Select from "react-select";

const statusOptions = [
  { label: "Paid", value: "paid" },
  { label: "Pending", value: "pending" },
  { label: "Failed", value: "failed" }
];

type OrderStatusReactSelectFilterProps = {
  value?: unknown;
  className?: string;
  onChange?: (value: unknown) => void;
};

export function OrderStatusReactSelectFilter({
  value,
  className,
  onChange
}: OrderStatusReactSelectFilterProps) {
  const selected =
    statusOptions.find((option) => String(option.value) === String(value)) ?? null;

  return (
    <div className={className}>
      <Select
        isClearable
        options={statusOptions}
        value={selected}
        classNamePrefix="fluikit-react-select"
        placeholder="Status"
        onChange={(next) => onChange?.(next?.value)}
      />
    </div>
  );
}

schemas/orders/react-select-table-filter.schema.ts

TS
export const reactSelectTableFilterSchema = {
  resource: "orders",
  table: {
    columns: ["orderNo", "customer", "status", "total"],
    filters: [
      {
        key: "status",
        label: "Status",
        type: "custom",
        component: "OrderStatusReactSelectFilter"
      }
    ]
  },
  registry: {
    components: ["OrderStatusReactSelectFilter"]
  }
} as const;

app/providers.tsx

TSX
import { FluiKitProvider, createRegistry } from "@vibeflui/core";
import { OrderStatusReactSelectFilter } from "@/components/vibeflui/filters/orders/OrderStatusReactSelectFilter";

const registry = createRegistry({
  components: {
    OrderStatusReactSelectFilter
  }
});

export function Providers({ children }: { children: React.ReactNode }) {
  return <FluiKitProvider registry={registry}>{children}</FluiKitProvider>;
}