diff --git a/.betterer.results b/.betterer.results index c260f7d0a2e..abc27670fe4 100644 --- a/.betterer.results +++ b/.betterer.results @@ -25,9 +25,6 @@ exports[`better eslint`] = { "e2e/utils/support/types.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx:5381": [ - [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] - ], "packages/grafana-alerting/src/grafana/notificationPolicies/utils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -725,9 +722,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/Forms/Checkbox.story.tsx:5381": [ [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] ], - "packages/grafana-ui/src/components/Forms/FieldArray.story.tsx:5381": [ - [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] - ], "packages/grafana-ui/src/components/Forms/Form.story.tsx:5381": [ [0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"], [0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"], @@ -836,9 +830,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/QueryField/QueryField.story.tsx:5381": [ [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] ], - "packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx:5381": [ - [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] - ], "packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx:5381": [ [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "0"], [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "1"] @@ -860,9 +851,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/Segment/SegmentSelect.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-ui/src/components/Select/Select.story.tsx:5381": [ - [0, 0, 0, "Skipping a11y tests is not allowed. Please fix the component or story instead.", "0"] - ], "packages/grafana-ui/src/components/Select/SelectBase.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], diff --git a/packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx b/packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx index 46f3f72ed6f..9c0d2bcfa8b 100644 --- a/packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx +++ b/packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx @@ -1,8 +1,11 @@ -import type { Meta, StoryObj } from '@storybook/react'; +import type { Meta, StoryFn, StoryObj } from '@storybook/react'; +import { useId } from 'react'; + +import { Field } from '@grafana/ui'; import { defaultDecorators } from '../../../../../tests/story-utils'; -import { ContactPointSelector } from './ContactPointSelector'; +import { ContactPointSelector, ContactPointSelectorProps } from './ContactPointSelector'; import mdx from './ContactPointSelector.mdx'; import { simpleContactPointsListScenario, withErrorScenario } from './ContactPointSelector.test.scenario'; @@ -14,11 +17,18 @@ const meta: Meta = { docs: { page: mdx, }, - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, }, }; +const StoryRenderFn: StoryFn = (args) => { + const id = useId(); + return ( + + + + ); +}; + export default meta; type Story = StoryObj; @@ -28,6 +38,7 @@ export const Basic: Story = { handlers: simpleContactPointsListScenario, }, }, + render: StoryRenderFn, }; export const WithError: Story = { @@ -36,4 +47,5 @@ export const WithError: Story = { handlers: withErrorScenario, }, }, + render: StoryRenderFn, }; diff --git a/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx b/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx index 69179f5c0a2..50e4ca0e3cf 100644 --- a/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx @@ -6,6 +6,7 @@ import { Button } from '../Button/Button'; import { Input } from '../Input/Input'; import { Stack } from '../Layout/Stack/Stack'; +import { Field } from './Field'; import { FieldArray } from './FieldArray'; import mdx from './FieldArray.mdx'; import { Form } from './Form'; @@ -21,8 +22,6 @@ const meta: Meta = { controls: { exclude: ['name', 'keyName', 'control', 'shouldUnregister'], }, - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, }, argTypes: { containerWidth: { control: { type: 'range', min: 100, max: 500, step: 10 } }, @@ -46,16 +45,22 @@ export const Simple: StoryFn = (args) => {
{fields.map((field, index) => ( - - + + + + + + ))}
diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.tsx index 1c2fdd6c3e8..80748c58888 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.tsx @@ -285,7 +285,6 @@ const getStyles = (theme: GrafanaTheme2) => { gap: theme.spacing(1), marginLeft: theme.spacing(2), color: theme.colors.text.secondary, - opacity: 0.7, }), description: css({ ...theme.typography.bodySmall, diff --git a/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx b/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx index a6dfbf973eb..2d3cf51788a 100644 --- a/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx +++ b/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx @@ -14,8 +14,6 @@ const meta: Meta = { docs: { page: mdx, }, - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, }, argTypes: {}, args: { diff --git a/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.tsx b/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.tsx index 9eafa437690..af7907b9562 100644 --- a/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.tsx +++ b/packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.tsx @@ -40,7 +40,10 @@ export const ScrollContainer = forwardRef -
+ {/* scrollable containers need tabindex set so keyboard users can focus them to scroll */} + {/* see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/a7d1a12a6198d546c4a06477b385b4fde03b762e/docs/rules/no-noninteractive-tabindex.md#:~:text=If%20you%20know,scroll%20containers%22. */} + {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */} +
{showScrollIndicators ? {children} : children}
diff --git a/packages/grafana-ui/src/components/Select/Select.story.tsx b/packages/grafana-ui/src/components/Select/Select.story.tsx index bf3a92de89a..007ad839743 100644 --- a/packages/grafana-ui/src/components/Select/Select.story.tsx +++ b/packages/grafana-ui/src/components/Select/Select.story.tsx @@ -2,12 +2,13 @@ import { auto } from '@popperjs/core'; import { action } from '@storybook/addon-actions'; import { Meta, StoryFn } from '@storybook/react'; import Chance from 'chance'; -import { useState } from 'react'; +import { useId, useState } from 'react'; import { SelectableValue, toIconName } from '@grafana/data'; import { getAvailableIcons } from '../../types/icon'; import { Alert } from '../Alert/Alert'; +import { Field } from '../Forms/Field'; import { Icon } from '../Icon/Icon'; import { AsyncMultiSelect, AsyncSelect, MultiSelect, Select } from './Select'; @@ -72,8 +73,6 @@ const meta: Meta = { 'value', ], }, - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, }, args: { width: 0, @@ -113,10 +112,12 @@ interface StoryProps extends Partial> { export const Basic: StoryFn = (args) => { const [value, setValue] = useState>(); + const id = useId(); return ( - <> + = (args) => { }} {...args} /> - + ); }; @@ -153,9 +156,11 @@ export const BasicVirtualizedList: StoryFn = (args) => { */ export const BasicSelectPlainValue: StoryFn = (args) => { const [value, setValue] = useState(); + const id = useId(); return ( - <> + { @@ -199,7 +206,7 @@ export const SelectWithOptionDescriptions: StoryFn = (args) => { prefix={getPrefix(args.icon)} {...args} /> - + ); }; @@ -208,10 +215,12 @@ export const SelectWithOptionDescriptions: StoryFn = (args) => { */ export const MultiPlainValue: StoryFn = (args) => { const [value, setValue] = useState(); + const id = useId(); return ( - <> + { @@ -220,16 +229,18 @@ export const MultiPlainValue: StoryFn = (args) => { prefix={getPrefix(args.icon)} {...args} /> - + ); }; export const MultiSelectWithOptionGroups: StoryFn = (args) => { const [value, setValue] = useState(); + const id = useId(); return ( - <> + { prefix={getPrefix(args.icon)} {...args} /> - + ); }; export const MultiSelectWithOptionGroupsVirtualized: StoryFn = (args) => { const [value, setValue] = useState(); + const id = useId(); return ( - <> + { prefix={getPrefix(args.icon)} {...args} /> - + ); }; export const MultiSelectBasic: StoryFn = (args) => { const [value, setValue] = useState>>([]); + const id = useId(); return (
- { - setValue(v); - action('onChange')(v); - }} - prefix={getPrefix(args.icon)} - {...args} - /> + + { + setValue(v); + action('onChange')(v); + }} + prefix={getPrefix(args.icon)} + {...args} + /> +
); }; @@ -314,20 +331,24 @@ MultiSelectBasic.args = { export const MultiSelectBasicWithSelectAll: StoryFn = (args) => { const [value, setValue] = useState>>([]); + const id = useId(); return (
- { - setValue(v); - action('onChange')(v); - }} - prefix={getPrefix(args.icon)} - {...args} - /> + + { + setValue(v); + action('onChange')(v); + }} + prefix={getPrefix(args.icon)} + {...args} + /> +
); }; @@ -341,19 +362,23 @@ MultiSelectBasicWithSelectAll.args = { export const MultiSelectAsync: StoryFn = (args) => { const [value, setValue] = useState>>(); + const id = useId(); return ( - { - setValue(v); - action('onChange')(v); - }} - prefix={getPrefix(args.icon)} - {...args} - /> + + { + setValue(v); + action('onChange')(v); + }} + prefix={getPrefix(args.icon)} + {...args} + /> + ); }; MultiSelectAsync.args = { @@ -362,29 +387,35 @@ MultiSelectAsync.args = { export const BasicSelectAsync: StoryFn = (args) => { const [value, setValue] = useState>(); + const id = useId(); return ( - { - setValue(v); - action('onChange')(v); - }} - prefix={getPrefix(args.icon)} - {...args} - /> + + { + setValue(v); + action('onChange')(v); + }} + prefix={getPrefix(args.icon)} + {...args} + /> + ); }; export const AutoMenuPlacement: StoryFn = (args) => { const [value, setValue] = useState>(); + const id = useId(); return ( - <> -
+
+ { @@ -419,8 +452,8 @@ export const WidthAuto: StoryFn = (args) => { {...args} width="auto" /> -
- + +
); }; @@ -428,9 +461,11 @@ export const CustomValueCreation: StoryFn = (args) => { const [value, setValue] = useState>(); const [customOptions, setCustomOptions] = useState>>([]); const options = generateOptions(); + const id = useId(); return ( - <> +