@byline/admin 3.12.1 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/fields/field-services-types.d.ts +50 -0
  2. package/dist/forms/form-context.js +30 -60
  3. package/dist/forms/form-modals.d.ts +30 -0
  4. package/dist/forms/form-modals.js +189 -0
  5. package/dist/forms/form-renderer.d.ts +8 -1
  6. package/dist/forms/form-renderer.js +31 -365
  7. package/dist/forms/form-status-display.d.ts +21 -0
  8. package/dist/forms/form-status-display.js +94 -0
  9. package/dist/forms/status-transitions.d.ts +23 -0
  10. package/dist/forms/status-transitions.js +37 -0
  11. package/dist/forms/status-transitions.test.node.d.ts +8 -0
  12. package/dist/forms/tree-placement-widget.d.ts +23 -0
  13. package/dist/forms/tree-placement-widget.js +176 -0
  14. package/dist/forms/tree-placement-widget.module.js +15 -0
  15. package/dist/forms/tree-placement-widget_module.css +69 -0
  16. package/dist/forms/use-form-layout.d.ts +35 -0
  17. package/dist/forms/use-form-layout.js +77 -0
  18. package/dist/forms/use-form-layout.test.node.d.ts +8 -0
  19. package/dist/forms/use-tracked-slot.d.ts +45 -0
  20. package/dist/forms/use-tracked-slot.js +46 -0
  21. package/dist/react.d.ts +1 -1
  22. package/package.json +5 -5
  23. package/src/fields/field-services-types.ts +50 -0
  24. package/src/forms/form-context.tsx +36 -92
  25. package/src/forms/form-modals.tsx +186 -0
  26. package/src/forms/form-renderer.tsx +42 -387
  27. package/src/forms/form-status-display.tsx +108 -0
  28. package/src/forms/status-transitions.test.node.ts +87 -0
  29. package/src/forms/status-transitions.ts +86 -0
  30. package/src/forms/tree-placement-widget.module.css +87 -0
  31. package/src/forms/tree-placement-widget.tsx +202 -0
  32. package/src/forms/use-form-layout.test.node.ts +82 -0
  33. package/src/forms/use-form-layout.ts +134 -0
  34. package/src/forms/use-tracked-slot.ts +101 -0
  35. package/src/react.ts +6 -0
@@ -0,0 +1,101 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * This Source Code is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
+ *
8
+ * Copyright (c) Infonomic Company Limited
9
+ */
10
+
11
+ import { type RefObject, useCallback, useRef } from 'react'
12
+
13
+ /**
14
+ * A dirty-tracked, ref-backed form slot with its own listener set — the shared
15
+ * machinery behind the document-grain system fields (`path`, advertised
16
+ * `availableLocales`, …). Each slot holds the current value, the value it was
17
+ * loaded with, and a set of subscribers; a `set` that moves the value away from
18
+ * its loaded baseline registers the slot's `dirtyKey` in the form's shared
19
+ * dirty set (and clears it again when the value returns to baseline), so the
20
+ * single Save button can branch on which buckets changed.
21
+ *
22
+ * Adding a new system slot is then a one-liner at the call site rather than a
23
+ * copy of ref + initial-ref + listener-set + get/set/subscribe.
24
+ */
25
+ export interface TrackedSlot<T> {
26
+ /** Current value (live ref read — not React state). */
27
+ get: () => T
28
+ /** Write a value; toggles `dirtyKey` against the loaded baseline. */
29
+ set: (value: T) => void
30
+ /** Subscribe to value changes; returns an unsubscribe fn. */
31
+ subscribe: (listener: (value: T) => void) => () => void
32
+ /** Re-baseline: adopt the current value as the new "clean" baseline (called on save). */
33
+ commitInitial: () => void
34
+ }
35
+
36
+ export interface UseTrackedSlotConfig<T> {
37
+ /** Initial / loaded value. */
38
+ initial: T
39
+ /** Key registered in the shared dirty set while this slot diverges from baseline. */
40
+ dirtyKey: string
41
+ /** The form's shared dirty-key set. */
42
+ dirtyFields: RefObject<Set<string>>
43
+ /** Notify the form's meta listeners (drives hasChanges → Save button). */
44
+ notifyMeta: () => void
45
+ /** Equality against the baseline. Defaults to `===` (identity). */
46
+ isEqual?: (a: T, b: T) => boolean
47
+ /** Defensive copy on read-in / write. Defaults to identity (fine for immutables). */
48
+ clone?: (value: T) => T
49
+ }
50
+
51
+ export function useTrackedSlot<T>(config: UseTrackedSlotConfig<T>): TrackedSlot<T> {
52
+ // Snapshot the config on every render into a ref so the returned callbacks
53
+ // can stay referentially stable (empty deps) while still reading the latest
54
+ // isEqual / clone / notifyMeta — matching the stable identities the previous
55
+ // inline implementation relied on.
56
+ const cfgRef = useRef(config)
57
+ cfgRef.current = config
58
+
59
+ const clone = useCallback((value: T): T => {
60
+ const fn = cfgRef.current.clone
61
+ return fn ? fn(value) : value
62
+ }, [])
63
+
64
+ const valueRef = useRef<T>(clone(config.initial))
65
+ const initialRef = useRef<T>(clone(config.initial))
66
+ const listeners = useRef<Set<(value: T) => void>>(new Set())
67
+
68
+ const get = useCallback(() => valueRef.current, [])
69
+
70
+ const set = useCallback(
71
+ (value: T) => {
72
+ const { dirtyKey, dirtyFields, notifyMeta, isEqual } = cfgRef.current
73
+ const next = clone(value)
74
+ valueRef.current = next
75
+ const equal = isEqual ? isEqual(next, initialRef.current) : next === initialRef.current
76
+ if (equal) {
77
+ dirtyFields.current.delete(dirtyKey)
78
+ } else {
79
+ dirtyFields.current.add(dirtyKey)
80
+ }
81
+ listeners.current.forEach((listener) => {
82
+ listener(next)
83
+ })
84
+ notifyMeta()
85
+ },
86
+ [clone]
87
+ )
88
+
89
+ const subscribe = useCallback((listener: (value: T) => void) => {
90
+ listeners.current.add(listener)
91
+ return () => {
92
+ listeners.current.delete(listener)
93
+ }
94
+ }, [])
95
+
96
+ const commitInitial = useCallback(() => {
97
+ initialRef.current = clone(valueRef.current)
98
+ }, [clone])
99
+
100
+ return { get, set, subscribe, commitInitial }
101
+ }
package/src/react.ts CHANGED
@@ -80,6 +80,12 @@ export type {
80
80
  CollectionListParams,
81
81
  CollectionListResponse,
82
82
  GetCollectionDocumentsFn,
83
+ GetTreeAncestorsFn,
84
+ GetTreeParentFn,
85
+ PlaceTreeNodeFn,
86
+ PlaceTreeNodeInput,
87
+ RemoveFromTreeFn,
88
+ TreeAncestor,
83
89
  UploadedFileResult,
84
90
  UploadFieldFn,
85
91
  } from './fields/field-services-types.js'