fix(@vben-core/form-ui): preserve array field focus
This commit is contained in:
@@ -485,6 +485,37 @@ describe('useVbenForm integration', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves array row inputs and focus while editing', async () => {
|
||||
const [Form] = useVbenForm({
|
||||
schema: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
component: TestInput,
|
||||
fieldName: 'name',
|
||||
label: 'Name',
|
||||
},
|
||||
],
|
||||
defaultValue: [{ name: 'Ada' }],
|
||||
fieldName: 'contacts',
|
||||
type: 'array',
|
||||
},
|
||||
],
|
||||
});
|
||||
const wrapper = mount(Form, { attachTo: document.body });
|
||||
wrappers.push(wrapper);
|
||||
await flushPromises();
|
||||
const input = wrapper.get('input');
|
||||
const inputElement = input.element;
|
||||
inputElement.focus();
|
||||
|
||||
await input.setValue('Ada Lovelace');
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.get('input').element).toBe(inputElement);
|
||||
expect(document.activeElement).toBe(inputElement);
|
||||
});
|
||||
|
||||
it('scopes resolve dependencies to array rows', async () => {
|
||||
const resolve = vi.fn(({ schema }: Record<string, any>) => ({
|
||||
componentProps: {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
VbenIconButton,
|
||||
VbenRenderContent,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { cn, isObject, set } from '@vben-core/shared/utils';
|
||||
import { cn, set } from '@vben-core/shared/utils';
|
||||
|
||||
import { injectRenderFormProps } from '../form-render/context';
|
||||
import FormField from '../form-render/form-field.vue';
|
||||
@@ -72,8 +72,6 @@ if (!form) {
|
||||
}
|
||||
const formActions = form;
|
||||
const arrayValue = formActions.useFieldValue(props.name);
|
||||
const rowKeys = new WeakMap<object, string>();
|
||||
let nextRowKey = 0;
|
||||
|
||||
const fields = computed<Record<string, any>[]>(() => {
|
||||
return Array.isArray(arrayValue.value) ? arrayValue.value : [];
|
||||
@@ -124,20 +122,6 @@ function removeRow(index: number) {
|
||||
void formActions.removeFieldValue(arrayPath.value, index);
|
||||
}
|
||||
|
||||
function getRowKey(row: Record<string, any>, index: number) {
|
||||
if (!isObject(row)) {
|
||||
return `${arrayPath.value}-${index}`;
|
||||
}
|
||||
const existingKey = rowKeys.get(row);
|
||||
if (existingKey) {
|
||||
return existingKey;
|
||||
}
|
||||
nextRowKey += 1;
|
||||
const key = `${arrayPath.value}-${nextRowKey}`;
|
||||
rowKeys.set(row, key);
|
||||
return key;
|
||||
}
|
||||
|
||||
function rowSchemas(index: number) {
|
||||
return props.schema.map((col) =>
|
||||
createArrayChildSchema(col as never, {
|
||||
@@ -179,8 +163,8 @@ function rowSchemas(index: number) {
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(entry, index) in fields"
|
||||
:key="getRowKey(entry, index)"
|
||||
v-for="(_, index) in fields"
|
||||
:key="`${arrayPath}-${index}`"
|
||||
class="border-border/60 border-b p-3 last:border-b-0 sm:grid sm:p-0"
|
||||
:style="gridStyle"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user