@contember/bindx-repeater 0.1.14 → 0.1.15

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.
@@ -1 +1 @@
1
- {"version":3,"file":"BlockRepeater.d.ts","sourceRoot":"","sources":["../../src/components/BlockRepeater.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAW,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAA;AACzE,OAAO,KAAK,EAGX,QAAQ,EAIR,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAyC,eAAe,EAAa,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAClI,OAAO,KAAK,EACX,kBAAkB,EAMlB,MAAM,aAAa,CAAA;AAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAC5B,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,SAAS,GAAG,OAAO,EACnB,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/D,WAAW,SAAS,MAAM,GAAG,MAAM,EAClC,EACD,KAAK,EACL,mBAAmB,EACnB,UAAU,EACV,MAAM,EACN,QAAQ,GACR,EAAE,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,YAAY,CA+HlG;AAGD,QAAA,MAAM,0BAA0B,EAAoB,OAAO,aAAa,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AAsF1H,OAAO,EAAE,0BAA0B,IAAI,qBAAqB,EAAE,CAAA"}
1
+ {"version":3,"file":"BlockRepeater.d.ts","sourceRoot":"","sources":["../../src/components/BlockRepeater.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAW,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAA;AACzE,OAAO,KAAK,EAGX,QAAQ,EAIR,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAyC,eAAe,EAAa,KAAK,iBAAiB,EAAwB,MAAM,wBAAwB,CAAA;AACxJ,OAAO,KAAK,EACX,kBAAkB,EAMlB,MAAM,aAAa,CAAA;AAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAC5B,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,SAAS,GAAG,OAAO,EACnB,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/D,WAAW,SAAS,MAAM,GAAG,MAAM,EAClC,EACD,KAAK,EACL,mBAAmB,EACnB,UAAU,EACV,MAAM,EACN,QAAQ,GACR,EAAE,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,YAAY,CAgIlG;AAGD,QAAA,MAAM,0BAA0B,EAAoB,OAAO,aAAa,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AAkG1H,OAAO,EAAE,0BAA0B,IAAI,qBAAqB,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Repeater.d.ts","sourceRoot":"","sources":["../../src/components/Repeater.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAW,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAA;AACzE,OAAO,KAAK,EAGX,QAAQ,EAGR,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAyC,eAAe,EAAa,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAClI,OAAO,KAAK,EACX,aAAa,EAMb,MAAM,aAAa,CAAA;AAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CACvB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,SAAS,GAAG,OAAO,EACnB,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9D,EACD,KAAK,EACL,UAAU,EACV,QAAQ,GACR,EAAE,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,YAAY,CAuHhF;AAGD,QAAA,MAAM,qBAAqB,EAAe,OAAO,QAAQ,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AA+E3G,OAAO,EAAE,qBAAqB,IAAI,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"Repeater.d.ts","sourceRoot":"","sources":["../../src/components/Repeater.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAW,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAA;AACzE,OAAO,KAAK,EAGX,QAAQ,EAGR,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAyC,eAAe,EAAa,KAAK,iBAAiB,EAAc,MAAM,wBAAwB,CAAA;AAC9I,OAAO,KAAK,EACX,aAAa,EAMb,MAAM,aAAa,CAAA;AAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CACvB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,SAAS,GAAG,OAAO,EACnB,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9D,EACD,KAAK,EACL,UAAU,EACV,QAAQ,GACR,EAAE,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,YAAY,CAwHhF;AAGD,QAAA,MAAM,qBAAqB,EAAe,OAAO,QAAQ,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AA+E3G,OAAO,EAAE,qBAAqB,IAAI,gBAAgB,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { EntityAccessor, HasManyRef, AnyBrand } from '@contember/bindx';
1
+ import type { EntityAccessor, HasManyAccessor, AnyBrand } from '@contember/bindx';
2
2
  /**
3
3
  * Hook that returns sorted items from a has-many ref and repairs order field values.
4
4
  *
@@ -6,5 +6,5 @@ import type { EntityAccessor, HasManyRef, AnyBrand } from '@contember/bindx';
6
6
  * @param orderField - Optional field name for sorting
7
7
  * @returns Sorted array of entity accessors
8
8
  */
9
- export declare function useSortedItems<T extends object, S = T, TBrand extends AnyBrand = AnyBrand, TEntityName extends string = string, TSchema extends Record<string, object> = Record<string, object>>(hasMany: HasManyRef<T, S, TBrand, TEntityName, TSchema>, orderField: string | undefined): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[];
9
+ export declare function useSortedItems<T extends object, S = T, TBrand extends AnyBrand = AnyBrand, TEntityName extends string = string, TSchema extends Record<string, object> = Record<string, object>>(hasMany: HasManyAccessor<T, S, TBrand, TEntityName, TSchema>, orderField: string | undefined): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[];
10
10
  //# sourceMappingURL=useSortedItems.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSortedItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useSortedItems.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAI5E;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,OAAO,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EACvD,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAgBtD"}
1
+ {"version":3,"file":"useSortedItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useSortedItems.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAIjF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAC5D,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAiBtD"}
package/dist/types.d.ts CHANGED
@@ -80,10 +80,15 @@ export interface RepeaterProps<TEntity, TSelected = TEntity, TBrand extends AnyB
80
80
  children: RepeaterRenderFn<TEntity, TSelected, TBrand, TEntityName, TSchema>;
81
81
  }
82
82
  /**
83
- * Minimal block definition for headless use.
83
+ * Block definition for headless use.
84
+ * Optional render/form functions declare block-specific field selections.
84
85
  */
85
- export interface BlockDefinition {
86
+ export interface BlockDefinition<TEntity extends object = object, TSelected = TEntity> {
86
87
  label?: ReactNode;
88
+ /** Render function for block preview. Used for selection collection. */
89
+ render?: (entity: EntityAccessor<TEntity, TSelected>) => ReactNode;
90
+ /** Form function for block editing. Used for selection collection. */
91
+ form?: (entity: EntityAccessor<TEntity, TSelected>) => ReactNode;
87
92
  }
88
93
  /**
89
94
  * Extended item info with block type discrimination.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,7 @@
1
- import type { EntityAccessor } from '@contember/bindx';
1
+ import type { EntityAccessor, AnyBrand } from '@contember/bindx';
2
2
  /**
3
3
  * Repairs the order field values of entities to be sequential (0, 1, 2, ...).
4
4
  * Only updates values that differ from their expected index.
5
- *
6
- * @param items - Array of entity accessors (already sorted)
7
- * @param orderField - Name of the numeric field to update
8
5
  */
9
- export declare function repairEntitiesOrder<T extends object, S = T>(items: EntityAccessor<T, S>[], orderField: string): void;
6
+ export declare function repairEntitiesOrder<T extends object, S = T, TBrand extends AnyBrand = AnyBrand, TEntityName extends string = string, TSchema extends Record<string, object> = Record<string, object>>(items: EntityAccessor<T, S, TBrand, TEntityName, TSchema>[], orderField: string): void;
10
7
  //# sourceMappingURL=repairEntitiesOrder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repairEntitiesOrder.d.ts","sourceRoot":"","sources":["../../src/utils/repairEntitiesOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,kBAAkB,CAAA;AAEhE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,CAAC,EAC1D,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAC7B,UAAU,EAAE,MAAM,GAChB,IAAI,CASN"}
1
+ {"version":3,"file":"repairEntitiesOrder.d.ts","sourceRoot":"","sources":["../../src/utils/repairEntitiesOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE/E;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,EAC3D,UAAU,EAAE,MAAM,GAChB,IAAI,CASN"}
@@ -1,11 +1,7 @@
1
- import type { EntityAccessor } from '@contember/bindx';
1
+ import type { EntityAccessor, AnyBrand } from '@contember/bindx';
2
2
  /**
3
3
  * Sorts entities by a numeric order field.
4
4
  * Returns a new sorted array.
5
- *
6
- * @param items - Array of entity accessors
7
- * @param orderField - Name of the numeric field to sort by
8
- * @returns New sorted array of entities
9
5
  */
10
- export declare function sortEntities<T extends object, S = T>(items: EntityAccessor<T, S>[], orderField: string | undefined): EntityAccessor<T, S>[];
6
+ export declare function sortEntities<T extends object, S = T, TBrand extends AnyBrand = AnyBrand, TEntityName extends string = string, TSchema extends Record<string, object> = Record<string, object>>(items: EntityAccessor<T, S, TBrand, TEntityName, TSchema>[], orderField: string | undefined): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[];
11
7
  //# sourceMappingURL=sortEntities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sortEntities.d.ts","sourceRoot":"","sources":["../../src/utils/sortEntities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,kBAAkB,CAAA;AAEhE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,CAAC,EACnD,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAcxB"}
1
+ {"version":3,"file":"sortEntities.d.ts","sourceRoot":"","sources":["../../src/utils/sortEntities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE/E;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,EAC3D,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAiBtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/bindx-repeater",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Repeater components for has-many list management",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -15,8 +15,8 @@
15
15
  "react": ">=18.0.0"
16
16
  },
17
17
  "dependencies": {
18
- "@contember/bindx": "0.1.14",
19
- "@contember/bindx-react": "0.1.14"
18
+ "@contember/bindx": "0.1.15",
19
+ "@contember/bindx-react": "0.1.15"
20
20
  },
21
21
  "files": [
22
22
  "dist",
@@ -8,7 +8,7 @@ import type {
8
8
  FieldRef,
9
9
  } from '@contember/bindx'
10
10
  import { SelectionScope, FIELD_REF_META } from '@contember/bindx'
11
- import { createCollectorProxy, mergeSelections, BINDX_COMPONENT, SCOPE_REF, type SelectionProvider } from '@contember/bindx-react'
11
+ import { createCollectorProxy, mergeSelections, BINDX_COMPONENT, SCOPE_REF, type SelectionProvider, useHasMany, useField } from '@contember/bindx-react'
12
12
  import type {
13
13
  BlockRepeaterProps,
14
14
  BlockRepeaterItems,
@@ -72,7 +72,8 @@ export function BlockRepeater<
72
72
  blocks,
73
73
  children,
74
74
  }: BlockRepeaterProps<TEntity, TSelected, TBrand, TEntityName, TSchema, TBlockNames>): ReactElement {
75
- const sortedItems = useSortedItems(field, sortableBy)
75
+ const fieldAccessor = useHasMany(field)
76
+ const sortedItems = useSortedItems(fieldAccessor, sortableBy)
76
77
 
77
78
  const items = useMemo((): BlockRepeaterItems<TEntity, TSelected, TBrand, TEntityName, TSchema> => {
78
79
  const createItemInfo = (
@@ -82,7 +83,7 @@ export function BlockRepeater<
82
83
  const isFirst = index === 0
83
84
  const isLast = index === sortedItems.length - 1
84
85
 
85
- const discriminationRef = (entity.$fields as Record<string, unknown>)[discriminationField] as FieldRef<string> | undefined
86
+ const discriminationRef = (entity.$fields as Record<string, unknown>)[discriminationField] as import('@contember/bindx').FieldAccessor<string> | undefined
86
87
  const blockType = discriminationRef?.value ?? null
87
88
  const blockDef = blockType !== null ? (blocks as Record<string, BlockDefinition>)[blockType] : undefined
88
89
  const block = blockDef !== undefined && blockType !== null
@@ -91,7 +92,7 @@ export function BlockRepeater<
91
92
 
92
93
  const remove = (): void => {
93
94
  if (sortableBy) {
94
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
95
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
95
96
  const currentIndex = items.findIndex(item => item.id === entity.id)
96
97
  if (currentIndex !== -1) {
97
98
  items.splice(currentIndex, 1)
@@ -103,7 +104,7 @@ export function BlockRepeater<
103
104
 
104
105
  const moveUp = (): void => {
105
106
  if (!sortableBy || isFirst) return
106
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
107
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
107
108
  const currentIndex = items.findIndex(item => item.id === entity.id)
108
109
  if (currentIndex === -1 || currentIndex === 0) return
109
110
  const newItems = arrayMove(items, currentIndex, currentIndex - 1)
@@ -112,7 +113,7 @@ export function BlockRepeater<
112
113
 
113
114
  const moveDown = (): void => {
114
115
  if (!sortableBy || isLast) return
115
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
116
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
116
117
  const currentIndex = items.findIndex(item => item.id === entity.id)
117
118
  if (currentIndex === -1 || currentIndex === items.length - 1) return
118
119
  const newItems = arrayMove(items, currentIndex, currentIndex + 1)
@@ -151,10 +152,10 @@ export function BlockRepeater<
151
152
  if (!sortableBy) {
152
153
  if (index === 'last' || index === undefined) {
153
154
  const entityId = field.add()
154
- const items = field.items
155
+ const items = fieldAccessor.items
155
156
  const newEntity = items.find(item => item.id === entityId)
156
157
  if (newEntity) {
157
- const discriminationRef = (newEntity.$fields as Record<string, unknown>)[discriminationField] as FieldRef<string> | undefined
158
+ const discriminationRef = (newEntity.$fields as Record<string, unknown>)[discriminationField] as import('@contember/bindx').FieldAccessor<string> | undefined
158
159
  discriminationRef?.setValue(type)
159
160
  }
160
161
  return
@@ -162,7 +163,7 @@ export function BlockRepeater<
162
163
  throw new Error('Cannot add item at specific index without sortableBy field')
163
164
  }
164
165
 
165
- const currentItems = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
166
+ const currentItems = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
166
167
 
167
168
  const resolvedIndex = (() => {
168
169
  switch (index) {
@@ -177,7 +178,7 @@ export function BlockRepeater<
177
178
  })()
178
179
 
179
180
  const entityId = field.add()
180
- const items = field.items
181
+ const items = fieldAccessor.items
181
182
  const newEntity = items.find(item => item.id === entityId)
182
183
 
183
184
  if (newEntity) {
@@ -185,14 +186,14 @@ export function BlockRepeater<
185
186
  newSortedItems.splice(resolvedIndex, 0, newEntity as EntityAccessor<TEntity, TSelected>)
186
187
  repairEntitiesOrder(newSortedItems, sortableBy)
187
188
 
188
- const discriminationRef = (newEntity.$fields as Record<string, unknown>)[discriminationField] as FieldRef<string> | undefined
189
+ const discriminationRef = (newEntity.$fields as Record<string, unknown>)[discriminationField] as import('@contember/bindx').FieldAccessor<string> | undefined
189
190
  discriminationRef?.setValue(type)
190
191
  }
191
192
  }
192
193
 
193
194
  return {
194
195
  addItem,
195
- isEmpty: field.length === 0,
196
+ isEmpty: fieldAccessor.length === 0,
196
197
  blockList,
197
198
  }
198
199
  }, [field, sortableBy, blocks, discriminationField])
@@ -243,6 +244,18 @@ blockRepeaterWithSelection.getSelection = (
243
244
  const syntheticChildren = props.children(mockItems, mockMethods)
244
245
  const jsxSelection = collectNested(syntheticChildren)
245
246
 
247
+ // Collect field selections from block render/form functions
248
+ for (const blockDef of Object.values(props.blocks) as BlockDefinition[]) {
249
+ if (blockDef.render) {
250
+ const renderJsx = blockDef.render(collectorEntity as EntityAccessor<object>)
251
+ if (renderJsx) mergeSelections(scope.toSelectionMeta(), collectNested(renderJsx))
252
+ }
253
+ if (blockDef.form) {
254
+ const formJsx = blockDef.form(collectorEntity as EntityAccessor<object>)
255
+ if (formJsx) mergeSelections(scope.toSelectionMeta(), collectNested(formJsx))
256
+ }
257
+ }
258
+
246
259
  const nestedSelection = scope.toSelectionMeta()
247
260
  mergeSelections(nestedSelection, jsxSelection)
248
261
 
@@ -7,7 +7,7 @@ import type {
7
7
  SelectionMeta,
8
8
  } from '@contember/bindx'
9
9
  import { SelectionScope, FIELD_REF_META } from '@contember/bindx'
10
- import { createCollectorProxy, mergeSelections, BINDX_COMPONENT, SCOPE_REF, type SelectionProvider } from '@contember/bindx-react'
10
+ import { createCollectorProxy, mergeSelections, BINDX_COMPONENT, SCOPE_REF, type SelectionProvider, useHasMany } from '@contember/bindx-react'
11
11
  import type {
12
12
  RepeaterProps,
13
13
  RepeaterItems,
@@ -60,7 +60,8 @@ export function Repeater<
60
60
  sortableBy,
61
61
  children,
62
62
  }: RepeaterProps<TEntity, TSelected, TBrand, TEntityName, TSchema>): ReactElement {
63
- const sortedItems = useSortedItems(field, sortableBy)
63
+ const fieldAccessor = useHasMany(field)
64
+ const sortedItems = useSortedItems(fieldAccessor, sortableBy)
64
65
 
65
66
  // Create stable items collection object
66
67
  const items = useMemo((): RepeaterItems<TEntity, TSelected, TBrand, TEntityName, TSchema> => {
@@ -73,7 +74,7 @@ export function Repeater<
73
74
 
74
75
  const remove = (): void => {
75
76
  if (sortableBy) {
76
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
77
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
77
78
  const currentIndex = items.findIndex(item => item.id === entity.id)
78
79
  if (currentIndex !== -1) {
79
80
  items.splice(currentIndex, 1)
@@ -85,7 +86,7 @@ export function Repeater<
85
86
 
86
87
  const moveUp = (): void => {
87
88
  if (!sortableBy || isFirst) return
88
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
89
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
89
90
  const currentIndex = items.findIndex(item => item.id === entity.id)
90
91
  if (currentIndex === -1 || currentIndex === 0) return
91
92
  const newItems = arrayMove(items, currentIndex, currentIndex - 1)
@@ -94,7 +95,7 @@ export function Repeater<
94
95
 
95
96
  const moveDown = (): void => {
96
97
  if (!sortableBy || isLast) return
97
- const items = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
98
+ const items = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
98
99
  const currentIndex = items.findIndex(item => item.id === entity.id)
99
100
  if (currentIndex === -1 || currentIndex === items.length - 1) return
100
101
  const newItems = arrayMove(items, currentIndex, currentIndex + 1)
@@ -130,7 +131,7 @@ export function Repeater<
130
131
  if (index === 'last' || index === undefined) {
131
132
  const entityId = field.add()
132
133
  if (preprocess) {
133
- const items = field.items
134
+ const items = fieldAccessor.items
134
135
  const newEntity = items.find(item => item.id === entityId)
135
136
  if (newEntity) {
136
137
  preprocess(newEntity as unknown as EntityAccessor<TEntity>)
@@ -141,7 +142,7 @@ export function Repeater<
141
142
  throw new Error('Cannot add item at specific index without sortableBy field')
142
143
  }
143
144
 
144
- const sortedItems = sortEntities(field.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
145
+ const sortedItems = sortEntities(fieldAccessor.items, sortableBy) as EntityAccessor<TEntity, TSelected>[]
145
146
 
146
147
  const resolvedIndex = (() => {
147
148
  switch (index) {
@@ -156,7 +157,7 @@ export function Repeater<
156
157
  })()
157
158
 
158
159
  const entityId = field.add()
159
- const items = field.items
160
+ const items = fieldAccessor.items
160
161
  const newEntity = items.find(item => item.id === entityId)
161
162
 
162
163
  if (newEntity) {
@@ -172,7 +173,7 @@ export function Repeater<
172
173
 
173
174
  return {
174
175
  addItem,
175
- isEmpty: field.length === 0,
176
+ isEmpty: fieldAccessor.length === 0,
176
177
  }
177
178
  }, [field, sortableBy])
178
179
 
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo } from 'react'
2
- import type { EntityAccessor, HasManyRef, AnyBrand } from '@contember/bindx'
2
+ import type { EntityAccessor, HasManyAccessor, AnyBrand } from '@contember/bindx'
3
3
  import { sortEntities } from '../utils/sortEntities.js'
4
4
  import { repairEntitiesOrder } from '../utils/repairEntitiesOrder.js'
5
5
 
@@ -17,10 +17,11 @@ export function useSortedItems<
17
17
  TEntityName extends string = string,
18
18
  TSchema extends Record<string, object> = Record<string, object>,
19
19
  >(
20
- hasMany: HasManyRef<T, S, TBrand, TEntityName, TSchema>,
20
+ hasMany: HasManyAccessor<T, S, TBrand, TEntityName, TSchema>,
21
21
  orderField: string | undefined,
22
22
  ): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[] {
23
- const items = hasMany.items
23
+ const rawItems = hasMany?.items
24
+ const items = Array.isArray(rawItems) ? rawItems : []
24
25
 
25
26
  const sortedItems = useMemo(
26
27
  () => sortEntities(items, orderField) as EntityAccessor<T, S, TBrand, TEntityName, TSchema>[],
package/src/types.ts CHANGED
@@ -128,10 +128,15 @@ export interface RepeaterProps<
128
128
  // ============================================================================
129
129
 
130
130
  /**
131
- * Minimal block definition for headless use.
131
+ * Block definition for headless use.
132
+ * Optional render/form functions declare block-specific field selections.
132
133
  */
133
- export interface BlockDefinition {
134
+ export interface BlockDefinition<TEntity extends object = object, TSelected = TEntity> {
134
135
  label?: ReactNode
136
+ /** Render function for block preview. Used for selection collection. */
137
+ render?: (entity: EntityAccessor<TEntity, TSelected>) => ReactNode
138
+ /** Form function for block editing. Used for selection collection. */
139
+ form?: (entity: EntityAccessor<TEntity, TSelected>) => ReactNode
135
140
  }
136
141
 
137
142
  /**
@@ -1,19 +1,22 @@
1
- import type { EntityAccessor, FieldRef } from '@contember/bindx'
1
+ import type { EntityAccessor, FieldAccessor, AnyBrand } from '@contember/bindx'
2
2
 
3
3
  /**
4
4
  * Repairs the order field values of entities to be sequential (0, 1, 2, ...).
5
5
  * Only updates values that differ from their expected index.
6
- *
7
- * @param items - Array of entity accessors (already sorted)
8
- * @param orderField - Name of the numeric field to update
9
6
  */
10
- export function repairEntitiesOrder<T extends object, S = T>(
11
- items: EntityAccessor<T, S>[],
7
+ export function repairEntitiesOrder<
8
+ T extends object,
9
+ S = T,
10
+ TBrand extends AnyBrand = AnyBrand,
11
+ TEntityName extends string = string,
12
+ TSchema extends Record<string, object> = Record<string, object>,
13
+ >(
14
+ items: EntityAccessor<T, S, TBrand, TEntityName, TSchema>[],
12
15
  orderField: string,
13
16
  ): void {
14
17
  for (let i = 0; i < items.length; i++) {
15
18
  const entity = items[i]!
16
- const field = (entity as Record<string, unknown>)[orderField] as FieldRef<number> | undefined
19
+ const field = (entity as unknown as Record<string, unknown>)[orderField] as FieldAccessor<number> | undefined
17
20
 
18
21
  if (field && field.value !== i) {
19
22
  field.setValue(i)
@@ -1,24 +1,29 @@
1
- import type { EntityAccessor, FieldRef } from '@contember/bindx'
1
+ import type { EntityAccessor, FieldAccessor, AnyBrand } from '@contember/bindx'
2
2
 
3
3
  /**
4
4
  * Sorts entities by a numeric order field.
5
5
  * Returns a new sorted array.
6
- *
7
- * @param items - Array of entity accessors
8
- * @param orderField - Name of the numeric field to sort by
9
- * @returns New sorted array of entities
10
6
  */
11
- export function sortEntities<T extends object, S = T>(
12
- items: EntityAccessor<T, S>[],
7
+ export function sortEntities<
8
+ T extends object,
9
+ S = T,
10
+ TBrand extends AnyBrand = AnyBrand,
11
+ TEntityName extends string = string,
12
+ TSchema extends Record<string, object> = Record<string, object>,
13
+ >(
14
+ items: EntityAccessor<T, S, TBrand, TEntityName, TSchema>[],
13
15
  orderField: string | undefined,
14
- ): EntityAccessor<T, S>[] {
16
+ ): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[] {
15
17
  if (!orderField) {
16
18
  return items
17
19
  }
18
20
 
21
+ if (!Array.isArray(items)) {
22
+ return []
23
+ }
19
24
  return [...items].sort((a, b) => {
20
- const aField = (a as Record<string, unknown>)[orderField] as FieldRef<number> | undefined
21
- const bField = (b as Record<string, unknown>)[orderField] as FieldRef<number> | undefined
25
+ const aField = (a as unknown as Record<string, unknown>)[orderField] as FieldAccessor<number> | undefined
26
+ const bField = (b as unknown as Record<string, unknown>)[orderField] as FieldAccessor<number> | undefined
22
27
 
23
28
  const aValue = aField?.value ?? Number.MAX_SAFE_INTEGER
24
29
  const bValue = bField?.value ?? Number.MAX_SAFE_INTEGER