Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0827a4c
feat(radio-group): add helperText and errorText properties
brandyscarney Feb 27, 2025
a8d5165
test(radio-group): add e2e test for supporting text
brandyscarney Feb 27, 2025
b945277
chore(): add updated snapshots
brandyscarney Feb 27, 2025
c1ac2bf
chore: build
brandyscarney Feb 27, 2025
f20d8ed
fix(radio-group): use inline block to avoid taking up entire width
brandyscarney Feb 27, 2025
fbf4f84
chore(): add updated snapshots
brandyscarney Feb 27, 2025
e3795e3
fix(radio-group): remove display
brandyscarney Feb 27, 2025
5c23457
chore(): add updated snapshots
brandyscarney Feb 27, 2025
ef31de3
fix(radio-group): fix firefox alignment
brandyscarney Feb 27, 2025
b9d8cb9
fix(angular): mark radio group as touched when radio is blurred
brandyscarney Feb 28, 2025
d71d7f4
style: lint
brandyscarney Feb 28, 2025
15c8a69
fix(radio-group): wrap slot in a div to resolve blurring on focus
brandyscarney Mar 4, 2025
5edfdcf
refactor(radio-group): change supporting-text class to radio-group-top
brandyscarney Mar 4, 2025
22d59cf
style: code comments
brandyscarney Mar 4, 2025
1e925ba
fix(radio-group): use proper classes and colors
brandyscarney Mar 4, 2025
5c8a1ab
test(radio-group): fix custom css
brandyscarney Mar 4, 2025
33417fe
chore(): add updated snapshots
brandyscarney Mar 4, 2025
55e1c29
fix(radio-group): use inline div to avoid extra spacing
brandyscarney Mar 4, 2025
051c74b
test(radio): update css to max 3 per row but wrap
brandyscarney Mar 4, 2025
11f607a
style: comment
brandyscarney Mar 4, 2025
c222328
Merge branch 'feature-8.5' into ROU-11554
brandyscarney Mar 4, 2025
eb42793
test(radio-group): update e2e test to verify correct element
brandyscarney Mar 5, 2025
d4230a0
Merge branch 'feature-8.5' into ROU-11554
brandyscarney Mar 5, 2025
a53ee64
style: add FW issue for tracking Stencil issue
brandyscarney Mar 5, 2025
cb10db6
fix(angular): add missing props
brandyscarney Mar 5, 2025
69db209
Merge branch 'feature-8.5' into ROU-11554
brandyscarney Mar 10, 2025
6a5f2f7
Merge branch 'feature-8.5' into ROU-11554
brandyscarney Mar 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,8 @@ ion-radio,part,mark
ion-radio-group,none
ion-radio-group,prop,allowEmptySelection,boolean,false,false,false
ion-radio-group,prop,compareWith,((currentValue: any, compareValue: any) => boolean) | null | string | undefined,undefined,false,false
ion-radio-group,prop,errorText,string | undefined,undefined,false,false
ion-radio-group,prop,helperText,string | undefined,undefined,false,false
ion-radio-group,prop,name,string,this.inputId,false,false
ion-radio-group,prop,value,any,undefined,false,false
ion-radio-group,event,ionChange,RadioGroupChangeEventDetail<any>,true
Expand Down
16 changes: 16 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,14 @@ export namespace Components {
* This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use strict equality (===) for comparison.
*/
"compareWith"?: string | RadioGroupCompareFn | null;
/**
* The error text to display at the top of the radio group.
*/
"errorText"?: string;
/**
* The helper text to display at the top of the radio group.
*/
"helperText"?: string;
/**
* The name of the control, which is submitted with the form data.
*/
Expand Down Expand Up @@ -7111,6 +7119,14 @@ declare namespace LocalJSX {
* This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use strict equality (===) for comparison.
*/
"compareWith"?: string | RadioGroupCompareFn | null;
/**
* The error text to display at the top of the radio group.
*/
"errorText"?: string;
/**
* The helper text to display at the top of the radio group.
*/
"helperText"?: string;
/**
* The name of the control, which is submitted with the form data.
*/
Expand Down
12 changes: 12 additions & 0 deletions core/src/components/radio-group/radio-group.ios.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import "../../themes/ionic.globals.ios";
@import "./radio-group";
@import "../item/item.ios.vars";

// iOS Radio Group Top in List
// --------------------------------------------------

// Add padding to the error and helper text when used in a
// list to align them with the list header and item text.
ion-list .radio-group-top {
@include padding-horizontal($item-ios-padding-start, $item-ios-padding-end);
}
12 changes: 12 additions & 0 deletions core/src/components/radio-group/radio-group.md.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import "../../themes/ionic.globals.md";
@import "./radio-group";
@import "../item/item.md.vars";

// Material Design Radio Group Top in List
// --------------------------------------------------

// Add padding to the error and helper text when used in a
// list to align them with the list header and item text.
ion-list .radio-group-top {
@include padding-horizontal($item-md-padding-start, $item-md-padding-end);
}
44 changes: 44 additions & 0 deletions core/src/components/radio-group/radio-group.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@import "../../themes/ionic.globals";

// Radio Group
// --------------------------------------------------

ion-radio-group {
// Prevents additional pixels from being rendered on top
vertical-align: top;
}

.radio-group-wrapper {
display: inline;
}

// Radio Group: Top
// --------------------------------------------------

.radio-group-top {
line-height: 1.5;
}

/**
* Error text should only be shown when .ion-invalid is present
* on the radio group. Otherwise the helper text should be shown.
*/
.radio-group-top .error-text {
display: none;

color: ion-color(danger, base);
}

.radio-group-top .helper-text {
display: block;

color: $text-color-step-300;
}

.ion-touched.ion-invalid .radio-group-top .error-text {
display: block;
}

.ion-touched.ion-invalid .radio-group-top .helper-text {
display: none;
}
74 changes: 73 additions & 1 deletion core/src/components/radio-group/radio-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ import type { RadioGroupChangeEventDetail, RadioGroupCompareFn } from './radio-g

@Component({
tag: 'ion-radio-group',
styleUrls: {
ios: 'radio-group.ios.scss',
md: 'radio-group.md.scss',
},
})
export class RadioGroup implements ComponentInterface {
private inputId = `ion-rg-${radioGroupIds++}`;
private helperTextId = `${this.inputId}-helper-text`;
private errorTextId = `${this.inputId}-error-text`;
private labelId = `${this.inputId}-lbl`;
private label?: HTMLIonLabelElement | null;

Expand Down Expand Up @@ -39,6 +45,16 @@ export class RadioGroup implements ComponentInterface {
*/
@Prop({ mutable: true }) value?: any | null;

/**
* The helper text to display at the top of the radio group.
*/
@Prop() helperText?: string;

/**
* The error text to display at the top of the radio group.
*/
@Prop() errorText?: string;

@Watch('value')
valueChanged(value: any | undefined) {
this.setRadioTabindex(value);
Expand Down Expand Up @@ -224,13 +240,69 @@ export class RadioGroup implements ComponentInterface {
radioToFocus?.setFocus();
}

/**
* Renders the helper text or error text values
*/
private renderHintText() {
const { helperText, errorText, helperTextId, errorTextId } = this;

const hasHintText = !!helperText || !!errorText;
if (!hasHintText) {
return;
}

return (
<div class="radio-group-top">
<div id={helperTextId} class="helper-text">
{helperText}
</div>
<div id={errorTextId} class="error-text">
{errorText}
</div>
</div>
);
}

private getHintTextID(): string | undefined {
const { el, helperText, errorText, helperTextId, errorTextId } = this;

if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
return errorTextId;
}

if (helperText) {
return helperTextId;
}

return undefined;
}

render() {
const { label, labelId, el, name, value } = this;
const mode = getIonMode(this);

renderHiddenInput(true, el, name, value, false);

return <Host role="radiogroup" aria-labelledby={label ? labelId : null} onClick={this.onClick} class={mode}></Host>;
return (
<Host
role="radiogroup"
aria-labelledby={label ? labelId : null}
aria-describedby={this.getHintTextID()}
aria-invalid={this.getHintTextID() === this.errorTextId}
onClick={this.onClick}
class={mode}
>
{this.renderHintText()}
{/*
TODO(FW-6279): Wrapping the slot in a div is a workaround due to a
Stencil issue. Without the wrapper, the children radio will fire the
blur event on focus, instead of waiting for them to be blurred.
*/}
<div class="radio-group-wrapper">
<slot></slot>
</div>
</Host>
);
}
}

Expand Down
Loading
Loading