openpencil/src/components/ui/AppInput.vue
Danila Poyarkov 2f88ef4827 refactor(ui): unify chat composer controls
- Add a canonical 24, 28, and 32 pixel control scale

- Rebuild the AI prompt as a multiline compound input

- Keep property-panel icon actions at the explicit compact size
2026-08-14 13:21:29 +03:00

75 lines
1.6 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
import { tv } from 'tailwind-variants'
import type { ControlSize } from '@/theme/control'
import theme from '@/theme/input'
interface AppInputProps {
id?: string
type?: 'text' | 'password' | 'number' | 'search'
placeholder?: string
ariaLabel?: string
readonly?: boolean
disabled?: boolean
autofocus?: boolean
min?: number
max?: number
step?: number
tone?: 'default' | 'panel'
size?: ControlSize
state?: 'idle' | 'mixed' | 'bound' | 'invalid'
}
const {
id,
type = 'text',
placeholder,
ariaLabel,
readonly,
disabled,
autofocus,
min,
max,
step,
tone = 'default',
size = 'md',
state = 'idle'
} = defineProps<AppInputProps>()
const inputClass = computed(() => tv(theme)({ tone, size, state }))
const modelValue = defineModel<string | number>({ required: true })
const emit = defineEmits<{
change: []
enter: [event: KeyboardEvent]
focus: [event: FocusEvent]
paste: [event: ClipboardEvent]
copy: [event: ClipboardEvent]
cut: [event: ClipboardEvent]
}>()
</script>
<template>
<input
:id="id"
v-model="modelValue"
:type="type"
:placeholder="placeholder"
:aria-label="ariaLabel"
:readonly="readonly"
:disabled="disabled"
:autofocus="autofocus"
:min="min"
:max="max"
:step="step"
:class="inputClass"
@change="emit('change')"
@keydown.enter="emit('enter', $event)"
@focus="emit('focus', $event)"
@paste="emit('paste', $event)"
@copy="emit('copy', $event)"
@cut="emit('cut', $event)"
/>
</template>