diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0ddb080..5564342c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ and this project adheres to
## [Unreleased]
+### Added
+
+- 🚸(frontend) hint min char search users #2064
+
### Changed
- 💄(frontend) improve comments highlights #1961
diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts
index a95b78aa..8f2418b4 100644
--- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts
+++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts
@@ -17,6 +17,41 @@ test.describe('Document create member', () => {
await page.goto('/');
});
+ test('it checks search hints', async ({ page, browserName }) => {
+ await createDoc(page, 'select-multi-users', browserName, 1);
+
+ await page.getByRole('button', { name: 'Share' }).click();
+
+ const shareModal = page.getByLabel('Share the document');
+ await expect(shareModal.getByText('Document owner')).toBeVisible();
+
+ const inputSearch = page.getByTestId('quick-search-input');
+ await inputSearch.fill('u');
+ await expect(shareModal.getByText('Document owner')).toBeHidden();
+ await expect(
+ shareModal.getByText('Type at least 3 characters to display user names'),
+ ).toBeVisible();
+ await inputSearch.fill('user');
+ await expect(
+ shareModal.getByText('Type at least 3 characters to display user names'),
+ ).toBeHidden();
+ await expect(shareModal.getByText('Choose a user')).toBeVisible();
+ await inputSearch.fill('anything');
+ await expect(shareModal.getByText('Choose a user')).toBeHidden();
+ await expect(
+ shareModal.getByText(
+ 'No results. Type a full email address to invite someone.',
+ ),
+ ).toBeVisible();
+ await inputSearch.fill('anything@test.com');
+ await expect(
+ shareModal.getByText(
+ 'No results. Type a full email address to invite someone.',
+ ),
+ ).toBeHidden();
+ await expect(shareModal.getByText('Choose the email')).toBeVisible();
+ });
+
test('it selects 2 users and 1 invitation', async ({ page, browserName }) => {
const inputFill = 'user.test';
const responsePromise = page.waitForResponse(
diff --git a/src/frontend/apps/impress/src/components/quick-search/QuickSearchInput.tsx b/src/frontend/apps/impress/src/components/quick-search/QuickSearchInput.tsx
index 8137464c..aa04efcf 100644
--- a/src/frontend/apps/impress/src/components/quick-search/QuickSearchInput.tsx
+++ b/src/frontend/apps/impress/src/components/quick-search/QuickSearchInput.tsx
@@ -48,7 +48,7 @@ export const QuickSearchInput = ({
$direction="row"
$align="center"
className="quick-search-input"
- $gap={spacingsTokens['2xs']}
+ $gap={spacingsTokens['xxs']}
$padding={{ horizontal: 'base', vertical: 'xxs' }}
>
@@ -62,6 +62,7 @@ export const QuickSearchInput = ({
placeholder={placeholder ?? t('Search')}
onValueChange={onFilter}
maxLength={254}
+ minLength={6}
data-testid="quick-search-input"
/>
diff --git a/src/frontend/apps/impress/src/components/quick-search/QuickSearchStyle.tsx b/src/frontend/apps/impress/src/components/quick-search/QuickSearchStyle.tsx
index 1aba150b..ffe86e64 100644
--- a/src/frontend/apps/impress/src/components/quick-search/QuickSearchStyle.tsx
+++ b/src/frontend/apps/impress/src/components/quick-search/QuickSearchStyle.tsx
@@ -18,14 +18,15 @@ export const QuickSearchStyle = createGlobalStyle`
[cmdk-input] {
border: none;
width: 100%;
- font-size: 17px;
+ font-size: 16px;
background: white;
outline: none;
color: var(--c--contextuals--content--semantic--neutral--primary);
border-radius: var(--c--globals--spacings--0);
+ font-family: var(--c--globals--font--families--base);
&::placeholder {
- color: var(--c--globals--colors--gray-500);
+ color: var(--c--contextuals--content--semantic--neutral--tertiary);
}
}
diff --git a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx
index f8e0c23e..2a880842 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx
@@ -124,7 +124,8 @@ export const DocShareAddMemberList = ({
$scope="surface"
$theme="tertiary"
$variation=""
- $border="1px solid var(--c--contextuals--border--semantic--contextual--primary)"
+ $border="1px solid var(--c--contextuals--border--surface--primary)"
+ $margin={{ bottom: 'sm' }}
>
{
/>
)}
{showMemberSection && isRootDoc && (
-
+
@@ -301,6 +301,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
searchUsersRawData={searchUsersQuery.data}
onSelect={onSelect}
userQuery={userQuery}
+ minLength={API_USERS_SEARCH_QUERY_MIN_LENGTH}
/>
)}
@@ -321,14 +322,35 @@ interface QuickSearchInviteInputSectionProps {
onSelect: (usr: User) => void;
searchUsersRawData: User[] | undefined;
userQuery: string;
+ minLength: number;
}
const QuickSearchInviteInputSection = ({
onSelect,
searchUsersRawData,
userQuery,
+ minLength,
}: QuickSearchInviteInputSectionProps) => {
const { t } = useTranslation();
+ const hint = useMemo(() => {
+ if (userQuery.length < minLength) {
+ return t('Type at least {{minLength}} characters to display user names', {
+ minLength,
+ });
+ }
+ if (isValidEmail(userQuery)) {
+ return t('Choose the email');
+ }
+ if (!searchUsersRawData?.length) {
+ return t('No results. Type a full email address to invite someone.');
+ }
+
+ return t('Choose a user');
+ }, [minLength, searchUsersRawData?.length, t, userQuery]);
+
+ useEffect(() => {
+ announce(hint, 'polite');
+ }, [hint]);
const searchUserData: QuickSearchData = useMemo(() => {
const users = searchUsersRawData || [];
@@ -347,7 +369,7 @@ const QuickSearchInviteInputSection = ({
);
return {
- groupName: t('Search user result'),
+ groupName: hint,
elements: users,
endActions:
isEmail && !hasEmailInUsers
@@ -359,12 +381,12 @@ const QuickSearchInviteInputSection = ({
]
: undefined,
};
- }, [onSelect, searchUsersRawData, t, userQuery]);
+ }, [searchUsersRawData, userQuery, hint, onSelect]);
return (