I was able to achieve my goal not by creating a custom control with multiple input fields but by creating creating a custom control which still accepted a single input, but would display inline with other controls.
Here’s the custom control for an inline numerical input:
class Customizer_Number_Inline_Control extends WP_Customize_Control {
public $fieldwidth="text";
public $type="number";
protected function render() {
$id = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
$class="customize-control customize-control-" . $this->type; ?>
<li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>" style="clear:none;display:inline-block;max-width:<?php echo $this->fieldwidth . "%"; ?>">
<?php $this->render_content(); ?>
</li>
<?php }
public function render_content() { ?>
<label class="inline">
<span class="customize-control-title" style="font-size:10px;line-height:10px;height:20px;"><?php echo esc_html( $this->label ); ?></span>
<input type="number" <?php $this->link(); ?> value="<?php echo intval( $this->value() ); ?>" />
</label>
<?php }
}
I added an additional parameter to set the width of the control so if you want to have three controls inline you set each of them to 33 (33%), if you want 2 you set each of them to 50%.. etc..
Implementing this into a setting looks something like this.
$wp_customize->add_setting( 'width', array (
'default' => '77',
'type' => 'option',
) );
$wp_customize->add_control( new Customizer_Number_Inline_Control( $wp_customize, 'width', array (
'label' => 'Width',
'type' => 'number',
'section' => 'site',
'priority' => 1,
'fieldwidth'=> '50', //set the field to 50% width so that we can display a second one next to it
) ) );