|
- <script setup lang="ts">
- import { onMounted, onUnmounted, ref } from 'vue'
-
- const query = defineModel<string>({ default: '' })
-
- let emit = defineEmits(['onChange', 'submit']);
-
- const inputRef = ref<HTMLInputElement | null>(null)
-
- const triggerChange = () => {
- emit('onChange', query.value)
- }
-
- const submit = () => {
- const value = query.value.trim()
- if (!value) return
- emit('submit', value)
- }
-
- const onGlobalKey = (event: KeyboardEvent) => {
- if (event.key !== '/' || event.metaKey || event.ctrlKey || event.altKey) return
- const target = event.target as HTMLElement | null
- const tag = target?.tagName
- if (tag === 'INPUT' || tag === 'TEXTAREA' || target?.isContentEditable) return
- event.preventDefault()
- inputRef.value?.focus()
- }
-
- onMounted(() => window.addEventListener('keydown', onGlobalKey))
- onUnmounted(() => window.removeEventListener('keydown', onGlobalKey))
- </script>
-
- <template>
- <form class="mx-auto w-full max-w-2xl" @submit.prevent="submit">
- <label class="sr-only" for="query-box">Query</label>
-
- <div
- class="group flex h-14 items-center gap-3 rounded-2xl border border-line bg-white/[0.035] px-3.5 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.04)] transition-[border-color,box-shadow,background-color] duration-200 focus-within:border-accent/55 focus-within:bg-white/[0.05] focus-within:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.06),0_0_0_3px_color-mix(in_oklab,var(--color-accent,oklch(0.82_0.1_180))_18%,transparent)]"
- >
- <span class="grid h-8 w-8 shrink-0 place-items-center rounded-xl border border-line text-muted">
- <svg
- class="h-3.5 w-3.5"
- viewBox="0 0 16 16"
- fill="none"
- stroke="currentColor"
- stroke-width="1.5"
- aria-hidden="true"
- >
- <circle cx="7" cy="7" r="4.25" />
- <path d="M10.4 10.4 14 14" stroke-linecap="round" />
- </svg>
- </span>
-
- <input
- id="query-box"
- ref="inputRef"
- v-model="query"
- type="text"
- autocomplete="off"
- spellcheck="false"
- placeholder="Ask something…"
- class="h-full min-w-0 flex-1 bg-transparent text-[15px] leading-none text-white caret-accent outline-none placeholder:text-muted/70"
- @input="triggerChange"
- />
-
- <kbd
- class="hidden h-6 shrink-0 items-center rounded-md border border-line px-1.5 font-mono text-[10px] tracking-wide text-muted sm:inline-flex"
- >
- /
- </kbd>
-
- <button
- type="submit"
- class="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-xl bg-accent/15 px-3 text-xs font-medium text-accent transition-colors hover:bg-accent/25 disabled:cursor-not-allowed disabled:opacity-40"
- :disabled="!query.trim()"
- >
- Send
- <svg class="h-3 w-3" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
- <path d="M2 6h8M7 3l3 3-3 3" stroke-linecap="round" stroke-linejoin="round" />
- </svg>
- </button>
- </div>
- </form>
- </template>
|