- The SPA loads the backend::lang bundle before /auth/me, sets the document language from meta.locale and renders plural messages with Intl.PluralRules; interpolate mirrors phrasebook for :name/:Name/:NAME - Create and record routes; mapWinterUrl maps recordUrl and redirects onto the controller's list, create and record routes only - List rows open their record; FormView loads the form schema and the record, shows context-allowed fields in the span grid, saves values keyed by field name and toasts the resolved saved message - A 422 puts each message under its field (aria-invalid, aria-describedby), shows the plural banner, focuses the first invalid field in schema order and clears a field's error on change - The D-05 registry maps text, textarea, number and dropdown; any other type renders the unsupported-field box with the type in DM Mono - The admin OpenAPI document declares the write request bodies (AdminRecord, AdminIDsRequest) and the list filter query as a deepObject, so the typed client can send them - New backend::lang form.load_failed key; boardwalk/dist rebuilt
32 lines
1.2 KiB
Vue
32 lines
1.2 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { controlAttributes, controlClass, type FieldControlProps } from '../registry'
|
|
|
|
const props = defineProps<FieldControlProps>()
|
|
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
|
|
|
|
// Winter textarea sizes mapped to rows; the design's Opis uses 4 (small).
|
|
const rowsBySize: Record<string, number> = { tiny: 2, small: 4, large: 8, huge: 12, giant: 18 }
|
|
|
|
const rows = computed(() => rowsBySize[props.field.size ?? ''] ?? 5)
|
|
const text = computed(() => (props.modelValue === null || props.modelValue === undefined ? '' : String(props.modelValue)))
|
|
const attrs = computed(() => controlAttributes(props.field))
|
|
</script>
|
|
|
|
<template>
|
|
<textarea
|
|
:id="controlId"
|
|
v-bind="attrs"
|
|
:name="field.name"
|
|
:rows="rows"
|
|
:value="text"
|
|
:required="field.required || undefined"
|
|
:aria-required="field.required ? 'true' : undefined"
|
|
:aria-invalid="invalid ? 'true' : undefined"
|
|
:aria-describedby="describedBy || undefined"
|
|
:class="controlClass(invalid)"
|
|
class="min-h-input resize-y py-2.5"
|
|
@input="emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)"
|
|
/>
|
|
</template>
|