diff --git a/frontend/app-development/features/textEditor/TextEditor.test.tsx b/frontend/app-development/features/textEditor/TextEditor.test.tsx index 7ad9d8dd614..5e544fdf74a 100644 --- a/frontend/app-development/features/textEditor/TextEditor.test.tsx +++ b/frontend/app-development/features/textEditor/TextEditor.test.tsx @@ -55,7 +55,9 @@ describe('TextEditor', () => { renderTextEditor(); const search = '1'; - const searchInput = screen.getByTestId('text-editor-search-default'); + const searchInput = screen.getByRole('searchbox', { + name: textMock('text_editor.search_for_text'), + }); await user.type(searchInput, search); expect(mockSetSearchParams).toHaveBeenCalledWith({ search }); diff --git a/frontend/dashboard/pages/Dashboard/Dashboard.module.css b/frontend/dashboard/pages/Dashboard/Dashboard.module.css index f3e27b388c9..55ae8aa0846 100644 --- a/frontend/dashboard/pages/Dashboard/Dashboard.module.css +++ b/frontend/dashboard/pages/Dashboard/Dashboard.module.css @@ -51,11 +51,6 @@ display: inline; } -.searchFieldContainer { - display: flex; - align-items: flex-end; -} - .clearSearchButton { height: 32px; width: 32px; diff --git a/frontend/dashboard/pages/Dashboard/Dashboard.tsx b/frontend/dashboard/pages/Dashboard/Dashboard.tsx index 690fa4aa738..ffffd59d42d 100644 --- a/frontend/dashboard/pages/Dashboard/Dashboard.tsx +++ b/frontend/dashboard/pages/Dashboard/Dashboard.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react'; import classes from './Dashboard.module.css'; import type { ChangeEvent, KeyboardEvent } from 'react'; -import { Textfield, Link } from '@digdir/designsystemet-react'; -import { StudioButton } from '@studio/components'; -import { XMarkIcon, PlusCircleIcon, PlusCircleFillIcon } from '@studio/icons'; +import { Link } from '@digdir/designsystemet-react'; +import { StudioSearch } from '@studio/components'; +import { PlusCircleIcon, PlusCircleFillIcon } from '@studio/icons'; import { useDebounce } from '@studio/hooks'; import { CenterContainer } from '../../components/CenterContainer'; import { DataModelsReposList } from '../../components/DataModelsRepoList'; @@ -48,23 +48,13 @@ export const Dashboard = ({ user, organizations, disableDebounce }: DashboardPro
-
- - {searchText && ( - } - variant='tertiary' - /> - )} -
+ {t('dashboard.new_service')} diff --git a/frontend/language/src/nb.json b/frontend/language/src/nb.json index ff4bda69562..e25f26a335c 100644 --- a/frontend/language/src/nb.json +++ b/frontend/language/src/nb.json @@ -29,7 +29,7 @@ "app_content_library.code_lists.no_content": "Dette biblioteket har ingen kodelister", "app_content_library.code_lists.page_name": "Kodelister", "app_content_library.code_lists.save_new_code_list": "Lagre", - "app_content_library.code_lists.search_placeholder": "Søk på kodelister", + "app_content_library.code_lists.search_label": "Søk på kodelister", "app_content_library.code_lists.upload_code_list": "Last opp din egen kodeliste", "app_content_library.images.info_box.description": "Du kan bruke bildene i biblioteket til å legge inn bilder i skjemaet. Du kan også laste opp et bilde med organisasjonens logo, og legge det som logobilde i innstillingene for appen.", "app_content_library.images.info_box.title": "Hva kan du bruke bildene til?", diff --git a/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.test.tsx b/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.test.tsx new file mode 100644 index 00000000000..9fd48de8149 --- /dev/null +++ b/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.test.tsx @@ -0,0 +1,47 @@ +import React, { type ForwardedRef } from 'react'; +import { render, screen } from '@testing-library/react'; +import type { StudioSearchProps } from './StudioSearch'; +import { StudioSearch } from './StudioSearch'; +import { testRefForwarding } from '../../test-utils/testRefForwarding'; +import { testRootClassNameAppending } from '../../test-utils/testRootClassNameAppending'; +import { testCustomAttributes } from '../../test-utils/testCustomAttributes'; + +describe('StudioSearch', () => { + it('should support forwarding the ref', () => { + testRefForwarding((ref) => renderTestSearch({}, ref), getSearchBox); + }); + + it('should append classname to root', () => { + testRootClassNameAppending((className) => renderTestSearch({ className })); + }); + + it('should allow custom attributes', () => { + testCustomAttributes(renderTestSearch, getSearchBox); + }); + + it('should render search field with label name when provided', () => { + const label = 'Search for something'; + renderTestSearch({ label }); + const search = screen.getByRole('searchbox', { name: label }); + expect(search).toBeInTheDocument(); + }); + + it('should render search field with label name when ID is set through props', () => { + const label = 'Search for something'; + const id = 'searchId'; + renderTestSearch({ label, id }); + const search = screen.getByRole('searchbox', { name: label }); + expect(search).toBeInTheDocument(); + }); +}); + +const renderTestSearch = ( + props: Partial = {}, + ref?: ForwardedRef, +) => { + return render(); +}; + +function getSearchBox(): HTMLInputElement { + return screen.getByRole('searchbox'); +} diff --git a/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.tsx b/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.tsx new file mode 100644 index 00000000000..4277f2428e7 --- /dev/null +++ b/frontend/libs/studio-components/src/components/StudioSearch/StudioSearch.tsx @@ -0,0 +1,28 @@ +import React, { forwardRef, useId } from 'react'; +import { Label, Search, type SearchProps } from '@digdir/designsystemet-react'; +import type { WithoutAsChild } from '../../types/WithoutAsChild'; + +export type StudioSearchProps = WithoutAsChild; + +const StudioSearch = forwardRef( + ({ size = 'sm', label, id, className, ...rest }, ref) => { + const generatedId = useId(); + const searchId = id ?? generatedId; + const showLabel = !!label; + + return ( +
+ {showLabel && ( + + )} + +
+ ); + }, +); + +StudioSearch.displayName = 'StudioSearch'; + +export { StudioSearch }; diff --git a/frontend/libs/studio-components/src/components/StudioSearch/index.ts b/frontend/libs/studio-components/src/components/StudioSearch/index.ts new file mode 100644 index 00000000000..6166f56d270 --- /dev/null +++ b/frontend/libs/studio-components/src/components/StudioSearch/index.ts @@ -0,0 +1 @@ +export { StudioSearch } from './StudioSearch'; diff --git a/frontend/libs/studio-components/src/components/index.ts b/frontend/libs/studio-components/src/components/index.ts index 57b988b2f79..5e44420b95f 100644 --- a/frontend/libs/studio-components/src/components/index.ts +++ b/frontend/libs/studio-components/src/components/index.ts @@ -50,6 +50,7 @@ export * from './StudioStatusRadioGroup'; export * from './StudioRecommendedNextAction'; export * from './StudioRedirectBox'; export * from './StudioResizableLayout'; +export * from './StudioSearch'; export * from './StudioSectionHeader'; export * from './StudioSpinner'; export * from './StudioSwitch'; diff --git a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.module.css b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.module.css index 29a20a33c21..434dcd00378 100644 --- a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.module.css +++ b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.module.css @@ -1,7 +1,7 @@ .actionsBar { display: grid; grid-template-columns: auto auto auto; - align-items: center; + align-items: flex-end; gap: var(--fds-spacing-3); justify-content: flex-start; } diff --git a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.test.tsx b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.test.tsx index 32b23f09182..a8ab7c7ee8e 100644 --- a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.test.tsx +++ b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.test.tsx @@ -13,12 +13,12 @@ const codeListName2 = 'codeListName2'; describe('CodeListsActionsBar', () => { afterEach(jest.clearAllMocks); - it('renders the search field with placeholder text', () => { + it('renders the search field with label', () => { renderCodeListsActionsBar(); - const searchFieldPlaceHolderText = screen.getByPlaceholderText( - textMock('app_content_library.code_lists.search_placeholder'), - ); - expect(searchFieldPlaceHolderText).toBeInTheDocument(); + const searchFieldLabelText = screen.getByRole('searchbox', { + name: textMock('app_content_library.code_lists.search_label'), + }); + expect(searchFieldLabelText).toBeInTheDocument(); }); it('renders the file uploader button', () => { diff --git a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.tsx b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.tsx index b761f36de0f..8c87f1004e0 100644 --- a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.tsx +++ b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeListsActionsBar/CodeListsActionsBar.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { Search } from '@digdir/designsystemet-react'; -import { StudioFileUploader } from '@studio/components'; +import { StudioFileUploader, StudioSearch } from '@studio/components'; import classes from './CodeListsActionsBar.module.css'; import { useTranslation } from 'react-i18next'; import type { CodeListWithMetadata } from '../CodeListPage'; @@ -36,10 +35,9 @@ export function CodeListsActionsBar({ return (
- { renderTextEditor({}); const textEntries = screen.getAllByRole('textbox'); - expect(textEntries[1]).toHaveValue(textValue1); + expect(textEntries[0]).toHaveValue(textValue1); const sortAlphabeticallyButton = screen.getByText(textMock('text_editor.sort_alphabetically')); await user.click(sortAlphabeticallyButton); const sortedTranslations = screen.getAllByRole('textbox'); - expect(sortedTranslations[1]).toHaveValue(textValue2); + expect(sortedTranslations[0]).toHaveValue(textValue2); }); it('signals correctly when a translation is changed', async () => { diff --git a/frontend/packages/text-editor/src/TextEditor.tsx b/frontend/packages/text-editor/src/TextEditor.tsx index 6829750b5cc..ee82806da52 100644 --- a/frontend/packages/text-editor/src/TextEditor.tsx +++ b/frontend/packages/text-editor/src/TextEditor.tsx @@ -2,10 +2,9 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import classes from './TextEditor.module.css'; import type { LangCode, TextResourceEntryDeletion, TextResourceIdMutation } from './types'; import type { UpsertTextResourceMutation } from 'app-shared/hooks/mutations/useUpsertTextResourceMutation'; -import { SearchField } from '@altinn/altinn-design-system'; import { Chip } from '@digdir/designsystemet-react'; import { ArrowsUpDownIcon } from '@studio/icons'; -import { StudioButton } from '@studio/components'; +import { StudioButton, StudioSearch } from '@studio/components'; import { RightMenu } from './RightMenu'; import { getRandNumber, mapResourceFilesToTableRows } from './utils'; import { defaultLangCode } from './constants'; @@ -88,6 +87,8 @@ export const TextEditor = ({ }; const handleSearchChange = (event: any) => setSearchQuery(event.target.value); + const handleClearSearch = () => setSearchQuery(''); + return (
@@ -107,14 +108,12 @@ export const TextEditor = ({
} -
- -
+
diff --git a/frontend/testing/playwright/pages/DashboardPage.ts b/frontend/testing/playwright/pages/DashboardPage.ts index 9b3fc132d3d..b28f3417140 100644 --- a/frontend/testing/playwright/pages/DashboardPage.ts +++ b/frontend/testing/playwright/pages/DashboardPage.ts @@ -93,7 +93,7 @@ export class DashboardPage extends BasePage { } public async typeInSearchField(word: string): Promise { - await this.page.getByLabel(this.textMock('dashboard.search')).fill(word); + await this.page.getByRole('searchbox', { name: this.textMock('dashboard.search') }).fill(word); } public async clickOnTestAppGiteaButton(appName: string): Promise {