bindings
6 months ago
commands
2 weeks ago
pro
2 weeks ago
_acf-compatibility.js
1 year ago
_acf-condition-types.js
8 months ago
_acf-condition.js
1 year ago
_acf-conditions.js
1 year ago
_acf-field-accordion.js
6 months ago
_acf-field-button-group.js
8 months ago
_acf-field-checkbox.js
1 month ago
_acf-field-color-picker.js
8 months ago
_acf-field-date-picker.js
1 month ago
_acf-field-date-time-picker.js
1 month ago
_acf-field-file.js
1 month ago
_acf-field-google-map.js
6 months ago
_acf-field-icon-picker.js
1 month ago
_acf-field-image.js
1 month ago
_acf-field-link.js
1 year ago
_acf-field-oembed.js
1 month ago
_acf-field-page-link.js
1 year ago
_acf-field-post-object.js
1 year ago
_acf-field-radio.js
1 month ago
_acf-field-range.js
1 year ago
_acf-field-relationship.js
1 month ago
_acf-field-select.js
1 month ago
_acf-field-tab.js
1 month ago
_acf-field-taxonomy.js
8 months ago
_acf-field-time-picker.js
1 month ago
_acf-field-true-false.js
1 month ago
_acf-field-url.js
1 year ago
_acf-field-user.js
1 year ago
_acf-field-wysiwyg.js
1 month ago
_acf-field.js
1 year ago
_acf-fields.js
1 year ago
_acf-helpers.js
1 year ago
_acf-hooks.js
1 year ago
_acf-internal-post-type.js
8 months ago
_acf-media.js
2 weeks ago
_acf-modal.js
1 year ago
_acf-model.js
1 year ago
_acf-notice.js
8 months ago
_acf-panel.js
1 year ago
_acf-popup.js
8 months ago
_acf-postbox.js
1 year ago
_acf-screen.js
10 months ago
_acf-select2.js
1 year ago
_acf-tinymce.js
6 months ago
_acf-tooltip.js
10 months ago
_acf-unload.js
1 year ago
_acf-validation.js
1 month ago
_acf.js
7 months ago
_browse-fields-modal.js
8 months ago
_field-group-compatibility.js
1 year ago
_field-group-conditions.js
1 year ago
_field-group-field.js
4 months ago
_field-group-fields.js
10 months ago
_field-group-locations.js
1 year ago
_field-group-settings.js
1 year ago
_field-group.js
10 months ago
acf-escaped-html-notice.js
1 year ago
acf-field-group.js
1 year ago
acf-input.js
1 year ago
acf-internal-post-type.js
1 year ago
acf.js
1 year ago
_acf-field-button-group.js
98 lines
| 1 | import { update } from '@wordpress/icons'; |
| 2 | |
| 3 | ( function ( $, undefined ) { |
| 4 | const Field = acf.Field.extend( { |
| 5 | type: 'button_group', |
| 6 | |
| 7 | events: { |
| 8 | 'click input[type="radio"]': 'onClick', |
| 9 | 'keydown label': 'onKeyDown', |
| 10 | }, |
| 11 | |
| 12 | $control: function () { |
| 13 | return this.$( '.acf-button-group' ); |
| 14 | }, |
| 15 | |
| 16 | $input: function () { |
| 17 | return this.$( 'input:checked' ); |
| 18 | }, |
| 19 | initialize: function () { |
| 20 | this.updateButtonStates(); |
| 21 | }, |
| 22 | |
| 23 | setValue: function ( val ) { |
| 24 | this.$( 'input[value="' + val + '"]' ) |
| 25 | .prop( 'checked', true ) |
| 26 | .trigger( 'change' ); |
| 27 | this.updateButtonStates(); |
| 28 | }, |
| 29 | |
| 30 | updateButtonStates: function () { |
| 31 | const labels = this.$control().find( 'label' ); |
| 32 | const input = this.$input(); |
| 33 | labels |
| 34 | .removeClass( 'selected' ) |
| 35 | .attr( 'aria-checked', 'false' ) |
| 36 | .attr( 'tabindex', '-1' ); |
| 37 | if ( input.length ) { |
| 38 | // If there's a checked input, mark its parent label as selected |
| 39 | input |
| 40 | .parent( 'label' ) |
| 41 | .addClass( 'selected' ) |
| 42 | .attr( 'aria-checked', 'true' ) |
| 43 | .attr( 'tabindex', '0' ); |
| 44 | } else { |
| 45 | labels.first().attr( 'tabindex', '0' ); |
| 46 | } |
| 47 | }, |
| 48 | onClick: function ( e, $el ) { |
| 49 | this.selectButton( $el.parent( 'label' ) ); |
| 50 | }, |
| 51 | onKeyDown: function ( event, label ) { |
| 52 | const key = event.which; |
| 53 | |
| 54 | // Space or Enter: select the button |
| 55 | if ( key === 13 || key === 32 ) { |
| 56 | event.preventDefault(); |
| 57 | this.selectButton( label ); |
| 58 | return; |
| 59 | } |
| 60 | |
| 61 | // Arrow keys: move focus between buttons |
| 62 | if ( key === 37 || key === 39 || key === 38 || key === 40 ) { |
| 63 | event.preventDefault(); |
| 64 | const labels = this.$control().find( 'label' ); |
| 65 | const currentIndex = labels.index( label ); |
| 66 | let nextIndex; |
| 67 | |
| 68 | // Left/Up arrow: move to previous, wrap to last if at start |
| 69 | if ( key === 37 || key === 38 ) { |
| 70 | nextIndex = |
| 71 | currentIndex > 0 ? currentIndex - 1 : labels.length - 1; |
| 72 | } |
| 73 | // Right/Down arrow: move to next, wrap to first if at end |
| 74 | else { |
| 75 | nextIndex = |
| 76 | currentIndex < labels.length - 1 ? currentIndex + 1 : 0; |
| 77 | } |
| 78 | |
| 79 | const nextLabel = labels.eq( nextIndex ); |
| 80 | labels.attr( 'tabindex', '-1' ); |
| 81 | nextLabel.attr( 'tabindex', '0' ).trigger( 'focus' ); |
| 82 | } |
| 83 | }, |
| 84 | |
| 85 | selectButton: function ( element ) { |
| 86 | const inputRadio = element.find( 'input[type="radio"]' ); |
| 87 | const isSelected = element.hasClass( 'selected' ); |
| 88 | inputRadio.prop( 'checked', true ).trigger( 'change' ); |
| 89 | if ( this.get( 'allow_null' ) && isSelected ) { |
| 90 | inputRadio.prop( 'checked', false ).trigger( 'change' ); |
| 91 | } |
| 92 | this.updateButtonStates(); |
| 93 | }, |
| 94 | } ); |
| 95 | |
| 96 | acf.registerFieldType( Field ); |
| 97 | } )( jQuery ); |
| 98 |