📱 fix: Resolve Android Device and Accessibility Issues of Sidebar Combobox (#3689)

* chore: Update @ariakit/react dependency to version 0.4.8

* refactor: Fix Combobox Android issue with radix-ui

* fix: Improve scrolling behavior by setting abort scroll state to false after scrolling to end

* wip: first pass switcher rewrite

* feat: Add button width calculation for ComboboxComponent

* refactor: Update ComboboxComponent styling for improved layout and appearance

* refactor: Update AssistantSwitcher component to handle null values for assistant names and avatar URLs

* refactor: Update ModelSwitcher component to use SimpleCombobox for improved functionality and styling

* refactor: Update Switcher Separator styling for improved layout and appearance

* refactor: Improve accessibility by adding aria-label to ComboboxComponent select items

* refactor: rename SimpleCombobox -> ControlCombobox
This commit is contained in:
Danny Avila 2024-08-18 19:02:46 -04:00 committed by GitHub
parent b22f1c166e
commit 87d95a9d82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 185 additions and 37 deletions

View file

@ -1,10 +1,10 @@
import { useEffect, useMemo } from 'react';
import { Combobox } from '~/components/ui';
import { isAssistantsEndpoint, LocalStorageKeys } from 'librechat-data-provider';
import type { AssistantsEndpoint } from 'librechat-data-provider';
import type { SwitcherProps, AssistantListItem } from '~/common';
import { useSetIndexOptions, useSelectAssistant, useLocalize, useAssistantListMap } from '~/hooks';
import { useChatContext, useAssistantsMapContext } from '~/Providers';
import ControlCombobox from '~/components/ui/ControlCombobox';
import Icon from '~/components/Endpoints/Icon';
export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
@ -31,7 +31,7 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
localStorage.getItem(`${LocalStorageKeys.ASST_ID_PREFIX}${index}${endpoint}`) ??
assistants[0]?.id ??
'';
const assistant = assistantMap?.[endpoint ?? '']?.[assistant_id];
const assistant = assistantMap[endpoint ?? ''][assistant_id];
if (!assistant) {
return;
@ -51,14 +51,14 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
const assistantOptions = useMemo(() => {
return assistants.map((assistant) => {
return {
label: assistant.name ?? '',
label: (assistant.name as string | null) ?? '',
value: assistant.id,
icon: (
<Icon
isCreatedByUser={false}
endpoint={endpoint}
assistantName={assistant.name ?? ''}
iconURL={(assistant.metadata?.avatar as string) ?? ''}
assistantName={(assistant.name as string | null) ?? ''}
iconURL={assistant.metadata?.avatar ?? ''}
/>
),
};
@ -66,7 +66,7 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
}, [assistants, endpoint]);
return (
<Combobox
<ControlCombobox
selectedValue={currentAssistant?.id ?? ''}
displayValue={
assistants.find((assistant) => assistant.id === selectedAssistant)?.name ??
@ -83,7 +83,7 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
isCreatedByUser={false}
endpoint={endpoint}
assistantName={currentAssistant?.name ?? ''}
iconURL={(currentAssistant?.metadata?.avatar as string) ?? ''}
iconURL={currentAssistant?.metadata?.avatar ?? ''}
/>
}
/>

View file

@ -1,10 +1,10 @@
import { useMemo, useRef, useCallback } from 'react';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import type { SwitcherProps } from '~/common';
import ControlCombobox from '~/components/ui/ControlCombobox';
import MinimalIcon from '~/components/Endpoints/MinimalIcon';
import { useSetIndexOptions, useLocalize } from '~/hooks';
import type { SwitcherProps } from '~/common';
import { useChatContext } from '~/Providers';
import { Combobox } from '~/components/ui';
import { mainTextareaId } from '~/common';
export default function ModelSwitcher({ isCollapsed }: SwitcherProps) {
@ -16,7 +16,10 @@ export default function ModelSwitcher({ isCollapsed }: SwitcherProps) {
const { endpoint, model = null } = conversation ?? {};
const models = useMemo(() => {
return modelsQuery?.data?.[endpoint ?? ''] ?? [];
return (modelsQuery.data?.[endpoint ?? ''] ?? []).map((model) => ({
label: model,
value: model,
}));
}, [modelsQuery, endpoint]);
const setModel = useCallback(
@ -34,7 +37,8 @@ export default function ModelSwitcher({ isCollapsed }: SwitcherProps) {
);
return (
<Combobox
<ControlCombobox
displayValue={model ?? ''}
selectPlaceholder={localize('com_ui_select_model')}
searchPlaceholder={localize('com_ui_select_search_model')}
isCollapsed={isCollapsed}

View file

@ -9,7 +9,7 @@ export default function Switcher(props: SwitcherProps) {
return (
<>
<AssistantSwitcher {...props} />
<Separator className="bg-gray-100/50 dark:bg-gray-600" />
<Separator className="max-w-[98%] bg-surface-tertiary" />
</>
);
} else if (isAssistantsEndpoint(props.endpoint)) {
@ -19,7 +19,7 @@ export default function Switcher(props: SwitcherProps) {
return (
<>
<ModelSwitcher {...props} />
<Separator className="bg-gray-100/50 dark:bg-gray-600" />
<Separator className="max-w-[98%] bg-surface-tertiary" />
</>
);
}