Skip to content

Experience Control: Improve accessibility and minor refactoring #103000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions client/a8c-for-agencies/components/a4a-feedback/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import './style.scss';

export function A4AFeedback( { type }: { type: FeedbackType } ) {
const translate = useTranslate();
const [ experience, setExperience ] = useState< string >( 'good' );
const [ experience, setExperience ] =
useState< React.ComponentProps< typeof ExperienceControl >[ 'value' ] >( 'good' );
const [ comments, setComments ] = useState< string >( '' );
const [ suggestions, setSuggestions ] = useState< FeedbackSuggestion[] >( [] );

Expand Down Expand Up @@ -46,7 +47,8 @@ export function A4AFeedback( { type }: { type: FeedbackType } ) {
<ExperienceControl
label={ translate( 'What was your experience like?' ) }
onChange={ ( experience ) => setExperience( experience ) }
selectedExperience={ experience }
value={ experience }
name="a4a-feedback-experience"
/>
{ suggestion && (
<FormFieldset>
Expand Down
8 changes: 8 additions & 0 deletions client/a8c-for-agencies/components/a4a-feedback/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ $highlight-color: #3858E9;
.form-fieldset {
margin-block-end: 0;
}

.a8c-experience-control .components-base-control__label {
@include heading-medium;
margin-block-end: 12px;
text-transform: uppercase;
color: var(--color-text);
}

}

.a4a-feedback__question-details {
Expand Down
6 changes: 4 additions & 2 deletions packages/calypso-storybook/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ module.exports = function storybookDefaultConfig( {
savePropValueAsString: true,
propFilter: ( prop ) => {
// Always show props declared in `@wordpress/components`
if ( prop.declarations.some( ( d ) => d.fileName.includes( '@wordpress/components' ) ) ) {
if (
prop.declarations?.some( ( d ) => d.fileName.includes( '@wordpress/components' ) )
) {
return true;
}

// Hide props declared in other `node_modules` (mostly built-in React props)
if ( prop.declarations.every( ( d ) => d.fileName.includes( 'node_modules' ) ) ) {
if ( prop.declarations?.every( ( d ) => d.fileName.includes( 'node_modules' ) ) ) {
return false;
}

Expand Down
84 changes: 0 additions & 84 deletions packages/components/src/experience-control/README.md

This file was deleted.

75 changes: 30 additions & 45 deletions packages/components/src/experience-control/icons.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,32 @@
export const IconGood = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon">
<path
id="Shape"
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.99452 13.0808C6.89004 13.0808 7.616 12.3549 7.616 11.4594C7.616 10.5638 6.89004 9.83789 5.99452 9.83789C5.09901 9.83789 4.37305 10.5638 4.37305 11.4594C4.37305 12.3549 5.09901 13.0808 5.99452 13.0808ZM18.0054 13.0808C18.901 13.0808 19.6269 12.3549 19.6269 11.4594C19.6269 10.5638 18.901 9.83789 18.0054 9.83789C17.1099 9.83789 16.384 10.5638 16.384 11.4594C16.384 12.3549 17.1099 13.0808 18.0054 13.0808ZM15.352 14.5221C13.6377 16.7223 10.493 17.1864 8.84968 14.7405C8.49299 14.2091 8.01618 14.0562 7.41927 14.2819C7.31736 14.3183 7.23185 14.382 7.16269 14.473C6.71865 15.0517 6.73138 15.6213 7.2009 16.1818C9.90335 19.4193 14.604 19.3756 17.0007 15.8542C17.4411 15.21 17.3137 14.7132 16.6186 14.3638L16.4439 14.2764C16.0107 14.0581 15.6468 14.1399 15.352 14.5221Z"
fill="#255C33"
/>
</g>
</svg>
);
};
export const IconGood = () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.99452 13.0808C6.89004 13.0808 7.616 12.3549 7.616 11.4594C7.616 10.5638 6.89004 9.83789 5.99452 9.83789C5.09901 9.83789 4.37305 10.5638 4.37305 11.4594C4.37305 12.3549 5.09901 13.0808 5.99452 13.0808ZM18.0054 13.0808C18.901 13.0808 19.6269 12.3549 19.6269 11.4594C19.6269 10.5638 18.901 9.83789 18.0054 9.83789C17.1099 9.83789 16.384 10.5638 16.384 11.4594C16.384 12.3549 17.1099 13.0808 18.0054 13.0808ZM15.352 14.5221C13.6377 16.7223 10.493 17.1864 8.84968 14.7405C8.49299 14.2091 8.01618 14.0562 7.41927 14.2819C7.31736 14.3183 7.23185 14.382 7.16269 14.473C6.71865 15.0517 6.73138 15.6213 7.2009 16.1818C9.90335 19.4193 14.604 19.3756 17.0007 15.8542C17.4411 15.21 17.3137 14.7132 16.6186 14.3638L16.4439 14.2764C16.0107 14.0581 15.6468 14.1399 15.352 14.5221Z"
fill="currentColor"
/>
</svg>
);

export const IconNeutral = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon">
<path
id="Shape"
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.99452 13.0808C6.89004 13.0808 7.616 12.3549 7.616 11.4594C7.616 10.5638 6.89004 9.83789 5.99452 9.83789C5.09901 9.83789 4.37305 10.5638 4.37305 11.4594C4.37305 12.3549 5.09901 13.0808 5.99452 13.0808ZM18.0054 13.0808C18.901 13.0808 19.6269 12.3549 19.6269 11.4594C19.6269 10.5638 18.901 9.83789 18.0054 9.83789C17.1099 9.83789 16.384 10.5638 16.384 11.4594C16.384 12.3549 17.1099 13.0808 18.0054 13.0808ZM7.57442 15.2678L16.4188 15.2832C16.9826 15.2842 17.4389 15.7421 17.438 16.3059L17.4377 16.4479C17.4367 17.0117 16.9788 17.468 16.415 17.467L7.57061 17.4516C7.00677 17.4506 6.55048 16.9927 6.55147 16.4289L6.55172 16.2869C6.5527 15.7231 7.01058 15.2668 7.57442 15.2678Z"
fill="#2F2F2F"
/>
</g>
</svg>
);
};
export const IconNeutral = () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.99452 13.0808C6.89004 13.0808 7.616 12.3549 7.616 11.4594C7.616 10.5638 6.89004 9.83789 5.99452 9.83789C5.09901 9.83789 4.37305 10.5638 4.37305 11.4594C4.37305 12.3549 5.09901 13.0808 5.99452 13.0808ZM18.0054 13.0808C18.901 13.0808 19.6269 12.3549 19.6269 11.4594C19.6269 10.5638 18.901 9.83789 18.0054 9.83789C17.1099 9.83789 16.384 10.5638 16.384 11.4594C16.384 12.3549 17.1099 13.0808 18.0054 13.0808ZM7.57442 15.2678L16.4188 15.2832C16.9826 15.2842 17.4389 15.7421 17.438 16.3059L17.4377 16.4479C17.4367 17.0117 16.9788 17.468 16.415 17.467L7.57061 17.4516C7.00677 17.4506 6.55048 16.9927 6.55147 16.4289L6.55172 16.2869C6.5527 15.7231 7.01058 15.2668 7.57442 15.2678Z"
fill="currentColor"
/>
</svg>
);

export const IconBad = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon">
<path
id="Shape"
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.99451 13.081C6.89002 13.081 7.61597 12.355 7.61597 11.4595C7.61597 10.564 6.89002 9.83801 5.99451 9.83801C5.09899 9.83801 4.37305 10.564 4.37305 11.4595C4.37305 12.355 5.09899 13.081 5.99451 13.081ZM18.0054 13.081C18.9009 13.081 19.6269 12.355 19.6269 11.4595C19.6269 10.564 18.9009 9.83801 18.0054 9.83801C17.1099 9.83801 16.384 10.564 16.384 11.4595C16.384 12.355 17.1099 13.081 18.0054 13.081ZM8.68587 17.0991C9.82145 15.3794 12.0708 14.7516 13.9052 15.7561C14.4784 16.0673 14.9043 16.5805 15.3137 17.0773C15.887 17.7652 16.7987 17.5577 17.099 16.717C17.169 16.5224 17.1866 16.3126 17.1503 16.1086C17.1139 15.9046 17.0247 15.7134 16.8915 15.5541C14.1181 12.2238 9.45021 12.2293 6.98797 15.8162C6.59489 16.3876 6.69497 16.8516 7.28824 17.2083L7.53939 17.3612C8.00527 17.6415 8.38742 17.5541 8.68587 17.0991Z"
fill="#660C0D"
/>
</g>
</svg>
);
};
export const IconBad = () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.99451 13.081C6.89002 13.081 7.61597 12.355 7.61597 11.4595C7.61597 10.564 6.89002 9.83801 5.99451 9.83801C5.09899 9.83801 4.37305 10.564 4.37305 11.4595C4.37305 12.355 5.09899 13.081 5.99451 13.081ZM18.0054 13.081C18.9009 13.081 19.6269 12.355 19.6269 11.4595C19.6269 10.564 18.9009 9.83801 18.0054 9.83801C17.1099 9.83801 16.384 10.564 16.384 11.4595C16.384 12.355 17.1099 13.081 18.0054 13.081ZM8.68587 17.0991C9.82145 15.3794 12.0708 14.7516 13.9052 15.7561C14.4784 16.0673 14.9043 16.5805 15.3137 17.0773C15.887 17.7652 16.7987 17.5577 17.099 16.717C17.169 16.5224 17.1866 16.3126 17.1503 16.1086C17.1139 15.9046 17.0247 15.7134 16.8915 15.5541C14.1181 12.2238 9.45021 12.2293 6.98797 15.8162C6.59489 16.3876 6.69497 16.8516 7.28824 17.2083L7.53939 17.3612C8.00527 17.6415 8.38742 17.5541 8.68587 17.0991Z"
fill="currentColor"
/>
</svg>
);
52 changes: 21 additions & 31 deletions packages/components/src/experience-control/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
import { useArgs } from '@storybook/preview-api';
import { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { ExperienceControl } from './index';

const meta: Meta< typeof ExperienceControl > = {
title: 'Unaudited/ExperienceControl',
title: 'packages/components/ExperienceControl',
component: ExperienceControl,
args: {
onChange: fn(),
},
render: function Render( args ) {
const [ { value }, updateArgs ] = useArgs();

return (
<ExperienceControl
{ ...args }
value={ value }
onChange={ ( newValue ) => {
updateArgs( { value: newValue } );
args.onChange?.( newValue );
} }
/>
);
},
};

export default meta;
Expand All @@ -12,35 +31,6 @@ type Story = StoryObj< typeof ExperienceControl >;
export const Default: Story = {
args: {
label: 'How was your experience?',
selectedExperience: 'good',
onChange: () => {},
},
};

export const WithHelpText: Story = {
args: {
label: 'Rate your satisfaction',
selectedExperience: 'good',
helpText: 'Please select an option that best describes your experience',
onChange: () => {},
value: 'good',
},
};

export const PreSelectedBad: Story = {
args: {
label: 'How was the support?',
selectedExperience: 'bad',
onChange: () => {},
},
};

// Example of using the Base component directly
export const CustomBase: Story = {
render: () => (
<ExperienceControl.Base label="Custom Experience Control">
<ExperienceControl.Option isSelected onClick={ () => {} }>
1
</ExperienceControl.Option>
</ExperienceControl.Base>
),
};
Loading