feat: add filter input

This commit is contained in:
YunYouJun
2022-11-06 02:54:20 +08:00
parent 5b60db8224
commit ba59b045c8
14 changed files with 62 additions and 9 deletions

2
src/components.d.ts vendored
View File

@@ -19,6 +19,8 @@ declare module '@vue/runtime-core' {
ReloadPrompt: typeof import('./components/ReloadPrompt.vue')['default'] ReloadPrompt: typeof import('./components/ReloadPrompt.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Search: typeof import('./components/Search.vue')['default']
SearchFood: typeof import('./components/SearchFood.vue')['default']
StapleTag: typeof import('./components/tags/StapleTag.vue')['default'] StapleTag: typeof import('./components/tags/StapleTag.vue')['default']
Switch: typeof import('./components/Switch.vue')['default'] Switch: typeof import('./components/Switch.vue')['default']
ToggleMode: typeof import('./components/ToggleMode.vue')['default'] ToggleMode: typeof import('./components/ToggleMode.vue')['default']

View File

@@ -5,7 +5,7 @@ import type { StuffItem } from '~/data/food'
import { meat, staple, tools, vegetable } from '~/data/food' import { meat, staple, tools, vegetable } from '~/data/food'
import recipeData from '~/data/recipe.json' import recipeData from '~/data/recipe.json'
import type { Recipe, RecipeItem } from '~/types' import type { Recipe, RecipeItem } from '~/types'
import { useRecipeStore } from '~/stores/recipe' import { useRecipeStore } from '~/store/recipe'
import { useInvisibleElement } from '~/composables/helper' import { useInvisibleElement } from '~/composables/helper'
import { useEmojiAnimation } from '~/composables/animation' import { useEmojiAnimation } from '~/composables/animation'
@@ -161,6 +161,8 @@ const randomRecipe = ref<RecipeItem>(generateRandomRecipe())
<!-- <Switch /> --> <!-- <Switch /> -->
<div class="cook-recipes" p="2"> <div class="cook-recipes" p="2">
<SearchFood />
<Transition mode="out-in"> <Transition mode="out-in">
<div class="cook-filter-recipes"> <div class="cook-filter-recipes">
<span v-if="!curStuff.length && !curTool" text="sm" p="2"> <span v-if="!curStuff.length && !curTool" text="sm" p="2">

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useAppStore } from '~/stores/app' import { useAppStore } from '~/store/app'
const app = useAppStore() const app = useAppStore()
const install = () => { const install = () => {

View File

@@ -0,0 +1,33 @@
<script lang="ts" setup>
import { useRecipeStore } from "~/store/recipe";
const rStore = useRecipeStore()
const clearKeyword = () => {
rStore.keyword = ''
}
</script>
<template>
<div m="auto b-2" max-w="500px">
<div relative text-xs>
<div v-show="rStore.keyword" cursor="pointer" absolute right-2 inline-flex justify="center" items-center h="full" opacity="70" @click="clearKeyword">
<div i-ri-close-line />
</div>
<input
id="input"
v-model="rStore.keyword"
placeholder="关键字过滤"
aria-label="搜索关键字"
type="text"
autocomplete="false"
p="x4 y2"
w="full"
text="center"
bg="transparent"
border="~ rounded gray-200 dark:gray-700"
class="focus:(dark:gray-500)"
>
<label class="hidden" for="input">快速搜索</label>
</div>
</div>
</template>

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { SearchMode } from '~/stores/recipe' import type { SearchMode } from '~/store/recipe'
import { useRecipeStore } from '~/stores/recipe' import { useRecipeStore } from '~/store/recipe'
const rStore = useRecipeStore() const rStore = useRecipeStore()

View File

@@ -3,7 +3,7 @@ import { storeToRefs } from 'pinia'
import { useGtm } from '@gtm-support/vue-gtm' import { useGtm } from '@gtm-support/vue-gtm'
import type { Recipe } from '~/types' import type { Recipe } from '~/types'
import { useRecipeStore } from '~/stores/recipe' import { useRecipeStore } from '~/store/recipe'
import type { StuffItem } from '~/data/food' import type { StuffItem } from '~/data/food'
export function useRecipe(recipe: Ref<Recipe>) { export function useRecipe(recipe: Ref<Recipe>) {
@@ -15,6 +15,12 @@ export function useRecipe(recipe: Ref<Recipe>) {
// 默认严格模式 // 默认严格模式
const displayedRecipe = computed(() => { const displayedRecipe = computed(() => {
// if keyword exist, return result directly
const keyword = rStore.keyword
if (keyword) {
return recipe.value.filter(item => item.name.includes(keyword))
}
if (curMode.value === 'strict') { if (curMode.value === 'strict') {
return recipe.value.filter((item) => { return recipe.value.filter((item) => {
const stuffFlag = curStuff.value.every(stuff => item.stuff.includes(stuff)) const stuffFlag = curStuff.value.every(stuff => item.stuff.includes(stuff))

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { links } from '~/constants'; import { links } from '~/constants';
import { useRecipeStore } from '~/stores/recipe' import { useRecipeStore } from '~/store/recipe'
const rStore = useRecipeStore() const rStore = useRecipeStore()
</script> </script>

View File

@@ -10,6 +10,11 @@ const namespace = 'cook'
export type SearchMode = 'survival' | 'loose' | 'strict' export type SearchMode = 'survival' | 'loose' | 'strict'
export const useRecipeStore = defineStore('recipe', () => { export const useRecipeStore = defineStore('recipe', () => {
/**
*
*/
const keyword = ref('')
// can not exported // can not exported
const curStuff = useStorage(`${namespace}:stuff`, new Set<string>()) const curStuff = useStorage(`${namespace}:stuff`, new Set<string>())
// const curTools = ref(new Set<string>()) // const curTools = ref(new Set<string>())
@@ -59,6 +64,7 @@ export const useRecipeStore = defineStore('recipe', () => {
} }
return { return {
keyword,
curTool, curTool,
curMode, curMode,
selectedStuff, selectedStuff,

View File

@@ -13,6 +13,10 @@ html.dark {
background: #121212; background: #121212;
} }
input:focus {
outline: none;
}
#nprogress { #nprogress {
pointer-events: none; pointer-events: none;
} }

View File

@@ -1,5 +1,5 @@
import { isClient } from '@vueuse/core' import { isClient } from '@vueuse/core'
import { useAppStore } from '~/stores/app' import { useAppStore } from '~/store/app'
/** /**
* https://web.dev/customize-install/#detect-install * https://web.dev/customize-install/#detect-install

View File

@@ -3,7 +3,7 @@
import { describe, it } from 'vitest' import { describe, it } from 'vitest'
// import { createTestingPinia } from '@pinia/testing' // import { createTestingPinia } from '@pinia/testing'
// import ChooseFood from '../src/components/ChooseFood.vue' // import ChooseFood from '../src/components/ChooseFood.vue'
// import { useRecipeStore } from '~/stores/recipe' // import { useRecipeStore } from '~/store/recipe'
describe('ChooseFood.vue', () => { describe('ChooseFood.vue', () => {
it('should render', async () => { it('should render', async () => {

View File

@@ -3,7 +3,7 @@ import { createPinia, setActivePinia } from 'pinia'
import { useRecipe } from '~/composables/recipe' import { useRecipe } from '~/composables/recipe'
import type { Recipe } from '~/types' import type { Recipe } from '~/types'
import recipeData from '~/data/recipe.json' import recipeData from '~/data/recipe.json'
import { useRecipeStore } from '~/stores/recipe' import { useRecipeStore } from '~/store/recipe'
const recipe = ref<Recipe>(recipeData as Recipe) const recipe = ref<Recipe>(recipeData as Recipe)