Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add loading indicator to combo box control author selector #68927

Open
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/components/src/combobox-control/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type { TokenInputProps } from '../form-token-field/types';
import { useDeprecated36pxDefaultSizeProp } from '../utils/use-deprecated-props';
import { withIgnoreIMEEvents } from '../utils/with-ignore-ime-events';
import { maybeWarnDeprecated36pxSize } from '../utils/deprecated-36px-size';
import Spinner from '../spinner';

const noop = () => {};

Expand Down Expand Up @@ -126,6 +127,7 @@ function ComboboxControl( props: ComboboxControlProps ) {
help,
allowReset = true,
className,
isLoading = false,
messages = {
selected: __( 'Item selected.' ),
},
Expand Down Expand Up @@ -362,6 +364,7 @@ function ComboboxControl( props: ComboboxControlProps ) {
onChange={ onInputChange }
/>
</FlexBlock>
{ isLoading && <Spinner /> }
{ allowReset && (
<Button
size="small"
Expand Down Expand Up @@ -396,6 +399,7 @@ function ComboboxControl( props: ComboboxControlProps ) {
__experimentalRenderItem={
__experimentalRenderItem
}
isLoading={ isLoading }
/>
) }
</div>
Expand Down
5 changes: 5 additions & 0 deletions packages/components/src/combobox-control/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ export type ComboboxControlProps = Pick<
* If passed, the combobox input will show a placeholder string if no values are present.
*/
placeholder?: string;

/**
* When loading, combobox will show a spinner
*/
isLoading?: boolean;
};
2 changes: 2 additions & 0 deletions packages/components/src/form-token-field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
__experimentalAutoSelectFirstMatch = false,
__nextHasNoMarginBottom = false,
tokenizeOnBlur = false,
isLoading = false,
} = useDeprecated36pxDefaultSizeProp< FormTokenFieldProps >( props );

if ( ! __nextHasNoMarginBottom ) {
Expand Down Expand Up @@ -743,6 +744,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
onHover={ onSuggestionHovered }
onSelect={ onSuggestionSelected }
__experimentalRenderItem={ __experimentalRenderItem }
isLoading={ isLoading }
/>
) }
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function SuggestionsList<
suggestions = [],
displayTransform,
instanceId,
isLoading,
__experimentalRenderItem,
}: SuggestionsListProps< T > ) {
const listRef = useRefEffect< HTMLUListElement >(
Expand Down Expand Up @@ -157,7 +158,7 @@ export function SuggestionsList<
);
/* eslint-enable jsx-a11y/click-events-have-key-events */
} ) }
{ suggestions.length === 0 && (
{ suggestions.length === 0 && ! isLoading && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SuggestionsList component is shared, which is why we're passing the isLoading prop, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right

<li className="components-form-token-field__suggestion is-empty">
{ __( 'No items found' ) }
</li>
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/form-token-field/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ export interface FormTokenFieldProps
* @default false
*/
tokenizeOnBlur?: boolean;

/**
* Is the component loading data?
*/
isLoading?: boolean;
}

/**
Expand All @@ -207,6 +212,7 @@ export interface SuggestionsListProps<
displayTransform: ( value: T ) => string;
instanceId: string | number;
__experimentalRenderItem?: ( args: { item: T } ) => ReactNode;
isLoading?: boolean;
}

export interface TokenProps extends TokenItem {
Expand Down
6 changes: 4 additions & 2 deletions packages/editor/src/components/post-author/combobox.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export default function PostAuthorCombobox() {
const [ fieldValue, setFieldValue ] = useState();

const { editPost } = useDispatch( editorStore );
const { authorId, authorOptions } = useAuthorsQuery( fieldValue );
const { authorId, authorOptions, isLoading } =
useAuthorsQuery( fieldValue );

/**
* Handle author selection.
Expand All @@ -44,13 +45,14 @@ export default function PostAuthorCombobox() {
<ComboboxControl
__nextHasNoMarginBottom
__next40pxDefaultSize
label={ __( 'Author' ) }
label={ __( 'Authorz' ) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, this was me trying to get my build working and not seeing changes. will revert!

options={ authorOptions }
value={ authorId }
onFilterValueChange={ debounce( handleKeydown, 300 ) }
onChange={ handleSelect }
allowReset={ false }
hideLabelFromVision
isLoading={ isLoading }
/>
);
}
7 changes: 4 additions & 3 deletions packages/editor/src/components/post-author/hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { store as editorStore } from '../../store';
import { AUTHORS_QUERY, BASE_QUERY } from './constants';

export function useAuthorsQuery( search ) {
const { authorId, authors, postAuthor } = useSelect(
const { authorId, authors, postAuthor, isLoading } = useSelect(
( select ) => {
const { getUser, getUsers } = select( coreStore );
const { getUser, getUsers, isResolving } = select( coreStore );
const { getEditedPostAttribute } = select( editorStore );
const _authorId = getEditedPostAttribute( 'author' );
const query = { ...AUTHORS_QUERY };
Expand All @@ -30,6 +30,7 @@ export function useAuthorsQuery( search ) {
authorId: _authorId,
authors: getUsers( query ),
postAuthor: getUser( _authorId, BASE_QUERY ),
isLoading: isResolving( 'getUsers', [ query ] ),
};
},
[ search ]
Expand Down Expand Up @@ -68,5 +69,5 @@ export function useAuthorsQuery( search ) {
return [ ...currentAuthor, ...fetchedAuthors ];
}, [ authors, postAuthor ] );

return { authorId, authorOptions, postAuthor };
return { authorId, authorOptions, postAuthor, isLoading };
}
Loading