@@ -6,13 +6,13 @@ export const [injectContainerContext, provideContainerContext, containerContextK
66
77<script setup>
88import { nanoid as uniqid } from ' nanoid' ;
9- import { watch , ref , computed , toRef , nextTick } from ' vue' ;
9+ import { onMounted , onUnmounted , watch , ref , computed , toRef , nextTick } from ' vue' ;
1010import Component from ' @/components/Component.js' ;
1111import Tabs from ' ./Tabs.vue' ;
1212import Values from ' @/components/publish/Values.js' ;
1313import { data_get } from ' @/bootstrap/globals.js' ;
1414
15- const emit = defineEmits ([' update:modelValue' , ' update:visibleValues' , ' update:modifiedFields' ]);
15+ const emit = defineEmits ([' update:modelValue' , ' update:visibleValues' , ' update:modifiedFields' , ' update:meta ' ]);
1616
1717const props = defineProps ({
1818 name: {
@@ -179,6 +179,12 @@ watch(
179179 { deep: true },
180180);
181181
182+ watch (
183+ meta,
184+ (meta ) => emit (' update:meta' , meta),
185+ { deep: true },
186+ );
187+
182188const avoidTrackingDirtyState = ref (false );
183189const trackingDirtyState = computed (() => props .trackDirtyState && ! avoidTrackingDirtyState .value )
184190const isDirty = computed (() => Statamic .$dirty .has (props .name ));
@@ -210,6 +216,10 @@ function setFieldValue(path, value) {
210216 data_set (values .value , path, value);
211217}
212218
219+ function setMeta (newMeta ) {
220+ meta .value = newMeta;
221+ }
222+
213223function setFieldMeta (path , value ) {
214224 data_set (meta .value , path, value);
215225}
@@ -236,6 +246,30 @@ function removeLocalizedField(path) {
236246 if (index !== - 1 ) localizedFields .value .splice (index, 1 );
237247}
238248
249+ const fieldFocus = ref ({});
250+
251+ const fieldLocks = computed (() => {
252+ const locks = {};
253+ for (const { handle , user } of Object .values (fieldFocus .value )) {
254+ if (! locks[handle]) {
255+ locks[handle] = user;
256+ }
257+ }
258+ return locks;
259+ });
260+
261+ function focusField (handle , user = Statamic .user ) {
262+ if (handle .includes (' .' )) throw new Error (' focusField only supports top-level fields.' );
263+ fieldFocus .value [user .id ] = { handle, user };
264+ }
265+
266+ function blurField (handle , user = Statamic .user ) {
267+ if (handle .includes (' .' )) throw new Error (' blurField only supports top-level fields.' );
268+ if (fieldFocus .value [user .id ]? .handle === handle) {
269+ delete fieldFocus .value [user .id ];
270+ }
271+ }
272+
239273function pushComponent (name , { props }) {
240274 const component = new Component (uniqid (), name, props);
241275 components .value .push (component);
@@ -273,11 +307,16 @@ const builtInProvides = {
273307 isTrackingOriginValues: computed (() => !! props .originValues ),
274308 setValues,
275309 setFieldValue,
310+ setMeta,
276311 setFieldMeta,
277312 setFieldPreviewValue,
278313 setRevealerField,
279314 unsetRevealerField,
280315 setHiddenField,
316+ fieldFocus,
317+ fieldLocks,
318+ focusField,
319+ blurField,
281320 isDirty,
282321 withoutDirtying,
283322};
@@ -294,6 +333,28 @@ const provided = { ...additionalProvides, ...builtInProvides };
294333
295334provideContainerContext({ ...provided, container: provided });
296335
336+ onMounted(() => {
337+ Statamic.$events.$emit('publish-container-created', {
338+ name: props.name,
339+ reference: props.reference,
340+ site: props.site,
341+ values,
342+ setFieldValue,
343+ setValues,
344+ meta,
345+ setMeta,
346+ setFieldMeta,
347+ pushComponent,
348+ fieldFocus,
349+ focusField,
350+ blurField,
351+ });
352+ });
353+
354+ onUnmounted(() => {
355+ Statamic.$events.$emit('publish-container-destroyed', { name: props.name });
356+ });
357+
297358defineExpose({
298359 name: props.name,
299360 values,
@@ -306,6 +367,7 @@ defineExpose({
306367 pushComponent,
307368 visibleValues,
308369 setValues,
370+ setMeta,
309371 setExtraValues,
310372});
311373
0 commit comments