Skip to main content

Button Set

A segmented control: every choice is visible on one row, as connected buttons. It covers single selection (radio semantics) and multiple selection (checkbox semantics) in one option type.

It is a presentation alternative to radio and checkboxes — the stored value is identical, so an existing option can switch to button-set without a data migration.

$options = [
'demo_button_set' => [
'label' => __( 'Button Set', 'unysonplus' ), // or false to hide the label column
'type' => 'button-set',
'value' => 'c2',
'desc' => __( 'Segmented control. Same stored value as a radio, shown on one row.',
'unysonplus' ),
'choices' => [
'c1' => __( 'Choice 1', 'unysonplus' ),
'c2' => __( 'Choice 2', 'unysonplus' ),
'c3' => __( 'Choice 3', 'unysonplus' ),
],
// — Optional attributes you can add —
// 'multiple' => true, // checkbox semantics; value becomes an array
// 'stretch' => true, // buttons share the row width evenly
// 'show_labels' => false, // icon-only buttons (label becomes the tooltip)
// 'allow_deselect' => true, // single mode: click the active button to clear it
// 'attr' => [ 'class' => 'my-class', 'data-foo' => 'bar' ],
],
];

Options

KeyTypeDefaultWhat it does
choicesarray[]key => label, or key => [ 'label' => …, 'icon' => … ]
valuestring / arraynullThe choice key, or [ key => true ] when multiple
multipleboolfalsefalse = radio semantics, true = checkbox semantics
stretchboolfalseButtons share the row evenly instead of sizing to their content
show_labelsbooltruefalse renders icon-only buttons
allow_deselectboolfalseSingle mode only — click the active button to clear the value

Icons

A choice can be a plain string, or an array with an icon class. The two forms can be mixed in the same set:

'choices' => [
'left' => [ 'label' => __( 'Left', 'unysonplus' ), 'icon' => 'dashicons dashicons-editor-alignleft' ],
'center' => __( 'Center', 'unysonplus' ),
'right' => [ 'label' => __( 'Right', 'unysonplus' ), 'icon' => 'dashicons dashicons-editor-alignright' ],
],

With 'show_labels' => false the buttons show only the icon, and the label becomes the button's tooltip and its accessible name — so nothing is lost for screen readers. This is the usual setup for alignment, heading-tag and layout pickers.

Colors are not configurable

The control inherits --wp-admin-theme-color through the framework's --fw-accent token, so it follows the admin color scheme the user chose. A per-option color would override that preference and break consistency with the rest of the panel. If a theme genuinely needs a different look, override the CSS custom property rather than adding an option key.

Accessibility

The control is built on native <input type="radio"> / <input type="checkbox"> elements with the input visually hidden and its <label> styled as the button. Keyboard navigation, focus rings, screen-reader group semantics and form serialization are all handled by the browser — there is no JavaScript involved in selection, and no third-party library.

Reading the value

Single (default)

button-set returns the choice key as a string, exactly like radio.

// In a shortcode — values arrive as $atts in view.php
$value = $atts['demo_button_set']; // e.g. 'c2'

// A per-page option (metabox)
$value = fw_get_db_post_option( get_the_ID(), 'demo_button_set' );

// A global option in Theme Settings
$value = fw_get_db_settings_option( 'demo_button_set' );

echo esc_html( $value );

When the field sits inside a box/group, read the group once and pick the field by key:

$book = fw_get_db_post_option( get_the_ID(), 'book' );
$value = $book['demo_button_set'];

Multiple

With 'multiple' => true it returns an array in the same shape as checkboxes — only the selected keys are present, each set to true:

$value = fw_get_db_settings_option( 'demo_button_set_multi' );

echo esc_html( implode( ', ', array_keys( $value ) ) ); // the selected keys

if ( ! empty( $value['header'] ) ) {
// 'header' is selected
}

Saved value

fw_print( fw_get_db_settings_option( 'demo_button_set' ) ) — single mode:

c2

fw_print( fw_get_db_settings_option( 'demo_button_set_multi' ) ) — multiple mode:

Array
(
[header] => 1
[sidebar] => 1
)

With 'allow_deselect' => true and nothing selected, single mode stores an empty string (''), which is how an option expresses "no override".

Migrating from radio or checkboxes

The value shapes match, so switching is a one-line change and existing saved values keep working:

'align' => [
- 'type' => 'radio',
+ 'type' => 'button-set',
'value' => 'center',
'choices' => [ 'left' => 'Left', 'center' => 'Center', 'right' => 'Right' ],
],

See also

  • radio — the same single-choice value, as a vertical list
  • checkboxes — the same multi-choice value, as a checkbox list
  • switch — a two-state toggle with custom labels
  • image-picker — choose one option by clicking an image swatch