0, 'right' => 0, 'bottom' => 0, 'left' => 0 ) );
$m_bottom = $J::defined( $margin, 'bottom' ) ? $J::get( $margin, 'bottom' ) : 15;
return $visibility_style . ' margin: ' . $J::str( $J::get( $margin, 'top' ) ) . 'px ' . $J::str( $J::get( $margin, 'right' ) ) . 'px ' . $J::str( $m_bottom ) . 'px ' . $J::str( $J::get( $margin, 'left' ) ) . 'px;';
}
/** `padding: ${fieldPadding.top}px ...` (fieldPadding = field.padding || zeros). */
protected function datetime_padding( $field ) {
$J = 'WPVFB_JS';
$p = $J::or_( $J::get( $field, 'padding' ), array( 'top' => 0, 'right' => 0, 'bottom' => 0, 'left' => 0 ) );
return 'padding: ' . $J::str( $J::get( $p, 'top' ) ) . 'px ' . $J::str( $J::get( $p, 'right' ) ) . 'px ' . $J::str( $J::get( $p, 'bottom' ) ) . 'px ' . $J::str( $J::get( $p, 'left' ) ) . 'px;';
}
/** onfocus/onblur/onmouseover/onmouseout border-color handlers. */
protected function datetime_handlers( $focus, $border, $hover ) {
$fb = $this->a( $focus );
$ib = $this->a( $border );
$hb = $this->a( $hover );
return 'data-wpvfb-border="' . $fb . '|' . $ib . '|' . $hb . '"';
}
/** Label block shared by time/name/date (hardcoded red asterisk span, as in the TS). */
protected function datetime_label( $field, $gs, $default_name ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
if ( 'none' === $g( 'labelPlacement' ) || 'hidden' === $f( 'labelVisibility' ) ) {
return '';
}
$label_font_size = ! $J::is_nullish( $J::nc( $f( 'wpvfbLabelFontSize' ), $f( 'fontSize' ) ) ) ? $J::nc( $f( 'wpvfbLabelFontSize' ), $f( 'fontSize' ) ) : $J::or_( $g( 'labelFontSize' ), 15 );
$label_lh_value = ! $J::is_nullish( $J::nc( $f( 'wpvfbLabelLineHeight' ), $f( 'lineHeight' ) ) ) ? $J::nc( $f( 'wpvfbLabelLineHeight' ), $f( 'lineHeight' ) ) : $J::or_( $g( 'labelLineHeight' ), $g( 'lineHeight' ), 1.5 );
$label_line_height = ( is_int( $label_lh_value ) || is_float( $label_lh_value ) ) ? $J::str( $label_lh_value ) . 'px' : $label_lh_value;
$label_font_weight = $J::defined( $field, 'labelFontWeight' ) ? $f( 'labelFontWeight' ) : $J::or_( $g( 'labelFontWeight' ), 600 );
$label_font_style = $J::or_( $f( 'labelFontStyle' ), 'normal' );
$left = 'left' === $g( 'labelPlacement' );
$lm_bottom = $J::defined( $field, 'labelMargin.bottom' ) ? $f( 'labelMargin.bottom' ) : 10;
return '';
}
/** Description
shared by time/name/date/html. */
protected function datetime_description( $field, $gs, $where, $desc_color ) {
$J = 'WPVFB_JS';
if ( $where !== $J::get( $gs, 'descriptionPlacement' ) || ! $J::truthy( $J::get( $field, 'description' ) ) ) {
return '';
}
return '
' . $this->t( $J::get( $field, 'description' ) ) . '
';
}
/** Absolutely positioned field icon . */
protected function datetime_icon( $field, $icon_position, $icon_color, $left_css, $right_css, $top ) {
return '';
}
/** String.prototype.replace(string, string): first occurrence only. */
protected function datetime_replace_first( $search, $replace, $subject ) {
$pos = strpos( $subject, $search );
return false === $pos ? $subject : substr_replace( $subject, $replace, $pos, strlen( $search ) );
}
protected function datetime_should_hide( $field ) {
$J = 'WPVFB_JS';
$v = $J::get( $field, 'visibility' );
return 'hidden' === $v || 'administrative' === $v || ( $J::truthy( $J::get( $field, 'enableConditionalLogic' ) ) && ! $J::truthy( $J::get( $field, 'conditionalLogicMet' ) ) );
}
// ------------------------------------------------------------------
/** renderTimeField — route.ts lines 5337-5561 */
public function render_time_field( $field, $gs ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
$visibility_style = $this->datetime_should_hide( $field ) ? 'display: none;' : '';
$custom_class = $J::truthy( $f( 'cssClassName' ) ) ? ' ' . $J::str( $f( 'cssClassName' ) ) : '';
$label_class = 'left' === $g( 'labelPlacement' ) ? 'flex items-start space-x-4 w-full' : 'flex flex-col';
$input_border_color = $J::or_( $f( 'inputBorderColor' ), $g( 'inputBorderColor' ), '#D1D5DB' );
$hover_border_color = $J::or_( $f( 'hoverBorderColor' ), $g( 'hoverBorderColor' ), '#6B7280' );
$focus_border_color = $J::or_( $f( 'focusBorderColor' ), $g( 'focusBorderColor' ), '#3B82F6' );
$input_background_color = $J::or_( $f( 'inputBackgroundColor' ), $g( 'inputBackgroundColor' ), '#F9FAFB' );
$placeholder_text_color = $J::or_( $f( 'placeholderTextColor' ), $g( 'placeholderTextColor' ), '#9CA3AF' );
$description_color = $J::or_( $f( 'descriptionColor' ), $g( 'descriptionColor' ), '#9CA3AF' );
$text_color = $J::or_( $f( 'textColor' ), $g( 'inputTextColor' ), $g( 'primaryTextColor' ), '#000000' );
$time_format = $J::or_( $f( 'timeFormat' ), '12hour' );
$is12 = '12hour' === $time_format;
$has_icon = $J::truthy( $f( 'fieldIcon' ) ) && 'none' !== $f( 'fieldIcon' );
$icon_position = $J::or_( $f( 'iconPosition' ), 'left' );
$icon_color = $J::or_( $f( 'iconColor' ), '#6B7280' );
$hour_placeholder = $J::or_( $f( 'subfields.hour.placeholder' ), 'HH' );
$minute_placeholder = $J::or_( $f( 'subfields.minute.placeholder' ), 'MM' );
$hour_value = $f( 'defaultValues.hour' ); // `?? undefined`: nullish → omitted
$minute_value = $f( 'defaultValues.minute' );
$ampm_value = $is12 ? $J::or_( $f( 'defaultValues.ampm' ), '' ) : '';
$input_styles = '
background-color: ' . $J::str( $input_background_color ) . ';
border-color: ' . $J::str( $input_border_color ) . ';
border-width: ' . $J::str( $J::or_( $g( 'inputSettings.borderWidth' ), 1 ) ) . 'px;
border-radius: ' . $J::str( $J::or_( $g( 'inputSettings.borderRadius' ), 4 ) ) . 'px;
border-style: solid !important;
font-family: inherit !important;
color: ' . $J::str( $text_color ) . ';
font-size: ' . $J::str( $g( 'fontSize' ) ) . 'px;
line-height: ' . $J::str( $g( 'lineHeight' ) ) . 'px;
letter-spacing: ' . $J::str( $g( 'letterSpacing' ) ) . 'px;
padding: 8px;
transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out;
text-align: center;
width: 100%;
';
$id_css = $this->css( $f( 'id' ) );
$ph = $this->css( $placeholder_text_color );
$placeholder_styles = '
input[id^="' . $id_css . '"]::placeholder {
color: ' . $ph . ' !important;
opacity: 1;
}
input[id^="' . $id_css . '"]:-ms-input-placeholder {
color: ' . $ph . ' !important;
}
input[id^="' . $id_css . '"]::-ms-input-placeholder {
color: ' . $ph . ' !important;
}
';
$width = $J::str( $J::or_( $f( 'width' ), '100%' ) );
$time_grid_styles = '
display: grid;
grid-template-columns: ' . ( $is12 ? '1fr auto 1fr 1fr' : '1fr auto 1fr' ) . ';
gap: 8px;
align-items: center;
width: ' . ( $has_icon ? 'calc(' . $width . ' - 24px)' : $width ) . ';
' . ( $has_icon ? 'margin-left: 24px;' : '' ) . '
';
$handlers = $this->datetime_handlers( $focus_border_color, $input_border_color, $hover_border_color );
$required_attr = $J::truthy( $f( 'required' ) ) ? 'data-required="true"' : '';
$id = $J::str( $f( 'id' ) );
$hour_input_html = '
a( $hour_value ) . '"' : '' ) . '
' . $required_attr . '
style="' . $this->a( $input_styles ) . '"
class="rounded-md border transition-all"
min="' . ( $is12 ? 1 : 0 ) . '"
max="' . ( $is12 ? 12 : 23 ) . '"
' . $handlers . '
data-wpvfb-clamp="1"
/>
';
$colon_html = '
:
';
$minute_input_html = '
a( $minute_value ) . '"' : '' ) . '
' . $required_attr . '
style="' . $this->a( $input_styles ) . '"
class="rounded-md border transition-all"
min="0"
max="59"
' . $handlers . '
data-wpvfb-clamp="1"
/>
';
$ampm_input_html = $is12 ? '
' : '';
$time_input_html = '
' . ( $has_icon ? $this->datetime_icon( $field, $icon_position, $icon_color, 'left: 0;', 'right: 0;', '50%' ) : '' ) . '
' . $hour_input_html . '
' . $colon_html . '
' . $minute_input_html . '
' . $ampm_input_html . '
';
return '
' . $this->add_inline_css( $placeholder_styles ) . '
' . $this->datetime_label( $field, $gs, 'Time' ) . '
' . $this->datetime_description( $field, $gs, 'above', $description_color ) . '
' . $time_input_html . '
' . $this->datetime_description( $field, $gs, 'below', $description_color ) . '
';
}
/** renderHtmlField — route.ts lines 5562-5638 */
public function render_html_field( $field, $gs ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
$visibility_style = $this->datetime_should_hide( $field ) ? 'display: none;' : '';
$custom_class = $J::truthy( $f( 'cssClassName' ) ) ? ' ' . $J::str( $f( 'cssClassName' ) ) : '';
$left = 'left' === $g( 'labelPlacement' );
$label_class = $left ? 'flex items-start space-x-4' : 'flex flex-col';
$description_color = $J::or_( $f( 'descriptionColor' ), $g( 'descriptionColor' ), '#9CA3AF' );
$html_content_styles = '
.html-content-wrapper,
.html-content-wrapper * {
font-size: 14px;
width: ' . $this->css( $J::or_( $f( 'width' ), '100%' ) ) . ';
}
';
$label_html = '';
if ( 'none' !== $g( 'labelPlacement' ) && 'hidden' !== $f( 'labelVisibility' ) ) {
$lm_bottom = $J::defined( $field, 'labelMargin.bottom' ) ? $f( 'labelMargin.bottom' ) : 10;
$label_html = '';
}
return '
' . $this->add_inline_css( $html_content_styles ) . '
' . $label_html . '
' . $this->h( $J::or_( $f( 'htmlContent' ), '
Enter your HTML content
' ) ) . '
' . $this->datetime_description( $field, $gs, 'below', $description_color ) . '
';
}
/** renderSectionField — route.ts lines 5639-5743 */
public function render_section_field( $field, $gs ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
if ( $this->datetime_should_hide( $field ) ) {
return '';
}
$custom_class = $J::truthy( $f( 'cssClassName' ) ) ? ' ' . $J::str( $f( 'cssClassName' ) ) : '';
$label_class = 'left' === $g( 'labelPlacement' ) ? 'flex items-start space-x-4' : 'flex flex-col';
$description_color = $J::or_( $f( 'descriptionColor' ), $g( 'descriptionColor' ), '#9CA3AF' );
// TS interpolates field.headingFormat raw as the tag name; only allow real heading/block tags.
$heading_tag = $J::str( $J::or_( $f( 'headingFormat' ), 'h3' ) );
if ( ! in_array( $heading_tag, array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div' ), true ) ) {
$heading_tag = 'h3';
}
$heading_font_size = ! $J::is_nullish( $J::nc( $f( 'wpvfbLabelFontSize' ), $f( 'fontSize' ) ) )
? $J::nc( $f( 'wpvfbLabelFontSize' ), $f( 'fontSize' ) )
: $J::or_( $g( 'headingFontSettings.headingFontSizes.' . $heading_tag ), $g( 'fontSize' ) );
$heading_lh_value = ! $J::is_nullish( $J::nc( $f( 'wpvfbLabelLineHeight' ), $f( 'lineHeight' ) ) )
? $J::nc( $f( 'wpvfbLabelLineHeight' ), $f( 'lineHeight' ) )
: $J::or_( $g( 'headingFontSettings.headingLineHeight' ), $g( 'lineHeight' ), 1.5 );
$heading_line_height = ( is_int( $heading_lh_value ) || is_float( $heading_lh_value ) ) ? $J::str( $heading_lh_value ) . 'px' : $heading_lh_value;
$font_weight = $J::defined( $field, 'labelFontWeight' ) ? $f( 'labelFontWeight' ) : 400;
$label_font_style = $J::or_( $f( 'labelFontStyle' ), 'normal' );
$heading_styles = '
color: ' . $J::str( $J::or_( $f( 'labelTextColor' ), $g( 'labelTextColor' ), $g( 'primaryTextColor' ) ) ) . ';
font-family: ' . $J::str( $J::or_( $f( 'fontFamily' ), $g( 'fontFamily' ) ) ) . ', sans-serif;
font-size: ' . $J::str( $heading_font_size ) . 'px;
line-height: ' . $J::str( $heading_line_height ) . ';
letter-spacing: ' . $J::str( $J::or_( $g( 'headingFontSettings.headingLetterSpacing' ), $g( 'letterSpacing' ) ) ) . 'px;
font-weight: ' . $J::str( $font_weight ) . ' !important;
font-style: ' . $J::str( $label_font_style ) . ';
';
$section_styles = '
margin-bottom: 16px;
width: ' . $J::str( $J::or_( $f( 'width' ), '100%' ) ) . ';
';
$desc = function ( $where ) use ( $J, $f, $g, $description_color ) {
if ( $where !== $g( 'descriptionPlacement' ) || ! $J::truthy( $f( 'description' ) ) ) {
return '';
}
return '
' . $this->t( $f( 'description' ) ) . '
';
};
$heading_html = 'hidden' !== $f( 'labelVisibility' )
? '<' . $heading_tag . ' style="' . $this->a( $heading_styles ) . '">
' . $this->t( $J::or_( $f( 'name' ), 'Section Heading' ) ) . '
' . $heading_tag . '>'
: '';
return '
' . $desc( 'above' ) . '
' . $heading_html . '
' . $desc( 'below' ) . '
';
}
/** renderNameField — route.ts lines 5744-6083 */
public function render_name_field( $field, $gs ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
$visibility_style = $this->datetime_should_hide( $field ) ? 'display: none;' : '';
$custom_class = $J::truthy( $f( 'cssClassName' ) ) ? ' ' . $J::str( $f( 'cssClassName' ) ) : '';
$label_class = 'left' === $g( 'labelPlacement' ) ? 'flex items-start space-x-4 w-full' : 'flex flex-col';
$input_border_color = $J::or_( $f( 'inputBorderColor' ), $g( 'inputBorderColor' ), '#D1D5DB' );
$hover_border_color = $J::or_( $f( 'hoverBorderColor' ), $g( 'hoverBorderColor' ), '#6B7280' );
$focus_border_color = $J::or_( $f( 'focusBorderColor' ), $g( 'focusBorderColor' ), '#3B82F6' );
$input_background_color = $J::or_( $f( 'inputBackgroundColor' ), $g( 'inputBackgroundColor' ), '#F9FAFB' );
$placeholder_text_color = $J::or_( $f( 'placeholderTextColor' ), $g( 'placeholderTextColor' ), '#9CA3AF' );
$description_color = $J::or_( $f( 'descriptionColor' ), $g( 'descriptionColor' ), '#9CA3AF' );
$text_color = $J::or_( $f( 'textColor' ), $g( 'inputTextColor' ), $g( 'primaryTextColor' ), '#000000' );
$has_icon = $J::truthy( $f( 'fieldIcon' ) ) && 'none' !== $f( 'fieldIcon' );
$icon_position = $J::or_( $f( 'iconPosition' ), 'left' );
$icon_color = $J::or_( $f( 'iconColor' ), '#6B7280' );
$input_padding = $has_icon
? ( 'left' === $icon_position ? '8px 8px 8px 32px' : '8px 32px 8px 8px' )
: '8px';
$input_styles = '
background-color: ' . $J::str( $input_background_color ) . ';
border-color: ' . $J::str( $input_border_color ) . ';
border-width: ' . $J::str( $J::or_( $g( 'inputSettings.borderWidth' ), 1 ) ) . 'px;
border-radius: ' . $J::str( $J::or_( $g( 'inputSettings.borderRadius' ), 4 ) ) . 'px;
border-style: solid !important;
font-family: inherit !important;
color: ' . $J::str( $text_color ) . ';
font-size: ' . $J::str( $g( 'fontSize' ) ) . 'px;
line-height: ' . $J::str( $g( 'lineHeight' ) ) . 'px;
letter-spacing: ' . $J::str( $g( 'letterSpacing' ) ) . 'px;
width: 100%;
box-sizing: border-box !important;
padding: ' . $input_padding . ';
transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out;
';
$sid = '#' . $this->css( $f( 'id' ) );
$ph = $this->css( $placeholder_text_color );
$sel = function ( $pseudo ) use ( $sid ) {
$out = array();
foreach ( array( 'prefix', 'first', 'middle', 'last', 'suffix' ) as $k ) {
$out[] = $sid . '-' . $k . $pseudo;
}
return implode( ",\n ", $out );
};
$placeholder_styles = '
' . $sel( '::placeholder' ) . ' {
color: ' . $ph . ' !important;
opacity: 1;
}
' . $sel( ':-ms-input-placeholder' ) . ' {
color: ' . $ph . ' !important;
}
' . $sel( '::-ms-input-placeholder' ) . ' {
color: ' . $ph . ' !important;
}
';
$sub_label_styles = '
font-size: 12px;
line-height: 16px;
color: #6B7280;
font-family: inherit !important;
';
$subfields = $f( 'subfields' );
$visible_count = 0;
if ( is_array( $subfields ) ) {
foreach ( $subfields as $sub ) {
if ( $J::truthy( $J::nc( $J::get( $sub, 'isVisible' ), false ) ) ) {
$visible_count++;
}
}
}
$visible_subfields_count = max( $visible_count, 2 );
$grid_styles = '
display: grid;
grid-template-columns: repeat(' . $visible_subfields_count . ', minmax(0, 1fr));
grid-template-areas: none;
gap: 8px;
width: ' . $J::str( $J::or_( $f( 'width' ), '100%' ) ) . ';
min-width: 0;
';
$name_field_responsive_styles = '
@media (max-width: 768px) {
.name-field-grid {
grid-template-columns: 1fr !important;
gap: 8px !important;
}
}
';
$prefix_default_value = $J::or_( $f( 'defaultPrefix' ), '' );
$prefix_options_html = '';
foreach ( $J::arr( $f( 'prefixOptions' ) ) as $option ) {
$ov = $J::get( $option, 'value' );
$prefix_options_html .= '';
}
$handlers = $this->datetime_handlers( $focus_border_color, $input_border_color, $hover_border_color );
$required_attr = $J::truthy( $f( 'required' ) ) ? 'data-required="true"' : '';
$id = $J::str( $f( 'id' ) );
$icon_html = $has_icon ? $this->datetime_icon( $field, $icon_position, $icon_color, 'left: 12px;', 'right: 12px;', '18px' ) : '';
$sub_label = function ( $key, $default ) use ( $J, $f, $sub_label_styles ) {
return '' . $this->t( $J::or_( $f( 'subfields.' . $key . '.label' ), $default ) ) . '';
};
$text_input = function ( $key, $placeholder_default, $label_default ) use ( $J, $f, $field, $id, $required_attr, $input_styles, $handlers, $icon_html, $sub_label ) {
if ( ! $J::truthy( $f( 'subfields.' . $key . '.isVisible' ) ) ) {
return '';
}
return '
' . $icon_html . '
' . $sub_label( $key, $label_default ) . '
';
};
$subfields_html = '';
if ( $J::truthy( $f( 'subfields.prefix.isVisible' ) ) ) {
$subfields_html .= '
' . $icon_html . '
' . $sub_label( 'prefix', 'Prefix' ) . '
';
}
$subfields_html .= $text_input( 'first', 'First Name', 'First' );
$subfields_html .= $text_input( 'middle', 'Middle', 'Middle' );
$subfields_html .= $text_input( 'last', 'Last Name', 'Last' );
$subfields_html .= $text_input( 'suffix', 'Suffix', 'Suffix' );
return '
' . $this->add_inline_css( $placeholder_styles ) . '
' . $this->datetime_label( $field, $gs, 'Name' ) . '
' . $this->datetime_description( $field, $gs, 'above', $description_color ) . '
' . $this->add_inline_css( $name_field_responsive_styles ) . '
' . $subfields_html . '
' . $this->datetime_description( $field, $gs, 'below', $description_color ) . '
';
}
/** renderDateField — route.ts lines 6084-6448 */
public function render_date_field( $field, $gs ) {
$J = 'WPVFB_JS';
$f = function ( $p ) use ( $field ) { return WPVFB_JS::get( $field, $p ); };
$g = function ( $p ) use ( $gs ) { return WPVFB_JS::get( $gs, $p ); };
$visibility_style = $this->datetime_should_hide( $field ) ? 'display: none;' : '';
$custom_class = $J::truthy( $f( 'cssClassName' ) ) ? ' ' . $J::str( $f( 'cssClassName' ) ) : '';
$label_class = 'left' === $g( 'labelPlacement' ) ? 'flex items-start space-x-4 w-full' : 'flex flex-col';
$input_border_color = $J::or_( $f( 'inputBorderColor' ), $g( 'inputBorderColor' ), '#D1D5DB' );
$hover_border_color = $J::or_( $f( 'hoverBorderColor' ), $g( 'hoverBorderColor' ), '#6B7280' );
$focus_border_color = $J::or_( $f( 'focusBorderColor' ), $g( 'focusBorderColor' ), '#3B82F6' );
$input_background_color = $J::or_( $f( 'inputBackgroundColor' ), $g( 'inputBackgroundColor' ), '#F9FAFB' );
$placeholder_text_color = $J::or_( $f( 'placeholderTextColor' ), $g( 'placeholderTextColor' ), '#9CA3AF' );
$description_color = $J::or_( $f( 'descriptionColor' ), $g( 'descriptionColor' ), '#9CA3AF' );
$text_color = $J::or_( $f( 'textColor' ), $g( 'inputTextColor' ), $g( 'primaryTextColor' ), '#000000' );
$date_input_type = $J::or_( $f( 'dateInputType' ), 'date-field' );
$date_format = $J::str( $J::or_( $f( 'dateFormat' ), 'mm/dd/yyyy' ) );
$placeholders = preg_split( '/[-\/.]/', $this->datetime_replace_first( 'yyyy', 'YYYY', $this->datetime_replace_first( 'dd', 'DD', $this->datetime_replace_first( 'mm', 'MM', $date_format ) ) ) );
$has_icon = $J::truthy( $f( 'fieldIcon' ) ) && 'none' !== $f( 'fieldIcon' );
$icon_position = $J::or_( $f( 'iconPosition' ), 'left' );
$icon_color = $J::or_( $f( 'iconColor' ), '#6B7280' );
$width = $J::str( $J::or_( $f( 'width' ), '100%' ) );
$input_styles = '
background-color: ' . $J::str( $input_background_color ) . ';
border-color: ' . $J::str( $input_border_color ) . ';
border-width: ' . $J::str( $J::or_( $g( 'inputSettings.borderWidth' ), 1 ) ) . 'px;
border-radius: ' . $J::str( $J::or_( $g( 'inputSettings.borderRadius' ), 4 ) ) . 'px;
border-style: solid !important;
font-family: inherit !important;
color: ' . $J::str( $text_color ) . ';
font-size: ' . $J::str( $g( 'fontSize' ) ) . 'px;
line-height: ' . $J::str( $g( 'lineHeight' ) ) . 'px;
letter-spacing: ' . $J::str( $g( 'letterSpacing' ) ) . 'px;
padding: 8px;
transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out;
width: ' . ( 'date-picker' === $date_input_type ? $width : '100%' ) . ';
';
$ph = $this->css( $placeholder_text_color );
$placeholder_styles = '
::placeholder {
color: ' . $ph . ' !important;
opacity: 1;
}
:-ms-input-placeholder {
color: ' . $ph . ' !important;
}
::-ms-input-placeholder {
color: ' . $ph . ' !important;
}
';
$default_month = $J::or_( $f( 'defaultValues.month' ), '' );
$default_day = $J::or_( $f( 'defaultValues.day' ), '' );
$default_year = $J::or_( $f( 'defaultValues.year' ), '' );
// Note: the stray "OI" before `width:` is in the the reference builder source (route.ts line 6158); kept for parity.
$grid_styles = '
display: flex;
gap: 8px;
OI width: ' . ( $has_icon ? 'calc(' . $width . ' - 24px)' : $width ) . ';
' . ( $has_icon ? 'margin-left: 24px;' : '' ) . '
';
$handlers = $this->datetime_handlers( $focus_border_color, $input_border_color, $hover_border_color );
$required_attr = $J::truthy( $f( 'required' ) ) ? 'data-required="true"' : '';
$id = $J::str( $f( 'id' ) );
$part_key = function ( $part ) {
$l = strtolower( $part );
return 'mm' === $l ? 'month' : ( 'dd' === $l ? 'day' : 'year' );
};
$default_for = function ( $key ) use ( $default_month, $default_day, $default_year ) {
return 'month' === $key ? $default_month : ( 'day' === $key ? $default_day : $default_year );
};
$icon_outside = $has_icon ? $this->datetime_icon( $field, $icon_position, $icon_color, 'left: 0;', 'right: 0;', '50%' ) : '';
// Date field (manual text inputs)
$parts_html = '';
foreach ( $placeholders as $part ) {
$key = $part_key( $part );
$max_length = 'year' === $key ? 4 : 2;
$parts_html .= '
';
}
$date_field_html = '
' . $icon_outside . '
' . $parts_html . '
';
// Date picker (Flatpickr)
$flatpickr_format = $this->datetime_replace_first( 'dd', 'd', $this->datetime_replace_first( 'mm', 'm', $this->datetime_replace_first( 'yyyy', 'Y', $date_format ) ) );
$default_date = '';
if ( $J::truthy( $f( 'defaultValues' ) ) ) {
$day = $f( 'defaultValues.day' );
$month = $f( 'defaultValues.month' );
$year = $f( 'defaultValues.year' );
if ( $J::truthy( $month ) && $J::truthy( $day ) && $J::truthy( $year ) ) {
$d = $J::str( $day );
$mo = $J::str( $month );
$y = $J::str( $year );
if ( 'mm/dd/yyyy' === $date_format ) {
$default_date = "{$mo}/{$d}/{$y}";
} elseif ( 'dd/mm/yyyy' === $date_format ) {
$default_date = "{$d}/{$mo}/{$y}";
} elseif ( 'yyyy-mm-dd' === $date_format ) {
$default_date = "{$y}-{$mo}-{$d}";
} elseif ( 'dd-mm-yyyy' === $date_format ) {
$default_date = "{$d}-{$mo}-{$y}";
} elseif ( 'yyyy/mm/dd' === $date_format ) {
$default_date = "{$y}/{$mo}/{$d}";
}
}
}
$c = function ( $v ) { return $this->css( $v ); };
$date_picker_styles = '
.flatpickr-wrapper {
position: relative;
width: ' . $c( $width ) . ';
}
.flatpickr-input {
background-color: ' . $c( $input_background_color ) . ' !important;
border-color: ' . $c( $input_border_color ) . ' !important;
border-width: ' . $c( $J::or_( $g( 'inputSettings.borderWidth' ), 1 ) ) . 'px !important;
border-radius: ' . $c( $J::or_( $g( 'inputSettings.borderRadius' ), 4 ) ) . 'px !important;
color: ' . $c( $text_color ) . ' !important;
font-size: ' . $c( $g( 'fontSize' ) ) . 'px !important;
padding: 8px ' . ( 'no-icon' !== $f( 'datePickerIcon' ) ? '32px' : '8px' ) . ' 8px 8px !important;
transition: border-color 0.2s ease-in-out;
width: 100%;
}
.flatpickr-input:hover {
border-color: ' . $c( $hover_border_color ) . ' !important;
}
.flatpickr-input:focus {
border-color: ' . $c( $focus_border_color ) . ' !important;
outline: none !important;
box-shadow: none !important;
}
.flatpickr-input::placeholder {
color: ' . $c( $placeholder_text_color ) . ' !important;
opacity: 1 !important;
}
.flatpickr-calendar {
font-family: ' . $c( $g( 'fontFamily' ) ) . ', sans-serif;
font-size: ' . $c( $g( 'fontSize' ) ) . 'px;
color: ' . $c( $text_color ) . ';
font-size: 12px !important;
}
.flatpickr-day {
font-size: 12px !important;
}
.flatpickr-yearDropdown {
font-size: 12px !important;
}
.flatpickr-monthDropdown-months {
font-size: 16px !important;
}
.flatpickr-time input {
font-size: 12px !important;
}
.flatpickr-icon {
font-size: 14px !important;
}
';
$placeholder = $f( 'placeholder' );
$picker_placeholder = ( $J::truthy( $placeholder ) && '' !== trim( $J::str( $placeholder ) ) ) ? $placeholder : $date_format;
$booking = $J::truthy( $f( 'bookingMode' ) );
$blackout_days = $J::is_array( $f( 'bookingBlackoutDays' ) ) ? $J::str( $f( 'bookingBlackoutDays' ) ) : '0,6';
$icon_pad = $has_icon ? ( 'left' === $icon_position ? 'padding-left: 32px !important;' : 'padding-right: 32px !important;' ) : '';
$date_picker_html = '
' . ( $has_icon ? $this->datetime_icon( $field, $icon_position, $icon_color, 'left: 12px;', 'right: 12px;', '50%' ) : '' ) . '
a( $J::or_( $f( 'bookingSlotDuration' ), 30 ) ) . '"' : '' ) . '
' . ( $booking ? 'data-booking-capacity="' . $this->a( $J::or_( $f( 'bookingCapacityPerSlot' ), 1 ) ) . '"' : '' ) . '
' . ( $booking ? 'data-booking-start-time="' . $this->a( $J::or_( $f( 'bookingStartTime' ), '09:00' ) ) . '"' : '' ) . '
' . ( $booking ? 'data-booking-end-time="' . $this->a( $J::or_( $f( 'bookingEndTime' ), '17:00' ) ) . '"' : '' ) . '
' . ( $booking ? 'data-booking-blackout-days="' . $this->a( $blackout_days ) . '"' : '' ) . '
' . ( $booking ? 'data-booking-blackout-dates="' . $this->a( $J::or_( $f( 'bookingBlackoutDates' ), '' ) ) . '"' : '' ) . '
' . $handlers . '
/>
' . ( 'no-icon' !== $f( 'datePickerIcon' )
? ''
: '' ) . '
' . ( $booking ? '
Select Available Timeslot:
' : '' ) . '
';
// Date dropdown
$months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );
$current_year = (int) gmdate( 'Y' );
$selects_html = '';
foreach ( $placeholders as $part ) {
$key = $part_key( $part );
$dv = $default_for( $key );
$sel = function ( $v ) use ( $dv ) {
return ( is_string( $dv ) && $dv === (string) $v ) ? 'selected' : '';
};
$options = '';
if ( 'month' === $key ) {
for ( $m = 0; $m < 12; $m++ ) {
$options .= '';
}
} elseif ( 'day' === $key ) {
for ( $d = 0; $d < 31; $d++ ) {
$options .= '';
}
} else {
for ( $i = 0; $i < 100; $i++ ) {
$yr = $current_year - $i;
$options .= '';
}
}
$selects_html .= '
';
}
// The TS leaves the outer .relative div unclosed here; kept as-is for parity.
$date_dropdown_html = '
' . $icon_outside . '
' . $selects_html . '
';
$date_input_html = 'date-field' === $date_input_type
? $date_field_html
: ( 'date-picker' === $date_input_type ? $date_picker_html : $date_dropdown_html );
return '
' . $this->add_inline_css( $placeholder_styles . ( 'date-picker' === $date_input_type ? $date_picker_styles : '' ) ) . '
' . $this->datetime_label( $field, $gs, 'Date Field' ) . '
' . $this->datetime_description( $field, $gs, 'above', $description_color ) . '
' . $date_input_html . '
' . $this->datetime_description( $field, $gs, 'below', $description_color ) . '
';
}
}