feat: Animate shopping list and increase touch target (#6569)

Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
This commit is contained in:
miah
2025-12-22 11:55:25 -06:00
committed by GitHub
parent 95e1bbce2b
commit 9d601ea4b5
2 changed files with 136 additions and 124 deletions

View File

@@ -7,8 +7,16 @@
no-gutters no-gutters
class="flex-nowrap align-center" class="flex-nowrap align-center"
> >
<v-col :cols="itemLabelCols"> <v-card
<div class="d-flex align-center flex-nowrap"> flat
link
class="grow"
@click="() => {
listItem.checked = !listItem.checked
$emit('checked', listItem)
}"
>
<div class="d-flex align-center flex-nowrap grow">
<v-checkbox <v-checkbox
v-model="listItem.checked" v-model="listItem.checked"
hide-details hide-details
@@ -25,84 +33,78 @@
<RecipeIngredientListItem :ingredient="listItem" /> <RecipeIngredientListItem :ingredient="listItem" />
</div> </div>
</div> </div>
</v-col> </v-card>
<v-spacer /> <div
<v-col v-if="!listItem.checked"
cols="auto" style="min-width: 72px"
class="text-right"
> >
<div <v-menu
v-if="!listItem.checked" offset-x
style="min-width: 72px" start
min-width="125px"
> >
<v-menu <template #activator="{ props }">
offset-x <v-tooltip
start v-if="recipeList && recipeList.length"
min-width="125px" open-delay="200"
> transition="slide-x-reverse-transition"
<template #activator="{ props }"> density="compact"
<v-tooltip location="end"
v-if="recipeList && recipeList.length" content-class="text-caption"
open-delay="200" >
transition="slide-x-reverse-transition" <template #activator="{ props: tooltipProps }">
density="compact" <v-btn
location="end" size="small"
content-class="text-caption" variant="text"
> class="ml-2"
<template #activator="{ props: tooltipProps }"> icon
<v-btn v-bind="tooltipProps"
size="small" @click="displayRecipeRefs = !displayRecipeRefs"
variant="text" >
class="ml-2" <v-icon>
icon {{ $globals.icons.potSteam }}
v-bind="tooltipProps" </v-icon>
@click="displayRecipeRefs = !displayRecipeRefs" </v-btn>
> </template>
<v-icon> <span>Toggle Recipes</span>
{{ $globals.icons.potSteam }} </v-tooltip>
</v-icon> <v-btn
</v-btn> size="small"
</template> variant="text"
<span>Toggle Recipes</span> class="ml-2"
</v-tooltip> icon
<v-btn @click="toggleEdit(true)"
size="small" >
variant="text" <v-icon>
class="ml-2" {{ $globals.icons.edit }}
icon </v-icon>
@click="toggleEdit(true)" </v-btn>
> <v-btn
<v-icon> size="small"
{{ $globals.icons.edit }} variant="text"
</v-icon> class="handle"
</v-btn> icon
<v-btn v-bind="props"
size="small" >
variant="text" <v-icon>
class="handle" {{ $globals.icons.arrowUpDown }}
icon </v-icon>
v-bind="props" </v-btn>
> </template>
<v-icon> <v-list density="compact">
{{ $globals.icons.arrowUpDown }} <v-list-item
</v-icon> v-for="action in contextMenu"
</v-btn> :key="action.event"
</template> density="compact"
<v-list density="compact"> @click="contextHandler(action.event)"
<v-list-item >
v-for="action in contextMenu" <v-list-item-title>
:key="action.event" {{ action.text }}
density="compact" </v-list-item-title>
@click="contextHandler(action.event)" </v-list-item>
> </v-list>
<v-list-item-title> </v-menu>
{{ action.text }} </div>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-col>
</v-row> </v-row>
<v-row <v-row
v-if="!listItem.checked && recipeList && recipeList.length && displayRecipeRefs" v-if="!listItem.checked && recipeList && recipeList.length && displayRecipeRefs"
@@ -311,4 +313,8 @@ export default defineNuxtComponent({
.strike-through { .strike-through {
text-decoration: line-through !important; text-decoration: line-through !important;
} }
.grow {
flex-grow: 1;
}
</style> </style>

View File

@@ -179,41 +179,45 @@
</BaseButton> </BaseButton>
</div> </div>
<BaseExpansionPanels v-for="(value, key) in itemsByLabel" :key="key" :v-model="0" start-open> <TransitionGroup name="scroll-x-transition">
<v-expansion-panel class="shopping-list-section"> <BaseExpansionPanels v-for="(value, key) in itemsByLabel" :key="key" :v-model="0" start-open>
<v-expansion-panel-title <v-expansion-panel class="shopping-list-section">
:color="getLabelColor(key)" <v-expansion-panel-title
class="body-1 font-weight-bold section-title" :color="getLabelColor(key)"
> class="body-1 font-weight-bold section-title"
{{ key }}
</v-expansion-panel-title>
<v-expansion-panel-text eager>
<VueDraggable
:model-value="value"
handle=".handle"
:delay="250"
:delay-on-touch-only="true"
@start="loadingCounter += 1"
@end="loadingCounter -= 1"
@update:model-value="updateIndexUncheckedByLabel(key.toString(), $event)"
> >
<ShoppingListItem {{ key }}
v-for="(item, index) in value" </v-expansion-panel-title>
:key="item.id" <v-expansion-panel-text eager>
v-model="value[index]" <VueDraggable
class="ml-2 my-2 w-auto" :model-value="value"
:labels="allLabels || []" handle=".handle"
:units="allUnits || []" :delay="250"
:foods="allFoods || []" :delay-on-touch-only="true"
:recipes="recipeMap" @start="loadingCounter += 1"
@checked="saveListItem" @end="loadingCounter -= 1"
@save="saveListItem" @update:model-value="updateIndexUncheckedByLabel(key.toString(), $event)"
@delete="deleteListItem(item)" >
/> <TransitionGroup name="scroll-x-transition">
</VueDraggable> <ShoppingListItem
</v-expansion-panel-text> v-for="(item, index) in value"
</v-expansion-panel> :key="item.id"
</BaseExpansionPanels> v-model="value[index]"
class="ml-2 my-2 w-auto"
:labels="allLabels || []"
:units="allUnits || []"
:foods="allFoods || []"
:recipes="recipeMap"
@checked="saveListItem"
@save="saveListItem"
@delete="deleteListItem(item)"
/>
</TransitionGroup>
</VueDraggable>
</v-expansion-panel-text>
</v-expansion-panel>
</BaseExpansionPanels>
</TransitionGroup>
<!-- Checked Items --> <!-- Checked Items -->
<v-expansion-panels flat> <v-expansion-panels flat>
<v-expansion-panel v-if="listItems.checked && listItems.checked.length > 0"> <v-expansion-panel v-if="listItems.checked && listItems.checked.length > 0">
@@ -243,18 +247,20 @@
</div> </div>
</v-expansion-panel-title> </v-expansion-panel-title>
<v-expansion-panel-text eager> <v-expansion-panel-text eager>
<div v-for="(item, idx) in listItems.checked" :key="item.id"> <TransitionGroup name="scroll-x-transition">
<ShoppingListItem <div v-for="(item, idx) in listItems.checked" :key="item.id">
v-model="listItems.checked[idx]" <ShoppingListItem
class="strike-through-note" v-model="listItems.checked[idx]"
:labels="allLabels || []" class="strike-through-note"
:units="allUnits || []" :labels="allLabels || []"
:foods="allFoods || []" :units="allUnits || []"
@checked="saveListItem" :foods="allFoods || []"
@save="saveListItem" @checked="saveListItem"
@delete="deleteListItem(item)" @save="saveListItem"
/> @delete="deleteListItem(item)"
</div> />
</div>
</TransitionGroup>
</v-expansion-panel-text> </v-expansion-panel-text>
</v-expansion-panel> </v-expansion-panel>
</v-expansion-panels> </v-expansion-panels>