Files
thoughtsync/frontend/src/components/BaseInput.vue
T
bvandeusenandClaude Opus 4.8 bf3d403648 M0: Vue 3 + TypeScript frontend — auth views + authed board shell
- Vite + Vue 3.5 + Pinia + vue-router + Tailwind (brand accent #F5C518),
  dark-mode aware, deterministic package-lock.json for `npm ci`.
- Session store (fetchMe/login/register/logout) over a credentials:'include'
  fetch client; router guards (requiresAuth / guestOnly) with lazy /me resolve.
- BaseButton + BaseInput primitives (focus rings, loading, error states).
- LoginView, RegisterView, and an authed BoardView shell with an empty state
  for the M1 masonry board — all at v1 polish (rule 24).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-19 13:17:38 -04:00

36 lines
1.2 KiB
Vue

<script setup lang="ts">
defineProps<{
id: string;
label: string;
modelValue: string;
type?: string;
autocomplete?: string;
placeholder?: string;
error?: string;
required?: boolean;
}>();
defineEmits<{ (e: "update:modelValue", value: string): void }>();
</script>
<template>
<div class="flex flex-col gap-1.5">
<label :for="id" class="text-sm font-medium text-neutral-700 dark:text-neutral-300">{{ label }}</label>
<input
:id="id"
:type="type ?? 'text'"
:value="modelValue"
:autocomplete="autocomplete"
:placeholder="placeholder"
:required="required"
:aria-invalid="error ? 'true' : undefined"
class="rounded-lg border bg-white px-3 py-2.5 text-sm text-neutral-900 shadow-sm transition
placeholder:text-neutral-400 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand
dark:bg-neutral-800 dark:text-neutral-100 dark:placeholder:text-neutral-500"
:class="error ? 'border-red-400 dark:border-red-500' : 'border-neutral-300 dark:border-neutral-700'"
@input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
/>
<p v-if="error" class="text-xs text-red-600 dark:text-red-400">{{ error }}</p>
</div>
</template>