diff --git a/packages/ui/lang/en.json b/packages/ui/lang/en.json
index 2570573528..733827aefd 100644
--- a/packages/ui/lang/en.json
+++ b/packages/ui/lang/en.json
@@ -5,6 +5,7 @@
     "Hours": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
     "Days": "{days, plural, =0 {today} =1 {yesterday} other {# days ago}}",
     "ShowMore": "Show more",
-    "ShowLess": "Show less"
+    "ShowLess": "Show less",
+    "Search": "Search"
   }
 }
diff --git a/packages/ui/src/components/EditWithIcon.svelte b/packages/ui/src/components/EditWithIcon.svelte
index 286507a95b..d0f0805f37 100644
--- a/packages/ui/src/components/EditWithIcon.svelte
+++ b/packages/ui/src/components/EditWithIcon.svelte
@@ -15,6 +15,7 @@
 
 <script lang="ts">
   import type { Asset } from '@anticrm/platform'
+  import { createEventDispatcher } from 'svelte'
   import type { AnySvelteComponent } from '../types'
   import Icon from './Icon.svelte'
   import IconClose from './icons/Close.svelte'
@@ -33,13 +34,14 @@
       focus = false
     }
   }
+  const dispatch = createEventDispatcher()
 </script>
 
 <div class="flex-between editbox" style={width ? 'width: ' + width : ''} on:click={() => textHTML.focus()}>
   <div class="mr-2"><Icon {icon} size={'small'} /></div>
-  <input bind:this={textHTML} type="text" bind:value {placeholder} on:change/>
+  <input bind:this={textHTML} type="text" bind:value {placeholder} on:change on:input on:keydown/>
   {#if value}
-    <div class="ml-2 btn" on:click={() => { textHTML.value = ''; textHTML.dispatchEvent(new Event('change')) }}>
+    <div class="ml-2 btn" on:click={() => { value = ''; dispatch('change', '') }}>
       <Icon icon={IconClose} size={'x-small'} />
     </div>
   {/if}
diff --git a/packages/ui/src/components/SearchEdit.svelte b/packages/ui/src/components/SearchEdit.svelte
new file mode 100644
index 0000000000..65145030a1
--- /dev/null
+++ b/packages/ui/src/components/SearchEdit.svelte
@@ -0,0 +1,42 @@
+<script lang="ts">
+  import { translate } from '@anticrm/platform'
+
+  import { createEventDispatcher } from 'svelte'
+  import ui from '../plugin'
+  import EditWithIcon from './EditWithIcon.svelte'
+  import IconSearch from './icons/Search.svelte'
+
+  export let value: string = ''
+
+  $: _search = value
+  const dispatch = createEventDispatcher()
+  let placeholder = ''
+
+  translate(ui.string.Search, {}).then((v) => {
+    placeholder = v
+  })
+</script>
+
+<EditWithIcon
+  icon={IconSearch}
+  placeholder={placeholder}
+  bind:value={_search}
+  on:change={() => {
+    if (_search === '') {
+      value = ''
+      dispatch('change', '')
+    }
+  }}
+  on:input={() => {
+    if (_search === '') {
+      value = ''
+      dispatch('change', '')
+    }
+  }}
+  on:keydown={(evt) => {
+    if (evt.key === 'Enter') {
+      value = _search
+      dispatch('change', _search)
+    }
+  }}
+/>
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index a925c511dd..df3efccda9 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -53,6 +53,7 @@ export { default as Row } from './components/Row.svelte'
 // export { default as CheckBoxWithLabel } from './components/CheckBoxWithLabel.svelte'
 // export { default as CheckBoxList } from './components/CheckBoxList.svelte.txt'
 export { default as EditWithIcon } from './components/EditWithIcon.svelte'
+export { default as SearchEdit } from './components/SearchEdit.svelte'
 export { default as Loading } from './components/Loading.svelte'
 export { default as Spinner } from './components/Spinner.svelte'
 export { default as Popup } from './components/Popup.svelte'
diff --git a/packages/ui/src/plugin.ts b/packages/ui/src/plugin.ts
index 4d632ee4e9..a2ce649acd 100644
--- a/packages/ui/src/plugin.ts
+++ b/packages/ui/src/plugin.ts
@@ -1,15 +1,15 @@
 //
 // Copyright © 2020, 2021 Anticrm Platform Contributors.
 // Copyright © 2021 Hardcore Engineering Inc.
-// 
+//
 // Licensed under the Eclipse Public License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License. You may
 // obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
-// 
+//
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// 
+//
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
@@ -29,6 +29,7 @@ export default plugin(uiId, {
     Hours: '' as IntlString,
     Days: '' as IntlString,
     ShowMore: '' as IntlString,
-    ShowLess: '' as IntlString
+    ShowLess: '' as IntlString,
+    Search: '' as IntlString
   }
-})
\ No newline at end of file
+})
diff --git a/plugins/contact-resources/src/components/Contacts.svelte b/plugins/contact-resources/src/components/Contacts.svelte
index 35a2bc9f7b..da7ccd8909 100644
--- a/plugins/contact-resources/src/components/Contacts.svelte
+++ b/plugins/contact-resources/src/components/Contacts.svelte
@@ -15,15 +15,20 @@
 -->
 
 <script lang="ts">
+  import { Doc, DocumentQuery } from '@anticrm/core'
   import { getClient } from '@anticrm/presentation'
-  import { Button, EditWithIcon, Icon, IconAdd, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
+  import { Button, Icon, IconAdd, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
   import view, { Viewlet } from '@anticrm/view'
   import { Table } from '@anticrm/view-resources'
   import contact from '../plugin'
   import CreateContact from './CreateContact.svelte'
 
   let search = ''
-  $: resultQuery = search === '' ? { } : { $search: search }
+  let resultQuery: DocumentQuery<Doc> = {}
+
+  function updateResultQuery (search: string): void {
+    resultQuery = (search === '') ? { } : { $search: search }
+  }
 
   const client = getClient()
   const tableDescriptor = client.findOne<Viewlet>(view.class.Viewlet, { attachTo: contact.class.Contact, descriptor: view.viewlet.Table })
@@ -42,7 +47,9 @@
     </div>
   </div>
   
-  <EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
+  <SearchEdit bind:value={search} on:change={() => {
+    updateResultQuery(search)
+  }}/>
   <Button icon={IconAdd} label={contact.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
 </div>
 
diff --git a/plugins/inventory-resources/src/components/Categories.svelte b/plugins/inventory-resources/src/components/Categories.svelte
index d62a675364..d51a7fb2b5 100644
--- a/plugins/inventory-resources/src/components/Categories.svelte
+++ b/plugins/inventory-resources/src/components/Categories.svelte
@@ -14,13 +14,18 @@
 // limitations under the License.
 -->
 <script lang="ts">
-  import { Button, EditWithIcon, Icon, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
-  import HierarchyView from './HierarchyView.svelte'
-  import CreateCategory from './CreateCategory.svelte'
+  import { Doc, DocumentQuery } from '@anticrm/core'
+  import { Button, Icon, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
   import inventory from '../plugin'
+  import CreateCategory from './CreateCategory.svelte'
+  import HierarchyView from './HierarchyView.svelte'
 
   let search = ''
-  $: resultQuery = search === '' ? {} : { $search: search }
+  let resultQuery: DocumentQuery<Doc> = {}
+
+  function updateResultQuery (search: string): void {
+    resultQuery = (search === '') ? { } : { $search: search }
+  }
 
   function showCreateDialog (ev: Event) {
     showPopup(CreateCategory, { space: inventory.space.Category }, ev.target as HTMLElement)
@@ -35,14 +40,9 @@
     </div>
   </div>
 
-  <EditWithIcon
-    icon={IconSearch}
-    placeholder={'Search'}
-    bind:value={search}
-    on:change={() => {
-      resultQuery = {}
-    }}
-  />
+  <SearchEdit bind:value={search} on:change={() => {
+    updateResultQuery(search)
+  }}/>
   <Button
     label={inventory.string.CreateCategoryShort}
     primary={true}
diff --git a/plugins/lead-resources/src/components/Customers.svelte b/plugins/lead-resources/src/components/Customers.svelte
index 3362901a5e..f4b9fd21bc 100644
--- a/plugins/lead-resources/src/components/Customers.svelte
+++ b/plugins/lead-resources/src/components/Customers.svelte
@@ -15,13 +15,17 @@
 -->
 
 <script lang="ts">
-  import { EditWithIcon, Icon, IconSearch, Label, ScrollBox } from '@anticrm/ui'
-
+  import { Doc, DocumentQuery } from '@anticrm/core'
+  import { Icon, Label, ScrollBox, SearchEdit } from '@anticrm/ui'
   import { Table } from '@anticrm/view-resources'
   import lead from '../plugin'
 
   let search = ''
-  $: resultQuery = search === '' ? { } : { $search: search }
+  let resultQuery: DocumentQuery<Doc> = {}
+
+  function updateResultQuery (search: string): void {
+    resultQuery = (search === '') ? { } : { $search: search }
+  }
 </script>
 
 <div class="customers-header-container">
@@ -32,7 +36,9 @@
     </div>
   </div>
   
-  <EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
+  <SearchEdit bind:value={search} on:change={() => {
+    updateResultQuery(search)
+  }}/>
 </div>
 
 <div class="container">
diff --git a/plugins/recruit-resources/src/components/Candidates.svelte b/plugins/recruit-resources/src/components/Candidates.svelte
index 000e8b35ae..6d7764d3f1 100644
--- a/plugins/recruit-resources/src/components/Candidates.svelte
+++ b/plugins/recruit-resources/src/components/Candidates.svelte
@@ -15,18 +15,21 @@
 -->
 
 <script lang="ts">
+  import contact from '@anticrm/contact'
+  import { Doc, DocumentQuery } from '@anticrm/core'
   import { getClient } from '@anticrm/presentation'
-
-  import { Button, EditWithIcon, Icon, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
-
+  import { Button, Icon, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
+  import view, { Viewlet } from '@anticrm/view'
   import { Table } from '@anticrm/view-resources'
   import recruit from '../plugin'
-  import contact from '@anticrm/contact'
-  import view, { Viewlet } from '@anticrm/view'
   import CreateCandidate from './CreateCandidate.svelte'
 
   let search = ''
-  $: resultQuery = search === '' ? { } : { $search: search }
+  let resultQuery: DocumentQuery<Doc> = {}
+
+  function updateResultQuery (search: string): void {
+    resultQuery = (search === '') ? { } : { $search: search }
+  }
 
   const client = getClient()
   const tableDescriptor = client.findOne<Viewlet>(view.class.Viewlet, { attachTo: recruit.mixin.Candidate, descriptor: view.viewlet.Table })
@@ -34,6 +37,7 @@
   function showCreateDialog (ev: Event) {
     showPopup(CreateCandidate, { space: recruit.space.CandidatesPublic }, ev.target as HTMLElement)
   }
+
 </script>
 
 <div class="candidates-header-container">
@@ -44,7 +48,9 @@
     </div>
   </div>
   
-  <EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
+  <SearchEdit bind:value={search} on:change={() => {
+    updateResultQuery(search)
+  }}/>
   <Button label={recruit.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
 </div>
 
diff --git a/plugins/workbench-resources/src/components/SpaceHeader.svelte b/plugins/workbench-resources/src/components/SpaceHeader.svelte
index 8f6e78eedb..c3433a321f 100644
--- a/plugins/workbench-resources/src/components/SpaceHeader.svelte
+++ b/plugins/workbench-resources/src/components/SpaceHeader.svelte
@@ -14,17 +14,15 @@
 -->
 
 <script lang="ts">
-  import core, { Class, Doc, WithLookup } from '@anticrm/core'
   import type { Ref, Space } from '@anticrm/core'
-  import { getClient, createQuery } from '@anticrm/presentation'
-  import { Icon, Button, EditWithIcon, IconSearch, Tooltip } from '@anticrm/ui'
+  import core, { Class, Doc, WithLookup } from '@anticrm/core'
+  import { createQuery, getClient } from '@anticrm/presentation'
   import type { AnyComponent } from '@anticrm/ui'
-  import { showPopup } from '@anticrm/ui'
-  import view, { Viewlet } from '@anticrm/view'
-
-  import { classIcon } from '../utils'
+  import { Button, Icon, SearchEdit, showPopup, Tooltip } from '@anticrm/ui'
+  import { Viewlet } from '@anticrm/view'
+  import { createEventDispatcher } from 'svelte'
   import workbench from '../plugin'
-
+  import { classIcon } from '../utils'
   import Header from './Header.svelte'
 
   export let spaceId: Ref<Space> | undefined
@@ -37,15 +35,24 @@
   const client = getClient()
   const query = createQuery()
   let space: Space | undefined
+  const dispatch = createEventDispatcher()
+
+  const prevSpaceId = spaceId
 
   $: query.query(core.class.Space, { _id: spaceId }, result => { space = result[0] })
 
-  function showCreateDialog(ev: Event) {
+  function showCreateDialog (ev: Event) {
     showPopup(createItemDialog as AnyComponent, { space: spaceId }, ev.target as HTMLElement)
   }
 
   let selectedViewlet = 0
   $: viewlet = viewlets[selectedViewlet]
+
+  $: if (prevSpaceId !== spaceId) {
+    search = ''
+    dispatch('search', '')
+  }
+
 </script>
 
 <div class="spaceheader-container">
@@ -55,14 +62,16 @@
       <div class="flex">
         {#each viewlets as viewlet, i}
           <Tooltip label={viewlet.$lookup?.descriptor?.label} direction={'top'}>
-            <div class="flex-center btn" class:selected={selectedViewlet === i} on:click={()=>{ selectedViewlet = i }}>
+            <div class="flex-center btn" class:selected={selectedViewlet === i} on:click={() => { selectedViewlet = i }}>
               <Icon icon={viewlet.$lookup?.descriptor?.icon} size={'small'}/>
             </div>
           </Tooltip>
         {/each}
       </div>
     {/if}      
-    <EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} />
+    <SearchEdit bind:value={search} on:change={() => {
+      dispatch('search', search)
+    }}/>
     {#if createItemDialog}
       <Button label={workbench.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
     {/if}
diff --git a/plugins/workbench-resources/src/components/SpaceView.svelte b/plugins/workbench-resources/src/components/SpaceView.svelte
index 9cf51edad0..02a8db6264 100644
--- a/plugins/workbench-resources/src/components/SpaceView.svelte
+++ b/plugins/workbench-resources/src/components/SpaceView.svelte
@@ -36,11 +36,13 @@
 
   let viewlets: WithLookup<Viewlet>[] = []
 
-  async function update(attachTo?: Ref<Class<Doc>>, currentSpace?: Ref<Space>): Promise<void> {
+  async function update (attachTo?: Ref<Class<Doc>>, currentSpace?: Ref<Space>): Promise<void> {
     if (attachTo) {
-      viewlets = await client.findAll(view.class.Viewlet, { attachTo }, { lookup: { 
-        descriptor: core.class.Class
-      }})
+      viewlets = await client.findAll(view.class.Viewlet, { attachTo }, {
+        lookup: {
+          descriptor: core.class.Class
+        }
+      })
       _class = attachTo
     }
     viewlet = viewlets[0]
@@ -48,12 +50,6 @@
   }
 
   $: update(currentView?.class, currentSpace)
-
-  function resetSearch (_space: Ref<Space> | undefined): void {
-    search = ''
-  }
-
-  $: resetSearch(currentSpace)
 </script>
 
 <SpaceHeader spaceId={space} {_class} {viewlets} {createItemDialog} bind:search={search} bind:viewlet={viewlet} />