diff --git a/src/features/events/components/EventTypeAutocomplete.tsx b/src/features/events/components/EventTypeAutocomplete.tsx index e24ef7d1f2..0e771c0c79 100644 --- a/src/features/events/components/EventTypeAutocomplete.tsx +++ b/src/features/events/components/EventTypeAutocomplete.tsx @@ -3,7 +3,7 @@ import { lighten } from '@mui/material/styles'; import makeStyles from '@mui/styles/makeStyles'; import { Add, Clear } from '@mui/icons-material'; import { Autocomplete, Box, TextField, Theme, Tooltip } from '@mui/material'; -import { FC, useEffect, useState } from 'react'; +import { FC, useEffect, useRef, useState } from 'react'; import EventTypesModel from '../models/EventTypesModel'; import messageIds from '../l10n/messageIds'; @@ -26,10 +26,25 @@ const useStyles = makeStyles((theme) => ({ borderColor: ({ showBorder }) => showBorder ? lighten(theme.palette.primary.main, 0.65) : '', borderRadius: 10, - maxWidth: '200px', paddingLeft: ({ showBorder }) => (showBorder ? 10 : 0), + paddingRight: ({ showBorder }) => (showBorder ? 0 : 10), transition: 'all 0.2s ease', }, + span: { + // Same styles as input + '&:focus, &:hover': { + borderColor: lighten(theme.palette.primary.main, 0.65), + paddingLeft: 10, + paddingRight: 0, + }, + border: '2px dotted transparent', + borderRadius: 10, + fontSize: '1rem', + paddingRight: 10, + // But invisible and positioned absolutely to not affect flow + position: 'absolute', + visibility: 'hidden', + }, })); type EventTypeAutocompleteProps = { @@ -58,21 +73,37 @@ const EventTypeAutocomplete: FC = ({ typesModel, value, }) => { + const messages = useMessages(messageIds); + const uncategorizedMsg = messages.type.uncategorized(); const [createdType, setCreatedType] = useState(''); + const [text, setText] = useState(value?.title ?? uncategorizedMsg); + const [dropdownListWidth, setDropdownListWidth] = useState(0); + const spanRef = useRef(null); const classes = useStyles({ showBorder }); - const messages = useMessages(messageIds); useEffect(() => { //When a user creates a new type, it is missing an event ID. //In here, when the length of the type changes, //it searches for the created event and updates event with an ID. if (createdType !== '') { - const newId = types.find((item) => item.title === createdType)!.id; - onChangeNewOption(newId!); + const newEventType = types.find((item) => item.title === createdType); + setText(newEventType!.title); + onChangeNewOption(newEventType!.id); } }, [types.length]); + useEffect(() => { + if (spanRef.current) { + const width = spanRef.current.offsetWidth; + setDropdownListWidth(width); + } + }, [spanRef.current, text]); + + useEffect(() => { + setText(value ? value.title : uncategorizedMsg); + }, [value]); + const allTypes: EventTypeOption[] = [ ...types, { @@ -93,6 +124,12 @@ const EventTypeAutocomplete: FC = ({ classes={{ root: classes.inputRoot, }} + componentsProps={{ + popper: { + placement: 'bottom-start', + style: { maxWidth: 380, minWidth: 180, width: dropdownListWidth }, + }, + }} disableClearable filterOptions={(options, { inputValue }) => { const searchedResults = fuse.search(inputValue); @@ -109,7 +146,7 @@ const EventTypeAutocomplete: FC = ({ }), { id: 'UNCATEGORIZED', - title: messages.type.uncategorized(), + title: uncategorizedMsg, }, ]; if ( @@ -128,11 +165,21 @@ const EventTypeAutocomplete: FC = ({ }); return inputValue ? filteredResult : options; }} - fullWidth getOptionLabel={(option) => option.title!} isOptionEqualToValue={(option, value) => option.title === value.title} - onBlur={() => onBlur()} + onBlur={() => { + // show 'uncategorized' in textField when blurring + if (!value && text !== uncategorizedMsg) { + setText(uncategorizedMsg); + } + //set text to previous input value when clicking away + if (value && text !== value.title) { + setText(value.title); + } + onBlur(); + }} onChange={(_, value) => { + setText(value.title); if (value.id == 'CREATE') { typesModel.addType(value.title!); setCreatedType(value.title!); @@ -150,19 +197,27 @@ const EventTypeAutocomplete: FC = ({ onFocus={() => onFocus()} options={allTypes} renderInput={(params) => ( - + <> + + {text} + + setText(e.target.value)} + size="small" + /> + )} renderOption={(props, option) => { return ( @@ -173,7 +228,7 @@ const EventTypeAutocomplete: FC = ({ {option.id == 'UNCATEGORIZED' && (
  • - {messages.type.uncategorized()} + {uncategorizedMsg}
  • )} {option.id == 'CREATE' && ( @@ -190,7 +245,7 @@ const EventTypeAutocomplete: FC = ({ ? value : { id: 'UNCATEGORIZED', - title: messages.type.uncategorized(), + title: text, } } />