Skip to content

Commit

Permalink
Radio group error (#2423)
Browse files Browse the repository at this point in the history
# Pull Request

## 🀨 Rationale

Includes `nimble-component` implementation for #2019

## πŸ‘©β€πŸ’» Implementation

- Adds `error-visible` and `error-text` attributes to the
`nimble-radio-group`
- Updates the radio group template to include an error icon and error
text
    - Note: This required forking FAST's template
- Updated radio group styling to match visual design

## πŸ§ͺ Testing

- Manually tested in storybook
- Forked FAST's radio group tests since the template was forked
- Updated matrix tests

## βœ… Checklist

<!--- Review the list and put an x in the boxes that apply or ~~strike
through~~ around items that don't (along with an explanation). -->

- [ ] I have updated the project documentation to reflect my changes or
determined no changes are needed.
  • Loading branch information
mollykreis authored Oct 9, 2024
1 parent 52a5408 commit 8aa7c1e
Show file tree
Hide file tree
Showing 8 changed files with 612 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Implement error states on nimble-radio-group",
"packageName": "@ni/nimble-components",
"email": "20542556+mollykreis@users.noreply.github.com",
"dependentChangeType": "patch"
}
12 changes: 10 additions & 2 deletions packages/nimble-components/src/radio-group/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
RadioGroup as FoundationRadioGroup,
radioGroupTemplate as template,
DesignSystem
} from '@microsoft/fast-foundation';
import { Orientation } from '@microsoft/fast-web-utilities';
import { attr } from '@microsoft/fast-element';
import { styles } from './styles';
import { template } from './template';
import type { ErrorPattern } from '../patterns/error/types';

declare global {
interface HTMLElementTagNameMap {
Expand All @@ -17,7 +19,13 @@ export { Orientation };
/**
* A nimble-styled grouping element for radio buttons
*/
export class RadioGroup extends FoundationRadioGroup {}
export class RadioGroup extends FoundationRadioGroup implements ErrorPattern {
@attr({ attribute: 'error-text' })
public errorText?: string;

@attr({ attribute: 'error-visible', mode: 'boolean' })
public errorVisible = false;
}

const nimbleRadioGroup = RadioGroup.compose({
baseName: 'radio-group',
Expand Down
17 changes: 17 additions & 0 deletions packages/nimble-components/src/radio-group/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import {
controlLabelDisabledFontColor,
controlLabelFont,
controlLabelFontColor,
controlLabelFontLineHeight,
smallPadding,
standardPadding
} from '../theme-provider/design-tokens';
import { styles as errorStyles } from '../patterns/error/styles';

export const styles = css`
${display('inline-block')}
${errorStyles}
.positioning-region {
display: flex;
gap: ${standardPadding};
position: relative;
}
:host([orientation='vertical']) .positioning-region {
Expand All @@ -23,6 +28,13 @@ export const styles = css`
flex-direction: row;
}
.label-container {
display: flex;
height: ${controlLabelFontLineHeight};
gap: ${smallPadding};
margin-bottom: ${smallPadding};
}
slot[name='label'] {
font: ${controlLabelFont};
color: ${controlLabelFontColor};
Expand All @@ -31,4 +43,9 @@ export const styles = css`
:host([disabled]) slot[name='label'] {
color: ${controlLabelDisabledFontColor};
}
.error-icon {
margin-left: auto;
margin-right: ${smallPadding};
}
`;
37 changes: 37 additions & 0 deletions packages/nimble-components/src/radio-group/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { elements, html, slotted } from '@microsoft/fast-element';
import { Orientation } from '@microsoft/fast-web-utilities';
import type { RadioGroup } from '.';
import { errorTextTemplate } from '../patterns/error/template';
import { iconExclamationMarkTag } from '../icons/exclamation-mark';

/* eslint-disable @typescript-eslint/indent */
export const template = html<RadioGroup>`
<template
role="radiogroup"
aria-disabled="${x => x.disabled}"
aria-readonly="${x => x.readOnly}"
@click="${(x, c) => x.clickHandler(c.event as MouseEvent)}"
@keydown="${(x, c) => x.keydownHandler(c.event as KeyboardEvent)}"
@focusout="${(x, c) => x.focusOutHandler(c.event as FocusEvent)}"
>
<div class="label-container">
<slot name="label"></slot>
<${iconExclamationMarkTag}
severity="error"
class="error-icon"
></${iconExclamationMarkTag}>
</div>
<div
class="positioning-region ${x => (x.orientation === Orientation.horizontal ? 'horizontal' : 'vertical')}"
part="positioning-region"
>
<slot
${slotted({
property: 'slottedRadioButtons',
filter: elements('[role=radio]')
})}
></slot>
${errorTextTemplate}
</div>
</template>
`;
Loading

0 comments on commit 8aa7c1e

Please sign in to comment.