diff --git a/addon/components/radio-button-input.hbs b/addon/components/radio-button-input.hbs new file mode 100644 index 00000000..8ef143f3 --- /dev/null +++ b/addon/components/radio-button-input.hbs @@ -0,0 +1 @@ + diff --git a/addon/components/radio-button-input.js b/addon/components/radio-button-input.js new file mode 100644 index 00000000..56f2fa82 --- /dev/null +++ b/addon/components/radio-button-input.js @@ -0,0 +1,33 @@ +import Component from '@glimmer/component'; +import { once } from '@ember/runloop'; +import { action } from '@ember/object'; + +/** + * The `` itself. + * + * A native replacement for `ember-radio-button`'s component of the same name, kept API- and + * DOM-identical so existing call sites and CSS are unaffected. See `radio-button.js`. + */ +export default class RadioButtonInputComponent extends Component { + /** + * `aria-checked` wants a string, and only when `checked` is genuinely boolean — an undefined + * `@checked` must leave the attribute off rather than render "undefined". + */ + get checkedStr() { + const checked = this.args.checked; + + if (typeof checked === 'boolean') { + return checked.toString(); + } + + return null; + } + + @action change() { + if (this.args.groupValue !== this.args.value) { + // Scheduled rather than called directly: a radio group swaps two inputs in the same + // interaction, and `once` collapses that into a single report of the new value. + once(this.args, 'changed', this.args.value); + } + } +} diff --git a/addon/components/radio-button.hbs b/addon/components/radio-button.hbs new file mode 100644 index 00000000..e0da2ace --- /dev/null +++ b/addon/components/radio-button.hbs @@ -0,0 +1,40 @@ +{{! template-lint-disable no-autofocus-attribute no-positive-tabindex }} +{{! Both rules exist to stop an author HARDCODING these. Here they are pass-through bindings — + the value is whatever the caller supplied, and dropping them would change the component's + argument list. `ember-radio-button`, which this replaces, forwarded both. }} +{{#if (has-block)}} + +{{else}} + +{{/if}} diff --git a/addon/components/radio-button.js b/addon/components/radio-button.js new file mode 100644 index 00000000..5aff5c56 --- /dev/null +++ b/addon/components/radio-button.js @@ -0,0 +1,51 @@ +import Component from '@glimmer/component'; +import { action } from '@ember/object'; +import { isEqual } from '@ember/utils'; + +/** + * A radio button bound to a group value. + * + * This is a native replacement for the `ember-radio-button` addon, which was pinned to a + * prerelease (3.0.0-beta.1) because its last stable release references the removed `Ember` global + * and throws on Ember 5. The component name, arguments and rendered DOM are identical, so call + * sites and stylesheets did not change. + * + * Arguments (all optional except `@value` and `@groupValue`): + * @value this button's value + * @groupValue the currently selected value; the button is checked when the two are equal + * @changed called with this button's value when it becomes selected + * @name @disabled @required @autofocus @tabindex forwarded to the input + * @radioClass class for the input, @radioId its id + * @classNames extra classes for the wrapping label (string or array) + * @checkedClass class added to the label while checked, default "checked" + * @ariaLabelledby @ariaDescribedby + * + * With a block it renders a `