diff --git a/packages/grafana-prometheus/src/querybuilder/shared/QueryOptionGroup.tsx b/packages/grafana-prometheus/src/querybuilder/shared/QueryOptionGroup.tsx index 8253d195ea0..451353512fe 100644 --- a/packages/grafana-prometheus/src/querybuilder/shared/QueryOptionGroup.tsx +++ b/packages/grafana-prometheus/src/querybuilder/shared/QueryOptionGroup.tsx @@ -19,6 +19,7 @@ export function QueryOptionGroup({ title, children, collapsedInfo }: Props) { return (
= (args) => { }} label={ - Collapse panel + My title { @@ -83,6 +83,7 @@ export const WithCustomLabel: StoryFn = (args) => { } + ariaLabel="My title" >

{args.children}

diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.tsx index 1a8ee9a8f33..8dd62c9932e 100644 --- a/packages/grafana-ui/src/components/Collapse/Collapse.tsx +++ b/packages/grafana-ui/src/components/Collapse/Collapse.tsx @@ -1,6 +1,5 @@ import { css, cx } from '@emotion/css'; -import { useId, useState } from 'react'; -import * as React from 'react'; +import { type PropsWithChildren, useId, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { t } from '@grafana/i18n'; @@ -92,11 +91,9 @@ const getStyles = (theme: GrafanaTheme2) => ({ }), }); -export interface Props { +interface BaseProps { /** Expand or collapse te content */ isOpen?: boolean; - /** Element or text for the Collapse header */ - label: React.ReactNode; /** Indicates loading state of the content */ loading?: boolean; /** Callback for the toggle functionality */ @@ -107,7 +104,20 @@ export interface Props { collapsible?: boolean; } -export const ControlledCollapse = ({ isOpen, onToggle, ...otherProps }: React.PropsWithChildren) => { +interface PropsWithStringLabel extends BaseProps { + label: string; + ariaLabel?: never; +} + +interface PropsWithCustomLabel extends BaseProps { + label: JSX.Element; + /** aria-label for the Collapse header. Required if passing a custom element as the label */ + ariaLabel: string; +} + +export type Props = PropsWithStringLabel | PropsWithCustomLabel; + +export const ControlledCollapse = ({ isOpen, onToggle, ...otherProps }: PropsWithChildren) => { const [open, setOpen] = useState(isOpen); return ( ) => { +export const Collapse = ({ + ariaLabel, + isOpen, + label, + loading, + onToggle, + className, + children, +}: PropsWithChildren) => { const style = useStyles2(getStyles); - const labelId = useId(); + const contentId = useId(); + const buttonLabel = + ariaLabel ?? (typeof label === 'string' ? label : t('grafana-ui.collapse.aria-label-default', 'Toggle collapse')); const onClickToggle = () => { if (onToggle) { @@ -141,21 +161,16 @@ export const Collapse = ({ isOpen, label, loading, onToggle, className, children {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
-
- {label} -
+
{label}
{isOpen && ( -
+
{children}
diff --git a/public/app/features/explore/CorrelationHelper.tsx b/public/app/features/explore/CorrelationHelper.tsx index 34fd82f52ec..004656b09df 100644 --- a/public/app/features/explore/CorrelationHelper.tsx +++ b/public/app/features/explore/CorrelationHelper.tsx @@ -171,6 +171,7 @@ export const CorrelationHelper = ({ exploreId, correlations }: Props) => { })} { setIsLabelDescOpen(!isLabelDescOpen); @@ -200,6 +201,7 @@ export const CorrelationHelper = ({ exploreId, correlations }: Props) => { { setIsTransformOpen(!isTransformOpen); diff --git a/public/app/features/explore/Logs/LogsContainer.tsx b/public/app/features/explore/Logs/LogsContainer.tsx index 4d06c3efcf4..13bc78b5849 100644 --- a/public/app/features/explore/Logs/LogsContainer.tsx +++ b/public/app/features/explore/Logs/LogsContainer.tsx @@ -308,7 +308,7 @@ class LogsContainer extends PureComponent - + {(controls) => ( @@ -326,7 +326,7 @@ class LogsContainer extends PureComponent - + Logs sample diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx index d48dabdf1fa..9418b467c08 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx @@ -151,7 +151,12 @@ export const SpanFilters = memo((props: SpanFilterProps) => { return (
- + diff --git a/public/app/features/visualization/data-hover/DataHoverRows.tsx b/public/app/features/visualization/data-hover/DataHoverRows.tsx index 0c9ca3759d7..d991dcc46ab 100644 --- a/public/app/features/visualization/data-hover/DataHoverRows.tsx +++ b/public/app/features/visualization/data-hover/DataHoverRows.tsx @@ -2,9 +2,9 @@ import { css } from '@emotion/css'; import { isString } from 'lodash'; import { FeatureLike } from 'ol/Feature'; import { useState } from 'react'; -import * as React from 'react'; import { DataFrame, FieldType, getFieldDisplayName, GrafanaTheme2 } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { Collapse, TabContent, useStyles2 } from '@grafana/ui'; import { GeomapLayerHover } from 'app/plugins/panel/geomap/event'; import { renderValue } from 'app/plugins/panel/geomap/utils/uiUtils'; @@ -37,6 +37,9 @@ export const DataHoverRows = ({ layers, activeTabIndex }: Props) => { return shouldDisplayCollapse ? ( { ); }; -export const generateLabel = (feature: FeatureLike, idx: number): string | React.ReactNode => { +export const generateLabel = (feature: FeatureLike, idx: number) => { const names = ['Name', 'name', 'Title', 'ID', 'id']; let props = feature.getProperties(); let first = ''; diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx index df27a4b83d8..f22bcddefd9 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx @@ -18,6 +18,7 @@ export function QueryOptionGroup({ title, children, collapsedInfo }: Props) { return (
{ window.localStorage.setItem(IS_LOKI_LOG_CONTEXT_UI_OPEN, (!isOpen).toString()); diff --git a/public/app/plugins/datasource/tempo/_importedDependencies/datasources/prometheus/QueryOptionGroup.tsx b/public/app/plugins/datasource/tempo/_importedDependencies/datasources/prometheus/QueryOptionGroup.tsx index dd68fa412ab..84bbd7d1ab5 100644 --- a/public/app/plugins/datasource/tempo/_importedDependencies/datasources/prometheus/QueryOptionGroup.tsx +++ b/public/app/plugins/datasource/tempo/_importedDependencies/datasources/prometheus/QueryOptionGroup.tsx @@ -24,6 +24,7 @@ export function QueryOptionGroup({ title, children, collapsedInfo, queryStats, o return (