Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('CreateEntryMenuTrigger general', () => {
const { getAllByTestId, getByTestId } = render(
<CreateEntryMenuTrigger {...props} onSelect={selectStub}>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -83,7 +83,7 @@ describe('CreateEntryMenuTrigger general', () => {
const { getAllByTestId, getByTestId } = render(
<CreateEntryMenuTrigger {...props} onSelect={selectStub}>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -103,7 +103,7 @@ describe('CreateEntryMenuTrigger general', () => {
contentTypes={fill(Array(21), CONTENT_TYPE_3) as ContentType[]}
>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -116,13 +116,13 @@ describe('CreateEntryMenuTrigger general', () => {
const contentTypes = fill(
fill(fill(Array(21), CONTENT_TYPE_1, 0, 10), CONTENT_TYPE_2, 10, 20),
CONTENT_TYPE_3,
20
20,
);

const { getByTestId, getAllByTestId } = render(
<CreateEntryMenuTrigger {...props} contentTypes={contentTypes}>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -132,21 +132,21 @@ describe('CreateEntryMenuTrigger general', () => {
const input = getByTestId('add-entry-menu-search');
fireEvent.change(input, { target: { value: '1' }, preventDefault: noop });
expect(getAllByTestId('contentType')).toHaveLength(10);
expect(getByTestId('add-entru-menu-search-results').textContent).toBe('10 results');
expect(getByTestId('add-entry-menu-search-results').textContent).toBe('10 results');

fireEvent.change(input, { target: { value: '3' }, preventDefault: noop });
expect(getAllByTestId('contentType')).toHaveLength(1);
expect(getByTestId('add-entru-menu-search-results').textContent).toBe('1 result');
expect(getByTestId('add-entry-menu-search-results').textContent).toBe('1 result');

fireEvent.change(input, { target: { value: '4' }, preventDefault: noop });
expect(getByTestId('add-entru-menu-search-results').textContent).toBe('No results found');
expect(getByTestId('add-entry-menu-search-results').textContent).toBe('No results found');
});

it('shows suggestedContentType in the list', () => {
const { getByTestId } = render(
<CreateEntryMenuTrigger {...props} suggestedContentTypeId={props.contentTypes[0].sys.id}>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -169,7 +169,7 @@ describe('CreateEntryMenuTrigger general', () => {
const { getByTestId, getAllByTestId } = render(
<CreateEntryMenuTrigger {...props} contentTypes={contentTypesWithExperience}>
{stub}
</CreateEntryMenuTrigger>
</CreateEntryMenuTrigger>,
);

act(() => {
Expand All @@ -184,7 +184,7 @@ describe('CreateEntryMenuTrigger general', () => {

// Ensure the experience type is not rendered
const experienceTypeItem = contentTypeItems.find(
(item) => item.textContent === 'experience-type'
(item) => item.textContent === 'experience-type',
);
expect(experienceTypeItem).toBeUndefined();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import React, { useState, useRef, useEffect, useMemo } from 'react';

import { TextInput, Menu, MenuProps } from '@contentful/f36-components';
import { TextInput, Menu, type MenuProps } from '@contentful/f36-components';
import { MagnifyingGlassIcon } from '@contentful/f36-icons';
import tokens from '@contentful/f36-tokens';
import { plural, t } from '@lingui/core/macro';
import { css } from 'emotion';
import get from 'lodash/get';

import { ContentType } from '../../types';
import type { ContentType } from '../../types';

const MAX_ITEMS_WITHOUT_SEARCH = 5;

Expand Down Expand Up @@ -65,7 +66,7 @@ export type CreateEntryMenuTriggerChild = (
export type CreateCustomEntryMenuItems = ({
closeMenu,
}: {
closeMenu: Function;
closeMenu: () => void;
}) => React.ReactElement;

interface CreateEntryMenuTrigger {
Expand All @@ -88,10 +89,13 @@ interface CreateEntryMenuTrigger {
export const CreateEntryMenuTrigger = ({
contentTypes,
suggestedContentTypeId,
contentTypesLabel,
contentTypesLabel = t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.AllContentTypesLabel',
message: 'All Content Types',
}),
title,
onSelect,
testId,
testId = 'create-entry-button-menu-trigger',
dropdownSettings = {
position: 'bottom-left',
},
Expand Down Expand Up @@ -178,8 +182,14 @@ export const CreateEntryMenuTrigger = ({

const renderSearchResultsCount = (resultsLength: number) =>
resultsLength ? (
<Menu.SectionTitle testId="add-entru-menu-search-results">
{resultsLength} result{resultsLength > 1 ? 's' : ''}
<Menu.SectionTitle testId="add-entry-menu-search-results">
{t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.SearchContentTypeResultsLabel',
message: plural(resultsLength, {
one: '# result',
other: '# results',
}),
})}
</Menu.SectionTitle>
) : null;

Expand All @@ -190,7 +200,17 @@ export const CreateEntryMenuTrigger = ({
);
const searchFilteredContentTypes = filteredContentTypes.filter(
(ct) =>
!searchInput || get(ct, 'name', 'Untitled').toLowerCase().includes(searchInput.toLowerCase()),
!searchInput ||
get(
ct,
'name',
t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.SearchContentTypeFallbackLabel',
message: 'Untitled',
}),
)
.toLowerCase()
.includes(searchInput.toLowerCase()),
);

return (
Expand All @@ -209,7 +229,7 @@ export const CreateEntryMenuTrigger = ({
<Menu.List
className={styles.dropdownList}
style={{
width: dropdownWidth != undefined ? `${dropdownWidth}px` : undefined,
width: dropdownWidth !== undefined ? `${dropdownWidth}px` : undefined,
maxHeight: `${maxDropdownHeight}px`,
}}
ref={menuListRef}
Expand All @@ -225,25 +245,31 @@ export const CreateEntryMenuTrigger = ({
{title && <Menu.SectionTitle className={styles.title}>{title}</Menu.SectionTitle>}

{isSearchable && (
<>
<div ref={textField} className={styles.inputWrapper}>
<TextInput
className={styles.searchInput}
placeholder="Search content type"
testId="add-entry-menu-search"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
/>
<MagnifyingGlassIcon size="small" className={styles.searchIcon} />
</div>
</>
<div ref={textField} className={styles.inputWrapper}>
<TextInput
className={styles.searchInput}
placeholder={t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.SearchContentTypePlaceholder',
message: 'Search content type',
})}
testId="add-entry-menu-search"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
/>
<MagnifyingGlassIcon size="small" className={styles.searchIcon} />
</div>
)}

{searchInput && renderSearchResultsCount(searchFilteredContentTypes.length)}

{suggestedContentType && !searchInput && (
<>
<Menu.SectionTitle>Suggested Content Type</Menu.SectionTitle>
<Menu.SectionTitle>
{t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.SuggestedContentTypeLabel',
message: 'Suggested Content Type',
})}
</Menu.SectionTitle>
<Menu.Item testId="suggested" onClick={() => handleSelect(suggestedContentType)}>
{get(suggestedContentType, 'name')}
</Menu.Item>
Expand All @@ -260,21 +286,27 @@ export const CreateEntryMenuTrigger = ({
key={`${get(contentType, 'name')}-${i}`}
onClick={() => handleSelect(contentType)}
>
{get(contentType, 'name', 'Untitled')}
{get(
contentType,
'name',
t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.ContentTypeFallbackLabel',
message: 'Untitled',
}),
)}
</Menu.Item>
))
) : (
<Menu.Item testId="add-entru-menu-search-results">No results found</Menu.Item>
<Menu.Item testId="add-entry-menu-search-results">
{t({
id: 'FieldEditors.Reference.CreateEntryMenuTrigger.NoResultsLabel',
message: 'No results found',
})}
</Menu.Item>
)}
</Menu.List>
)}
</Menu>
</span>
);
};

CreateEntryMenuTrigger.defaultProps = {
testId: 'create-entry-button-menu-trigger',
contentTypesLabel: 'All Content Types',
filterExperienceTypes: true,
};