@firecms/core 3.0.1 → 3.1.0-canary.1df3b2c

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 (170) hide show
  1. package/README.md +1 -1
  2. package/dist/components/AIIcon.d.ts +16 -0
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
  6. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
  7. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
  8. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
  9. package/dist/components/EntityCollectionView/Board.d.ts +2 -0
  10. package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
  11. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
  12. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
  13. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
  14. package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
  15. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
  16. package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
  17. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
  18. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
  19. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
  20. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +49 -0
  21. package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
  22. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
  23. package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
  24. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
  25. package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
  26. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +2 -0
  27. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  28. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
  29. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
  30. package/dist/components/VirtualTable/types.d.ts +2 -0
  31. package/dist/components/index.d.ts +3 -0
  32. package/dist/contexts/index.d.ts +10 -0
  33. package/dist/core/DrawerNavigationGroup.d.ts +45 -0
  34. package/dist/core/index.d.ts +1 -0
  35. package/dist/form/validation.d.ts +3 -2
  36. package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
  37. package/dist/hooks/useCollapsedGroups.d.ts +4 -1
  38. package/dist/index.es.js +5239 -1590
  39. package/dist/index.es.js.map +1 -1
  40. package/dist/index.umd.js +5233 -1585
  41. package/dist/index.umd.js.map +1 -1
  42. package/dist/preview/PropertyPreviewProps.d.ts +5 -0
  43. package/dist/preview/components/DatePreview.d.ts +13 -3
  44. package/dist/preview/components/ImagePreview.d.ts +5 -1
  45. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  46. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  47. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
  48. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
  49. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
  50. package/dist/types/collections.d.ts +42 -2
  51. package/dist/types/datasource.d.ts +0 -1
  52. package/dist/types/plugins.d.ts +46 -1
  53. package/dist/types/properties.d.ts +259 -4
  54. package/dist/util/__tests__/conditions.test.d.ts +1 -0
  55. package/dist/util/__tests__/objects.test.d.ts +1 -0
  56. package/dist/util/conditions.d.ts +26 -0
  57. package/dist/util/entities.d.ts +1 -2
  58. package/dist/util/index.d.ts +2 -1
  59. package/dist/util/property_utils.d.ts +2 -1
  60. package/dist/util/resolutions.d.ts +1 -1
  61. package/package.json +10 -7
  62. package/src/app/Scaffold.tsx +14 -15
  63. package/src/components/AIIcon.tsx +39 -0
  64. package/src/components/ArrayContainer.tsx +1 -4
  65. package/src/components/ClearFilterSortButton.tsx +19 -16
  66. package/src/components/ConfirmationDialog.tsx +0 -2
  67. package/src/components/DeleteEntityDialog.tsx +2 -4
  68. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
  69. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
  70. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
  71. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
  72. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
  73. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
  74. package/src/components/EntityCollectionView/Board.tsx +324 -0
  75. package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
  76. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
  77. package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
  78. package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
  79. package/src/components/EntityCollectionView/EntityCard.tsx +231 -0
  80. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +713 -0
  81. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
  82. package/src/components/EntityCollectionView/EntityCollectionView.tsx +485 -203
  83. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
  84. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
  85. package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
  86. package/src/components/EntityCollectionView/ViewModeToggle.tsx +202 -0
  87. package/src/components/EntityCollectionView/board_types.ts +113 -0
  88. package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
  89. package/src/components/ErrorTooltip.tsx +2 -1
  90. package/src/components/HomePage/DefaultHomePage.tsx +47 -10
  91. package/src/components/HomePage/HomePageDnD.tsx +56 -41
  92. package/src/components/HomePage/NavigationCard.tsx +20 -18
  93. package/src/components/HomePage/NavigationGroup.tsx +17 -16
  94. package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
  95. package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
  96. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
  97. package/src/components/ReferenceWidget.tsx +2 -4
  98. package/src/components/SelectableTable/SelectableTable.tsx +75 -67
  99. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
  100. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
  101. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
  102. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
  103. package/src/components/UnsavedChangesDialog.tsx +0 -2
  104. package/src/components/UserDisplay.tsx +4 -4
  105. package/src/components/VirtualTable/VirtualTable.tsx +170 -19
  106. package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
  107. package/src/components/VirtualTable/VirtualTableHeader.tsx +20 -11
  108. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
  109. package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
  110. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  111. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
  112. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +17 -4
  113. package/src/components/VirtualTable/types.tsx +2 -0
  114. package/src/components/common/useColumnsIds.tsx +95 -3
  115. package/src/components/index.tsx +4 -0
  116. package/src/contexts/BreacrumbsContext.tsx +15 -8
  117. package/src/contexts/index.ts +10 -0
  118. package/src/core/DefaultAppBar.tsx +39 -26
  119. package/src/core/DefaultDrawer.tsx +42 -56
  120. package/src/core/DrawerNavigationGroup.tsx +118 -0
  121. package/src/core/DrawerNavigationItem.tsx +4 -3
  122. package/src/core/EntityEditView.tsx +41 -43
  123. package/src/core/SideDialogs.tsx +4 -2
  124. package/src/core/index.tsx +1 -0
  125. package/src/form/PropertyFieldBinding.tsx +58 -43
  126. package/src/form/components/StorageItemPreview.tsx +2 -1
  127. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
  128. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
  129. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
  130. package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
  131. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +21 -17
  132. package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
  133. package/src/form/validation.ts +245 -160
  134. package/src/hooks/useBreadcrumbsController.tsx +18 -0
  135. package/src/hooks/useBuildNavigationController.tsx +42 -19
  136. package/src/hooks/useCollapsedGroups.ts +12 -4
  137. package/src/internal/useBuildDataSource.ts +69 -34
  138. package/src/internal/useBuildSideDialogsController.tsx +11 -8
  139. package/src/internal/useBuildSideEntityController.tsx +2 -4
  140. package/src/internal/useRestoreScroll.tsx +26 -14
  141. package/src/preview/PropertyPreview.tsx +40 -32
  142. package/src/preview/PropertyPreviewProps.tsx +6 -0
  143. package/src/preview/components/DatePreview.tsx +72 -4
  144. package/src/preview/components/EmptyValue.tsx +1 -1
  145. package/src/preview/components/ImagePreview.tsx +37 -21
  146. package/src/preview/components/StorageThumbnail.tsx +16 -12
  147. package/src/preview/components/UrlComponentPreview.tsx +28 -25
  148. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
  149. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
  150. package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
  151. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
  152. package/src/routes/CustomCMSRoute.tsx +1 -0
  153. package/src/routes/FireCMSRoute.tsx +26 -13
  154. package/src/types/collections.ts +48 -3
  155. package/src/types/datasource.ts +54 -56
  156. package/src/types/plugins.tsx +51 -1
  157. package/src/types/properties.ts +347 -27
  158. package/src/util/__tests__/conditions.test.ts +506 -0
  159. package/src/util/__tests__/objects.test.ts +196 -0
  160. package/src/util/callbacks.ts +6 -3
  161. package/src/util/collections.ts +51 -6
  162. package/src/util/conditions.ts +339 -0
  163. package/src/util/entities.ts +28 -29
  164. package/src/util/entity_cache.ts +2 -1
  165. package/src/util/index.ts +2 -1
  166. package/src/util/objects.ts +31 -13
  167. package/src/util/{references.ts → previews.ts} +14 -0
  168. package/src/util/property_utils.tsx +36 -10
  169. package/src/util/resolutions.ts +57 -55
  170. /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
@@ -7,7 +7,7 @@ import { FieldProps, FormContext } from "./fields";
7
7
  import { CMSType, Property } from "./properties";
8
8
  import { EntityStatus } from "./entities";
9
9
  import { ResolvedProperty } from "./resolved_entities";
10
- import { NavigationGroupMapping } from "./navigation";
10
+ import { NavigationGroupMapping, CMSView } from "./navigation";
11
11
  import { InternalUserManagement } from "./internal_user_management";
12
12
 
13
13
  /**
@@ -46,6 +46,12 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
46
46
 
47
47
  userManagement?: InternalUserManagement
48
48
 
49
+ /**
50
+ * Views to be automatically added to the navigation.
51
+ * These views will be merged with the views provided to useBuildNavigationController.
52
+ */
53
+ views?: CMSView[];
54
+
49
55
  homePage?: {
50
56
 
51
57
  /**
@@ -161,6 +167,50 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
161
167
  collection: EC;
162
168
  tableController: EntityTableController;
163
169
  }>;
170
+
171
+ /**
172
+ * Callback called when columns are reordered via drag and drop.
173
+ * Used by plugins to persist the new column order.
174
+ */
175
+ onColumnsReorder?: (props: {
176
+ fullPath: string;
177
+ parentCollectionIds: string[];
178
+ collection: EC;
179
+ newPropertiesOrder: string[];
180
+ }) => void;
181
+
182
+ /**
183
+ * Callback called when Kanban board columns are reordered via drag and drop.
184
+ * Used by plugins to persist the new Kanban column order.
185
+ */
186
+ onKanbanColumnsReorder?: (props: {
187
+ fullPath: string;
188
+ parentCollectionIds: string[];
189
+ collection: EC;
190
+ kanbanColumnProperty: string;
191
+ newColumnsOrder: string[];
192
+ }) => void;
193
+
194
+ /**
195
+ * Component to render when Kanban view is missing configuration.
196
+ * Used to provide a CTA to open the collection editor to configure Kanban.
197
+ */
198
+ KanbanSetupComponent?: React.ComponentType<{
199
+ collection: EC;
200
+ fullPath: string;
201
+ parentCollectionIds: string[];
202
+ }>;
203
+
204
+ /**
205
+ * Component to render an "Add Column" button at the end of the Kanban board.
206
+ * Used to allow adding new enum values to the column property.
207
+ */
208
+ AddKanbanColumnComponent?: React.ComponentType<{
209
+ collection: EC;
210
+ fullPath: string;
211
+ parentCollectionIds: string[];
212
+ columnProperty: string;
213
+ }>;
164
214
  }
165
215
 
166
216
  form?: {
@@ -12,14 +12,14 @@ import { AuthController } from "./auth";
12
12
  */
13
13
  export type DataType<T extends CMSType = CMSType> =
14
14
  T extends string ? "string" :
15
- T extends number ? "number" :
16
- T extends boolean ? "boolean" :
17
- T extends Date ? "date" :
18
- T extends GeoPoint ? "geopoint" :
19
- T extends Vector ? "vector" :
20
- T extends EntityReference ? "reference" :
21
- T extends Array<any> ? "array" :
22
- T extends Record<string, any> ? "map" : never;
15
+ T extends number ? "number" :
16
+ T extends boolean ? "boolean" :
17
+ T extends Date ? "date" :
18
+ T extends GeoPoint ? "geopoint" :
19
+ T extends Vector ? "vector" :
20
+ T extends EntityReference ? "reference" :
21
+ T extends Array<any> ? "array" :
22
+ T extends Record<string, any> ? "map" : never;
23
23
 
24
24
  /**
25
25
  * @group Entity properties
@@ -52,13 +52,13 @@ export type AnyProperty =
52
52
  */
53
53
  export type Property<T extends CMSType = any> =
54
54
  T extends string ? StringProperty :
55
- T extends number ? NumberProperty :
56
- T extends boolean ? BooleanProperty :
57
- T extends Date ? DateProperty :
58
- T extends GeoPoint ? GeopointProperty :
59
- T extends EntityReference ? ReferenceProperty :
60
- T extends Array<CMSType> ? ArrayProperty<T> :
61
- T extends Record<string, any> ? MapProperty<T> : AnyProperty;
55
+ T extends number ? NumberProperty :
56
+ T extends boolean ? BooleanProperty :
57
+ T extends Date ? DateProperty :
58
+ T extends GeoPoint ? GeopointProperty :
59
+ T extends EntityReference ? ReferenceProperty :
60
+ T extends Array<CMSType> ? ArrayProperty<T> :
61
+ T extends Record<string, any> ? MapProperty<T> : AnyProperty;
62
62
 
63
63
  /**
64
64
  * Interface including all common properties of a CMS property
@@ -167,6 +167,19 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
167
167
  * It defaults to 100, but you can set it to 50 to have two fields in the same row.
168
168
  */
169
169
  widthPercentage?: number;
170
+
171
+ /**
172
+ * Declarative conditions for dynamic property behavior using JSON Logic.
173
+ *
174
+ * An alternative to PropertyBuilder functions that can be:
175
+ * - Stored in the database as JSON
176
+ * - Edited via the collection editor UI
177
+ * - Evaluated at runtime like property builders
178
+ *
179
+ * @see PropertyConditions for available condition options
180
+ * @see https://jsonlogic.com/ for JSON Logic syntax
181
+ */
182
+ conditions?: PropertyConditions;
170
183
  }
171
184
 
172
185
  /**
@@ -195,6 +208,281 @@ export interface PropertyDisabledConfig {
195
208
  hidden?: boolean;
196
209
  }
197
210
 
211
+ /**
212
+ * A JSON Logic rule that gets evaluated at runtime.
213
+ * @see https://jsonlogic.com/
214
+ *
215
+ * Common operators:
216
+ * - Comparison: ==, !=, ===, !==, >, <, >=, <=
217
+ * - Logic: and, or, !, !!
218
+ * - Data access: var, missing, missing_some
219
+ * - Array: in, map, filter, reduce, all, some, none, merge
220
+ * - String: substr, cat
221
+ * - Numeric: +, -, *, /, %, min, max
222
+ *
223
+ * Custom operators:
224
+ * - hasRole(roleId) - check if user has role by ID
225
+ * - hasAnyRole([roleIds]) - check if user has any of the roles
226
+ * - isToday(timestamp) - check if timestamp is today
227
+ * - isPast(timestamp) - check if timestamp is in the past
228
+ * - isFuture(timestamp) - check if timestamp is in the future
229
+ *
230
+ * @group Entity properties
231
+ */
232
+ export type JsonLogicRule = Record<string, any>;
233
+
234
+ /**
235
+ * Conditions for individual enum values within a property.
236
+ * @group Entity properties
237
+ */
238
+ export interface EnumValueConditions {
239
+ /**
240
+ * Disable this enum option when condition is true.
241
+ * The option appears grayed out and cannot be selected.
242
+ */
243
+ disabled?: JsonLogicRule;
244
+
245
+ /**
246
+ * Message explaining why this option is disabled.
247
+ */
248
+ disabledMessage?: string;
249
+
250
+ /**
251
+ * Completely hide this enum option when condition is true.
252
+ * The option is removed from the dropdown/list.
253
+ */
254
+ hidden?: JsonLogicRule;
255
+ }
256
+
257
+ /**
258
+ * Declarative conditions for dynamic property behavior.
259
+ * All conditions are JSON Logic rules evaluated against ConditionContext.
260
+ *
261
+ * An alternative to PropertyBuilder functions that can be:
262
+ * - Stored in the database as JSON
263
+ * - Edited via the collection editor UI
264
+ * - Evaluated at runtime like property builders
265
+ *
266
+ * @see https://jsonlogic.com/ for JSON Logic syntax
267
+ * @group Entity properties
268
+ */
269
+ export interface PropertyConditions {
270
+
271
+ // ═══════════════════════════════════════════════════════════════════════
272
+ // FIELD STATE CONDITIONS
273
+ // ═══════════════════════════════════════════════════════════════════════
274
+
275
+ /**
276
+ * Disable the field when this condition evaluates to true.
277
+ * The field becomes non-editable but still visible (unless also hidden).
278
+ *
279
+ * @example Disable when another field has a specific value
280
+ * ```json
281
+ * { "==": [{ "var": "values.status" }, "archived"] }
282
+ * ```
283
+ */
284
+ disabled?: JsonLogicRule;
285
+
286
+ /**
287
+ * Message to display when the field is disabled by a condition.
288
+ */
289
+ disabledMessage?: string;
290
+
291
+ /**
292
+ * Clear the field's value when it becomes disabled.
293
+ * @default false
294
+ */
295
+ clearOnDisabled?: boolean;
296
+
297
+ /**
298
+ * Hide the field completely when this condition evaluates to true.
299
+ * The field is removed from the form (not just visually hidden).
300
+ */
301
+ hidden?: JsonLogicRule;
302
+
303
+ /**
304
+ * Make the field read-only when this condition evaluates to true.
305
+ * Renders as a preview instead of an input.
306
+ */
307
+ readOnly?: JsonLogicRule;
308
+
309
+ // ═══════════════════════════════════════════════════════════════════════
310
+ // VALIDATION CONDITIONS
311
+ // ═══════════════════════════════════════════════════════════════════════
312
+
313
+ /**
314
+ * Make the field required when this condition evaluates to true.
315
+ * Overrides the static `validation.required` setting.
316
+ */
317
+ required?: JsonLogicRule;
318
+
319
+ /**
320
+ * Custom message when conditional required validation fails.
321
+ */
322
+ requiredMessage?: string;
323
+
324
+ /**
325
+ * Dynamic minimum value for number/string length.
326
+ * Should evaluate to a number.
327
+ */
328
+ min?: JsonLogicRule;
329
+
330
+ /**
331
+ * Dynamic maximum value for number/string length.
332
+ * Should evaluate to a number.
333
+ */
334
+ max?: JsonLogicRule;
335
+
336
+ // ═══════════════════════════════════════════════════════════════════════
337
+ // VALUE CONDITIONS
338
+ // ═══════════════════════════════════════════════════════════════════════
339
+
340
+ /**
341
+ * Dynamic default value for new entities.
342
+ * Should evaluate to a value of the appropriate type for the field.
343
+ * Only applied when entityId is empty (new entity).
344
+ */
345
+ defaultValue?: JsonLogicRule;
346
+
347
+ // ═══════════════════════════════════════════════════════════════════════
348
+ // ENUM CONDITIONS (for string/number properties with enumValues)
349
+ // ═══════════════════════════════════════════════════════════════════════
350
+
351
+ /**
352
+ * Conditions for individual enum values.
353
+ * Keys are the enum value IDs, values are condition configs.
354
+ *
355
+ * @example Disable certain enum options based on user role
356
+ * ```json
357
+ * {
358
+ * "admin": {
359
+ * "disabled": { "!": { "hasRole": "admin" } },
360
+ * "disabledMessage": "Admin option requires admin role"
361
+ * }
362
+ * }
363
+ * ```
364
+ */
365
+ enumConditions?: Record<string | number, EnumValueConditions>;
366
+
367
+ /**
368
+ * Filter which enum values are available.
369
+ * Should evaluate to an array of allowed enum value IDs.
370
+ */
371
+ allowedEnumValues?: JsonLogicRule;
372
+
373
+ /**
374
+ * Exclude specific enum values.
375
+ * Should evaluate to an array of enum value IDs to exclude.
376
+ */
377
+ excludedEnumValues?: JsonLogicRule;
378
+
379
+ // ═══════════════════════════════════════════════════════════════════════
380
+ // REFERENCE CONDITIONS (for reference properties)
381
+ // ═══════════════════════════════════════════════════════════════════════
382
+
383
+ /**
384
+ * Dynamic path for reference properties.
385
+ * Should evaluate to a collection path string.
386
+ */
387
+ referencePath?: JsonLogicRule;
388
+
389
+ /**
390
+ * Dynamic filter for reference selection.
391
+ * Should evaluate to a FilterValues object.
392
+ */
393
+ referenceFilter?: JsonLogicRule;
394
+
395
+ // ═══════════════════════════════════════════════════════════════════════
396
+ // ARRAY CONDITIONS (for array properties)
397
+ // ═══════════════════════════════════════════════════════════════════════
398
+
399
+ /**
400
+ * Can elements be added to the array?
401
+ */
402
+ canAddElements?: JsonLogicRule;
403
+
404
+ /**
405
+ * Can elements be reordered in the array?
406
+ */
407
+ sortable?: JsonLogicRule;
408
+
409
+ // ═══════════════════════════════════════════════════════════════════════
410
+ // STORAGE CONDITIONS (for file upload properties)
411
+ // ═══════════════════════════════════════════════════════════════════════
412
+
413
+ /**
414
+ * Dynamic accepted file types.
415
+ * Should evaluate to an array of MIME types.
416
+ */
417
+ acceptedFiles?: JsonLogicRule;
418
+
419
+ /**
420
+ * Dynamic maximum file size in bytes.
421
+ * Should evaluate to a number.
422
+ */
423
+ maxFileSize?: JsonLogicRule;
424
+ }
425
+
426
+ /**
427
+ * Context available during JSON Logic condition evaluation.
428
+ * Mirrors PropertyBuilderProps but adapted for JSON serialization.
429
+ * @group Entity properties
430
+ */
431
+ export interface ConditionContext {
432
+ /**
433
+ * Current form/entity values.
434
+ * Date values are converted to Unix timestamps (milliseconds).
435
+ */
436
+ values: Record<string, any>;
437
+
438
+ /**
439
+ * Previous values before the current edit session.
440
+ */
441
+ previousValues: Record<string, any>;
442
+
443
+ /**
444
+ * Current value of this property specifically.
445
+ */
446
+ propertyValue: any;
447
+
448
+ /**
449
+ * Collection path (e.g., "products", "users/uid123/orders")
450
+ */
451
+ path: string;
452
+
453
+ /**
454
+ * Entity ID. Undefined for new entities.
455
+ */
456
+ entityId?: string;
457
+
458
+ /**
459
+ * Whether this is a new entity being created.
460
+ */
461
+ isNew: boolean;
462
+
463
+ /**
464
+ * Index of this property (only for array items).
465
+ */
466
+ index?: number;
467
+
468
+ /**
469
+ * Current authenticated user information.
470
+ */
471
+ user: {
472
+ uid: string;
473
+ email: string | null;
474
+ displayName: string | null;
475
+ photoURL: string | null;
476
+ /** Role IDs the user has (extracted from Role[].id) */
477
+ roles: string[];
478
+ };
479
+
480
+ /**
481
+ * Current timestamp as Unix milliseconds.
482
+ */
483
+ now: number;
484
+ }
485
+
198
486
  /**
199
487
  * @group Entity properties
200
488
  */
@@ -290,14 +578,14 @@ export type PropertyBuilderProps<M extends Record<string, any> = any> =
290
578
  */
291
579
  export type PropertyBuilder<T extends CMSType = any, M extends Record<string, any> = any> =
292
580
  ({
293
- values,
294
- previousValues,
295
- propertyValue,
296
- index,
297
- path,
298
- entityId,
299
- authController
300
- }: PropertyBuilderProps<M>) => Property<T> | null;
581
+ values,
582
+ previousValues,
583
+ propertyValue,
584
+ index,
585
+ path,
586
+ entityId,
587
+ authController
588
+ }: PropertyBuilderProps<M>) => Property<T> | null;
301
589
 
302
590
  /**
303
591
  * @group Entity properties
@@ -353,6 +641,27 @@ export interface BooleanProperty extends BaseProperty<boolean> {
353
641
 
354
642
  }
355
643
 
644
+ /**
645
+ * Configuration options for the markdown editor.
646
+ * @group Entity properties
647
+ */
648
+ export interface MarkdownConfig {
649
+ /**
650
+ * Allow HTML input/output. When set to false, HTML tags in pasted content
651
+ * will be stripped and only markdown-compatible formatting will be preserved.
652
+ * Defaults to true for backwards compatibility.
653
+ */
654
+ html?: boolean;
655
+
656
+ /**
657
+ * Convert pasted text to markdown format. When enabled, rich text pasted
658
+ * from external sources (like Google Docs or Word) will be converted to
659
+ * clean markdown instead of preserving HTML styles.
660
+ * Defaults to false.
661
+ */
662
+ transformPastedText?: boolean;
663
+ }
664
+
356
665
  /**
357
666
  * @group Entity properties
358
667
  */
@@ -369,10 +678,13 @@ export interface StringProperty extends BaseProperty<string> {
369
678
 
370
679
  /**
371
680
  * Should this string property be displayed as a markdown field. If true,
372
- * the field is rendered as a text editors that supports markdown highlight
681
+ * the field is rendered as a text editor that supports markdown highlight
373
682
  * syntax. It also includes a preview of the result.
683
+ *
684
+ * You can also pass a configuration object to customize the markdown editor
685
+ * behavior, particularly how HTML content is handled during paste operations.
374
686
  */
375
- markdown?: boolean;
687
+ markdown?: boolean | MarkdownConfig;
376
688
 
377
689
  /**
378
690
  * You can use the enum values providing a map of possible
@@ -620,6 +932,14 @@ export interface DateProperty extends BaseProperty<Date> {
620
932
  * Add an icon to clear the value and set it to `null`. Defaults to `false`
621
933
  */
622
934
  clearable?: boolean;
935
+
936
+ /**
937
+ * IANA timezone string (e.g., "America/New_York", "Europe/London").
938
+ * Used to display and input dates in the specified timezone.
939
+ * The value stored will always be in UTC.
940
+ * If not provided, uses the user's local timezone.
941
+ */
942
+ timezone?: string;
623
943
  }
624
944
 
625
945
  /**
@@ -951,7 +1271,7 @@ export interface ImageResize {
951
1271
  * - `contain`: Scale down to fit within bounds, preserving aspect ratio (default)
952
1272
  * - `cover`: Scale to fill bounds, preserving aspect ratio (may crop)
953
1273
  */
954
- mode?: 'contain' | 'cover';
1274
+ mode?: "contain" | "cover";
955
1275
 
956
1276
  /**
957
1277
  * Output format for the resized image.
@@ -960,7 +1280,7 @@ export interface ImageResize {
960
1280
  * - `png`: Convert to PNG
961
1281
  * - `webp`: Convert to WebP
962
1282
  */
963
- format?: 'original' | 'jpeg' | 'png' | 'webp';
1283
+ format?: "original" | "jpeg" | "png" | "webp";
964
1284
 
965
1285
  /**
966
1286
  * Quality for lossy formats (JPEG, WebP). Number between 0 and 100.