export interface TagItem { id: string; key: string; label: string; value?: string | null; vocabularyId?: string | null; vocabularyKey?: string | null; vocabulary?: { key: string; } | null; parentId?: string | null; hierarchyPath?: string | null; color?: string | null; icon?: string | null; description?: string | null; } export interface TagsWidgetProps { /** The entity type being tagged, e.g. "Invoice", "BillingAccount" */ entityType: string; /** The entity's ID */ entityId: string; /** Workspace scope — widget renders nothing when empty */ workspaceId?: string; /** * Current tags on the entity (controlled). * The parent is responsible for fetching and storing these from its own model. */ tags: TagItem[]; /** * Called when the user picks or creates a tag. * The parent should persist the tag on the entity record and update `tags`. * The widget will also call notifyTagAssigned internally to keep the graph in sync. */ onAdd: (tag: TagItem) => void | Promise; /** * Called when the user removes a tag badge. * The parent should remove the tag from the entity record and update `tags`. * The widget will also call notifyTagRemoved internally to keep the graph in sync. */ onRemove: (tagId: string) => void | Promise; /** * Constrain search/creation to a specific vocabulary. * When omitted and allowCreate=true, a workspace-level "General" vocabulary * is automatically resolved (or created) on first tag creation. */ vocabularyId?: string; /** Allow creating new tags on the fly. Default: true */ allowCreate?: boolean; /** * When true, emit graph-only notifyTagAssigned/Removed mutations after the parent * persists the entity-owned tags. Disable when the entity's own graph event is the * canonical projection path. */ syncGraphNotifications?: boolean; maxTags?: number; className?: string; } /** * TagsWidget - compact, embeddable tag input (controlled). * * Drop this next to any entity to let users search/assign/create tags without * leaving the current page. The widget is **controlled**: the parent owns the * tag list and persists it on the entity record. The widget's only * responsibilities are: * 1. Rendering the badge strip and search/create popover. * 2. Calling onAdd / onRemove so the parent can update its state. * 3. Firing notifyTagAssigned / notifyTagRemoved mutations to wspace-tags-svc * so ArangoDB stays in sync (tagged_with edges) — no UniversalTagAssignment * row is written to Postgres. * * ```tsx * import { TagsWidget } from '@burdenoff/fe-libs/tag'; * * function InvoiceRow({ invoice }) { * const [tags, setTags] = useState(invoice.tags ?? []); * const [updateInvoice] = useMutation(UPDATE_INVOICE_TAGS); * * const handleAdd = async (tag) => { * const next = [...tags, tag]; * setTags(next); * await updateInvoice({ variables: { id: invoice.id, tagIds: next.map(t => t.id) } }); * }; * const handleRemove = async (tagId) => { * const next = tags.filter(t => t.id !== tagId); * setTags(next); * await updateInvoice({ variables: { id: invoice.id, tagIds: next.map(t => t.id) } }); * }; * * return ( * * ); * } * ``` */ export declare function TagsWidget({ entityType, entityId, workspaceId, tags, onAdd, onRemove, vocabularyId: vocabIdProp, allowCreate, syncGraphNotifications, maxTags, className, }: TagsWidgetProps): import("react/jsx-runtime").JSX.Element | null; //# sourceMappingURL=TagsWidget.d.ts.map