Hydrates
Hydrates transform module config into frontend schema. The backend (PHP) and frontend (Vue) communicate via a schema contract: hydrates produce schema; input components consume it.
Flow
Module config (type: 'checklist') → InputHydrator → ChecklistHydrate → schema { type: 'input-checklist', ... }
↓
FormBase/FormBaseField → mapTypeToComponent('input-checklist') → VInputChecklist (Checklist.vue)- Module config defines inputs with
type(e.g.checklist,select,price) - InputHydrator resolves:
studlyName($input['type']) . 'Hydrate'→ e.g.ChecklistHydrate - Hydrate sets
$input['type'] = 'input-{kebab}'and enriches schema (items, endpoint, rules, etc.) - render() pipeline:
setDefaults()→hydrate()→hydrateRecords()→hydrateRules()→ strips backend-only keys - Frontend receives schema via Inertia; FormBaseField uses
mapTypeToComponent(type)→ Vue component
Resolution
| Config type | Hydrate class | Output type (schema) | Vue component |
|---|---|---|---|
| assignment | AssignmentHydrate | input-assignment | VInputAssignment |
| authorize | AuthorizeHydrate | select | v-select (Vuetify) |
| autocomplete | AutocompleteHydrate | select / input-select-scroll | v-autocomplete (Vuetify) |
| browser | BrowserHydrate | input-browser | VInputBrowser |
| chat | ChatHydrate | input-chat | VInputChat |
| checkbox | CheckboxHydrate | checkbox | v-checkbox (Vuetify) |
| checklist | ChecklistHydrate | input-checklist | VInputChecklist |
| checklist-group | ChecklistGroupHydrate | input-checklist-group | VInputChecklistGroup |
| combobox | ComboboxHydrate | combobox / input-select-scroll | v-combobox (Vuetify) |
| comparison-table | ComparisonTableHydrate | input-comparison-table | VInputComparisonTable |
| creator | CreatorHydrate | input-browser | VInputBrowser |
| date | DateHydrate | input-date | VInputDate |
| file | FileHydrate | input-file | VInputFile |
| filepond | FilepondHydrate | input-filepond | VInputFilepond |
| filepond-avatar | FilepondAvatarHydrate | input-filepond-avatar | VInputFilepondAvatar |
| form-tabs (tab-group) | FormTabsHydrate | input-form-tabs | VInputFormTabs |
| image | ImageHydrate | input-image | VInputImage |
| json | JsonHydrate | group | (group layout) |
| json-repeater | JsonRepeaterHydrate | input-repeater | VInputRepeater |
| payment-service | PaymentServiceHydrate | input-payment-service | VInputPaymentService |
| price | PriceHydrate | input-price | VInputPrice |
| process | ProcessHydrate | input-process | VInputProcess |
| radio-group | RadioGroupHydrate | input-radio-group | VInputRadioGroup |
| repeater | RepeaterHydrate | input-repeater | VInputRepeater |
| relationships | RelationshipsHydrate | input-relationships | VInputRelationships ⚠️ |
| select | SelectHydrate | select | v-select (Vuetify) |
| select-scroll | SelectScrollHydrate | input-select-scroll | VInputSelectScroll |
| spread | SpreadHydrate | input-spread | VInputSpread |
| stateable | StateableHydrate | select | v-select (Vuetify) |
| switch | SwitchHydrate | input-switch | VInputSwitch |
| tag | TagHydrate | input-tag | VInputTag |
| tagger | TaggerHydrate | input-tagger | VInputTagger |
| ... | ... | input- | VInput |
Rule: studlyName($input['type']) . 'Hydrate' → class in src/Hydrates/Inputs/
Hydrate Output Types (registry.js)
| Output type | Vue component |
|---|---|
| input-assignment | VInputAssignment |
| input-browser | VInputBrowser |
| input-chat | VInputChat |
| input-checklist | VInputChecklist |
| input-checklist-group | VInputChecklistGroup |
| input-comparison-table | VInputComparisonTable |
| input-date | VInputDate |
| input-file | VInputFile |
| input-filepond | VInputFilepond |
| input-filepond-avatar | VInputFilepondAvatar |
| input-form-tabs | VInputFormTabs |
| input-image | VInputImage |
| input-payment-service | VInputPaymentService |
| input-price | VInputPrice |
| input-process | VInputProcess |
| input-radio-group | VInputRadioGroup |
| input-repeater | VInputRepeater |
| input-select-scroll | VInputSelectScroll |
| input-spread | VInputSpread |
| input-tag | VInputTag |
| input-tagger | VInputTagger |
Schema Contract
Common keys (frontend expects): name, label, default, rules, items, itemValue, itemTitle, col, disabled, creatable, editable
Selectable: cascadeKey, cascades, repository, endpoint
Files: accept, maxFileSize, translated, max
Hydrate-only (stripped before frontend): route, model, repository, cascades, connector
Adding a New Input
- PHP: Create
src/Hydrates/Inputs/{Studly}Hydrate.phpextendingInputHydrate- Set
$input['type'] = 'input-{kebab}'inhydrate()(orselectfor select-based hydrates like AuthorizeHydrate, StateableHydrate) - Define
$requirementsfor default schema keys
- Set
- Vue: Create
vue/src/js/components/inputs/{Studly}.vue- Use
useInput,makeInputProps,makeInputEmitsfrom@/hooks - Component registers as
VInput{Studly}viaincludeFormInputsglob
- Use
- Registry (optional): Add to
hydrateTypeMapinregistry.jsfor explicit mapping
See the create-input-hydrate and create-vue-input commands.