mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TimeRangePicker: Improve screen reader support (#89409)
* Aria-expanded and tabs * Remove weird prop * Remove unused import * Fix padding * Use useId
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { isString } from 'lodash';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback, useId, useState } from 'react';
|
||||
|
||||
import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@@ -9,8 +9,8 @@ import { useStyles2 } from '../../../themes';
|
||||
import { t, Trans } from '../../../utils/i18n';
|
||||
import { Button } from '../../Button';
|
||||
import { Field } from '../../Forms/Field';
|
||||
import { RadioButtonGroup } from '../../Forms/RadioButtonGroup/RadioButtonGroup';
|
||||
import { Select } from '../../Select/Select';
|
||||
import { Tab, TabContent, TabsBar } from '../../Tabs';
|
||||
import { TimeZonePicker } from '../TimeZonePicker';
|
||||
import { TimeZoneDescription } from '../TimeZonePicker/TimeZoneDescription';
|
||||
import { TimeZoneOffset } from '../TimeZonePicker/TimeZoneOffset';
|
||||
@@ -36,6 +36,10 @@ export const TimePickerFooter = (props: Props) => {
|
||||
const [isEditing, setEditing] = useState(false);
|
||||
const [editMode, setEditMode] = useState('tz');
|
||||
|
||||
const timeSettingsId = useId();
|
||||
const timeZoneSettingsId = useId();
|
||||
const fiscalYearSettingsId = useId();
|
||||
|
||||
const onToggleChangeTimeSettings = useCallback(
|
||||
(event?: React.MouseEvent) => {
|
||||
if (event) {
|
||||
@@ -78,62 +82,79 @@ export const TimePickerFooter = (props: Props) => {
|
||||
variant="secondary"
|
||||
onClick={onToggleChangeTimeSettings}
|
||||
size="sm"
|
||||
aria-expanded={isEditing}
|
||||
aria-controls={timeSettingsId}
|
||||
icon={isEditing ? 'angle-up' : 'angle-down'}
|
||||
>
|
||||
<Trans i18nKey="time-picker.footer.change-settings-button">Change time settings</Trans>
|
||||
</Button>
|
||||
</section>
|
||||
{isEditing ? (
|
||||
<div className={style.editContainer}>
|
||||
<div>
|
||||
<RadioButtonGroup
|
||||
value={editMode}
|
||||
options={[
|
||||
{ label: t('time-picker.footer.time-zone-option', 'Time zone'), value: 'tz' },
|
||||
{ label: t('time-picker.footer.fiscal-year-option', 'Fiscal year'), value: 'fy' },
|
||||
]}
|
||||
onChange={setEditMode}
|
||||
></RadioButtonGroup>
|
||||
</div>
|
||||
{editMode === 'tz' ? (
|
||||
<section
|
||||
data-testid={selectors.components.TimeZonePicker.containerV2}
|
||||
className={cx(style.timeZoneContainer, style.timeSettingContainer)}
|
||||
>
|
||||
<TimeZonePicker
|
||||
includeInternal={true}
|
||||
onChange={(timeZone) => {
|
||||
onToggleChangeTimeSettings();
|
||||
|
||||
if (isString(timeZone)) {
|
||||
onChangeTimeZone(timeZone);
|
||||
}
|
||||
}}
|
||||
onBlur={onToggleChangeTimeSettings}
|
||||
menuShouldPortal={false}
|
||||
/>
|
||||
</section>
|
||||
) : (
|
||||
<section
|
||||
data-testid={selectors.components.TimeZonePicker.containerV2}
|
||||
className={cx(style.timeZoneContainer, style.timeSettingContainer)}
|
||||
>
|
||||
<Field
|
||||
className={style.fiscalYearField}
|
||||
label={t('time-picker.footer.fiscal-year-start', 'Fiscal year start month')}
|
||||
<div className={style.editContainer} id={timeSettingsId}>
|
||||
<TabsBar>
|
||||
<Tab
|
||||
label={t('time-picker.footer.time-zone-option', 'Time zone')}
|
||||
active={editMode === 'tz'}
|
||||
onChangeTab={() => {
|
||||
setEditMode('tz');
|
||||
}}
|
||||
aria-controls={timeZoneSettingsId}
|
||||
/>
|
||||
<Tab
|
||||
label={t('time-picker.footer.fiscal-year-option', 'Fiscal year')}
|
||||
active={editMode === 'fy'}
|
||||
onChangeTab={() => {
|
||||
setEditMode('fy');
|
||||
}}
|
||||
aria-controls={fiscalYearSettingsId}
|
||||
/>
|
||||
</TabsBar>
|
||||
<TabContent>
|
||||
{editMode === 'tz' ? (
|
||||
<section
|
||||
role="tabpanel"
|
||||
data-testid={selectors.components.TimeZonePicker.containerV2}
|
||||
id={timeZoneSettingsId}
|
||||
className={cx(style.timeZoneContainer, style.timeSettingContainer)}
|
||||
>
|
||||
<Select
|
||||
value={fiscalYearStartMonth}
|
||||
menuShouldPortal={false}
|
||||
options={monthOptions}
|
||||
onChange={(value) => {
|
||||
if (onChangeFiscalYearStartMonth) {
|
||||
onChangeFiscalYearStartMonth(value.value ?? 0);
|
||||
<TimeZonePicker
|
||||
includeInternal={true}
|
||||
onChange={(timeZone) => {
|
||||
onToggleChangeTimeSettings();
|
||||
|
||||
if (isString(timeZone)) {
|
||||
onChangeTimeZone(timeZone);
|
||||
}
|
||||
}}
|
||||
onBlur={onToggleChangeTimeSettings}
|
||||
menuShouldPortal={false}
|
||||
/>
|
||||
</Field>
|
||||
</section>
|
||||
)}
|
||||
</section>
|
||||
) : (
|
||||
<section
|
||||
role="tabpanel"
|
||||
data-testid={selectors.components.TimeZonePicker.containerV2}
|
||||
id={fiscalYearSettingsId}
|
||||
className={cx(style.timeZoneContainer, style.timeSettingContainer)}
|
||||
>
|
||||
<Field
|
||||
className={style.fiscalYearField}
|
||||
label={t('time-picker.footer.fiscal-year-start', 'Fiscal year start month')}
|
||||
>
|
||||
<Select
|
||||
value={fiscalYearStartMonth}
|
||||
menuShouldPortal={false}
|
||||
options={monthOptions}
|
||||
onChange={(value) => {
|
||||
if (onChangeFiscalYearStartMonth) {
|
||||
onChangeFiscalYearStartMonth(value.value ?? 0);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
</section>
|
||||
)}
|
||||
</TabContent>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -143,7 +164,7 @@ export const TimePickerFooter = (props: Props) => {
|
||||
const getStyle = (theme: GrafanaTheme2) => ({
|
||||
container: css({
|
||||
borderTop: `1px solid ${theme.colors.border.weak}`,
|
||||
padding: '11px',
|
||||
padding: theme.spacing(1.5),
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
@@ -151,7 +172,8 @@ const getStyle = (theme: GrafanaTheme2) => ({
|
||||
}),
|
||||
editContainer: css({
|
||||
borderTop: `1px solid ${theme.colors.border.weak}`,
|
||||
padding: '11px',
|
||||
padding: theme.spacing(1.5),
|
||||
paddingTop: 0,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user