-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
enhancement: improve filters for mobile (#5994)
* enhancement: improve filters for mobile * chore: code conventions --------- Co-authored-by: Jean Ribeiro <contact@jeanribeiro.dev> Co-authored-by: Jean Ribeiro <iamjeanribeiro@gmail.com>
- Loading branch information
1 parent
da8b94c
commit f7a2aa0
Showing
13 changed files
with
387 additions
and
6 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
packages/mobile/components/drawers/DateTimePickerDrawer.svelte
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,70 @@ | ||
<script lang="ts"> | ||
import SveltyPicker from 'svelty-picker' | ||
import { Button } from '@ui' | ||
import { localize } from '@core/i18n' | ||
import { closeDrawer, DrawerId } from '@/auxiliary/drawer' | ||
export let value: Date = undefined | ||
export let startDate: Date = null | ||
export let mode: 'auto' | 'datetime' | 'date' | 'time' = 'auto' | ||
export let onConfirm: (value: Date) => void = () => {} | ||
const sveltyPickerStartDate = convertDateToSveltyPickerFormat(startDate) | ||
let sveltyPickerDate = convertDateToSveltyPickerFormat(value) ?? sveltyPickerStartDate | ||
function convertDateToSveltyPickerFormat(date: Date): string { | ||
return date?.toLocaleString('sv') | ||
} | ||
function onConfirmClick(): void { | ||
onConfirm(new Date(sveltyPickerDate)) | ||
closeDrawer(DrawerId.DateTimePicker) | ||
} | ||
</script> | ||
|
||
<datetime-picker-drawer class="w-full h-full space-y-6 flex flex-auto flex-col items-center flex-shrink-0"> | ||
<SveltyPicker | ||
pickerOnly | ||
autoclose | ||
{mode} | ||
clearBtn={false} | ||
todayBtn={false} | ||
startDate={sveltyPickerStartDate} | ||
format="yyyy-mm-dd hh:ii" | ||
theme="datetime-picker-colors" | ||
bind:value={sveltyPickerDate} | ||
/> | ||
<Button onClick={onConfirmClick} classes="w-full">{localize('actions.confirm')}</Button> | ||
</datetime-picker-drawer> | ||
|
||
<style type="text/scss"> | ||
:global(body.scheme-dark) { | ||
:global(.datetime-picker-colors) { | ||
--sdt-color: theme('colors.white'); | ||
--sdt-btn-bg-hover: theme('colors.gray.800'); | ||
--sdt-btn-bg-hover: theme('colors.gray.800'); | ||
--sdt-btn-header-bg-hover: theme('colors.gray.800'); | ||
--sdt-clock-bg: theme('colors.gray.800'); | ||
--sdt-clock-bg-minute: theme('colors.gray.800'); | ||
} | ||
} | ||
:global(.datetime-picker-colors) { | ||
--sdt-primary: theme('colors.blue.500'); | ||
--sdt-color: theme('colors.gray.600'); | ||
--sdt-color-selected: theme('colors.white'); | ||
--sdt-bg-main: none; | ||
--sdt-bg-today: var(--sdt-primary); | ||
--sdt-today-color: theme('colors.white'); | ||
--sdt-btn-bg-hover: theme('colors.gray.200'); | ||
--sdt-btn-header-bg-hover: theme('colors.gray.200'); | ||
--sdt-clock-bg: theme('colors.gray.200'); | ||
--sdt-clock-bg-minute: theme('colors.gray.200'); | ||
--sdt-clock-bg-shadow: none; | ||
--sdt-shadow: none; | ||
} | ||
</style> |
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
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
35 changes: 35 additions & 0 deletions
35
packages/mobile/components/molecules/DateInputButton.svelte
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,35 @@ | ||
<script lang="ts"> | ||
import { Icon, Text } from '@ui' | ||
import { appSettings } from '@core/app' | ||
import { formatDate } from '@core/i18n' | ||
import { DrawerId, openDrawer } from '@/auxiliary/drawer' | ||
import { Icon as IconEnum } from '@lib/auxiliary/icon' | ||
export let value: string = undefined | ||
export let onConfirm: (value: string) => void = () => {} | ||
let anchor: HTMLElement | ||
$: formattedDate = value ? formatDate(new Date(value), { dateStyle: 'short', locale: $appSettings.language }) : '' | ||
function onShowDateTimePickerClick(): void { | ||
openDrawer(DrawerId.DateTimePicker, { onConfirm, mode: 'date' }) | ||
} | ||
</script> | ||
|
||
<button | ||
bind:this={anchor} | ||
on:click={onShowDateTimePickerClick} | ||
class="flex flex-row justify-between border border-solid border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 hover:border-gray-500 dark:hover:border-gray-700 text-center rounded-xl px-2 py-1" | ||
> | ||
<Icon width="20" height="20" classes="text-gray-500" icon={IconEnum.Calendar} /> | ||
<Text>{formattedDate}</Text> | ||
</button> | ||
|
||
<style lang="scss"> | ||
button { | ||
width: 93px; | ||
} | ||
</style> |
38 changes: 38 additions & 0 deletions
38
packages/mobile/components/molecules/filter-items/AssetFilterItem.svelte
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,38 @@ | ||
<script lang="ts"> | ||
import { Radio } from '@ui' | ||
import type { IDropdownChoice } from '@core/utils' | ||
import { AssetFilterUnit } from '@core/utils/interfaces/filter' | ||
import { visibleSelectedAccountAssets } from '@core/wallet' | ||
export let filterUnit: AssetFilterUnit | ||
const { baseCoin, nativeTokens } = $visibleSelectedAccountAssets | ||
const choices: IDropdownChoice[] = [baseCoin, ...nativeTokens].map((choice) => ({ | ||
label: choice.metadata.name, | ||
value: choice.id, | ||
})) | ||
if (!filterUnit.selected) { | ||
filterUnit.selected = baseCoin.id | ||
} | ||
let selectedFilterUnit: string = filterUnit.selected | ||
$: selectedFilterUnit, updateFilterUnit() | ||
function updateFilterUnit(): void { | ||
let asset = undefined | ||
if (selectedFilterUnit === baseCoin.id) { | ||
asset = baseCoin | ||
} else { | ||
asset = nativeTokens.find((_nativeToken) => _nativeToken.id === selectedFilterUnit) | ||
} | ||
filterUnit.selected = asset?.id || '' | ||
} | ||
</script> | ||
|
||
<asset-filter-item class="flex flex-col overflow-y-auto"> | ||
{#each choices as choice} | ||
<Radio value={choice.value} bind:group={selectedFilterUnit} label={choice.label} /> | ||
{/each} | ||
</asset-filter-item> |
103 changes: 103 additions & 0 deletions
103
packages/mobile/components/molecules/filter-items/DateFilterItem.svelte
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,103 @@ | ||
<script lang="ts"> | ||
import { DateInputButton } from '@components' | ||
import { Icon, NumberInput, Radio, Text } from '@ui' | ||
import { localize } from '@core/i18n' | ||
import type { IDropdownChoice } from '@core/utils' | ||
import { DateFilterOption, DateUnit } from '@core/utils/enums/filters' | ||
import { DateFilterUnit } from '@core/utils/interfaces/filter' | ||
import { Icon as IconEnum } from '@lib/auxiliary/icon' | ||
export let filterUnit: DateFilterUnit | ||
const choices: IDropdownChoice[] = filterUnit.choices.map((choice) => ({ | ||
label: localize(`${filterUnit.localeKey}.${choice}`), | ||
value: choice, | ||
})) | ||
const unitChoices: IDropdownChoice[] = Object.keys(DateUnit).map((val) => ({ | ||
label: localize(`${filterUnit.localeKey}.${val}`), | ||
value: val, | ||
})) | ||
let selectedFilterUnit: DateFilterOption = filterUnit.selected | ||
$: selectedFilterUnit, updateFilterUnit() | ||
function updateFilterUnit(): void { | ||
const updated = filterUnit.selected !== selectedFilterUnit | ||
filterUnit.selected = selectedFilterUnit | ||
if (updated) { | ||
switch (filterUnit.selected) { | ||
case DateFilterOption.Equals: | ||
case DateFilterOption.After: | ||
case DateFilterOption.AfterOrEquals: | ||
case DateFilterOption.Before: | ||
filterUnit.subunit = { | ||
type: 'single', | ||
value: undefined, | ||
} | ||
break | ||
case DateFilterOption.Range: | ||
filterUnit.subunit = { | ||
type: 'range', | ||
start: undefined, | ||
end: undefined, | ||
} | ||
break | ||
case DateFilterOption.Last: | ||
filterUnit.subunit = { | ||
type: 'unit', | ||
amount: '0', | ||
unit: DateUnit.Days, | ||
} | ||
break | ||
} | ||
} | ||
} | ||
function updateSubunitStart(value: string): void { | ||
if (filterUnit.subunit.type === 'range') { | ||
filterUnit.subunit.start = value | ||
} | ||
} | ||
function updateSubunitEnd(value: string): void { | ||
if (filterUnit.subunit.type === 'range') { | ||
filterUnit.subunit.end = value | ||
} | ||
} | ||
function updateSubunitValue(value: string): void { | ||
if (filterUnit.subunit.type === 'single') { | ||
filterUnit.subunit.value = value | ||
} | ||
} | ||
</script> | ||
|
||
<date-filter-options class="flex flex-col overflow-y-auto"> | ||
{#each choices as choice} | ||
<Radio value={choice.value} bind:group={selectedFilterUnit} label={choice.label} /> | ||
{/each} | ||
</date-filter-options> | ||
|
||
{#if filterUnit.selected} | ||
<div class="flex flex-row items-center space-x-2 mt-2"> | ||
{#if filterUnit.selected !== DateFilterOption.Range} | ||
<Icon height="24" width="20" icon={IconEnum.ArrowRight} /> | ||
{/if} | ||
{#if filterUnit.subunit.type === 'range'} | ||
<DateInputButton value={filterUnit.subunit.start} onConfirm={updateSubunitStart} /> | ||
<Text>{localize('general.and')}</Text> | ||
<DateInputButton value={filterUnit.subunit.end} onConfirm={updateSubunitEnd} /> | ||
{:else if filterUnit.subunit.type === 'single'} | ||
<DateInputButton value={filterUnit.subunit.value} onConfirm={updateSubunitValue} /> | ||
{:else if filterUnit.subunit.type === 'unit'} | ||
<NumberInput bind:value={filterUnit.subunit.amount} placeholder="" /> | ||
<date-filter-subunit-options class="flex flex-col overflow-y-auto flex-shrink-0"> | ||
{#each unitChoices as choice} | ||
<Radio value={choice.value} bind:group={filterUnit.subunit.unit} label={choice.label} /> | ||
{/each} | ||
</date-filter-subunit-options> | ||
{/if} | ||
</div> | ||
{/if} |
64 changes: 64 additions & 0 deletions
64
packages/mobile/components/molecules/filter-items/NumberFilterItem.svelte
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,64 @@ | ||
<script lang="ts"> | ||
import { Icon, NumberInput, Radio, Text } from '@ui' | ||
import { localize } from '@core/i18n' | ||
import type { IDropdownChoice } from '@core/utils' | ||
import { NumberFilterOption } from '@core/utils/enums/filters' | ||
import { NumberFilterUnit } from '@core/utils/interfaces/filter' | ||
import { Icon as IconEnum } from '@lib/auxiliary/icon' | ||
export let filterUnit: NumberFilterUnit | ||
const choices: IDropdownChoice[] = filterUnit.choices.map((choice) => ({ | ||
label: localize(`${filterUnit.localeKey}.${choice}`), | ||
value: choice, | ||
})) | ||
let selectedFilterUnit: NumberFilterOption = filterUnit.selected | ||
$: selectedFilterUnit, updateFilterUnit() | ||
function updateFilterUnit(): void { | ||
const updated = filterUnit.selected !== selectedFilterUnit | ||
filterUnit.selected = selectedFilterUnit | ||
if (updated) { | ||
switch (filterUnit.selected) { | ||
case NumberFilterOption.Equal: | ||
case NumberFilterOption.Greater: | ||
case NumberFilterOption.Less: | ||
filterUnit.subunit = { | ||
type: 'single', | ||
amount: '', | ||
} | ||
break | ||
case NumberFilterOption.Range: | ||
filterUnit.subunit = { | ||
type: 'range', | ||
start: '', | ||
end: '', | ||
} | ||
break | ||
} | ||
} | ||
} | ||
</script> | ||
|
||
<number-filter-options class="flex flex-col overflow-y-auto"> | ||
{#each choices as choice} | ||
<Radio value={choice.value} bind:group={selectedFilterUnit} label={choice.label} /> | ||
{/each} | ||
</number-filter-options> | ||
|
||
{#if filterUnit.selected} | ||
<div class="flex flex-row items-center space-x-2 mt-2"> | ||
<Icon height="24" width="20" icon={IconEnum.ArrowRight} /> | ||
{#if filterUnit.subunit.type === 'range'} | ||
<NumberInput bind:value={filterUnit.subunit.start} autofocus placeholder="" /> | ||
<Text>{localize('general.and')}</Text> | ||
<NumberInput bind:value={filterUnit.subunit.end} placeholder="" /> | ||
{:else} | ||
<NumberInput bind:value={filterUnit.subunit.amount} autofocus placeholder="" /> | ||
{/if} | ||
</div> | ||
{/if} |
34 changes: 34 additions & 0 deletions
34
packages/mobile/components/molecules/filter-items/OrderFilterItem.svelte
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,34 @@ | ||
<script lang="ts"> | ||
import { HR, Radio } from '@ui' | ||
import { localize } from '@core/i18n' | ||
import type { IDropdownChoice } from '@core/utils' | ||
import { OrderOption } from '@core/utils/enums/filters' | ||
import { OrderFilterUnit } from '@core/utils/interfaces/filter' | ||
export let filterUnit: OrderFilterUnit | ||
const choices: IDropdownChoice[] = filterUnit.choices.map((choice) => ({ | ||
label: localize(`${filterUnit.localeKey}.${choice}`), | ||
value: choice, | ||
})) | ||
const ascDescChoices: IDropdownChoice[] = [OrderOption.Asc, OrderOption.Desc].map((choice) => ({ | ||
label: localize(`filters.ascDesc.${choice}`), | ||
value: choice, | ||
})) | ||
</script> | ||
|
||
<order-filter-item class="flex flex-col justify-between space-y-2"> | ||
<div> | ||
{#each choices as choice} | ||
<Radio value={choice.value} bind:group={filterUnit.selected} label={choice.label} /> | ||
{/each} | ||
</div> | ||
<HR /> | ||
<div> | ||
{#each ascDescChoices as choice} | ||
<Radio value={choice.value} bind:group={filterUnit.ascDesc} label={choice.label} /> | ||
{/each} | ||
</div> | ||
</order-filter-item> |
Oops, something went wrong.