refactor: improve accessibility and i18n for search components
• Replace label with ariaLabel prop • Add searchPlaceholder support • Use i18n keys for messages • Improve aria-label attributes • Standardize noResultsMessage fallback
This commit is contained in:
parent
ed5911f656
commit
ad247f2fc1
4 changed files with 20 additions and 12 deletions
|
|
@ -185,9 +185,11 @@ const GraphLabels = () => {
|
|||
renderOption={(item) => <div style={{ whiteSpace: 'pre' }}>{item}</div>}
|
||||
getOptionValue={(item) => item}
|
||||
getDisplayValue={(item) => <div style={{ whiteSpace: 'pre' }}>{item}</div>}
|
||||
notFound={<div className="py-6 text-center text-sm">No labels found</div>}
|
||||
label={t('graphPanel.graphLabels.label')}
|
||||
notFound={<div className="py-6 text-center text-sm">{t('graphPanel.graphLabels.noLabels')}</div>}
|
||||
ariaLabel={t('graphPanel.graphLabels.label')}
|
||||
placeholder={t('graphPanel.graphLabels.placeholder')}
|
||||
searchPlaceholder={t('graphPanel.graphLabels.placeholder')}
|
||||
noResultsMessage={t('graphPanel.graphLabels.noLabels')}
|
||||
value={label !== null ? label : '*'}
|
||||
onChange={(newLabel) => {
|
||||
const currentLabel = useSettingsStore.getState().queryLabel;
|
||||
|
|
|
|||
|
|
@ -215,8 +215,9 @@ export const GraphSearchInput = ({
|
|||
onFocus={(id) => {
|
||||
if (id !== messageId && onFocus) onFocus(id ? { id, type: 'nodes' } : null)
|
||||
}}
|
||||
label={'item'}
|
||||
ariaLabel={t('graphPanel.search.placeholder')}
|
||||
placeholder={t('graphPanel.search.placeholder')}
|
||||
noResultsMessage={t('graphPanel.search.placeholder')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ export interface AsyncSearchProps<T> {
|
|||
onChange: (value: string) => void
|
||||
/** Callback when focus changes */
|
||||
onFocus: (value: string) => void
|
||||
/** Label for the select field */
|
||||
label: string
|
||||
/** Accessibility label for the search field */
|
||||
ariaLabel?: string
|
||||
/** Placeholder text when no selection */
|
||||
placeholder?: string
|
||||
/** Disable the entire select */
|
||||
|
|
@ -67,7 +67,7 @@ export function AsyncSearch<T>({
|
|||
getOptionValue,
|
||||
notFound,
|
||||
loadingSkeleton,
|
||||
label,
|
||||
ariaLabel,
|
||||
placeholder = 'Select...',
|
||||
value,
|
||||
onChange,
|
||||
|
|
@ -179,6 +179,7 @@ export function AsyncSearch<T>({
|
|||
placeholder={placeholder}
|
||||
value={searchTerm}
|
||||
className="max-h-8"
|
||||
aria-label={ariaLabel}
|
||||
onFocus={handleFocus}
|
||||
onValueChange={(value) => {
|
||||
setSearchTerm(value)
|
||||
|
|
@ -198,7 +199,7 @@ export function AsyncSearch<T>({
|
|||
!error &&
|
||||
options.length === 0 &&
|
||||
(notFound || (
|
||||
<CommandEmpty>{noResultsMessage ?? `No ${label.toLowerCase()} found.`}</CommandEmpty>
|
||||
<CommandEmpty>{noResultsMessage || 'No results found.'}</CommandEmpty>
|
||||
))}
|
||||
<CommandGroup>
|
||||
{options.map((option, idx) => (
|
||||
|
|
|
|||
|
|
@ -43,10 +43,12 @@ export interface AsyncSelectProps<T> {
|
|||
value: string
|
||||
/** Callback when selection changes */
|
||||
onChange: (value: string) => void
|
||||
/** Label for the select field */
|
||||
label: string
|
||||
/** Accessibility label for the select field */
|
||||
ariaLabel?: string
|
||||
/** Placeholder text when no selection */
|
||||
placeholder?: string
|
||||
/** Display text for search placeholder */
|
||||
searchPlaceholder?: string
|
||||
/** Disable the entire select */
|
||||
disabled?: boolean
|
||||
/** Custom width for the popover *
|
||||
|
|
@ -76,8 +78,9 @@ export function AsyncSelect<T>({
|
|||
getDisplayValue,
|
||||
notFound,
|
||||
loadingSkeleton,
|
||||
label,
|
||||
ariaLabel,
|
||||
placeholder = 'Select...',
|
||||
searchPlaceholder,
|
||||
value,
|
||||
onChange,
|
||||
disabled = false,
|
||||
|
|
@ -200,6 +203,7 @@ export function AsyncSelect<T>({
|
|||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
aria-label={ariaLabel}
|
||||
className={cn(
|
||||
'justify-between',
|
||||
disabled && 'cursor-not-allowed opacity-50',
|
||||
|
|
@ -223,7 +227,7 @@ export function AsyncSelect<T>({
|
|||
<Command shouldFilter={false}>
|
||||
<div className="relative w-full border-b">
|
||||
<CommandInput
|
||||
placeholder={`Search ${label.toLowerCase()}...`}
|
||||
placeholder={searchPlaceholder || 'Search...'}
|
||||
value={searchTerm}
|
||||
onValueChange={(value) => {
|
||||
setSearchTerm(value)
|
||||
|
|
@ -244,7 +248,7 @@ export function AsyncSelect<T>({
|
|||
options.length === 0 &&
|
||||
(notFound || (
|
||||
<CommandEmpty>
|
||||
{noResultsMessage ?? `No ${label.toLowerCase()} found.`}
|
||||
{noResultsMessage || 'No results found.'}
|
||||
</CommandEmpty>
|
||||
))}
|
||||
<CommandGroup>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue