From 01e9a8e40351a87f6548a4f55de842d6f6918ad0 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 15 Sep 2026 02:44:28 +0000
Subject: [PATCH] =Found little glitch with auto-adding rewrite rules to taxonomy Registrar instances where we have the post type as the base in the url rewrite

---
 inc/meta/Form.php |  388 ++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 226 insertions(+), 162 deletions(-)

diff --git a/inc/meta/Form.php b/inc/meta/Form.php
index 57bdd85..c09f280 100644
--- a/inc/meta/Form.php
+++ b/inc/meta/Form.php
@@ -2,6 +2,8 @@
 namespace JVBase\meta;
 
 use DateTime;
+use JVBase\base\Site;
+use JVBase\integrations\services\GoogleMaps;
 use JVBase\registrar\Registrar;
 
 if (!defined('ABSPATH')) {
@@ -26,7 +28,10 @@
 			$value = '';
 		}
 		if (!empty($config['hidden'])) {
-			return '';
+            if ($config['type'] !== 'upload') {
+                return static::renderHidden($name, $value, $config);
+            }
+            return '';
 		}
 
 		$type = $config['type'] ?? 'text';
@@ -53,12 +58,19 @@
 	/**
 	 * Render complete form from Meta instance
 	 */
-	public static function renderFormFrom(Meta $meta, string $endpoint, array $options = []): string
+	public static function renderFormFrom(Meta $meta, string $endpoint, array $options = [], array $fields = []): string
 	{
 		$id = $options['form-id'] ?? $endpoint;
 		$classes = isset($options['classes']) ? ' class="' . implode(' ', $options['classes']) . '"' : '';
+		$formID = isset($options['showFormID']) && $options['showFormID']!== false;
 
-		$output = '<form id="' . esc_attr($endpoint) . '"' . $classes . ' data-save="' . esc_attr($endpoint) . '" data-form-id="' . esc_attr($id) . '">';
+		$output = sprintf(
+			'<form id="%s"%s data-save="%s"%s>',
+			esc_attr($endpoint),
+			$classes,
+			esc_attr($endpoint),
+			$formID ? ' data-form-id="'.esc_attr($id).'"' : '',
+		);
 
 		if (!empty($options['heading'])) {
 			$output .= '<h2>' . esc_html($options['heading']) . '</h2>';
@@ -71,8 +83,12 @@
 			}
 		}
 
-		foreach ($meta->configs() as $name => $config) {
-			$output .= static::render($name, $meta->get($name), $config);
+
+		$allFields = $meta->getAll($fields);
+
+		foreach ($allFields as $name => $value) {
+			$config = $meta->config($name);
+			$output .= static::render($name, $value, $config);
 		}
 
 		if (!empty($options['submit'])) {
@@ -88,8 +104,11 @@
 	// Helper Methods
 	// ─────────────────────────────────────────────────────────────
 
-	public static function fieldWrap(string $name, string $content, array $config): string
+	public static function fieldWrap(string $name, string $content, array $config, bool $col = false): string
 	{
+		if (!array_key_exists('type', $config)) {
+			jvbDump('No type set for '.$name.' with config: '.print_r($config, true));
+		}
 		$classes = static::buildClasses($config);
 		$datasets = static::buildDatasets($config);
 
@@ -107,7 +126,7 @@
 		$output .= static::buildCharacterLimit($config);
 		$output .= static::buildLabel($name, $config);
 		if (!array_key_exists('skipInput', $config)) {
-			$output .= static::buildInput($content);
+			$output .= static::buildInput($content, $col);
 		} else {
 			$output .= $content;
 		}
@@ -211,14 +230,15 @@
 			return '';
 		}
 
-		public static function buildInput(string $content):string
+		public static function buildInput(string $content, bool $col = false):string
 		{
 			return sprintf(
-				'<div class="field-input-wrapper">
+				'<div class="wrapper row%s">
 			%s
-			<span class="validation-icon success" hidden aria-hidden="true">%s</span>
-			<span class="validation-icon error" hidden aria-hidden="true">%s</span>
+			<span class="validation success" hidden aria-hidden="true">%s</span>
+			<span class="validation error" hidden aria-hidden="true">%s</span>
 			</div><span class="validation-message" hidden role="alert"></span>',
+				$col ? ' col' : '',
 				$content,
 				jvbIcon('check-circle'),
 				jvbIcon('x-circle')
@@ -306,6 +326,15 @@
 		return static::fieldWrap($name, $input, $config);
 	}
 
+    protected static function renderHidden(string $name, mixed $value, array $config):string
+    {
+        return sprintf(
+            '<input type="hidden" name="%s" value="%s">',
+            esc_attr($name),
+            esc_attr($value)
+        );
+    }
+
 	protected static function renderTextarea(string $name, mixed $value, array $config): string
 	{
 		$rows = $config['rows'] ?? 5;
@@ -346,13 +375,19 @@
 		if (!array_key_exists('class', $config)) {
 			$config['class']=[];
 		}
-		$config['class'][] ='quantity-input';
+		$config['class'][] = 'quantity-input';
+        $config['class'][] = 'row';
+        $config['class'][] = 'nowrap';
+
+        if (array_key_exists('isCart', $config) && $config['isCart'] === true) {
+
+        }
 
 		$attrs = static::inputAttrs($name, $config);
 
 		$value = ($value !== '') ? ' value="'.esc_attr($value).'"' : '';
 		$input = sprintf(
-			'<div class="quantity">
+			'<div class="row nowrap">
 				<button type="button" class="decrease" title="%s" aria-label="Decrease %s">%s</button>
 				<input type="number"%s%s />
 				<button type="button" class="increase" title="%s" aria-label="Increase %s">%s</button>
@@ -459,19 +494,21 @@
 		if (!array_key_exists('class', $config)) {
 			$config['class'] = [];
 		}
-		$config['class'][] ='row btw';
+		$config['class'][] ='row x-btw';
 
 		$checked = filter_var($value, FILTER_VALIDATE_BOOLEAN);
 
 		$input = sprintf(
-			'<label class="toggle-switch row">
+			'<label class="switch row">
                 <input type="checkbox" value="1"%s%s />
                 <div class="slider"></div>
+                %s
                 <span class="toggle-label">%s</span>
             </label>',
 			static::inputAttrs($name, $config),
 			$checked ? ' checked' : '',
-			array_key_exists('required', $config) && $config['required']===true ? '<span class="required" aria-label="required">*</span>' : ''
+			array_key_exists('required', $config) && $config['required']===true ? '<span class="required" aria-label="required">*</span>' : '',
+			$config['label']??''
 		);
 
 		unset($config['label']);
@@ -550,17 +587,17 @@
 			$checked = in_array($optValue, $values) ? ' checked' : '';
 			$checkboxes .= sprintf(
 				'
-                    <input type="checkbox" name="%s[]" id="%s-%s" value="%s"%s />
+                    <input type="checkbox" name="%s" id="%s-%s" value="%s"%s/>
 				<label class="checkbox-option" for="%s-%s">
                     <span>%s</span>
                 </label>',
 				esc_attr($name),
 				esc_attr($name),
-				$optValue,
+				esc_attr($optValue),
 				esc_attr($optValue),
 				$checked,
 				esc_attr($name),
-				$optValue,
+				esc_attr($optValue),
 				esc_html($optLabel)
 			);
 		}
@@ -585,10 +622,15 @@
 				? '<span class="required" aria-label="required">*</span>' : ''
 		);
 
+
 		foreach ($options as $optValue => $optConfig) {
+			$class = '';
 			if (is_array($optConfig)) {
 				$optLabel    = $optConfig['label'] ?? $optValue;
 				$optIcon     = $optConfig['icon'] ?? null;
+				if ($optIcon) {
+					$class = ' class="btn"';
+				}
 				$optDisabled = !empty($optConfig['disabled']) ? ' disabled' : '';
 			} else {
 				$optLabel    = $optConfig;
@@ -603,11 +645,12 @@
 			$optId = esc_attr($idPrefix . $name . '-' . $optValue);
 
 			$radios .= sprintf(
-				'<input type="radio" name="%s" id="%s" value="%s"%s%s%s />
+				'<input type="radio" name="%s" id="%s" value="%s"%s%s%s%s />
             <label class="radio-option" for="%s" title="%s">%s</label>',
 				esc_attr($name),
 				$optId,
 				esc_attr($optValue),
+				$class,
 				checked($value, $optValue, false),
 				$optDisabled,
 				$inputClass,
@@ -629,7 +672,7 @@
 			//File Type
 			'subtype'	=> 'image',		//'image', 'video', 'document', 'any'
 			'accepted'	=> null,		//null = use subtype defaults, or define an array of specific MIME types
-			//Upload Behavious
+			//Upload Behaviours
 			'multiple'	=> false,		//single or multiple uploads
 			'limit'		=> 15, 			//Max number of uploads (0 = unlimited)
 			'mode'		=> 'direct',	// 'direct' or 'selection' TODO: unneeded?
@@ -638,7 +681,8 @@
 			'max_size'	=> null,		//override default size limits
 			'convert'	=> 'webp',		//Image conversion format
 			'quality'	=> 90,			//Conversion quality
-			'inputData' => []
+			'inputData' => [],
+			'data'	=> []
 		];
 		$config = array_merge($defaults, $config);
 
@@ -648,7 +692,7 @@
 			return '';
 		}
 		$validate = [
-			'subtype'	=> ['image', 'video', 'document', 'any'],
+			'subtype'	=> ['image', 'video', 'document', 'any','timeline'],
 			'mode'		=> ['direct', 'selection'],
 			'destination'=> ['meta', 'post', 'post_group']
 		];
@@ -665,7 +709,9 @@
 		//Add upload config to the datasets (handled by fieldWrap())
 		$attrs = ['subtype', 'mode', 'destination', 'max_size'];
 		foreach ($attrs as $attr) {
-			$config['data'][$attr] = $config[$attr];
+			if (array_key_exists($attr, $config)) {
+				$config['data'][$attr] = $config[$attr];
+			}
 		}
 		$config['data']['upload-field'] = '';
 		$config['data']['type'] = $config['multiple'] ? 'gallery' : 'single';
@@ -685,7 +731,13 @@
 
 		$attachmentIds = static::parseIds($value);
 
+
 		$input = sprintf(
+			'<input type="hidden" name="%s" value="%s">',
+			esc_attr($name),
+			esc_attr(!empty($attachmentIds) ? implode(',', $attachmentIds) : '')
+		);
+		$input .= sprintf(
 			'<div class="file-upload-container">
 			<div class="file-upload-wrapper">
 				<input type="file"
@@ -740,11 +792,6 @@
 
 		$input .= '</div>'; // closes .file-upload-container
 
-		$input .= sprintf(
-			'<input type="hidden" name="%s" value="%s">',
-			esc_attr($name),
-			esc_attr(!empty($attachmentIds) ? implode(',', $attachmentIds) : '')
-		);
 
 		unset($config['description']);
 		unset($config['label']);
@@ -757,7 +804,7 @@
 					<div class="preview-actions">
 						<div class="selection-controls">
 							<div class="selected">
-								<div class="field">
+								<div class="field checkbox">
 									<input type="checkbox" id="select-all-uploads" data-select-all data-selects="item-grid" name="select-all-uploads">
 									<label for="select-all-uploads">
 										Select All
@@ -768,7 +815,7 @@
 								</div>
 							</div>
 
-							<div class="selection-actions row btw" hidden>
+							<div class="selection-actions row x-btw" hidden>
 								<button type="button" data-action="add-to-group">
 									%sGroup
 								</button>
@@ -804,15 +851,11 @@
 
 			public static function renderExistingAttachment(int $attachmentId, string $subtype):string
 			{
-				switch ($subtype){
-					case 'video':
-						return static::renderVideoPreview($attachmentId);
-					case 'document':
-					case 'file':
-						return static::renderFilePreview($attachmentId);
-					default:
-						return static::renderImagePreview($attachmentId);
-				}
+				return match ($subtype) {
+					'video' => static::renderVideoPreview($attachmentId),
+					'document', 'file' => static::renderFilePreview($attachmentId),
+					default => static::renderImagePreview($attachmentId),
+				};
 			}
 			protected static function renderUploadItemStart(?int $attachmentId = null):string
 			{
@@ -832,9 +875,9 @@
 				protected static function renderUploadItemActions(?int $attachmentId = null):string
 				{
 					return sprintf(
-						'<div class="item-actions row btw">
-						<div class="radio-button">
-							<input type="radio" class="featured btn" name="featured" id="featured%d" hidden>
+						'<div class="item-actions row x-btw">
+						<div class="btn">
+							<input type="radio" class="featured btn" name="featured" id="featured%s" hidden>
 							<label for="featured">
 								%s%s<span class="screen-reader-text">Set as featured image</span>
 							</label>
@@ -900,12 +943,12 @@
 								'label' => 'Video Caption',
 								'data'  => ['id' => $ID]
 							],
-							'image-description' => [
-								'type'  => 'textarea',
-								'value' => $description,
-								'label' => 'Video Description',
-								'data'  => ['id' => $ID]
-							]
+//							'image-description' => [
+//								'type'  => 'textarea',
+//								'value' => $description,
+//								'label' => 'Video Description',
+//								'data'  => ['id' => $ID]
+//							]
 						]
 					];
 
@@ -968,12 +1011,12 @@
 								'label' => 'File Caption',
 								'data'  => ['id' => $ID]
 							],
-							'image-description' => [
-								'type'  => 'textarea',
-								'value' => $description,
-								'label' => 'File Description',
-								'data'  => ['id' => $ID]
-							]
+//							'image-description' => [
+//								'type'  => 'textarea',
+//								'value' => $description,
+//								'label' => 'File Description',
+//								'data'  => ['id' => $ID]
+//							]
 						]
 					];
 
@@ -986,7 +1029,7 @@
 
 					return $out;
 				}
-				public static function renderImagePreview(?int $ID = null, ?array $additionalFields = null):string
+				public static function renderImagePreview(?int $ID = null, ?array $additionalFields = null, bool $isTemplate = false):string
 				{
 					$out = static::renderUploadItemStart($ID);
 					//add image preview
@@ -1030,30 +1073,30 @@
 								'label' => 'Image Caption',
 								'data'  => ['id' => $ID]
 							],
-							'image-description' => [
-								'type'  => 'textarea',
-								'value' => $description,
-								'label' => 'Image Description',
-								'data'  => ['id' => $ID]
-							]
+//							'image-description' => [
+//								'type'  => 'textarea',
+//								'value' => $description,
+//								'label' => 'Image Description',
+//								'data'  => ['id' => $ID]
+//							]
 						]
 					];
 
 					$out .= static::render('image_data', '', $fields);
-
-					$out .= static::renderUploadItemMetaEnd();
 					if ($additionalFields) {
 						$out .= static::additionalFields($additionalFields);
 					}
+					$out .= static::renderUploadItemMetaEnd();
 
 					return $out;
 				}
 				protected static function additionalFields(array $fields):string
 				{
-					$out = '';
+					$out = '<details class="fields"><summary>'.jvbDashIcon('edit').'Edit Fields</summary>';
 					foreach ($fields as $name => $config) {
 						$out .= static::render($name, '', $config);
 					}
+					$out .= '</details>';
 					return $out;
 				}
 
@@ -1128,6 +1171,9 @@
 
 		protected static function getAcceptedTypesLabel(array $config):string
 		{
+			if (!array_key_exists('subtype', $config) || $config['subtype'] === 'timeline') {
+				$config['subtype'] = 'image';
+			}
 			$labels = [
 				'image'	=> 'JPG, JPEG, PNG, GIF, or WEBP',
 				'video'	=> 'MP4, WEBM, or MOV',
@@ -1179,7 +1225,7 @@
 			'type'		=> $config['subtype'],
 		], $config);
 
-		$registrar = Registrar::getInstance($config['subtype']);
+		$registrar = Registrar::getInstance($config[$config['subtype']]);
 		$icon = jvbDefaultIcon();
 		if ($registrar){
 			$icon = $registrar->getIcon()??jvbDefaultIcon();
@@ -1188,7 +1234,7 @@
 		$containerId = sprintf('%s-%s-selector', $name, $config['subtype']);
 
 		$input = sprintf(
-			'<div class="row btw">
+			'<div class="row x-btw">
     <input type="hidden" name="%s" value="%s">
     <label for="%s-autocomplete">%s<span>%s</span></label>',
 			esc_attr($name),
@@ -1205,7 +1251,7 @@
 		}
 		$plural = static::getPlural($config);
 		$input .= sprintf(
-			'<div class="selected-items row" role="region" aria-label="Selected %s"></div>',
+			'<div class="selected-items row left" role="region" aria-label="Selected %s"></div>',
 			$plural[1]??''
 		);
 
@@ -1333,8 +1379,15 @@
 						$plural
 					);
 					break;
+				default:
+					$attr = false;
+					$single = false;
+					$plural = false;
 			}
 
+			if (!$attr || !$single || !$plural) {
+				return '';
+			}
 			$dataAttrs = [];
 			if ($config['update']) {
 				$dataAttrs[] = 'data-update="false"';
@@ -1401,72 +1454,63 @@
 
 	protected static function renderLocation(string $name, mixed $value, array $config): string
 	{
-		$googleMaps = JVB()->connect('maps');
-		if (!$googleMaps->isSetUp()) {
-			return '<div class="notice notice-warning"><p>Google Maps not configured. Please configure in Integrations settings.</p></div>';
-		}
+		$location = is_array($value) ? $value : [];
+		$fields = ['address', 'street', 'city', 'province', 'postal_code', 'country', 'lat', 'lng'];
 
-		$field_id = esc_attr($name);
-		$map_id = sprintf('%s_map', $field_id);
-		$components = ['address', 'lat', 'lng', 'street', 'city', 'province', 'postal_code', 'country'];
-		if (!empty($value)) {
-			$lat = (float)$value['lat']??'';
-			$lng = (float)$value['lng']??'';
 
-			$coords = [
-				'lat'	=> $lat,
-				'ng'	=> $lng
-			];
-		} else {
-			$coords = null;
-		}
-		if (!array_key_exists('data', $config)) {
-			$config['data'] =[];
-		}
-		$js_config = [
-			'fieldId' 	=> $field_id,
-			'initialCoords' => $coords
-		];
-
-		$json_config = htmlspecialchars(json_encode($js_config), ENT_QUOTES, 'UTF-8');
-		$config['data']['location-field-init'] = $json_config;
-
-		$input = '';
-		if (!empty($value) && array_key_exists('address', $value)) {
-			$input = sprintf(
-				'<p><b>Current location:</b> %s</p><p class="hint">Search below to change:</p>',
-				esc_html($value['address'])
-			);
-		}
-		$links = (!empty($value)) ? jvbLocationLinks($value) : '';
-		$input .= sprintf(
-			'<div class="location-search-wrapper">
-			<div class="autocomplete-wrapper"></div>
-			<div class="location-preview">
-				<div id="%s" class="location-map"></div>
-				%s
-			</div>',
-			esc_attr($map_id),
-			$links
+		$input = sprintf(
+			'<h3>%s</h3><input type="search" id="%s-search" placeholder="%s" autocomplete="off" data-ignore data-location-search />
+        <p class="message" hidden aria-live="polite">{ <span>Searching locations</span> }</p>
+        <ul class="search-results"></ul><p><small><i>{ All Results © OpenStreetMap contributors, ODbL 1.0 }</i></small></p>',
+			$config['label'],
+			esc_attr($name),
+			esc_attr($config['placeholder'] ?? 'Search for an address…'),
 		);
 
-		if (!empty($value)) {
-			foreach($components as $el) {
-				$input .= sprintf(
-					'<input type="hidden"
-					name="%s[%s]"
-					value="%s"
-					data-location-field="%s">',
-					esc_attr($name),
-					$el,
-					$value[$el]??'',
-					$el
-				);
-			}
+		$input .= '<fieldset class="location"><legend>Current Location</legend>';
+		foreach ($fields as $field) {
+			$title = match($field) {
+				'address'   => 'House Number',
+				'lat'       => 'Latitude',
+				'lng'       => 'Longitude',
+				'postal_code'   => 'Postal Code',
+				default     => ucfirst($field)
+			};
+			$open = match($field) {
+				'address','postal_code','lat' => '<div class="row">',
+				default => '',
+			};
+			$close = match ($field) {
+				'street','country','lng'    => '</div>',
+				default => '',
+			};
+			$input .= sprintf(
+			'%s<div><label for="%s|%s">%s</label>
+				<input type="text" name="%s" data-field-name="%s" id="%s|%s" value="%s" /></div>%s',
+				$open,
+				esc_attr($name),
+				esc_attr($field),
+				$title,
+				esc_attr("{$name}|{$field}"),
+				esc_attr($field),
+				esc_attr($name),
+				esc_attr($field),
+				esc_attr($location[$field] ?? ''),
+				$close
+			);
 		}
+		$input .= '</fieldset>';
 
-		$input .= '</div>';
+//		if (!empty($location['lat']) && !empty($location['lng'])) {
+//			$input .= sprintf(
+//				'<div class="location-preview" data-lat="%s" data-lng="%s"></div>',
+//				esc_attr($location['lat']),
+//				esc_attr($location['lng'])
+//			);
+//		}
 
+		$config['skipInput'] = true;
+		$config['label'] = false;
 		return static::fieldWrap($name, $input, $config);
 	}
 
@@ -1479,7 +1523,7 @@
 		$config['data']['tag-format'] = esc_attr($tagFormat);
 
 		$input = sprintf(
-			'<h3>%s</h3><div class="row start wrap">',
+			'<h3>%s</h3><div class="row left wrap">',
 			esc_html($config['label']??'')
 		);
 
@@ -1494,7 +1538,7 @@
 			$input .= static::render($newName, '', $fieldConfig);
 		}
 		$input .= sprintf(
-			'<button type="button" class="button add-tag">%s<span>%s</span></button></div>',
+			'<button type="button" class="button add-tag">%s<span>%s</span></button>',
 			jvbIcon('plus'),
 			$config['add_label']??'Add'
 		);
@@ -1512,7 +1556,7 @@
 
 		unset($config['label']);
 
-		return static::fieldWrap($name, $input, $config);
+		return static::fieldWrap($name, $input, $config, true);
 	}
 		protected static function renderTagItems(array $fields, mixed $value, string $name, string $tagFormat):string
 		{
@@ -1582,7 +1626,7 @@
 						$values = array_filter(array_values($values));
 						return implode(', ', $values) ?: 'New Item';
 					default:
-						if (strpos($tagFormat, '{') !== false) {
+						if (str_contains($tagFormat, '{')) {
 							$text = $tagFormat;
 							foreach ($values as $key => $value) {
 								$text = str_replace('{'.$key.'}', $value, $text);
@@ -1597,8 +1641,8 @@
 	{
 		$fields = $config['fields'] ?? [];
 		$rows = is_array($value) ? $value : [];
-		if(array_key_exists('row_label', $config)) {
-			$config['data']['label'] = esc_attr($config['row_label']);
+		if(array_key_exists('add_label', $config)) {
+			$config['data']['label'] = esc_attr($config['add_label']);
 		}
 
 		$input = sprintf(
@@ -1607,16 +1651,21 @@
 		);
 
 		$input .= '<div class="repeater-items">';
-		$rowTitle = array_key_exists('new_row', $config) ? $config['new_row'] : 'New Item';
+
+        $hasTitle = array_key_exists('row_label', $config);
 		if(!empty($rows)) {
 			foreach ($rows as $index=>$row) {
-				$input .= static::renderRepeaterRow($config['fields'], $row, $index, $name, $rowTitle);
+                $titleReference = $hasTitle ? $config['row_label'] : null;
+                $rowTitle = !is_null($titleReference) ? $row[$titleReference] : 'New Item';
+
+				$input .= static::renderRepeaterRow($config['fields'], $row, $index, $name, $rowTitle, $titleReference);
 			}
 		}
 		$input .= '</div>';
 
+        $titleReference = $hasTitle ? $config['row_label'] : null;
 		$input .= '<template class="'.uniqid('repeaterRow').'">';
-			$input .= static::renderRepeaterRow($config['fields'], [], '','',$rowTitle);
+			$input .= static::renderRepeaterRow($config['fields'], [], '','','New Item', $titleReference);
 		$input .= '</template>';
 
 		$input .= sprintf(
@@ -1628,27 +1677,25 @@
 		unset($config['label']);
 		return static::fieldWrap($name, $input, $config);
 	}
-		protected static function renderRepeaterRow(array $fields, array $values, int|string $index, string $name, string $rowTitle='New Item'):string
+		protected static function renderRepeaterRow(array $fields, array $values, int|string $index, string $name, string $rowTitle='New Item', ?string $rowTitleField = null):string
 		{
 			$displayNumber = (is_string($index)) ? $index : ($index +1);
 
+
 			$output = sprintf(
-				'<div class="repeater-row" data-index="%s">
-						<button type="button" class="remove-row" title="Remove">
-							%s
-						</button>
+				'<div class="repeater-row row nowrap" data-index="%s">
+                        <span class="drag-handle row">%s</span>
 						<details%s>
-							<summary class="row btw repeater-row-header">
-								<span class="drag-handle">%s</span>
+							<summary class="row x-btw repeater-row-header">
 								<span class="row-number">#%s</span>
-								<span class="row-title">%s</span>
+								<span class="row-title"%s>%s</span>
 							</summary>
 							<div class="repeater-row-content">',
 				esc_attr($index),
-				jvbIcon('trash'),
+                jvbIcon('dots-six-vertical'),
 				is_string($index) ? ' open' : '',
-				jvbIcon('dots-six-vertical'),
 				$displayNumber,
+                is_null($rowTitleField) ? '' : 'data-label="'.$rowTitleField.'"',
 				$rowTitle
 			);
 			foreach ($fields as $fieldName => $fieldConfig) {
@@ -1657,7 +1704,11 @@
 				$output .= static::render($fullName, $fieldValue, $fieldConfig);
 			}
 
-			return $output.'</div></details></div>';
+			return $output.sprintf('</div></details><button type="button" class="remove-row" title="Remove">
+							%s
+						</button></div>',
+                    jvbIcon('trash'),
+                );
 		}
 
 	/**
@@ -1672,8 +1723,8 @@
 		$fields = $config['fields'] ?? [];
 		$values = is_array($value) ? $value : [];
 
-		$wrapper = (array_key_exists('wrap', $config)) ? 'details' : 'fieldset';
-		$legend = (array_key_exists('wrap', $config)) ? 'summary' : 'legend';
+		$wrapper = (array_key_exists('wrap', $config) && $config['wrap'] === 'details') ? 'details' : 'fieldset';
+		$legend = (array_key_exists('wrap', $config) && $config['wrap'] === 'details') ? 'summary' : 'legend';
 
 		$output = sprintf(
 			'<%s><%s>%s</%s>'
@@ -1686,7 +1737,7 @@
 
 		foreach ($fields as $fieldName => $fieldConfig) {
 			$fieldValue = $values[$fieldName] ?? '';
-			$fullName = array_key_exists('wrap', $config) ? $fieldName : "{$name}:{$fieldName}";
+			$fullName = "{$name}|{$fieldName}";
 			$output .= static::render($fullName, $fieldValue, $fieldConfig);
 		}
 
@@ -1700,7 +1751,7 @@
 	{
 		return sprintf('<dialog id="jvb-selector" aria-labelledby="modal-title" aria-modal="true">
 				<div class="wrap col">
-					<header class="modal-header">
+					<header class="row">
 						<h3 id="modal-title">Select Taxonomy</h3>
 					</header>
 
@@ -1710,8 +1761,8 @@
 					<div class="items-wrap">
 						<!-- Common/Favorite terms section -->
 						<details class="favourite-terms" hidden>
-							<summary class="title row btw">Your Go Tos:</summary>
-							<ul class="favourite-list row btw"></ul>
+							<summary class="title row x-btw">Your Go Tos:</summary>
+							<ul class="favourite-list row x-btw"></ul>
 						</details>
 
 						<!-- Pagination info -->
@@ -1729,7 +1780,7 @@
 							{ <span>loading items</span> }
 						</p>
 						<!-- Terms list -->
-						<ul class="items-container col start" role="listbox" aria-label="Available terms">
+						<ul class="items-container col top" role="listbox" aria-label="Available terms">
 							<!-- Terms will be populated here -->
 						</ul>
 
@@ -1748,7 +1799,7 @@
 
 					<!-- Create new term section -->
 					<details class="create-term" hidden>
-						<summary class="row btw">Add New Term</summary>
+						<summary class="row x-btw">Add New Term</summary>
 						<div class="create-new-term-section">
 							<form class="create-term" data-nocache data-form-id="create-term" data-save="terms">
 								<div class="form-group">
@@ -1794,33 +1845,46 @@
 			<template class="selectedTerm">
 				<div class="selected-item row">
 					<span class="item-name"></span>
-					<button type="button" class="remove-term row">%s</button>
+					<button type="button" class="remove-term">%s</button>
 				</div>
 			</template>
 			<template class="termBreadcrumb">
 				<button type="button" class="path-level"></button>
 			</template>',
-			static::search('Search terms', 'search-terms'),
+			str_replace('class="search-container', 'class="open search-container', static::search('Search terms', 'search-terms')),
 			 jvbModalActions(),
 			jvbIcon('plus-square'),
 			jvbIcon('x')
 		);
 	}
 
-	public static function search(string $placeholder = 'Search...', string $id = 'search'):string
+	public static function search(string $placeholder = 'Search...', string $id = 'search', string $label = '', string $buttonText = '',bool $buttonInside = false,  bool $hideSearch = false):string
 	{
 		$id = sanitize_title($id);
+		$label = empty($label) ? '' : sprintf(
+			'<h3>%s</h3>',
+			$label
+		);
+		$buttonText = empty($buttonText) ? '' : sprintf(
+			'<span>%s</span>',
+			$buttonText
+		);
+		$hideSearch = $hideSearch ? ' hidden' : '';
 		return sprintf(
-			'<div class="search-container row start nowrap">
-				<input type="search" id="%s" placeholder="%s">
+			'%s<div class="search-container row left nowrap%s">
+				<input type="search" id="%s" placeholder="%s"%s>
 				<button title="Clear Search" type="button" class="clear-search" aria-label="Clear search"
 					onclick="this.previousElementSibling.value = \'\'; this.previousElementSibling.focus();">%s</button>
-				<button type="button" title="Search" class="toggle search" aria-label="Toggles search input visually" onclick="this.parentNode.classList.toggle(\'open\');this.previousElementSibling.previousElementSibling.focus();">%s</button>
+				<button type="button" title="Search" class="toggle search" aria-label="Toggles search input visually" onclick="this.parentNode.classList.toggle(\'open\');this.previousElementSibling.previousElementSibling.focus();">%s%s</button>
 				</div>',
+			$label,
+			$buttonInside ? ' insideButton' : '',
 			$id,
 			$placeholder,
+			$hideSearch,
 			jvbIcon('x', ['title' => 'Clear Search']),
-			jvbIcon('magnifying-glass')
+			jvbIcon('magnifying-glass'),
+			$buttonText
 		);
 	}
 }

--
Gitblit v1.10.0