From 7ff475e41c325f0d8e9a310ab8a378b8f93341ac Mon Sep 17 00:00:00 2001 From: Jonathan Zempel Date: Tue, 1 Aug 2023 16:22:26 -0400 Subject: [PATCH 1/4] fix(combobox): address multiselectable state issues with new `TagGroup` component --- packages/dropdowns.next/.size-snapshot.json | 16 ++-- .../src/elements/combobox/Combobox.tsx | 88 +++++++++---------- .../src/elements/combobox/TagGroup.tsx | 41 +++++++++ packages/dropdowns.next/src/types/index.ts | 15 ++++ packages/dropdowns.next/src/views/index.ts | 1 + 5 files changed, 109 insertions(+), 52 deletions(-) create mode 100644 packages/dropdowns.next/src/elements/combobox/TagGroup.tsx diff --git a/packages/dropdowns.next/.size-snapshot.json b/packages/dropdowns.next/.size-snapshot.json index 59c5e80d9e7..3440c79eaec 100644 --- a/packages/dropdowns.next/.size-snapshot.json +++ b/packages/dropdowns.next/.size-snapshot.json @@ -1,20 +1,20 @@ { "index.cjs.js": { - "bundled": 55344, - "minified": 40274, - "gzipped": 9098 + "bundled": 55791, + "minified": 40497, + "gzipped": 9252 }, "index.esm.js": { - "bundled": 50695, - "minified": 35869, - "gzipped": 8627, + "bundled": 51142, + "minified": 36092, + "gzipped": 8676, "treeshaked": { "rollup": { - "code": 28209, + "code": 28410, "import_statements": 1064 }, "webpack": { - "code": 31080 + "code": 31283 } } } diff --git a/packages/dropdowns.next/src/elements/combobox/Combobox.tsx b/packages/dropdowns.next/src/elements/combobox/Combobox.tsx index 7c369a62c28..f1adca1a379 100644 --- a/packages/dropdowns.next/src/elements/combobox/Combobox.tsx +++ b/packages/dropdowns.next/src/elements/combobox/Combobox.tsx @@ -18,7 +18,7 @@ import React, { } from 'react'; import PropTypes from 'prop-types'; import { ThemeContext } from 'styled-components'; -import { IOption, IUseComboboxReturnValue, useCombobox } from '@zendeskgarden/container-combobox'; +import { IUseComboboxReturnValue, useCombobox } from '@zendeskgarden/container-combobox'; import { DEFAULT_THEME, useText, useWindow } from '@zendeskgarden/react-theming'; import { VALIDATION } from '@zendeskgarden/react-forms'; import ChevronIcon from '@zendeskgarden/svg-icons/src/16/chevron-down-stroke.svg'; @@ -31,13 +31,13 @@ import { StyledInputIcon, StyledInput, StyledInputGroup, + StyledTagsButton, StyledTrigger, StyledValue } from '../../views'; -import { StyledTagsButton } from '../../views/combobox/StyledTagsButton'; import { Listbox } from './Listbox'; -import { Tag } from './Tag'; -import { toOptions, toString } from './utils'; +import { TagGroup } from './TagGroup'; +import { toOptions } from './utils'; const MAX_TAGS = 4; @@ -82,6 +82,7 @@ export const Combobox = forwardRef( ) => { const { hasHint, hasMessage, labelProps, setLabelProps } = useFieldContext(); const [isLabelHovered, setIsLabelHovered] = useState(false); + const [isTagGroupExpanded, setIsTagGroupExpanded] = useState(false); const [optionTagProps, setOptionTagProps] = useState>( {} ); @@ -99,7 +100,6 @@ export const Combobox = forwardRef( const triggerRef = useRef(null); const inputRef = useRef(null); const listboxRef = useRef(null); - const tagsButtonRef = useRef(null); /* istanbul ignore next */ const theme = useContext(ThemeContext) || DEFAULT_THEME; const environment = useWindow(theme); @@ -178,10 +178,18 @@ export const Combobox = forwardRef( ...(getTriggerProps({ onFocus: () => { hasFocus.current = true; + + if (isMultiselectable) { + setIsTagGroupExpanded(true); + } }, onBlur: event => { if (event.relatedTarget === null || !triggerRef.current?.contains(event.relatedTarget)) { hasFocus.current = false; + + if (isMultiselectable) { + setIsTagGroupExpanded(false); + } } } }) as HTMLAttributes) @@ -215,44 +223,6 @@ export const Combobox = forwardRef( return () => labelProps && setLabelProps(undefined); }, [getLabelProps, labelProps, setLabelProps]); - const Tags = ({ selectedOptions }: { selectedOptions: IOption[] }) => { - const value = selectedOptions.length - maxTags; - - return ( - <> - {selectedOptions.map((option, index) => { - const key = toString(option); - const disabled = isDisabled || option.disabled; - const hidden = !hasFocus.current && index >= maxTags; - - return ( -