@contember/bindx-react 0.1.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.
- package/dist/batching/QueryBatcher.d.ts +31 -0
- package/dist/batching/QueryBatcher.d.ts.map +1 -0
- package/dist/batching/index.d.ts +2 -0
- package/dist/batching/index.d.ts.map +1 -0
- package/dist/components/EntityScope.d.ts +28 -0
- package/dist/components/EntityScope.d.ts.map +1 -0
- package/dist/dataview/DataGrid.d.ts +45 -0
- package/dist/dataview/DataGrid.d.ts.map +1 -0
- package/dist/dataview/DataGridPagination.d.ts +24 -0
- package/dist/dataview/DataGridPagination.d.ts.map +1 -0
- package/dist/dataview/DataGridToolbar.d.ts +16 -0
- package/dist/dataview/DataGridToolbar.d.ts.map +1 -0
- package/dist/dataview/DataViewContext.d.ts +32 -0
- package/dist/dataview/DataViewContext.d.ts.map +1 -0
- package/dist/dataview/columns.d.ts +115 -0
- package/dist/dataview/columns.d.ts.map +1 -0
- package/dist/dataview/contextHooks.d.ts +48 -0
- package/dist/dataview/contextHooks.d.ts.map +1 -0
- package/dist/dataview/dataAttribute.d.ts +6 -0
- package/dist/dataview/dataAttribute.d.ts.map +1 -0
- package/dist/dataview/export.d.ts +46 -0
- package/dist/dataview/export.d.ts.map +1 -0
- package/dist/dataview/filterComponents.d.ts +127 -0
- package/dist/dataview/filterComponents.d.ts.map +1 -0
- package/dist/dataview/filterContext.d.ts +10 -0
- package/dist/dataview/filterContext.d.ts.map +1 -0
- package/dist/dataview/filterHooks.d.ts +74 -0
- package/dist/dataview/filterHooks.d.ts.map +1 -0
- package/dist/dataview/filterScope.d.ts +54 -0
- package/dist/dataview/filterScope.d.ts.map +1 -0
- package/dist/dataview/filterWrappers.d.ts +65 -0
- package/dist/dataview/filterWrappers.d.ts.map +1 -0
- package/dist/dataview/index.d.ts +21 -0
- package/dist/dataview/index.d.ts.map +1 -0
- package/dist/dataview/infiniteLoad.d.ts +32 -0
- package/dist/dataview/infiniteLoad.d.ts.map +1 -0
- package/dist/dataview/loaderComponents.d.ts +80 -0
- package/dist/dataview/loaderComponents.d.ts.map +1 -0
- package/dist/dataview/pagingComponents.d.ts +50 -0
- package/dist/dataview/pagingComponents.d.ts.map +1 -0
- package/dist/dataview/renderCellValue.d.ts +9 -0
- package/dist/dataview/renderCellValue.d.ts.map +1 -0
- package/dist/dataview/selectionComponents.d.ts +62 -0
- package/dist/dataview/selectionComponents.d.ts.map +1 -0
- package/dist/dataview/sortingComponents.d.ts +39 -0
- package/dist/dataview/sortingComponents.d.ts.map +1 -0
- package/dist/dataview/stateStorage.d.ts +19 -0
- package/dist/dataview/stateStorage.d.ts.map +1 -0
- package/dist/dataview/useDataView.d.ts +58 -0
- package/dist/dataview/useDataView.d.ts.map +1 -0
- package/dist/dataview/useDataViewState.d.ts +89 -0
- package/dist/dataview/useDataViewState.d.ts.map +1 -0
- package/dist/hooks/BackendAdapterContext.d.ts +110 -0
- package/dist/hooks/BackendAdapterContext.d.ts.map +1 -0
- package/dist/hooks/ContemberBindxProvider.d.ts +67 -0
- package/dist/hooks/ContemberBindxProvider.d.ts.map +1 -0
- package/dist/hooks/createBindx.d.ts +39 -0
- package/dist/hooks/createBindx.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useBindxEvents.d.ts +83 -0
- package/dist/hooks/useBindxEvents.d.ts.map +1 -0
- package/dist/hooks/useEntity.d.ts +123 -0
- package/dist/hooks/useEntity.d.ts.map +1 -0
- package/dist/hooks/useEntityBeforePersist.d.ts +22 -0
- package/dist/hooks/useEntityBeforePersist.d.ts.map +1 -0
- package/dist/hooks/useEntityCore.d.ts +52 -0
- package/dist/hooks/useEntityCore.d.ts.map +1 -0
- package/dist/hooks/useEntityImpl.d.ts +105 -0
- package/dist/hooks/useEntityImpl.d.ts.map +1 -0
- package/dist/hooks/useEntityList.d.ts +102 -0
- package/dist/hooks/useEntityList.d.ts.map +1 -0
- package/dist/hooks/useEntityListCore.d.ts +49 -0
- package/dist/hooks/useEntityListCore.d.ts.map +1 -0
- package/dist/hooks/useEntityListImpl.d.ts +70 -0
- package/dist/hooks/useEntityListImpl.d.ts.map +1 -0
- package/dist/hooks/useErrors.d.ts +72 -0
- package/dist/hooks/useErrors.d.ts.map +1 -0
- package/dist/hooks/usePersist.d.ts +115 -0
- package/dist/hooks/usePersist.d.ts.map +1 -0
- package/dist/hooks/useSelectionCollection.d.ts +41 -0
- package/dist/hooks/useSelectionCollection.d.ts.map +1 -0
- package/dist/hooks/useSelectionCollectionForList.d.ts +40 -0
- package/dist/hooks/useSelectionCollectionForList.d.ts.map +1 -0
- package/dist/hooks/useStableSelectionMeta.d.ts +11 -0
- package/dist/hooks/useStableSelectionMeta.d.ts.map +1 -0
- package/dist/hooks/useStoreSubscription.d.ts +19 -0
- package/dist/hooks/useStoreSubscription.d.ts.map +1 -0
- package/dist/hooks/useUndo.d.ts +45 -0
- package/dist/hooks/useUndo.d.ts.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/jsx/SelectionMeta.d.ts +2 -0
- package/dist/jsx/SelectionMeta.d.ts.map +1 -0
- package/dist/jsx/analyzer.d.ts +22 -0
- package/dist/jsx/analyzer.d.ts.map +1 -0
- package/dist/jsx/collectorProxy.d.ts +14 -0
- package/dist/jsx/collectorProxy.d.ts.map +1 -0
- package/dist/jsx/componentBuilder.d.ts +51 -0
- package/dist/jsx/componentBuilder.d.ts.map +1 -0
- package/dist/jsx/componentBuilder.types.d.ts +268 -0
- package/dist/jsx/componentBuilder.types.d.ts.map +1 -0
- package/dist/jsx/componentBuilderCompat.d.ts +17 -0
- package/dist/jsx/componentBuilderCompat.d.ts.map +1 -0
- package/dist/jsx/componentFactory.d.ts +39 -0
- package/dist/jsx/componentFactory.d.ts.map +1 -0
- package/dist/jsx/components/Entity.d.ts +82 -0
- package/dist/jsx/components/Entity.d.ts.map +1 -0
- package/dist/jsx/components/EntityList.d.ts +48 -0
- package/dist/jsx/components/EntityList.d.ts.map +1 -0
- package/dist/jsx/components/Field.d.ts +27 -0
- package/dist/jsx/components/Field.d.ts.map +1 -0
- package/dist/jsx/components/HasMany.d.ts +34 -0
- package/dist/jsx/components/HasMany.d.ts.map +1 -0
- package/dist/jsx/components/HasOne.d.ts +25 -0
- package/dist/jsx/components/HasOne.d.ts.map +1 -0
- package/dist/jsx/components/HasRole.d.ts +51 -0
- package/dist/jsx/components/HasRole.d.ts.map +1 -0
- package/dist/jsx/components/If.d.ts +51 -0
- package/dist/jsx/components/If.d.ts.map +1 -0
- package/dist/jsx/components/Show.d.ts +33 -0
- package/dist/jsx/components/Show.d.ts.map +1 -0
- package/dist/jsx/components/index.d.ts +8 -0
- package/dist/jsx/components/index.d.ts.map +1 -0
- package/dist/jsx/conditions.d.ts +310 -0
- package/dist/jsx/conditions.d.ts.map +1 -0
- package/dist/jsx/createComponent.d.ts +44 -0
- package/dist/jsx/createComponent.d.ts.map +1 -0
- package/dist/jsx/index.d.ts +19 -0
- package/dist/jsx/index.d.ts.map +1 -0
- package/dist/jsx/inlineProxy.d.ts +14 -0
- package/dist/jsx/inlineProxy.d.ts.map +1 -0
- package/dist/jsx/legacyTypes.d.ts +26 -0
- package/dist/jsx/legacyTypes.d.ts.map +1 -0
- package/dist/jsx/proxy.d.ts +2 -0
- package/dist/jsx/proxy.d.ts.map +1 -0
- package/dist/jsx/proxyShared.d.ts +14 -0
- package/dist/jsx/proxyShared.d.ts.map +1 -0
- package/dist/jsx/runtimeProxy.d.ts +11 -0
- package/dist/jsx/runtimeProxy.d.ts.map +1 -0
- package/dist/jsx/standaloneCreateComponent.d.ts +30 -0
- package/dist/jsx/standaloneCreateComponent.d.ts.map +1 -0
- package/dist/jsx/types.d.ts +109 -0
- package/dist/jsx/types.d.ts.map +1 -0
- package/dist/jsx/withCollector.d.ts +39 -0
- package/dist/jsx/withCollector.d.ts.map +1 -0
- package/dist/roles/RoleContext.d.ts +31 -0
- package/dist/roles/RoleContext.d.ts.map +1 -0
- package/dist/roles/index.d.ts +2 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/package.json +34 -0
- package/src/batching/QueryBatcher.ts +114 -0
- package/src/batching/index.ts +1 -0
- package/src/components/EntityScope.tsx +43 -0
- package/src/hooks/BackendAdapterContext.tsx +214 -0
- package/src/hooks/ContemberBindxProvider.tsx +158 -0
- package/src/hooks/index.ts +61 -0
- package/src/hooks/useBindxEvents.ts +229 -0
- package/src/hooks/useEntity.ts +489 -0
- package/src/hooks/useEntityBeforePersist.ts +32 -0
- package/src/hooks/useEntityList.ts +444 -0
- package/src/hooks/useErrors.ts +150 -0
- package/src/hooks/usePersist.ts +377 -0
- package/src/hooks/useSelectionCollection.ts +122 -0
- package/src/hooks/useStoreSubscription.ts +51 -0
- package/src/hooks/useUndo.ts +83 -0
- package/src/index.ts +357 -0
- package/src/jsx/SelectionMeta.ts +2 -0
- package/src/jsx/analyzer.ts +261 -0
- package/src/jsx/collectorProxy.ts +282 -0
- package/src/jsx/componentBuilder.ts +180 -0
- package/src/jsx/componentBuilder.types.ts +463 -0
- package/src/jsx/componentBuilderCompat.ts +39 -0
- package/src/jsx/componentFactory.ts +400 -0
- package/src/jsx/components/Entity.tsx +383 -0
- package/src/jsx/components/EntityList.tsx +147 -0
- package/src/jsx/components/Field.tsx +79 -0
- package/src/jsx/components/HasMany.tsx +109 -0
- package/src/jsx/components/HasOne.tsx +78 -0
- package/src/jsx/components/HasRole.tsx +95 -0
- package/src/jsx/components/If.tsx +127 -0
- package/src/jsx/components/Show.tsx +56 -0
- package/src/jsx/components/index.ts +20 -0
- package/src/jsx/conditions.ts +472 -0
- package/src/jsx/createComponent.ts +175 -0
- package/src/jsx/index.ts +135 -0
- package/src/jsx/legacyTypes.ts +30 -0
- package/src/jsx/proxy.ts +1 -0
- package/src/jsx/proxyShared.ts +42 -0
- package/src/jsx/standaloneCreateComponent.ts +47 -0
- package/src/jsx/types.ts +192 -0
- package/src/jsx/withCollector.ts +45 -0
- package/src/roles/RoleContext.tsx +57 -0
- package/src/roles/index.ts +1 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export {
|
|
2
|
+
BindxProvider,
|
|
3
|
+
useBackendAdapter,
|
|
4
|
+
useSnapshotStore,
|
|
5
|
+
useDispatcher,
|
|
6
|
+
useBatchPersister,
|
|
7
|
+
useBindxContext,
|
|
8
|
+
useSchemaRegistry,
|
|
9
|
+
type BindxProviderProps,
|
|
10
|
+
type BindxContextValue,
|
|
11
|
+
} from './BackendAdapterContext.js'
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
usePersist,
|
|
15
|
+
usePersistEntity,
|
|
16
|
+
type PersistApi,
|
|
17
|
+
type EntityPersistApi,
|
|
18
|
+
type AnyRefWithMeta,
|
|
19
|
+
} from './usePersist.js'
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
useEntity,
|
|
23
|
+
type UseEntityOptions,
|
|
24
|
+
type LoadingEntityAccessor,
|
|
25
|
+
type ErrorEntityAccessor,
|
|
26
|
+
type NotFoundEntityAccessor,
|
|
27
|
+
type ReadyEntityAccessor,
|
|
28
|
+
type EntityAccessorResult,
|
|
29
|
+
} from './useEntity.js'
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
useEntityList,
|
|
33
|
+
type UseEntityListOptions,
|
|
34
|
+
type LoadingEntityListAccessor,
|
|
35
|
+
type ErrorEntityListAccessor,
|
|
36
|
+
type ReadyEntityListAccessor,
|
|
37
|
+
type EntityListAccessorResult,
|
|
38
|
+
} from './useEntityList.js'
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
ContemberBindxProvider,
|
|
42
|
+
schemaNamesToDef,
|
|
43
|
+
} from './ContemberBindxProvider.js'
|
|
44
|
+
|
|
45
|
+
export { useUndo, type UndoHookResult } from './useUndo.js'
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
useOnEvent,
|
|
49
|
+
useOnEntityEvent,
|
|
50
|
+
useOnFieldEvent,
|
|
51
|
+
useIntercept,
|
|
52
|
+
useInterceptEntity,
|
|
53
|
+
useInterceptField,
|
|
54
|
+
} from './useBindxEvents.js'
|
|
55
|
+
|
|
56
|
+
export { useEntityBeforePersist } from './useEntityBeforePersist.js'
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
useEntityErrors,
|
|
60
|
+
type EntityErrorsState,
|
|
61
|
+
} from './useErrors.js'
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { useBindxContext } from './BackendAdapterContext.js'
|
|
3
|
+
import type {
|
|
4
|
+
EventTypeMap,
|
|
5
|
+
AfterEventTypes,
|
|
6
|
+
BeforeEventTypes,
|
|
7
|
+
EventListener,
|
|
8
|
+
Interceptor,
|
|
9
|
+
} from '@contember/bindx'
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Event Listener Hooks
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Subscribe to a global bindx event.
|
|
17
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* useOnEvent('field:changed', (event) => {
|
|
22
|
+
* console.log('Any field changed:', event)
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function useOnEvent<T extends AfterEventTypes>(
|
|
27
|
+
eventType: T,
|
|
28
|
+
listener: EventListener<EventTypeMap[T]>,
|
|
29
|
+
): void {
|
|
30
|
+
const { dispatcher } = useBindxContext()
|
|
31
|
+
const emitter = dispatcher.getEventEmitter()
|
|
32
|
+
const listenerRef = useRef(listener)
|
|
33
|
+
|
|
34
|
+
// Always keep the ref up to date
|
|
35
|
+
listenerRef.current = listener
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const handler: EventListener<EventTypeMap[T]> = (event) => {
|
|
39
|
+
listenerRef.current(event)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const unsub = emitter.on(eventType, handler)
|
|
43
|
+
return unsub
|
|
44
|
+
}, [emitter, eventType])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to an entity-scoped bindx event.
|
|
49
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* useOnEntityEvent('entity:persisted', 'Article', articleId, (event) => {
|
|
54
|
+
* toast.success('Article saved!')
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function useOnEntityEvent<T extends AfterEventTypes>(
|
|
59
|
+
eventType: T,
|
|
60
|
+
entityType: string,
|
|
61
|
+
entityId: string,
|
|
62
|
+
listener: EventListener<EventTypeMap[T]>,
|
|
63
|
+
): void {
|
|
64
|
+
const { dispatcher } = useBindxContext()
|
|
65
|
+
const emitter = dispatcher.getEventEmitter()
|
|
66
|
+
const listenerRef = useRef(listener)
|
|
67
|
+
|
|
68
|
+
// Always keep the ref up to date
|
|
69
|
+
listenerRef.current = listener
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const handler: EventListener<EventTypeMap[T]> = (event) => {
|
|
73
|
+
listenerRef.current(event)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const unsub = emitter.onEntity(eventType, entityType, entityId, handler)
|
|
77
|
+
return unsub
|
|
78
|
+
}, [emitter, eventType, entityType, entityId])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe to a field-scoped bindx event.
|
|
83
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* useOnFieldEvent('field:changed', 'Article', articleId, 'title', (event) => {
|
|
88
|
+
* console.log('Title changed:', event.oldValue, '->', event.newValue)
|
|
89
|
+
* })
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function useOnFieldEvent<T extends AfterEventTypes>(
|
|
93
|
+
eventType: T,
|
|
94
|
+
entityType: string,
|
|
95
|
+
entityId: string,
|
|
96
|
+
fieldName: string,
|
|
97
|
+
listener: EventListener<EventTypeMap[T]>,
|
|
98
|
+
): void {
|
|
99
|
+
const { dispatcher } = useBindxContext()
|
|
100
|
+
const emitter = dispatcher.getEventEmitter()
|
|
101
|
+
const listenerRef = useRef(listener)
|
|
102
|
+
|
|
103
|
+
// Always keep the ref up to date
|
|
104
|
+
listenerRef.current = listener
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const handler: EventListener<EventTypeMap[T]> = (event) => {
|
|
108
|
+
listenerRef.current(event)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const unsub = emitter.onField(eventType, entityType, entityId, fieldName, handler)
|
|
112
|
+
return unsub
|
|
113
|
+
}, [emitter, eventType, entityType, entityId, fieldName])
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Interceptor Hooks
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Add a global interceptor for a before event.
|
|
122
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```tsx
|
|
126
|
+
* useIntercept('field:changing', (event) => {
|
|
127
|
+
* if (event.newValue === '') {
|
|
128
|
+
* return { action: 'cancel' }
|
|
129
|
+
* }
|
|
130
|
+
* return { action: 'continue' }
|
|
131
|
+
* })
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export function useIntercept<T extends BeforeEventTypes>(
|
|
135
|
+
eventType: T,
|
|
136
|
+
interceptor: Interceptor<EventTypeMap[T]>,
|
|
137
|
+
): void {
|
|
138
|
+
const { dispatcher } = useBindxContext()
|
|
139
|
+
const emitter = dispatcher.getEventEmitter()
|
|
140
|
+
const interceptorRef = useRef(interceptor)
|
|
141
|
+
|
|
142
|
+
// Always keep the ref up to date
|
|
143
|
+
interceptorRef.current = interceptor
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
const handler: Interceptor<EventTypeMap[T]> = (event) => {
|
|
147
|
+
return interceptorRef.current(event)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const unsub = emitter.intercept(eventType, handler)
|
|
151
|
+
return unsub
|
|
152
|
+
}, [emitter, eventType])
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Add an entity-scoped interceptor.
|
|
157
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```tsx
|
|
161
|
+
* useInterceptEntity('entity:persisting', 'Article', articleId, (event) => {
|
|
162
|
+
* if (!isValid) {
|
|
163
|
+
* return { action: 'cancel' }
|
|
164
|
+
* }
|
|
165
|
+
* return { action: 'continue' }
|
|
166
|
+
* })
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export function useInterceptEntity<T extends BeforeEventTypes>(
|
|
170
|
+
eventType: T,
|
|
171
|
+
entityType: string,
|
|
172
|
+
entityId: string,
|
|
173
|
+
interceptor: Interceptor<EventTypeMap[T]>,
|
|
174
|
+
): void {
|
|
175
|
+
const { dispatcher } = useBindxContext()
|
|
176
|
+
const emitter = dispatcher.getEventEmitter()
|
|
177
|
+
const interceptorRef = useRef(interceptor)
|
|
178
|
+
|
|
179
|
+
// Always keep the ref up to date
|
|
180
|
+
interceptorRef.current = interceptor
|
|
181
|
+
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
const handler: Interceptor<EventTypeMap[T]> = (event) => {
|
|
184
|
+
return interceptorRef.current(event)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const unsub = emitter.interceptEntity(eventType, entityType, entityId, handler)
|
|
188
|
+
return unsub
|
|
189
|
+
}, [emitter, eventType, entityType, entityId])
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Add a field-scoped interceptor.
|
|
194
|
+
* Automatically handles subscription lifecycle and cleanup.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```tsx
|
|
198
|
+
* useInterceptField('field:changing', 'Article', articleId, 'title', (event) => {
|
|
199
|
+
* if (event.newValue === '') {
|
|
200
|
+
* return { action: 'cancel' }
|
|
201
|
+
* }
|
|
202
|
+
* return { action: 'continue' }
|
|
203
|
+
* })
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export function useInterceptField<T extends BeforeEventTypes>(
|
|
207
|
+
eventType: T,
|
|
208
|
+
entityType: string,
|
|
209
|
+
entityId: string,
|
|
210
|
+
fieldName: string,
|
|
211
|
+
interceptor: Interceptor<EventTypeMap[T]>,
|
|
212
|
+
): void {
|
|
213
|
+
const { dispatcher } = useBindxContext()
|
|
214
|
+
const emitter = dispatcher.getEventEmitter()
|
|
215
|
+
const interceptorRef = useRef(interceptor)
|
|
216
|
+
|
|
217
|
+
// Always keep the ref up to date
|
|
218
|
+
interceptorRef.current = interceptor
|
|
219
|
+
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
const handler: Interceptor<EventTypeMap[T]> = (event) => {
|
|
222
|
+
return interceptorRef.current(event)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const unsub = emitter.interceptField(eventType, entityType, entityId, fieldName, handler)
|
|
226
|
+
return unsub
|
|
227
|
+
}, [emitter, eventType, entityType, entityId, fieldName])
|
|
228
|
+
}
|
|
229
|
+
|