Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions frontend/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,16 @@
}
},
"search": {
"examples": {
"address": "Address",
"latest_block": "Latest Block",
"latest_epoch": "Latest Epoch",
"title": "Examples:",
"token": "Token",
"transaction": "Transaction",
"tx": "TX",
"validator": "Validator"
},
"filter_aria_label": "Filter by type",
"history": {
"action": {
Expand Down
9 changes: 9 additions & 0 deletions frontend/layers/base/app/components/BaseChip.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<script setup lang="ts">
import type { IconName } from '#layers/base/app/components/BaseIcon.vue'

const {
size = 'sm',
variant = 'neutral',
} = defineProps<{
icon?: IconName,
isSelected: boolean,
size?: 'sm',
variant?: 'neutral',
Expand All @@ -12,12 +15,18 @@ const {
<template>
<button
class="text-nowrap border-1 font-semibold focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-300"
type="button"
:class="[
variant === 'neutral' && 'bg-gray-100 dark:bg-gray-900 border-gray-200 dark:border-gray-800 text-gray-600 dark:text-gray-400 aria-pressed:bg-gray-200 dark:aria-pressed:bg-gray-700 aria-pressed:border-gray-300 dark:aria-pressed:border-gray-700 aria-pressed:text-black dark:aria-pressed:text-white aria-pressed:shadow-none',
size === 'sm' && 'px-md py-xs rounded-md ',
icon && 'flex items-center gap-md',
]"
:aria-pressed="isSelected"
>
<BaseIcon
v-if="icon"
:name="icon"
/>
<slot />
</button>
</template>
11 changes: 8 additions & 3 deletions frontend/layers/base/app/components/BaseSearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ watchDebounced(
async () => {
emit('search', input.value)
},
{
immediate: false,
},
)

const groupedResults = computed(() => {
Expand Down Expand Up @@ -182,6 +179,13 @@ const idSearchInput = useId()
</div>
</RkComboboxContent>
</RkComboboxRoot>

<div
v-if="$slots['search-examples']"
class="overflow-x-auto p-2xl z-10 bg-gray-50 dark:bg-gray-950 mt-xl rounded-xl shadow-[inset_0_-1px_0_0_rgba(255,255,255,0.18)]"
>
<slot name="search-examples" />
</div>
</form>
</template>

Expand All @@ -191,6 +195,7 @@ form {

&:before {
position: absolute;
z-index: -1;
content: '';
top: 0;
left: 0;
Expand Down
39 changes: 39 additions & 0 deletions frontend/layers/products/app/components/BlockchainSearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const { t: $t } = useTranslation()

const emit = defineEmits<{
(e: 'search', input: string): void,
(e: 'click:example', type: 'address' | 'token' | 'transaction' | 'validator'): void,
}>()

const searchParams = defineModel<BlockchainSearchParams>({
Expand Down Expand Up @@ -108,6 +109,44 @@ watch(hasResults, () => {
:results="resultsOrHistory"
@search="handleSearch"
>
<template #search-examples>
<div class="flex items-center">
<section class="flex gap-lg">
<div class="py-xs px-md border-gray-400 font-semibold text-gray-400">
{{ $t('products.landing_page.search.examples.title') }}
</div>
<BaseChip
:is-selected="false"
icon="switch-horizontal"
:aria-label="$t('products.landing_page.search.examples.transaction')"
@click="emit('click:example', 'transaction')"
>
{{ $t('products.landing_page.search.examples.tx') }}
</BaseChip>
<BaseChip
:is-selected="false"
icon="hash"
@click="emit('click:example', 'address')"
>
{{ $t('products.landing_page.search.examples.address') }}
</BaseChip>
<BaseChip
:is-selected="false"
icon="stack-2"
@click="emit('click:example', 'validator')"
>
{{ $t('products.landing_page.search.examples.validator') }}
</BaseChip>
<BaseChip
:is-selected="false"
icon="hexagon"
@click="emit('click:example', 'token')"
>
{{ $t('products.landing_page.search.examples.token') }}
</BaseChip>
</section>
</div>
</template>
<template #dropdown-fixed-header="{ idSearchInput }">
<div
class="min-h-fit overflow-x-auto overscroll-contain flex gap-md items-center px-2xl py-lg"
Expand Down
41 changes: 37 additions & 4 deletions frontend/layers/products/app/pages/products/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ const searchTypes: BlockchainSearchParams['types'] = [
'validator_by_public_key',
'validators_by_withdrawal_credential',
]
const networks = [
1,
560048,
] satisfies ChainId[]
const searchParams = ref<BlockchainSearchParams>({
input: '',
networks: [
1,
560048,
],
networks,
types: searchTypes,
})

Expand All @@ -71,6 +72,37 @@ const handleSearch = (input: string) => {
}
execute()
}

const handleExampleClick = (type: 'address' | 'token' | 'transaction' | 'validator') => {
if (type === 'address') {
searchParams.value = {
...searchParams.value,
input: '0x5AbfEc25f74Cd88437631A7731906932776356f9',
types: [ 'address' ],
}
}
if (type === 'token') {
searchParams.value = {
...searchParams.value,
input: '0x26D5Bd2dfEDa983ECD6c39899e69DAE6431Dffbb',
types: [ 'token' ],
}
}
if (type === 'transaction') {
searchParams.value = {
...searchParams.value,
input: '0x4978b2aeed51747c2fd1d681e7da3fd73e7ef328c3634c1a2dc1e7829f1c2622',
types: [ 'transaction' ],
}
}
if (type === 'validator') {
searchParams.value = {
...searchParams.value,
input: '5',
types: [ 'validator_by_index' ],
}
}
}
</script>

<template>
Expand Down Expand Up @@ -101,6 +133,7 @@ const handleSearch = (input: string) => {
:is-loading="status === 'pending'"
:has-error="!!error"
@search="handleSearch"
@click:example="handleExampleClick"
/>
</ProductLandingpageSection>
<ProductLandingpageSection class="mt-11xl">
Expand Down