/**
 * Registry of input types available in `<DocumentTemplateBuilder>` (the
 * structured editor for document templates) AND consumable by the runtime
 * renderer (`useDocumentTemplate` in `./template.ts`).
 *
 * **Single registration entry point:** `registerDocumentTemplateInputType`.
 *
 * Use it from a Nuxt plugin to add an entry app-wide. The same `entry` object
 * carries everything — dropdown label, builder-UI flags, and an optional
 * `render` function consumed by the runtime renderer in `template.ts`:
 *
 * ```ts
 * // app/plugins/document-template-inputs.ts
 * export default defineNuxtPlugin(() => {
 *   registerDocumentTemplateInputType({
 *     label: 'From Staff',
 *     value: 'FromStaff',
 *     render(item, _parents, dataVariable) {
 *       return `<FromStaff :staff-id="${dataVariable}.${item.variableName}" />`
 *     },
 *   })
 * })
 * ```
 *
 * For rare page-scoped extensions, call `useDocumentTemplateInputType()` in
 * `<script setup>` — it wraps `register` + `onScopeDispose` so the entry is
 * removed automatically when the component unmounts.
 *
 * Merge order (later wins on `value` collision):
 *   built-in ⊕ runtime-registry
 *
 * The runtime renderer dispatches as follows inside `templateItemToString`:
 *   1. If the registered entry for `inputType` has a `render` function → call it.
 *   2. Else if `inputType` is one of the built-in special cases (Header,
 *      Separator, FormTable, …) → use the hand-written switch arm.
 *   3. Else → `processDefaultTemplate` (the v-model/label fallback).
 *
 * The `computedValue` post-pass (appending `<FormHidden>` to write a derived
 * value back to `data[variableName]`) still runs unconditionally, so custom
 * renderers don't need to handle it.
 */
import type { DocumentTemplateItem } from './template.js';
/**
 * Signature for a custom renderer registered against a specific `inputType`.
 *
 * Must return the Vue template fragment string to splice into the document
 * template. Receives:
 *
 *   - `item` — a `cloneDeep`'d copy of the template item, with two
 *     transformations already applied to `item.inputAttributes`:
 *       1. `migrateInputAttributes()` — Vuetify v3→v4 attribute migration
 *          (e.g. bare `dense` → `density="compact"`).
 *       2. If `item.conditionalDisplay` was set, `v-if="<expr>"` has already
 *          been appended. **Renderers don't need to handle
 *          `conditionalDisplay` separately** — just include
 *          `item.inputAttributes` on the emitted tag.
 *   - `parentTemplates` — chain of ancestor template codes (used by nested
 *     types like `DocumentForm` / `FormTable`); pass-through to nested
 *     `useDocumentTemplate()` calls when relevant.
 *   - `dataVariable` — the form `data` variable name. `"data"` at the top
 *     level; nested tables pass their row alias (e.g. `"row"`).
 *
 * **Helpers safe to import from `./template`:**
 *
 *   - `buildValidationRules(item.validationRules)` — produces the
 *     `:rules="[rules.x()]"` attribute string (or `''` when no rules).
 *     The same helper used by the built-in switch arms.
 *   - `optionStringToChoiceObject(item.inputOptions)` — parses
 *     `"a|1,b|2"` / array forms into `ChoiceItem[]`.
 *   - `escapeObjectForInlineBinding(obj)` — `JSON.stringify` + `'` escaping
 *     for inline `v-bind` payloads.
 *   - `processDefaultTemplate(item, insideTemplate?, optionString?, validationRules?, dataVariable?)`
 *     — the same fallback used for unknown types. Call it from a renderer
 *     when you want "the default plus a wrapper".
 *
 * **Handled for you AFTER `render` returns:**
 *
 *   - The `computedValue` post-pass that appends
 *     `<FormHidden v-model="data.x" :hook="()=>computedValue"/>`
 *     when both `item.computedValue` and `item.variableName` are set.
 *   - Column wrapping (`<v-col cols=…>`), `columnAttributes`, `customClass`,
 *     `customStyle` are applied by the caller (`columnWrapTemplateItemString`).
 *
 * **What `optionString` is and why it isn't passed:** the built-in switch
 * arms precompute an `optionString` for the specific built-in option-bearing
 * types (`MasterAutocomplete`, `VSelect`, `VAutocomplete`, `VCombobox`,
 * `FormCheckboxGroup`, `VRadio`, `VRadioInline`, `Header`). For any
 * custom-registered `inputType` that string is empty, so passing it would
 * be dead weight. Compose your own option markup with the two helpers above
 * when needed.
 *
 * **Minimal "field-shaped" renderer template:**
 *
 *   ```ts
 *   import { buildValidationRules } from '@ramathibodi/nuxt-commons'
 *
 *   render(item, _parents, dataVariable) {
 *     const variable = (item.variableName ?? '').replace(/[^\w$]/g, '')
 *     const attrs = item.inputAttributes ? ` ${item.inputAttributes.trim()}` : ''
 *     const rules = item.validationRules ? buildValidationRules(item.validationRules) : ''
 *     return `<MyComponent `
 *       + `:value="${dataVariable}.${variable}" `
 *       + `@update:value="v => ${dataVariable}.${variable} = v"`
 *       + `${attrs}${rules ? ' ' + rules : ''}/>`
 *   }
 *   ```
 */
export type DocumentTemplateInputTypeRenderer = (item: DocumentTemplateItem, parentTemplates: string | string[], dataVariable: string) => string;
export interface DocumentTemplateInputType {
    /** Label shown in the input-type dropdown. */
    label: string;
    /**
     * `inputType` value stored in the template JSON. For app-specific types,
     * this must be a globally-registered Vue component tag — the runtime
     * renderer emits it as `<value v-model=… label=… …/>`.
     */
    value: string;
    /** Default `true`. Set `false` for decoration types (e.g. `Header`, `Separator`). */
    needsVariableName?: boolean;
    /** Default `true`. Set `false` for types that have no label (e.g. `Separator`, `CustomCode`). */
    needsLabel?: boolean;
    /** Default `true`. Set `false` for types laid out outside the grid (e.g. `Separator`, `FormHidden`). */
    needsWidth?: boolean;
    /**
     * Whether the generic `inputOptions` editor (textarea / specific editor)
     * is shown. Default `true`. Set `false` only when the type has no
     * meaningful inputOptions (e.g. `Separator`, `CustomCode`, `FormFile`).
     */
    showsOptions?: boolean;
    /** Default `false`. Set `true` to make `inputOptions` required in the editor. */
    requiresOptions?: boolean;
    /** Override the textarea label (`'Input Options'` by default). */
    optionsLabel?: string;
    /**
     * Render the choice-array editor instead of a plain textarea. Applies to
     * the choice-style inputs (select, radio, checkbox-group, etc.).
     */
    optionsAsChoice?: boolean;
    /**
     * Marks the type as having a custom inputOptions sub-editor handled inline
     * by `TemplateBuilder.vue` (FormHidden / FormTable / FormTableData). Apps
     * cannot extend this; new built-ins must update the builder UI as well.
     */
    hasSpecificOptionEditor?: boolean;
    /** Default `false`. Hides the Validations expansion panel. */
    hidesValidationRules?: boolean;
    /** Default `false`. Hides the `Input Attributes` field inside Advanced settings. */
    hidesInputAttributes?: boolean;
    /** Default `false`. Hides the `Column Attributes` field inside Advanced settings. */
    hidesColumnAttributes?: boolean;
    /** Default `false`. Hides the entire Advanced settings expansion panel. */
    hidesAdvancedSettings?: boolean;
    /** Default `false`. Hides the Class and Styles expansion panel. */
    hidesClassAndStyle?: boolean;
    /**
     * Optional renderer that overrides the default `<Tag v-model="…" label="…"/>`
     * emission for this `inputType`. Use when an app component does not follow
     * the standard contract (different value prop, slot content, etc.).
     */
    render?: DocumentTemplateInputTypeRenderer;
}
/**
 * Built-in registry. One entry per inputType that `TemplateBuilder.vue`
 * historically hard-coded. Flag values mirror the previous arrays
 * (`requireOption`, `notRequireVariable`, `notRequireLabel`, `notRequireWidth`,
 * `notRequireOptions`, `notRequireRules`, `notRequireInputAttributes`,
 * `notRequireColumnAttributes`, `notRequireAdvancedSetting`,
 * `notRequireClassAndStyle`, `choiceOption`, `inputOptionsLabel`,
 * `hasSpecificOption`).
 */
export declare const BUILT_IN_DOCUMENT_TEMPLATE_INPUT_TYPES: readonly DocumentTemplateInputType[];
/**
 * Merge multiple lists of input-type definitions. Later entries win on
 * `value` collision, allowing a consumer to override a built-in entry's
 * label or flags (e.g. relabel "Text Field" to "Free Text" in one app).
 *
 * Render functions follow the same precedence: a later entry without
 * `render` does NOT clear an earlier-registered render (the shallow merge
 * keeps the prior value). To explicitly remove a render, set
 * `render: undefined` on the later entry, or call
 * `unregisterDocumentTemplateInputType`.
 */
export declare function mergeDocumentTemplateInputTypes(...lists: Array<readonly DocumentTemplateInputType[] | DocumentTemplateInputType[] | undefined | null>): DocumentTemplateInputType[];
/**
 * Register (or upsert) an input-type entry. Returns an `unregister()`
 * function so callers — especially HMR-aware Nuxt plugins — can revert the
 * registration. Calling `register` twice with the same `value` performs a
 * shallow merge, matching the wider `mergeDocumentTemplateInputTypes`
 * semantics. No-op (and returns a no-op unregister) when `entry` lacks a
 * string `value`.
 *
 * **Where to call from:**
 * - Nuxt plugin (`app/plugins/*.ts`) — the canonical place for app-wide
 *   registration. Entries persist for the lifetime of the app.
 * - Inside a Vue component setup — prefer `useDocumentTemplateInputType`
 *   instead; it wraps this function with auto-cleanup on unmount.
 */
export declare function registerDocumentTemplateInputType(entry: DocumentTemplateInputType): () => void;
/** Explicit removal — handy in unit tests and for one-off cleanup. */
export declare function unregisterDocumentTemplateInputType(value: string): void;
/**
 * Page-scoped registration. Calls `registerDocumentTemplateInputType` and
 * schedules the returned `unregister()` on `onScopeDispose`, so the entry
 * is removed automatically when the surrounding effect scope (typically a
 * Vue component's setup) is disposed.
 *
 * If called outside an effect scope, the registration persists for the
 * lifetime of the runtime — at which point you should use
 * `registerDocumentTemplateInputType` directly so the lifecycle is explicit.
 */
export declare function useDocumentTemplateInputType(entry: DocumentTemplateInputType): void;
/** Snapshot of the runtime registry. Internal — exported for tests. */
export declare function _getDocumentTemplateRuntimeRegistry(): DocumentTemplateInputType[];
/** Test-only reset. Does not affect built-ins. */
export declare function _resetDocumentTemplateRuntimeRegistry(): void;
/**
 * Look up a single entry from the merged registry (built-in ⊕ runtime).
 * Used by `templateItemToString` to decide whether a custom `render` is in
 * play.
 */
export declare function getDocumentTemplateInputTypeEntry(value: string): DocumentTemplateInputType | undefined;
/**
 * Read the merged input-type registry: built-in ⊕ runtime registry.
 * Stable across calls (re-reads on every call so HMR-driven re-registration
 * picks up). Returns a fresh array — callers may mutate without affecting
 * the underlying state.
 */
export declare function useDocumentTemplateInputTypes(): DocumentTemplateInputType[];
