Full Vue 3 + Vite + TypeScript + Tailwind SPA replacing the vanilla JS static frontend. Includes router, Pinia stores (auth/tasks/calendar/devops), axios API client with all endpoints, UI components (Button/Card/Dialog/Badge/Input/etc), calendar grid with lane-packing algorithm and DnD support, SSE live feed, and all 11 views. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 lines
897 B
Vue
34 lines
897 B
Vue
<script setup lang="ts">
|
|
import { cn } from '@/lib/utils'
|
|
|
|
const props = defineProps<{
|
|
modelValue?: string
|
|
placeholder?: string
|
|
disabled?: boolean
|
|
rows?: number
|
|
class?: string
|
|
id?: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: string]
|
|
}>()
|
|
</script>
|
|
|
|
<template>
|
|
<textarea
|
|
:id="id"
|
|
:value="modelValue"
|
|
:placeholder="placeholder"
|
|
:disabled="disabled"
|
|
:rows="rows ?? 3"
|
|
:class="cn(
|
|
'flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm',
|
|
'ring-offset-background placeholder:text-muted-foreground',
|
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
'disabled:cursor-not-allowed disabled:opacity-50 resize-none',
|
|
props.class
|
|
)"
|
|
@input="emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)"
|
|
/>
|
|
</template>
|