-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
324 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Usage | ||
|
||
TBD |
151 changes: 151 additions & 0 deletions
151
src/components/AdvancedSearchBar/AdvancedSearchBar.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import { AdvancedSearchBar } from '@/components'; | ||
import mdx from './AdvancedSearchBar.mdx'; | ||
import iconOverview from '@/assets/images/iconOverview.svg'; | ||
import routeDecorator, { | ||
routeTemplate | ||
} from '../../../.storybook/routeDecorator'; | ||
|
||
export default { | ||
title: 'Components/Advanced Search Bar', | ||
component: AdvancedSearchBar, | ||
decorators: [ | ||
routeDecorator('/', [ | ||
{ | ||
path: '/advanced-search', | ||
component: { | ||
template: routeTemplate('advanced-search') | ||
} | ||
} | ||
]) | ||
], | ||
parameters: { | ||
docs: { | ||
page: mdx | ||
} | ||
} | ||
}; | ||
|
||
const PrimaryTemplate = (args, { argTypes }) => ({ | ||
props: Object.keys(argTypes), | ||
components: { AdvancedSearchBar }, | ||
setup: () => ({ args }), | ||
template: ` | ||
<AdvancedSearchBar v-bind='args'> | ||
<template | ||
#default="{ result }" | ||
class="min-w-full" | ||
> | ||
<td> | ||
<img class="w-5 h-5" :src="result.img" /> | ||
</td> | ||
<td> | ||
{{ result.description }} | ||
</td> | ||
<td> | ||
{{ result.type }} | ||
</td> | ||
<td> | ||
> | ||
</td> | ||
</template> | ||
</AdvancedSearchBar> | ||
` | ||
}); | ||
|
||
export const Primary = PrimaryTemplate.bind({}); | ||
Primary.args = { | ||
searchFunction: (searchTerm) => { | ||
const allPostCards = [ | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'campaign ad', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'soccer postcard', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'baseball mail', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'basketball email', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'campaign ad 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'soccer postcard 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'baseball mail 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'basketball email 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'campaign ad', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'soccer postcard', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'baseball mail', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: `/${iconOverview}`, | ||
description: 'basketball email', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'campaign ad 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'soccer postcard 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'baseball mail 1000', | ||
type: 'postcard' | ||
}, | ||
{ | ||
img: 'https://upload.wikimedia.org/wikipedia/commons/1/13/Tunnel_View%2C_Yosemite_Valley%2C_Yosemite_NP_-_Diliff.jpg', | ||
description: 'basketball email 1000', | ||
type: 'postcard' | ||
} | ||
]; | ||
const results = allPostCards.filter((postCard) => | ||
postCard.description.includes(searchTerm) | ||
); | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve(results); | ||
}, 1500); // waits for 1500ms before returning results, so it's more 'realistic' | ||
}); | ||
}, | ||
link: '/advanced-search', | ||
count: 10 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
<template> | ||
<div ref="searchBar" class="relative"> | ||
<TextInput | ||
id="searchBar" | ||
v-model="searchTerm" | ||
class="min-w-full" | ||
:label="t('search.textLabel')" | ||
:sr-only-label="true" | ||
> | ||
<template #iconLeft> | ||
<MagnifyingGlass size="l" /> | ||
</template> | ||
<template #iconRight> | ||
<button | ||
:class="[ | ||
'block', | ||
searchTerm ? 'opacity-100 cursor-pointer' : 'opacity-0' | ||
]" | ||
:aria-label="t('search.closeLabel')" | ||
:disabled="disabled" | ||
data-testid="clearSearchButton" | ||
@click="clearSearch" | ||
> | ||
<XmarkLarge /> | ||
</button> | ||
</template> | ||
</TextInput> | ||
<div | ||
v-if="visible || searchTerm.value" | ||
class="bg-white shadow overflow-y-auto min-w-full absolute" | ||
role="results" | ||
> | ||
<!-- If search is still running do not perform any action and show a searching bar --> | ||
<template v-if="searching"> | ||
{{ t('search.loading') }} | ||
</template> | ||
<!-- If search is done and seach has results, show the results --> | ||
<template v-else-if="!searching && searchResults.length"> | ||
<div v-for="eachSearch in searchResults"> | ||
<LobTable | ||
class="min-w-full divide-y divide-gray-200" | ||
space="sm" | ||
> | ||
<TableHeader> | ||
<slot name="header" :result="eachSearch" /> | ||
</TableHeader> | ||
<TableBody> | ||
<TableRow | ||
v-for="result in eachSearch.results" | ||
:key="result" | ||
class="text-gray-500 hover:text-primary-700 cursor-pointer" | ||
@click="hide" | ||
> | ||
<slot name="body" :result="result" /> | ||
</TableRow> | ||
</TableBody> | ||
</LobTable> | ||
</div> | ||
<!-- If search has results and user wants to show a footer, the total number of results --> | ||
<div v-if="footer" class="flow-root"> | ||
<div class="float-left"> | ||
{{ totalResults }} {{ t('search.matchingResults') }} | ||
</div> | ||
<div class="float-right"> | ||
<LobLink | ||
:to="link" | ||
:underline="false" | ||
class="hover:text-primary-700" | ||
@click="hide" | ||
> | ||
{{ t('search.seeAllResults') }} | ||
</LobLink> | ||
</div> | ||
</div> | ||
</template> | ||
<!-- If no results are found show a no results message --> | ||
<template v-else> | ||
{{ t('search.noResults') }} | ||
</template> | ||
</div> | ||
</div> | ||
</template> | ||
<script setup lang="ts"> | ||
import TextInput from '../TextInput/TextInput'; | ||
import LobTable from '../Table/Table'; | ||
import TableHeader from '../Table/TableHeader'; | ||
import TableBody from '../Table/TableBody'; | ||
import TableRow from '../Table/TableRow'; | ||
import LobLink from '../Link/Link.vue'; | ||
import MagnifyingGlass from '../Icons/MagnifyingGlass'; | ||
import XmarkLarge from '../Icons/XmarkLarge'; | ||
import { ref, watch, computed } from 'vue'; | ||
const searchTerm = ref(''); | ||
const searchResults = ref([]); | ||
const searching = ref(false); | ||
const visible = ref(false); | ||
const timeout = ref(null); | ||
const props = withDefaults( | ||
defineProps<{ | ||
searchFunction: Function; | ||
count?: number; | ||
link?: string; | ||
footer?: boolean; | ||
}>(), | ||
{ | ||
count: 0, | ||
link: '', | ||
footer: true | ||
} | ||
); | ||
const disabled = computed(() => !searchTerm); | ||
const totalResults = computed(() => props.count); | ||
watch(searchTerm, async (newSearchTerm) => { | ||
if (newSearchTerm) { | ||
visible.value = true; | ||
debounceSearch(); | ||
} | ||
}); | ||
function debounceSearch(searchTerm: string, delayMs: number = 500) { | ||
searching.value = true; | ||
clearTimeout(timeout); | ||
timeout.value = setTimeout(async () => { | ||
search(searchTerm); | ||
}, delayMs); | ||
} | ||
function testFunction() { | ||
return [ | ||
{ | ||
title: 'Test 1', | ||
icon: 'Creative', | ||
results: [ | ||
'tess1', | ||
'test2' | ||
] | ||
} | ||
] | ||
} | ||
function search(searchTerm: string) { | ||
searchResults.value = ref([]); | ||
searchResults.value = testFunction(searchTerm); | ||
Check warning Code scanning / CodeQL Superfluous trailing arguments Warning
Superfluous argument passed to
function testFunction Error loading related location Loading |
||
searching.value = false; | ||
} | ||
function clearSearch(){ | ||
if(searchTerm.value){ | ||
searchTerm.value = ''; | ||
searchResults.value = []; | ||
visible.value = false; | ||
} | ||
} | ||
function hide(){ | ||
visible.value = false; | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as AdvancedSearchBar } from './AdvancedSearchBar.vue'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters