{{-- The product's custom fields (boboko-core's Product::$custom_fields), rendered inside the add-to-cart
so their values travel with it as custom_fields[key]. text → input, textarea → textarea, file → photo upload. The label is styled like the product option labels (option-buttons / color-swatch); the optional help_text shows under it. Help text is product-page only; the cart/checkout line meta only snapshots the label. A photo is uploaded as soon as it's picked (custom-field-upload-controller.js) and only the resulting File row's id (boboko-core's Modules\Core\File\ Models\File) is submitted with the form — the file input itself has no name. It still carries `required`, so the browser's own validation blocks add-to-cart until a photo is picked, and the controller marks it invalid (setCustomValidity) while the upload is in flight. --}} @props(['fields' => []]) @use('App\Http\Controllers\CustomFieldUploadController')
@foreach ($fields as $field) @php $id = 'custom-field-'.$field['key']; $name = 'custom_fields['.$field['key'].']'; $required = (bool) ($field['required'] ?? false); $hint = filled($field['help_text'] ?? null) ? $field['help_text'] : null; // mb-1 on top of the field's gap-2 matches the option labels' mb-3; // with a hint, the label + hint group carries that spacing instead. $labelClass = 'font-bold text-sm uppercase tracking-wide'.($hint ? '' : ' mb-1'); $hintId = $hint ? $id.'-hint' : null; @endphp @switch($field['type']) @case('textarea') @break @case('file') @break @default @endswitch @endforeach