Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion resources/js/components/ui/Publish/Field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const {
focusField,
blurField,
container,
name: containerName,
direction: contentDirection,
} = injectContainerContext();
const {
Expand Down Expand Up @@ -88,7 +89,8 @@ watch(
{ immediate: true },
);

const fieldId = computed(() => `field_${fullPath.value.replaceAll('.', '_')}`);
// Include the container name so stacked containers (e.g. nested field settings) don't share ids.
const fieldId = computed(() => `field_${containerName.value}_${fullPath.value.replaceAll('.', '_')}`);
const namePrefix = '';
const isRequired = computed(() => props.config.required);
const fieldtype = useTemplateRef('fieldtype');
Expand Down
10 changes: 5 additions & 5 deletions resources/js/tests/browser/GroupLayout.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async function render(fields, width, values = {}, meta = {}) {
document.body.append(host);
wrapper = mount(Container, {
attachTo: host,
props: { blueprint: { tabs: [] }, modelValue: values, meta, site: 'default' },
props: { name: 'test', blueprint: { tabs: [] }, modelValue: values, meta, site: 'default' },
global: {
components: {
...components,
Expand All @@ -70,7 +70,7 @@ async function render(fields, width, values = {}, meta = {}) {
}

function rectangle(id) {
return document.getElementById(`field_${id}`).getBoundingClientRect();
return document.getElementById(`field_test_${id}`).getBoundingClientRect();
}

function assertStacked(first, second) {
Expand All @@ -83,7 +83,7 @@ function assertStacked(first, second) {

test.each([600, 900, 1200])('a 25% group stays inside a %ipx publish panel', async width => {
await render([text('heading', 75), group('options', [text('tag'), text('design')], { width: 25 })], width);
const groupElement = document.getElementById('field_options_tag').closest('.group-fieldtype').getBoundingClientRect();
const groupElement = document.getElementById('field_test_options_tag').closest('.group-fieldtype').getBoundingClientRect();
for (const name of ['options_tag', 'options_design']) {
const input = rectangle(name);
expect(input.right).toBeLessThanOrEqual(groupElement.right + 1);
Expand All @@ -109,7 +109,7 @@ test.each([false, true])('a wide group preserves 50/50 columns with border=%s',
test('nested groups do not inherit a parent column span', async () => {
await render([group('outer', [text('heading', 75), group('inner', [text('first', 50), text('second', 50)], { width: 25 })])], 1000);
assertStacked('outer_inner_first', 'outer_inner_second');
const input = document.getElementById('field_outer_inner_first');
const input = document.getElementById('field_test_outer_inner_first');
const bounds = input.closest('.group-fieldtype').getBoundingClientRect();
expect(Math.abs(input.getBoundingClientRect().width - bounds.width)).toBeLessThan(1);
});
Expand Down Expand Up @@ -145,7 +145,7 @@ test.each([511, 512])('a group uses its own %ipx breakpoint width', async width

test('editing a nested field updates its form value', async () => {
await render([group('options', [text('first'), text('second')], { width: 25 })], 1000, { options: { first: 'Original', second: 'Retained' } });
await wrapper.find('#field_options_first').setValue('Updated');
await wrapper.find('#field_test_options_first').setValue('Updated');
expect(wrapper.vm.values).toEqual({ options: { first: 'Updated', second: 'Retained' } });
});

Expand Down
11 changes: 10 additions & 1 deletion resources/js/tests/components/Fields.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ const Probe = defineComponent({
},
});

async function mountFields(values, provide = {}) {
async function mountFields(values, provide = {}, props = {}) {
const wrapper = mount(Container, {
props: {
blueprint: { tabs: [] },
modelValue: values,
site: 'default',
...props,
},
global: {
components: { 'hidden-fieldtype': HiddenFieldtype },
Expand Down Expand Up @@ -83,3 +84,11 @@ test('a hidden fieldtype does not get a replicator preview', async () => {

expect(previews.value).toEqual({});
});

test('field ids are unique across publish containers', async () => {
const outer = await mountFields({ protected: true, scheme: 'password' }, {}, { name: 'outer' });
const inner = await mountFields({ protected: true, scheme: 'password' }, {}, { name: 'inner' });

expect(outer.find('#field_outer_scheme').exists()).toBe(true);
expect(inner.find('#field_inner_scheme').exists()).toBe(true);
});
Loading