Link

A single-record picker for a Frappe doctype. Composes Combobox and fetches its options directly from frappe.desk.search.search_link — pick a doctype, and the rest works.

Simple

A bare picker. v-model carries the selected record's primary key (a string), or null when nothing is selected.

Labeling, Description, Error, Required

Link accepts the standard input labeling props — label, description, error, required — and forwards them to the underlying Combobox, so ARIA wiring (aria-required, aria-invalid, aria-errormessage) and the InputLabel chrome render identically to a standalone Combobox.

Filters

The filters prop is a Record<string, unknown> passed straight through to search_link. Frappe's underlying endpoint also accepts list-form and SQL-string filters, but the component boundary intentionally narrows to the dict form — it covers every CRM call site without leaking backend serialization into the public API. Reactive — changing filters triggers a refetch. The #footer slot is the canonical home for a filter-status row (or any non-selectable popover affordance) and renders below both the options list and the creatable create-new row.

Creatable

creatable: true injects a "Create" row at the bottom of the popover, visible only when the user has typed. Clicking it emits @create with the typed query — the consumer owns the create flow (typically a dialog) and assigns the freshly-created record back to v-model on success. To replace the default create row markup (icon, helper text, copy), supply the #item-create slot — scope is { query }.

Suffix

By default, Link renders a clear button in the suffix slot when modelValue is non-null and required: false. To replace it with your own affordance — an "Open record" link, an "Edit" button — supply #suffix. The slot fully takes over; if you still want a clear button alongside your action, render one yourself. To dismiss the options dropdown when your action takes over (e.g. opens a dialog), bind v-model:open and set it to false.

Member Picker

Link forwards every Combobox per-row slot — #item-prefix, #item-label, #item-suffix, #item — so a doctype picker can render an avatar, role, or any other contextual chrome without dropping down to <Combobox> directly.

Combobox passthrough

Link composes Combobox and forwards unrecognized props via $attrs and all non-overridden slots. Anything in the Combobox API that Link doesn't claim itself (options, loading, and the #suffix / #item-create slots which have Link-specific defaults) reaches the underlying component unchanged.

API Reference

Show types
typescript
import type { InputLabelingProps } from '../../src/composables/useInputLabeling'

export interface LinkProps extends InputLabelingProps {
  doctype: string
  filters?: Record<string, unknown>
  creatable?: boolean
  disabled?: boolean
  placeholder?: string
}

export interface LinkEmits {
  'update:modelValue': [value: string | null]
  'update:open': [value: boolean]
  create: [query: string]
}

export interface LinkExposed {
  reload: () => void
}

export type LinkOption = {
  label: string
  value: string
  description?: string
}
doctype*
string
filters
= {}
Record<string, unknown>
creatable
= false
boolean
disabled
= false
boolean
label
string

Label rendered above (or beside, for binary controls) the input.

description
string

Helper text rendered below the input. Hidden when `error` is set.

error
string | FrappeUIError

Error message rendered below the input. When set, the control receives `aria-invalid="true"` and `data-state="invalid"`. May be either a string or an `Error` object whose `messages?: string[]` is rendered as stacked lines (with `Error.message` as the fallback).

required
boolean

Marks the field as required. Renders an asterisk next to the label and forwards `required` / `aria-required` to the underlying control.

id
string

HTML id of the underlying control. Auto-generated via `useId()` if omitted.

modelValue
= null
string | null
open
= false
boolean
suffix
{ open: boolean; disabled: boolean; query: string; selectedOption: ComboboxSelectableOption | null;
update:modelValue
unknown[]

Fired when the model value changes.

update:open
unknown[]

Fired when the open state changes.

create
[query: string]