better accessibliity

This commit is contained in:
Nate Kelley 2025-10-07 21:55:32 -06:00
parent d6e3ab9a51
commit b6d7ba91c1
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
4 changed files with 49 additions and 21 deletions

View File

@ -32,11 +32,11 @@ export const GlobalSearchModal = () => {
selectedAssets,
selectedDateRange,
}),
[selectedAssets]
[selectedAssets, selectedDateRange]
);
const assetTypes: AssetType[] | undefined = useMemo(() => {
if (selectedAssets) {
if (selectedAssets?.length) {
return selectedAssets;
}
if (!hasQuery) {

View File

@ -2,7 +2,12 @@ import type { AssetType } from '@buster/server-shared/assets';
import React, { useMemo } from 'react';
import { Button } from '@/components/ui/buttons';
import { DateRangePickerContent } from '@/components/ui/date/DateRangePicker';
import { Dropdown, type DropdownProps, type IDropdownItem } from '@/components/ui/dropdown';
import {
createDropdownItem,
Dropdown,
type DropdownProps,
type IDropdownItem,
} from '@/components/ui/dropdown';
import BarsFilter from '@/components/ui/icons/NucleoIconOutlined/bars-filter';
import Calendar from '@/components/ui/icons/NucleoIconOutlined/calendar';
import Grid2 from '@/components/ui/icons/NucleoIconOutlined/grid-2';
@ -30,41 +35,59 @@ export const GlobalSearchModalFilters = React.memo(
value: 'metric_file' satisfies AssetType,
selected: selectedAssets?.includes('metric_file'),
icon: <ASSET_ICONS.metrics />,
onClick: () => setSelectedAssets([...(selectedAssets || []), 'metric_file']),
},
{
label: 'Chats',
value: 'chat' satisfies AssetType,
icon: <ASSET_ICONS.chats />,
onClick: () => setSelectedAssets([...(selectedAssets || []), 'chat']),
},
{
label: 'Reports',
value: 'report_file' satisfies AssetType,
icon: <ASSET_ICONS.reports />,
onClick: () => setSelectedAssets([...(selectedAssets || []), 'report_file']),
},
{
label: 'Dashboards',
value: 'dashboard_file',
icon: <ASSET_ICONS.dashboards />,
onClick: () => setSelectedAssets([...(selectedAssets || []), 'dashboard_file']),
},
{
label: 'Collections',
value: 'collection' satisfies AssetType,
icon: <ASSET_ICONS.collections />,
onClick: () => setSelectedAssets([...(selectedAssets || []), 'collection']),
},
].map((item) => ({
...item,
selected: selectedAssets?.includes(item.value as AssetType),
onClick: () => {
console.log(
'onClick',
item.value,
selectedAssets,
selectedAssets?.includes(item.value as AssetType)
);
if (selectedAssets?.includes(item.value as AssetType)) {
setSelectedAssets(selectedAssets.filter((v) => v !== item.value));
} else {
setSelectedAssets([...(selectedAssets || []), item.value as AssetType]);
}
},
})) as IDropdownItem<AssetType>['items'],
};
}, [selectedAssets, setSelectedAssets]);
const DatesDropdownItems: IDropdownItem = useMemo(() => {
return {
const closeContent = () => {
document.dispatchEvent(
new KeyboardEvent('keydown', {
key: 'Escape',
bubbles: true,
cancelable: true,
})
);
};
return createDropdownItem({
label: 'Date range',
value: 'date-range',
icon: <Calendar />,
@ -76,15 +99,9 @@ export const GlobalSearchModalFilters = React.memo(
disableDateAfter={getNow().add(12, 'hours').toDate()}
initialDateFrom={selectedDateRange?.from}
initialDateTo={selectedDateRange?.to}
cancelButtonText="Clear"
showResetButton={false}
onUpdate={({ range }) => {
document.dispatchEvent(
new KeyboardEvent('keydown', {
key: 'Escape',
bubbles: true,
cancelable: true,
})
);
if (range.from == null && range.to == null) {
setSelectedDateRange(null);
} else {
@ -93,11 +110,16 @@ export const GlobalSearchModalFilters = React.memo(
to: range.to ?? new Date(),
});
}
closeContent();
}}
onCancel={() => {
setSelectedDateRange(null);
closeContent();
}}
/>,
],
};
}, []);
});
}, [selectedDateRange, setSelectedDateRange]);
const items: DropdownProps['items'] = [AssetTypeDropdownItems, DatesDropdownItems];

View File

@ -185,6 +185,8 @@ export interface DateRangePickerContentProps {
onUpdate?: (values: { range: DateRange }) => void;
/** Callback when Cancel button is clicked */
onCancel?: () => void;
cancelButtonText?: string;
showResetButton?: boolean;
}
export const DateRangePickerContent: FC<DateRangePickerContentProps> = ({
@ -194,6 +196,8 @@ export const DateRangePickerContent: FC<DateRangePickerContentProps> = ({
disableDateAfter,
onUpdate,
onCancel,
cancelButtonText = 'Cancel',
showResetButton = false,
}) => {
const [range, setRange] = useState<DateRange>({
from: getDateAdjustedForTimezone(initialDateFrom),
@ -395,6 +399,7 @@ export const DateRangePickerContent: FC<DateRangePickerContentProps> = ({
<div className="flex justify-between gap-2 py-2 px-4 border-t">
<Button
variant="ghost"
className={cn(!showResetButton && 'invisible')}
onClick={() => {
setRange({
from: null,
@ -412,7 +417,7 @@ export const DateRangePickerContent: FC<DateRangePickerContentProps> = ({
}}
variant="ghost"
>
Cancel
{cancelButtonText}
</Button>
<Button
onClick={() => {

View File

@ -20,11 +20,12 @@ export const SearchInput: React.FC<
<div className="flex flex-col gap-y-0">
<div className="flex min-h-12 items-center space-x-3 justify-between px-5">
<Command.Input
className={cn('text-md placeholder:text-gray-light')}
className={cn('text-md placeholder:text-gray-light w-full h-full')}
value={searchValue}
placeholder={placeholder}
onValueChange={onChangeValue}
autoFocus={debouncedAutoFocus}
tabIndex={0}
/>
{filterContent}
</div>