diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts index b3de884796..e02ff1c2a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts @@ -12,7 +12,7 @@ export const manifests: Array = [ }, }, { - name: 'Data Type Search Result Item ', + name: 'Data Type Search Result Item', alias: 'Umb.SearchResultItem.DataType', type: 'searchResultItem', forEntityTypes: [UMB_DATA_TYPE_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/search/manifests.ts index 7c1175adff..5c2f886811 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/search/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ }, }, { - name: 'Dictionary Search Result Item ', + name: 'Dictionary Search Result Item', alias: 'Umb.SearchResultItem.Dictionary', type: 'searchResultItem', forEntityTypes: [UMB_DICTIONARY_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts index c4d0e06b8c..cfd1ce09e8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ }, }, { - name: 'Document Search Result Item ', + name: 'Document Search Result Item', alias: 'Umb.SearchResultItem.Document', type: 'searchResultItem', element: () => import('./document-search-result-item.element.js'), diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts index 649b46b431..4bf8dcd6d6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts @@ -12,7 +12,7 @@ export const manifests: Array = [ }, }, { - name: 'Media Type Search Result Item ', + name: 'Media Type Search Result Item', alias: 'Umb.SearchResultItem.MediaType', type: 'searchResultItem', forEntityTypes: [UMB_MEDIA_TYPE_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts index 82e9d81d68..82b25aa8b4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ }, }, { - name: 'Media Search Result Item ', + name: 'Media Search Result Item', alias: 'Umb.SearchResultItem.Media', type: 'searchResultItem', forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts index ef5b13f9d8..4062f3a23b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts @@ -12,7 +12,7 @@ export const manifests: Array = [ }, }, { - name: 'Member Type Search Result Item ', + name: 'Member Type Search Result Item', alias: 'Umb.SearchResultItem.MemberType', type: 'searchResultItem', forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts index e191b088b8..c285ebf573 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ }, }, { - name: 'Member Search Result Item ', + name: 'Member Search Result Item', alias: 'Umb.SearchResultItem.Member', type: 'searchResultItem', forEntityTypes: [UMB_MEMBER_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts index fbaf7b411d..30377229d6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts @@ -1,5 +1,5 @@ import type { UmbSearchProvider, UmbSearchResultItemModel } from '../types.js'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { ManifestSearchResultItem } from '../extensions/types.js'; import { css, html, @@ -9,14 +9,15 @@ import { query, state, property, + when, } from '@umbraco-cms/backoffice/external/lit'; +import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; import '../search-result/search-result-item.element.js'; -import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; -import type { ManifestSearchResultItem } from '../extensions/types.js'; type SearchProvider = { name: string; @@ -282,48 +283,62 @@ export class UmbSearchModalElement extends UmbLitElement { override render() { return html`
- ${this.#renderSearchIcon()} +
+ ${when( + this._loading, + () => html``, + () => html``, + )} +
this.#setShowFakeCursor(true)} - @focus=${() => this.#setShowFakeCursor(false)} - type="text" - placeholder=${this.localize.term('placeholders_search')} - autocomplete="off" /> + @focus=${() => this.#setShowFakeCursor(false)} />
- ${this.#renderSearchTags()} - ${this._search - ? html`
${this._searchResults.length > 0 ? this.#renderResults() : this.#renderNoResults()}
` - : this.#renderNavigationTips()} + ${when( + this._search, + () => html` + +
+ ${when( + this._searchResults.length > 0, + () => this.#renderResults(), + () => this.#renderNoResults(), + )} +
+
+ `, + () => this.#renderNavigationTips(), + )} `; } - #renderSearchIcon() { - return html`
- ${this._loading ? html`` : html``} -
`; - } - #renderSearchTags() { - return html`
- ${repeat( - this._searchProviders, - (searchProvider) => searchProvider, - (searchProvider) => - html``, - )} -
`; + return html` +
+ ${repeat( + this._searchProviders, + (searchProvider) => searchProvider.alias, + (searchProvider) => html` + + `, + )} +
+ `; } #renderResults() { @@ -337,9 +352,9 @@ export class UmbSearchModalElement extends UmbLitElement { #renderResultItem(item: UmbSearchResultItemModel, index: number) { return html` ${this.localize.term('general_searchNoResult')}`; + if (this._loading) return nothing; + return html`
${this.localize.term('general_searchNoResult')}
`; } #renderNavigationTips() { @@ -360,34 +376,10 @@ export class UmbSearchModalElement extends UmbLitElement { ${this.localize.term('globalSearch_navigateSearchProviders')} ${this.localize.term('globalSearch_navigateSearchResults')} `; @@ -405,9 +397,9 @@ export class UmbSearchModalElement extends UmbLitElement { background-color: var(--uui-color-surface); box-sizing: border-box; color: var(--uui-color-text); - font-size: 1rem; padding-bottom: var(--uui-size-space-2); } + #navigation-tips { display: grid; grid-template-columns: 50px 50px auto; @@ -418,6 +410,7 @@ export class UmbSearchModalElement extends UmbLitElement { margin-top: var(--uui-size-layout-3); margin-inline: auto; } + .navigation-tips-key { display: flex; align-items: center; @@ -428,21 +421,24 @@ export class UmbSearchModalElement extends UmbLitElement { font-size: 0.9rem; font-weight: bold; } + #navigation-tips .navigation-tips-key + span { margin-left: var(--uui-size-space-2); } + #top { background-color: var(--uui-color-surface); display: flex; height: 48px; flex-shrink: 0; } + #main { display: flex; flex-direction: column; height: 100%; - overflow: auto; } + #search-providers { display: flex; flex-wrap: wrap; @@ -450,6 +446,7 @@ export class UmbSearchModalElement extends UmbLitElement { padding: 0 var(--uui-size-space-5); padding-bottom: var(--uui-size-space-2); } + .search-provider { padding: var(--uui-size-space-3) var(--uui-size-space-4); background: var(--uui-color-surface-alt); @@ -460,28 +457,34 @@ export class UmbSearchModalElement extends UmbLitElement { cursor: pointer; border: 2px solid transparent; } + .search-provider:hover { background: var(--uui-color-surface-emphasis); color: var(--uui-color-interactive-emphasis); } + .search-provider.active { background: var(--uui-color-focus); color: var(--uui-color-selected-contrast); border-color: transparent; } + .search-provider.active:focus { outline-offset: -4px; outline-color: var(--uui-color-focus); } + input { all: unset; height: 100%; width: 100%; } + #input-wrapper { width: 100%; position: relative; } + #input-wrapper-fake-cursor { position: absolute; left: 0; @@ -493,6 +496,7 @@ export class UmbSearchModalElement extends UmbLitElement { bottom: 14px; animation: blink-animation 1s infinite; } + @keyframes blink-animation { 0%, 50% { @@ -503,11 +507,13 @@ export class UmbSearchModalElement extends UmbLitElement { border-color: transparent; } } + button { font-family: unset; font-size: unset; cursor: pointer; } + #search-icon { display: flex; align-items: center; @@ -515,6 +521,7 @@ export class UmbSearchModalElement extends UmbLitElement { aspect-ratio: 1; height: 100%; } + #no-results { display: flex; flex-direction: column; @@ -526,21 +533,25 @@ export class UmbSearchModalElement extends UmbLitElement { color: var(--uui-color-text-alt); margin: var(--uui-size-space-5) 0; } + .search-item { color: var(--uui-color-text); text-decoration: none; outline-offset: -3px; display: flex; } + .search-item:hover { background: var(--uui-color-surface-emphasis); color: var(--uui-color-interactive-emphasis); } + .search-item:focus { outline: 2px solid var(--uui-color-interactive-emphasis); border-radius: 6px; outline-offset: -4px; } + .search-item.active:not(:focus-within) { outline: 2px solid var(--uui-color-border); border-radius: 6px; diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts index 92e8418235..cc5b612061 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts @@ -1,67 +1,41 @@ import type { UmbSearchResultItemModel } from '../types.js'; +import { css, customElement, html, nothing, property, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -const elementName = 'umb-search-result-item'; -@customElement(elementName) +@customElement('umb-search-result-item') export class UmbSearchResultItemElement extends UmbLitElement { @property({ type: Object }) item?: UmbSearchResultItemModel; override render() { if (!this.item) return nothing; - return html` - - ${this.item.icon ? html`` : this.#renderHashTag()} - - ${this.item.name} - `; - } - - #renderHashTag() { - return html` - - - - + ${when( + this.item.icon, + (icon) => html``, + () => html``, + )} + ${this.item.name} +
`; } static override styles = [ - UmbTextStyles, css` :host { - padding: var(--uui-size-space-3) var(--uui-size-space-5); border-radius: var(--uui-border-radius); - display: grid; - grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5); - align-items: center; - width: 100%; outline-offset: -3px; - } - .item-icon { - margin-bottom: auto; - margin-top: 5px; - } - .item-icon { - opacity: 0.4; - } - .item-name { + padding: var(--uui-size-space-3) var(--uui-size-space-5); + display: flex; - flex-direction: column; - } - .item-icon > * { - height: 1rem; - display: flex; - width: min-content; - } - a { - text-decoration: none; - color: inherit; + gap: var(--uui-size-space-3); + align-items: center; + + width: 100%; + + > span { + flex: 1; + } } `, ]; @@ -71,6 +45,6 @@ export { UmbSearchResultItemElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbSearchResultItemElement; + 'umb-search-result-item': UmbSearchResultItemElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts index e105f12be5..e0acfec7c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts @@ -12,7 +12,7 @@ export const manifests: Array = [ }, }, { - name: 'Template Search Result Item ', + name: 'Template Search Result Item', alias: 'Umb.SearchResultItem.Template', type: 'searchResultItem', forEntityTypes: [UMB_TEMPLATE_ENTITY_TYPE],