fix empty value and close combobox input on select (#7590)

This commit is contained in:
James Gatz 2024-06-26 11:03:18 +02:00 committed by GitHub
parent e410998552
commit aaabdfdd79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,5 @@
import { IconName } from '@fortawesome/fontawesome-svg-core'; import { IconName } from '@fortawesome/fontawesome-svg-core';
import React, { Fragment } from 'react'; import React, { Fragment, useRef } from 'react';
import { Button, ComboBox, Dialog, DialogTrigger, Heading, Input, ListBox, ListBoxItem, Popover } from 'react-aria-components'; import { Button, ComboBox, Dialog, DialogTrigger, Heading, Input, ListBox, ListBoxItem, Popover } from 'react-aria-components';
import { useFetcher, useNavigate, useParams, useRouteLoaderData } from 'react-router-dom'; import { useFetcher, useNavigate, useParams, useRouteLoaderData } from 'react-router-dom';
@ -50,6 +50,8 @@ export const EnvironmentPicker = ({
const navigate = useNavigate(); const navigate = useNavigate();
const globalEnvironmentListBox = useRef<HTMLDivElement>(null);
return ( return (
<DialogTrigger isOpen={isOpen} onOpenChange={onOpenChange}> <DialogTrigger isOpen={isOpen} onOpenChange={onOpenChange}>
<Button className="py-1 px-4 max-w-full gap-2 truncate flex items-center justify-center aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all text-sm"> <Button className="py-1 px-4 max-w-full gap-2 truncate flex items-center justify-center aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all text-sm">
@ -72,25 +74,6 @@ export const EnvironmentPicker = ({
key={activeEnvironment._id} key={activeEnvironment._id}
items={collectionEnvironmentList} items={collectionEnvironmentList}
disabledKeys={selectedEnvironments.map(e => e.id)} disabledKeys={selectedEnvironments.map(e => e.id)}
// disallowEmptySelection
// onSelectionChange={selection => {
// if (selection === 'all') {
// return;
// }
// const environmentId = selection.values().next().value;
// setActiveEnvironmentFetcher.submit(
// {
// environmentId,
// },
// {
// method: 'POST',
// action: `/organization/${organizationId}/project/${projectId}/workspace/${workspaceId}/environment/set-active`,
// }
// );
// }}
// selectedKeys={[activeEnvironment._id || '']}
onAction={environmentId => { onAction={environmentId => {
setActiveEnvironmentFetcher.submit( setActiveEnvironmentFetcher.submit(
{ {
@ -149,71 +132,77 @@ export const EnvironmentPicker = ({
</Button> </Button>
)} )}
</Heading> </Heading>
<ComboBox <div>
aria-label='Global Environment' <ComboBox
shouldFocusWrap aria-label='Global Environment'
allowsCustomValue={false} shouldFocusWrap
menuTrigger='focus' key={activeGlobalBaseEnvironment?._id}
defaultFilter={(textValue, filter) => { allowsCustomValue={false}
const match = Boolean(fuzzyMatch( menuTrigger='focus'
filter, defaultFilter={(textValue, filter) => {
textValue, const match = Boolean(fuzzyMatch(
{ splitSpace: false, loose: true } filter,
)?.indexes); textValue,
{ splitSpace: false, loose: true }
)?.indexes);
return match; return match;
}} }}
onSelectionChange={environmentId => { onSelectionChange={environmentId => {
if (environmentId === 'all' || !environmentId) { if (environmentId === 'all' || environmentId === null) {
return; return;
}
setActiveGlobalEnvironmentFetcher.submit(
{
environmentId,
},
{
method: 'POST',
action: `/organization/${organizationId}/project/${projectId}/workspace/${workspaceId}/environment/set-active-global`,
} }
);
}} setActiveGlobalEnvironmentFetcher.submit(
inputValue={selectedGlobalBaseEnvironment?.workspaceName || selectedGlobalBaseEnvironment?.name || ''} {
selectedKey={selectedGlobalBaseEnvironmentId} environmentId,
defaultItems={[...globalBaseEnvironments.map(baseEnv => { },
return { {
id: baseEnv._id, method: 'POST',
icon: 'code', action: `/organization/${organizationId}/project/${projectId}/workspace/${workspaceId}/environment/set-active-global`,
name: baseEnv.workspaceName || baseEnv.name, }
textValue: baseEnv.workspaceName || baseEnv.name, );
};
}), { id: '', icon: 'cancel', name: 'No Global Environment', textValue: 'No Global Environment' }]} globalEnvironmentListBox.current?.focus();
> }}
<div className='px-2 mx-2 my-2 flex items-center gap-2 group rounded-sm border border-solid border-[--hl-sm] bg-[--color-bg] text-[--color-font] focus:outline-none focus:ring-1 focus:ring-[--hl-md] transition-colors'> defaultInputValue={selectedGlobalBaseEnvironment?.workspaceName || selectedGlobalBaseEnvironment?.name || ''}
<Input aria-label='Global Environment' placeholder='Choose a global environment' className="py-1 placeholder:italic w-full pl-2 pr-7 " /> selectedKey={selectedGlobalBaseEnvironmentId}
<Button className="aspect-square gap-2 truncate flex items-center justify-center aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all text-sm"> defaultItems={[...globalBaseEnvironments.map(baseEnv => {
<Icon icon="caret-down" className='w-5 flex-shrink-0' /> return {
</Button> id: baseEnv._id,
</div> icon: 'code',
<Popover className="min-w-max max-h-[90vh] !z-10 border grid grid-flow-col auto-cols-[min(250px,calc(45vw))] overflow-hidden divide-x divide-solid divide-[--hl-md] select-none text-sm border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] rounded-md focus:outline-none" placement='bottom start' offset={8}> name: baseEnv.workspaceName || baseEnv.name,
<ListBox<{ name: string; icon: IconName }> textValue: baseEnv.workspaceName || baseEnv.name,
className="select-none text-sm min-w-max p-2 flex flex-col overflow-y-auto focus:outline-none" };
> }), { id: '', icon: 'cancel', name: 'No Global Environment', textValue: 'No Global Environment' }]}
{item => ( >
<ListBoxItem <div className='px-2 mx-2 my-2 flex items-center gap-2 group rounded-sm border border-solid border-[--hl-sm] bg-[--color-bg] text-[--color-font] focus:outline-none focus:ring-1 focus:ring-[--hl-md] transition-colors'>
textValue={item.name} <Input aria-label='Global Environment' placeholder='Choose a global environment' className="py-1 placeholder:italic w-full pl-2 pr-7 " />
className="aria-disabled:opacity-30 aria-selected:bg-[--hl-sm] rounded aria-disabled:cursor-not-allowed flex gap-2 px-[--padding-md] aria-selected:font-bold items-center text-[--color-font] h-[--line-height-xs] w-full text-md whitespace-nowrap bg-transparent hover:bg-[--hl-sm] disabled:cursor-not-allowed focus:bg-[--hl-xs] data-[focused]:bg-[--hl-xs] focus:outline-none transition-colors" <Button className="aspect-square gap-2 truncate flex items-center justify-center aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all text-sm">
> <Icon icon="caret-down" className='w-5 flex-shrink-0' />
<Icon icon={item.icon} className='w-4' /> </Button>
<span className='truncate'>{item.name}</span> </div>
</ListBoxItem> <Popover className="min-w-max max-h-[90vh] !z-10 border grid grid-flow-col auto-cols-[min(250px,calc(45vw))] overflow-hidden divide-x divide-solid divide-[--hl-md] select-none text-sm border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] rounded-md focus:outline-none" placement='bottom start' offset={8}>
)} <ListBox<{ name: string; icon: IconName }>
</ListBox> className="select-none text-sm min-w-max p-2 flex flex-col overflow-y-auto focus:outline-none"
</Popover> >
</ComboBox> {item => (
<ListBoxItem
textValue={item.name}
className="aria-disabled:opacity-30 aria-selected:bg-[--hl-sm] rounded aria-disabled:cursor-not-allowed flex gap-2 px-[--padding-md] aria-selected:font-bold items-center text-[--color-font] h-[--line-height-xs] w-full text-md whitespace-nowrap bg-transparent hover:bg-[--hl-sm] disabled:cursor-not-allowed focus:bg-[--hl-xs] data-[focused]:bg-[--hl-xs] focus:outline-none transition-colors"
>
<Icon icon={item.icon} className='w-4' />
<span className='truncate'>{item.name}</span>
</ListBoxItem>
)}
</ListBox>
</Popover>
</ComboBox>
</div>
<ListBox <ListBox
aria-label='Select a Global Environment' aria-label='Select a Global Environment'
selectionMode='none' selectionMode='none'
ref={globalEnvironmentListBox}
disallowEmptySelection disallowEmptySelection
key={activeGlobalEnvironment?._id} key={activeGlobalEnvironment?._id}
items={globalEnvironmentList} items={globalEnvironmentList}