Browse Source

ref(compactSelect): Add loading indicator (#34932)

Vu Luong 2 years ago
parent
commit
ca1819e633

+ 2 - 0
docs-ui/stories/components/form-fields.stories.js

@@ -338,6 +338,8 @@ CompactSelectField.args = {
   menuTitle: '',
   isSearchable: false,
   isDisabled: false,
+  isClearable: false,
+  isLoading: false,
   multiple: false,
   placeholder: 'Search…',
   closeOnSelect: true,

+ 22 - 4
static/app/components/forms/compactSelect.tsx

@@ -20,6 +20,7 @@ import SelectControl, {
   ControlProps,
   GeneralSelectValue,
 } from 'sentry/components/forms/selectControl';
+import LoadingIndicator from 'sentry/components/loadingIndicator';
 import overflowEllipsis from 'sentry/styles/overflowEllipsis';
 import space from 'sentry/styles/space';
 
@@ -37,6 +38,11 @@ interface Props<OptionType>
    * Pass class name to the outer wrap
    */
   className?: string;
+  /**
+   * Whether new options are being loaded. When true, CompactSelect will
+   * display a loading indicator in the header.
+   */
+  isLoading?: boolean;
   onChangeValueMap?: (value: OptionType[]) => ControlProps<OptionType>['value'];
   /**
    * Tag name for the outer wrap, defaults to `div`
@@ -88,14 +94,17 @@ export const CompactSelectControl = ({
   ...props
 }: React.ComponentProps<typeof selectComponents.Control>) => {
   const {hasValue, selectProps} = props;
-  const {isSearchable, menuTitle, isClearable} = selectProps;
+  const {isSearchable, menuTitle, isClearable, isLoading} = selectProps;
 
   return (
     <Fragment>
-      {(menuTitle || isClearable) && (
+      {(menuTitle || isClearable || isLoading) && (
         <MenuHeader>
-          <MenuTitle>{menuTitle}</MenuTitle>
-          {hasValue && isClearable && (
+          <MenuTitle>
+            <span>{menuTitle}</span>
+          </MenuTitle>
+          {isLoading && <StyledLoadingIndicator size={12} mini />}
+          {hasValue && isClearable && !isLoading && (
             <ClearButton size="zero" borderless onClick={() => props.clearValue()}>
               Clear
             </ClearButton>
@@ -337,6 +346,7 @@ const Overlay = styled('div')<{minWidth?: number}>`
 const MenuHeader = styled('div')`
   position: relative;
   display: flex;
+  align-items: center;
   justify-content: space-between;
   padding: ${space(0.25)} ${space(1)} ${space(0.25)} ${space(1.5)};
   box-shadow: 0 1px 0 ${p => p.theme.translucentInnerBorder};
@@ -351,6 +361,14 @@ const MenuTitle = styled('span')`
   margin-right: ${space(2)};
 `;
 
+const StyledLoadingIndicator = styled(LoadingIndicator)`
+  && {
+    margin: ${space(0.5)} ${space(0.5)} ${space(0.5)} ${space(1)};
+    height: ${space(1.5)};
+    width: ${space(1.5)};
+  }
+`;
+
 const ClearButton = styled(Button)`
   font-size: ${p => p.theme.fontSizeSmall};
   color: ${p => p.theme.subText};