From 290ebbbfa711ba8a6d9e267b28e10ca3d6b0bcc0 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Thu, 23 Apr 2026 14:12:49 -0700 Subject: [PATCH 01/30] Accessibility improvements: add labels for input elements --- packages/components/package-lock.json | 4 +-- packages/components/package.json | 2 +- .../components/releaseNotes/components.md | 4 +++ packages/components/src/index.ts | 2 ++ .../src/internal/components/DateInput.tsx | 7 ++++ .../chart/ChartBuilderModal.test.tsx | 8 ++--- .../components/chart/ChartColorInputs.tsx | 17 +++++++--- .../chart/ChartFieldAggregateOptions.tsx | 5 +-- .../components/chart/ChartFieldOption.tsx | 3 +- .../components/chart/ChartLabelInput.tsx | 3 +- .../components/chart/ChartSettingsPanel.tsx | 9 +++-- .../components/chart/TrendlineOption.tsx | 8 +++-- ...IssuesListDefPropertiesPanel.test.tsx.snap | 2 ++ .../internal/components/editable/Controls.tsx | 3 +- .../components/editable/EditableGrid.tsx | 1 + .../entities/EntityMoveConfirmationModal.tsx | 1 + .../forms/input/RadioGroupInput.tsx | 1 + .../components/forms/input/SelectInput.tsx | 8 ++--- .../internal/components/search/SearchBox.tsx | 1 + .../components/src/internal/renderers.tsx | 1 + .../src/internal/util/utils.test.ts | 34 +++++++++++++++++++ .../components/src/internal/util/utils.ts | 10 ++++++ .../src/public/QueryModel/GridPanel.tsx | 1 + .../src/public/QueryModel/SearchBox.tsx | 1 + 24 files changed, 111 insertions(+), 25 deletions(-) diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index 20d3c73ad6..a5c841ae87 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.31.2", + "version": "7.31.3-develop.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.31.2", + "version": "7.31.3-develop.1", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/packages/components/package.json b/packages/components/package.json index e1456d220b..2187ee7eb6 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.31.2", + "version": "7.31.3-develop.1", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ diff --git a/packages/components/releaseNotes/components.md b/packages/components/releaseNotes/components.md index 99801d41c1..54cc043984 100644 --- a/packages/components/releaseNotes/components.md +++ b/packages/components/releaseNotes/components.md @@ -1,6 +1,10 @@ # @labkey/components Components, models, actions, and utility functions for LabKey applications and pages +### version TBD +*Released*: TBD +- Accessibility improvements: add labels or aria-labels to input elements + ### version 7.31.1 *Released*: 23 April 2026 - GitHub Issue 911: Fix overflow for field filtering modal diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 3fa5e576c2..a08517780f 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -73,6 +73,7 @@ import { quoteValueWithDelimiters, setIsTestEnv, splitMultiValueForImport, + stringToHtmlId, uncapitalizeFirstChar, valueIsEmpty, withTransformedKeys, @@ -1334,6 +1335,7 @@ export { genCellKey, GENERAL_ASSAY_PROVIDER_NAME, generateId, + stringToHtmlId, generateNameWithTimestamp, getActionErrorMessage, getActionValuesForFilterProps, diff --git a/packages/components/src/internal/components/DateInput.tsx b/packages/components/src/internal/components/DateInput.tsx index c7754e9102..7bafa0f195 100644 --- a/packages/components/src/internal/components/DateInput.tsx +++ b/packages/components/src/internal/components/DateInput.tsx @@ -4,6 +4,7 @@ import DatePicker, { DatePickerProps } from 'react-datepicker'; import { getDateFNSDateFormat, parseDateFNSTimeFormat } from '../util/Date'; import { Container } from './base/models/Container'; +import { stringToHtmlId } from '../util/utils'; export interface DateInputProps { container?: Container; @@ -33,9 +34,12 @@ export const DateInput: FC = memo(props => { [onSelect] ); + const id = stringToHtmlId(pickerProps.name) ?? 'date-input'; + return ( = memo(props => { ref={input} onSelect={onSelect_} /> + + {pickerProps.placeholderText} + diff --git a/packages/components/src/internal/components/chart/ChartBuilderModal.test.tsx b/packages/components/src/internal/components/chart/ChartBuilderModal.test.tsx index 031644ac82..0638a6751a 100644 --- a/packages/components/src/internal/components/chart/ChartBuilderModal.test.tsx +++ b/packages/components/src/internal/components/chart/ChartBuilderModal.test.tsx @@ -346,7 +346,7 @@ describe('ChartBuilderModal', () => { expect(document.querySelectorAll('input')).toHaveLength(21); expect(document.querySelector('input[value=automatic]').hasAttribute('checked')).toBe(true); expect(document.querySelector('input[value=manual]').hasAttribute('checked')).toBe(false); - expect(document.querySelector('input[name=aggregate-method]').getAttribute('value')).toBe('SUM'); + expect(document.querySelector('input[name=aggregateMethod]').getAttribute('value')).toBe('SUM'); expect(document.querySelectorAll('input[name=error-bar-method]')).toHaveLength(3); expect(document.querySelector('input[value=SD]').hasAttribute('checked')).toBe(false); expect(document.querySelector('input[value=SEM]').hasAttribute('checked')).toBe(false); @@ -388,7 +388,7 @@ describe('ChartBuilderModal', () => { expect(document.querySelectorAll('input')).toHaveLength(21); expect(document.querySelector('input[value=automatic]').hasAttribute('checked')).toBe(true); expect(document.querySelector('input[value=manual]').hasAttribute('checked')).toBe(false); - expect(document.querySelector('input[name=aggregate-method]').getAttribute('value')).toBe('MEAN'); + expect(document.querySelector('input[name=aggregateMethod]').getAttribute('value')).toBe('MEAN'); expect(document.querySelectorAll('input[name=error-bar-method]')).toHaveLength(3); expect(document.querySelector('input[value=SD]').hasAttribute('checked')).toBe(false); expect(document.querySelector('input[value=SEM]').hasAttribute('checked')).toBe(true); @@ -424,7 +424,7 @@ describe('ChartBuilderModal', () => { expect(document.querySelectorAll('input')).toHaveLength(19); expect(document.querySelector('input[name=x]').getAttribute('value')).toBe('field1'); expect(document.querySelector('input[name=y]').getAttribute('value')).toBe('field2'); - expect(document.querySelectorAll('input[name=aggregate-method]')).toHaveLength(0); + expect(document.querySelectorAll('input[name=aggregateMethod]')).toHaveLength(0); expect(document.querySelector('input[name=trendlineType]').getAttribute('value')).toBe('option1'); expect(document.querySelectorAll('input[name=trendlineAsymptoteMin]')).toHaveLength(0); expect(document.querySelectorAll('input[name=trendlineAsymptoteMax]')).toHaveLength(0); @@ -462,7 +462,7 @@ describe('ChartBuilderModal', () => { expect(document.querySelectorAll('input')).toHaveLength(19); expect(document.querySelector('input[name=x]').getAttribute('value')).toBe('field1'); expect(document.querySelector('input[name=y]').getAttribute('value')).toBe('field2'); - expect(document.querySelectorAll('input[name=aggregate-method]')).toHaveLength(0); + expect(document.querySelectorAll('input[name=aggregateMethod]')).toHaveLength(0); expect(document.querySelectorAll('input[name=trendlineType]')).toHaveLength(1); expect(document.querySelectorAll('.field-option-icon')).toHaveLength(2); // gear icon for x and y axis diff --git a/packages/components/src/internal/components/chart/ChartColorInputs.tsx b/packages/components/src/internal/components/chart/ChartColorInputs.tsx index 757a3c8cf7..44839a88ae 100644 --- a/packages/components/src/internal/components/chart/ChartColorInputs.tsx +++ b/packages/components/src/internal/components/chart/ChartColorInputs.tsx @@ -270,11 +270,12 @@ export const ChartColorInputs: FC = memo(({ chartConfig, {showColorPaletteScale && (
- + = memo(({ chartConfig, <>
- + = memo(({ chartConfig,
{!chartConfig.geomOptions?.hideDataPoints && (
- + = memo(({ chartConfig,
)}
- + = memo(props => { return ( <>
-